HitResponse Brick::collision(GameObject& other, const CollisionHit& hit_){ Player* player = dynamic_cast<Player*> (&other); if (player) { if (player->does_buttjump) try_break(player); } BadGuy* badguy = dynamic_cast<BadGuy*> (&other); if(badguy) { // hit contains no information for collisions with blocks. // Badguy's bottom has to be below the top of the brick // SHIFT_DELTA is required to slide over one tile gaps. if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){ try_break(player); } } Portable* portable = dynamic_cast<Portable*> (&other); if(portable) { MovingObject* moving = dynamic_cast<MovingObject*> (&other); if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) { try_break(player); } } Explosion* explosion = dynamic_cast<Explosion*> (&other); if(explosion && explosion->hurts()) { try_break(player); } return Block::collision(other, hit_); }
void Kugelblitz::try_activate() { // Much smaller offscreen distances to pop out of nowhere and surprise Tux float X_OFFSCREEN_DISTANCE = 400; float Y_OFFSCREEN_DISTANCE = 600; Player* player = get_nearest_player(); if (!player) return; Vector dist = player->get_bbox().get_middle() - get_bbox().get_middle(); if ((fabsf(dist.x) <= X_OFFSCREEN_DISTANCE) && (fabsf(dist.y) <= Y_OFFSCREEN_DISTANCE)) { set_state(STATE_ACTIVE); if (!is_initialized) { // if starting direction was set to AUTO, this is our chance to re-orient the badguy if (start_dir == AUTO) { Player* player = get_nearest_player(); if (player && (player->get_bbox().p1.x > get_bbox().p2.x)) { dir = RIGHT; } else { dir = LEFT; } } initialize(); is_initialized = true; } activate(); } }
void Yeti::drop_stalactite() { // make a stalactite falling down and shake camera a bit Sector::current()->camera->shake(.1f, 0, 10); auto player = get_nearest_player(); if (!player) return; Sector* sector = Sector::current(); for(const auto& obj : sector->gameobjects) { auto stalactite = dynamic_cast<YetiStalactite*>(obj.get()); if(stalactite && stalactite->is_hanging()) { if (hit_points >= 3) { // drop stalactites within 3 of player, going out with each jump float distancex = fabsf(stalactite->get_bbox().get_middle().x - player->get_bbox().get_middle().x); if(distancex < stomp_count*32) { stalactite->start_shaking(); } } else { /* if (hitpoints < 3) */ // drop every 3rd pair of stalactites if(((((int)stalactite->get_pos().x + 16) / 64) % 3) == (stomp_count % 3)) { stalactite->start_shaking(); } } } /* if(stalactite && stalactite->is_hanging()) */ } }
void Toad::set_state(ToadState newState) { if (newState == IDLE) { physic.set_velocity_x(0); physic.set_velocity_y(0); if (!frozen) sprite->set_action(dir == LEFT ? "idle-left" : "idle-right"); recover_timer.start(TOAD_RECOVER_TIME); } else if (newState == JUMPING) { sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right"); physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED); physic.set_velocity_y(VERTICAL_SPEED); SoundManager::current()->play( HOP_SOUND, get_pos()); } else if (newState == FALLING) { Player* player = get_nearest_player(); // face player if (player && (player->get_bbox().p2.x < get_bbox().p1.x) && (dir == RIGHT)) dir = LEFT; if (player && (player->get_bbox().p1.x > get_bbox().p2.x) && (dir == LEFT)) dir = RIGHT; sprite->set_action(dir == LEFT ? "idle-left" : "idle-right"); } state = newState; }
void Stalactite::active_update(float elapsed_time) { if(state == STALACTITE_HANGING) { auto player = get_nearest_player(); if (player && !player->get_ghost_mode()) { if(player->get_bbox().p2.x > bbox.p1.x - SHAKE_RANGE_X && player->get_bbox().p1.x < bbox.p2.x + SHAKE_RANGE_X && player->get_bbox().p2.y > bbox.p1.y && player->get_bbox().p1.y < bbox.p2.y + SHAKE_RANGE_Y && Sector::current()->can_see_player(bbox.get_middle())) { timer.start(SHAKE_TIME); state = STALACTITE_SHAKING; SoundManager::current()->play("sounds/cracking.wav", get_pos()); } } } else if(state == STALACTITE_SHAKING) { shake_delta = Vector(static_cast<float>(graphicsRandom.rand(-3, 3)), 0.0f); if(timer.check()) { state = STALACTITE_FALLING; physic.enable_gravity(true); set_colgroup_active(COLGROUP_MOVING); } } else if(state == STALACTITE_FALLING) { movement = physic.get_movement(elapsed_time); } }
HitResponse BonusBlock::collision(GameObject& other, const CollisionHit& hit_){ auto player = dynamic_cast<Player*> (&other); if (player) { if (player->does_buttjump) try_drop(player); } auto badguy = dynamic_cast<BadGuy*> (&other); if(badguy) { // hit contains no information for collisions with blocks. // Badguy's bottom has to be below the top of the block // SHIFT_DELTA is required to slide over one tile gaps. if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > bbox.get_top() + SHIFT_DELTA ) ){ try_open(player); } } auto portable = dynamic_cast<Portable*> (&other); if(portable) { auto moving = dynamic_cast<MovingObject*> (&other); if(moving->get_bbox().get_top() > bbox.get_bottom() - SHIFT_DELTA) { try_open(player); } } return Block::collision(other, hit_); }
/* ** msRotateSymbol - Clockwise rotation of a symbol definition. Contributed ** by MapMedia, with clean up by SDL. Currently only type VECTOR and PIXMAP ** symbols are handled. */ symbolObj *msRotateVectorSymbol(symbolObj *symbol, double angle) { double angle_rad=0.0; double cos_a, sin_a; double minx=0.0, miny=0.0, maxx=0.0, maxy=0.0; symbolObj *newSymbol = NULL; double dp_x, dp_y, xcor, ycor; double TOL=0.00000000001; int i; /* assert(symbol->type == MS_SYMBOL_VECTOR); */ newSymbol = (symbolObj *) malloc(sizeof(symbolObj)); msCopySymbol(newSymbol, symbol, NULL); /* TODO: do we really want to do this for all symbol types? */ angle_rad = (MS_DEG_TO_RAD*angle); sin_a = sin(angle_rad); cos_a = cos(angle_rad); dp_x = symbol->sizex * .5; /* get the shift vector at 0,0 */ dp_y = symbol->sizey * .5; /* center at 0,0 and rotate; then move back */ for( i=0; i < symbol->numpoints; i++) { /* don't rotate PENUP commands (TODO: should use a constant here) */ if ((symbol->points[i].x == -99.0) || (symbol->points[i].x == -99.0) ) { newSymbol->points[i].x = -99.0; newSymbol->points[i].y = -99.0; continue; } newSymbol->points[i].x = dp_x + ((symbol->points[i].x-dp_x)*cos_a - (symbol->points[i].y-dp_y)*sin_a); newSymbol->points[i].y = dp_y + ((symbol->points[i].x-dp_x)*sin_a + (symbol->points[i].y-dp_y)*cos_a); } /* get the new bbox of the symbol, because we need it to get the new dimensions of the new symbol */ get_bbox(newSymbol->points, newSymbol->numpoints, &minx, &miny, &maxx, &maxy); if ( (fabs(minx)>TOL) || (fabs(miny)>TOL) ) { xcor = minx*-1.0; /* symbols always start at 0,0 so get the shift vector */ ycor = miny*-1.0; for( i=0; i < newSymbol->numpoints; i++) { if ((newSymbol->points[i].x == -99.0) || (newSymbol->points[i].x == -99.0)) continue; newSymbol->points[i].x = newSymbol->points[i].x + xcor; newSymbol->points[i].y = newSymbol->points[i].y + ycor; } /* update the bbox to get the final dimension values for the symbol */ get_bbox(newSymbol->points, newSymbol->numpoints, &minx, &miny, &maxx, &maxy); } newSymbol->sizex = maxx; newSymbol->sizey = maxy; return newSymbol; }
bool MrTree::collision_squished(GameObject& object) { // replace with Stumpy Vector stumpy_pos = get_pos(); stumpy_pos.x += 20; stumpy_pos.y += 25; auto stumpy = std::make_shared<Stumpy>(stumpy_pos, dir); remove_me(); Sector::current()->add_object(stumpy); // give Feedback SoundManager::current()->play("sounds/mr_tree.ogg", get_pos()); Player* player = dynamic_cast<Player*>(&object); if (player) player->bounce(*this); // spawn some particles // TODO: provide convenience function in MovingSprite or MovingObject? for (int px = (int)stumpy->get_bbox().p1.x; px < (int)stumpy->get_bbox().p2.x; px+=10) { Vector ppos = Vector(px, stumpy->get_bbox().p1.y-5); float angle = graphicsRandom.randf(-M_PI_2, M_PI_2); float velocity = graphicsRandom.randf(45, 90); float vx = sin(angle)*velocity; float vy = -cos(angle)*velocity; Vector pspeed = Vector(vx, vy); Vector paccel = Vector(0, Sector::current()->get_gravity()*10); Sector::current()->add_object(std::make_shared<SpriteParticle>("images/objects/particles/leaf.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1)); } if (!frozen){ //Frozen Mr.Trees don't spawn any PoisonIvys. // spawn PoisonIvy Vector leaf1_pos(stumpy_pos.x - POISONIVY_WIDTH - 1, stumpy_pos.y - POISONIVY_Y_OFFSET); Rectf leaf1_bbox(leaf1_pos.x, leaf1_pos.y, leaf1_pos.x + POISONIVY_WIDTH, leaf1_pos.y + POISONIVY_HEIGHT); if (Sector::current()->is_free_of_movingstatics(leaf1_bbox, this)) { auto leaf1 = std::make_shared<PoisonIvy>(leaf1_bbox.p1, LEFT); leaf1->countMe = false; Sector::current()->add_object(leaf1); } // spawn PoisonIvy Vector leaf2_pos(stumpy_pos.x + sprite->get_current_hitbox_width() + 1, stumpy_pos.y - POISONIVY_Y_OFFSET); Rectf leaf2_bbox(leaf2_pos.x, leaf2_pos.y, leaf2_pos.x + POISONIVY_WIDTH, leaf2_pos.y + POISONIVY_HEIGHT); if (Sector::current()->is_free_of_movingstatics(leaf2_bbox, this)) { auto leaf2 = std::make_shared<PoisonIvy>(leaf2_bbox.p1, RIGHT); leaf2->countMe = false; Sector::current()->add_object(leaf2); } } return true; }
graphics::color Gradient::color_at(posn point) const { if (contains(point)) { // Maps the bounding box to the unit square sample x = (point.x - get_bbox().left()) / get_bbox().width(); sample y = (point.y - get_bbox().top()) / get_bbox().height(); return color_at(x, y); } else { return color::transparent; } }
symbolObj* rotateVectorSymbolPoints(symbolObj *symbol, double angle_rad) { double dp_x, dp_y, xcor, ycor; double sin_a, cos_a; double minx,miny,maxx,maxy; symbolObj *newSymbol; double TOL=0.00000000001; int i; angle_rad = -angle_rad; newSymbol = (symbolObj *) msSmallMalloc(sizeof(symbolObj)); msCopySymbol(newSymbol, symbol, NULL); sin_a = sin(angle_rad); cos_a = cos(angle_rad); dp_x = symbol->sizex * .5; /* get the shift vector at 0,0 */ dp_y = symbol->sizey * .5; /* center at 0,0 and rotate; then move back */ for( i=0; i < symbol->numpoints; i++) { /* don't rotate PENUP commands (TODO: should use a constant here) */ if ((symbol->points[i].x == -99.0) && (symbol->points[i].y == -99.0) ) { newSymbol->points[i].x = -99.0; newSymbol->points[i].y = -99.0; continue; } newSymbol->points[i].x = dp_x + ((symbol->points[i].x-dp_x)*cos_a - (symbol->points[i].y-dp_y)*sin_a); newSymbol->points[i].y = dp_y + ((symbol->points[i].x-dp_x)*sin_a + (symbol->points[i].y-dp_y)*cos_a); } /* get the new bbox of the symbol, because we need it to get the new dimensions of the new symbol */ get_bbox(newSymbol->points, newSymbol->numpoints, &minx, &miny, &maxx, &maxy); if ( (fabs(minx)>TOL) || (fabs(miny)>TOL) ) { xcor = minx*-1.0; /* symbols always start at 0,0 so get the shift vector */ ycor = miny*-1.0; for( i=0; i < newSymbol->numpoints; i++) { if ((newSymbol->points[i].x == -99.0) && (newSymbol->points[i].y == -99.0)) continue; newSymbol->points[i].x = newSymbol->points[i].x + xcor; newSymbol->points[i].y = newSymbol->points[i].y + ycor; } /* update the bbox to get the final dimension values for the symbol */ get_bbox(newSymbol->points, newSymbol->numpoints, &minx, &miny, &maxx, &maxy); } newSymbol->sizex = maxx; newSymbol->sizey = maxy; return newSymbol; }
void Star::draw(DrawingContext& context){ //Draw the Sprite. MovingSprite::draw(context); //Draw the light when dark context.get_light( get_bbox().get_middle(), &light ); if (light.red + light.green + light.blue < 3.0){ MovingSprite::draw(context); context.push_target(); context.set_target(DrawingContext::LIGHTMAP); lightsprite->draw(context, get_bbox().get_middle(), 0); context.pop_target(); } }
void Flower::draw(DrawingContext& context) { //Draw the Sprite. sprite->draw(context, get_pos(), LAYER_OBJECTS, drawing_effect); //Draw the light when dark context.get_light( get_bbox().get_middle(), &light ); if (light.red + light.green + light.blue < 3.0){ context.push_target(); context.set_target(DrawingContext::LIGHTMAP); lightsprite->draw(context, get_bbox().get_middle(), 0); context.pop_target(); } }
void Explosion::draw(DrawingContext& context) { //Draw the Sprite. sprite->draw(context, get_pos(), LAYER_OBJECTS+40); //Explosions produce light (if ambient light is not maxed) context.get_light( get_bbox().get_middle(), &light); if (light.red + light.green + light.blue < 3.0){ context.push_target(); context.set_target(DrawingContext::LIGHTMAP); lightsprite->draw(context, get_bbox().get_middle(), 0); context.pop_target(); } }
HitResponse BadGuy::collision(GameObject& other, const CollisionHit& hit) { if (!is_active()) return ABORT_MOVE; auto badguy = dynamic_cast<BadGuy*> (&other); if (badguy && badguy->is_active() && badguy->m_col.get_group() == COLGROUP_MOVING) { /* Badguys don't let badguys squish other badguys. It's bad. */ #if 0 // hit from above? if (badguy->get_bbox().get_bottom() < (bbox.get_top() + 16)) { if (collision_squished(*badguy)) { return ABORT_MOVE; } } #endif return collision_badguy(*badguy, hit); } auto player = dynamic_cast<Player*> (&other); if (player) { // hit from above? if (player->get_bbox().get_bottom() < (m_col.m_bbox.get_top() + 16)) { if (player->is_stone()) { kill_fall(); return FORCE_MOVE; } if (collision_squished(*player)) { return FORCE_MOVE; } } if (player->is_stone()) { collision_solid(hit); return FORCE_MOVE; } return collision_player(*player, hit); } auto bullet = dynamic_cast<Bullet*> (&other); if (bullet) return collision_bullet(*bullet, hit); return FORCE_MOVE; }
void Kugelblitz::draw(DrawingContext& context) { sprite->draw(context, get_pos(), layer); //Only draw light in dark areas context.get_light( get_bbox().get_middle(), &light ); if (light.red + light.green < 2.0){ context.push_target(); context.set_target(DrawingContext::LIGHTMAP); sprite->draw(context, get_pos(), layer); lightsprite->draw(context, get_bbox().get_middle(), 0); context.pop_target(); } }
bool InvisibleBlock::collides(GameObject& other, const CollisionHit& ) const { if(visible) return true; // if we're not visible, only register a collision if this will make us visible auto player = dynamic_cast<Player*> (&other); if ((player) && (player->get_movement().y <= 0) && (player->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA)) { return true; } return false; }
virtual void go() { release(); param *p = param::instance(); update_values(p); Iso_rectangle_2 bbox = get_bbox(p); std::string ndvi_file = p->get<boost::filesystem::path>("ndvi").string(); std::string dsm_file = p->get<boost::filesystem::path>("dsm" ).string(); clip_bbox(bbox,ndvi_file); clip_bbox(bbox,dsm_file ); gradient_functor gf(p->get<double>("sigmaD")); oriented_gradient_view grad_view(dsm_file, bbox, gf); oriented_ndvi_view ndvi_view(ndvi_file, bbox); m_confg_visitor->add_layer(ndvi_file); m_confg_visitor->add_layer(dsm_file); set_bbox(p,bbox); wxPoint p0(wxCoord(bbox.min().x()),wxCoord(bbox.min().y())); wxPoint p1(wxCoord(bbox.max().x()),wxCoord(bbox.max().y())); m_confg_visitor->set_bbox(wxRect(p0,p1)); init_visitor (p,*m_visitor); create_configuration(p,grad_view,ndvi_view,m_config); create_sampler (p,m_sampler); create_schedule (p,m_schedule); create_end_test (p,m_end_test); m_thread = new boost::thread( simulated_annealing::optimize<configuration,sampler,schedule,end_test,visitor>, boost::ref(*m_config), boost::ref(*m_sampler), boost::ref(*m_schedule), boost::ref(*m_end_test), boost::ref(*m_visitor) ); }
void BadGuy::try_activate() { // Don't activate if player is dying Player* player = get_nearest_player(); if (!player) return; if (!is_offscreen()) { set_state(STATE_ACTIVE); if (!is_initialized) { // if starting direction was set to AUTO, this is our chance to re-orient the badguy if (start_dir == AUTO) { Player* player_ = get_nearest_player(); if (player_ && (player_->get_bbox().p1.x > get_bbox().p2.x)) { dir = RIGHT; } else { dir = LEFT; } } initialize(); is_initialized = true; } activate(); } }
void Iceflame::draw(DrawingContext& context) { context.push_target(); //Rotate the Sprite (3 rotations per revolution) sprite->set_angle(angle * 360.0f / (2*M_PI) * 3); //Draw the Sprite. sprite->draw(context, get_pos(), LAYER_OBJECTS); //Draw the light if dark context.get_light( get_bbox().get_middle(), &light ); if (light.blue + light.green < 2.0){ context.set_target(DrawingContext::LIGHTMAP); lightsprite->draw(context, get_bbox().get_middle(), 0); } context.pop_target(); }
HitResponse BicyclePlatformChild::collision(GameObject& other, const CollisionHit& ) { const float gravity = Sector::get().get_gravity(); // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this: auto mo = dynamic_cast<MovingObject*>(&other); if (!mo) return FORCE_MOVE; if ((mo->get_bbox().get_bottom()) > (m_col.m_bbox.get_top() + 2)) return FORCE_MOVE; auto pl = dynamic_cast<Player*>(mo); if (pl) { if (pl->is_big()) m_momentum += m_parent.m_momentum_change_rate * gravity; auto po = pl->get_grabbed_object(); auto pomo = dynamic_cast<MovingObject*>(po); if (m_contacts.insert(pomo).second) { m_momentum += m_parent.m_momentum_change_rate * gravity; } } if (m_contacts.insert(&other).second) { m_momentum += m_parent.m_momentum_change_rate * Sector::get().get_gravity(); } return FORCE_MOVE; }
HitResponse Block::collision(GameObject& other, const CollisionHit& ) { Player* player = dynamic_cast<Player*> (&other); if(player) { if(player->get_bbox().get_top() > get_bbox().get_bottom() - 7.0) { hit(*player); } } // only interact with other objects if... // 1) we are bouncing // and // 2) the object is not portable (either never or not currently) Portable* portable = dynamic_cast<Portable*> (&other); if(bouncing && (portable == 0 || (!portable->is_portable()))) { // Badguys get killed BadGuy* badguy = dynamic_cast<BadGuy*> (&other); if(badguy) { badguy->kill_fall(); } // Coins get collected Coin* coin = dynamic_cast<Coin*> (&other); if(coin) { coin->collect(); } } return SOLID; }
static UINT calc_ppem_for_height(HDC hdc, LONG height) { BYTE os2[78]; /* size of version 0 table */ BYTE hhea[8]; /* just enough to get the ascender and descender */ LONG ascent = 0, descent = 0; UINT emsize; if(height < 0) return -height; if(GetFontData(hdc, MS_MAKE_TAG('O','S','/','2'), 0, os2, sizeof(os2)) == sizeof(os2)) { ascent = GET_BE_WORD(os2 + 74); /* usWinAscent */ descent = GET_BE_WORD(os2 + 76); /* usWinDescent */ } if(ascent + descent == 0) { if(GetFontData(hdc, MS_MAKE_TAG('h','h','e','a'), 0, hhea, sizeof(hhea)) == sizeof(hhea)) { ascent = (signed short)GET_BE_WORD(hhea + 4); /* Ascender */ descent = -(signed short)GET_BE_WORD(hhea + 6); /* Descender */ } } if(ascent + descent == 0) return height; get_bbox(hdc, NULL, &emsize); return MulDiv(emsize, height, ascent + descent); }
void Plant::active_update(float elapsed_time) { BadGuy::active_update(elapsed_time); if(state == PLANT_SLEEPING) { auto player = get_nearest_player(); if (player) { Rectf pb = player->get_bbox(); bool inReach_left = (pb.p2.x >= bbox.p2.x-((dir == LEFT) ? 256 : 0)); bool inReach_right = (pb.p1.x <= bbox.p1.x+((dir == RIGHT) ? 256 : 0)); bool inReach_top = (pb.p2.y >= bbox.p2.y); bool inReach_bottom = (pb.p1.y <= bbox.p1.y); if (inReach_left && inReach_right && inReach_top && inReach_bottom) { // wake up sprite->set_action(dir == LEFT ? "waking-left" : "waking-right"); if(!timer.started()) timer.start(WAKE_TIME); state = PLANT_WAKING; } } } if(state == PLANT_WAKING) { if(timer.check()) { // start walking sprite->set_action(dir == LEFT ? "left" : "right"); physic.set_velocity_x(dir == LEFT ? -PLANT_SPEED : PLANT_SPEED); state = PLANT_WALKING; } } }
void BadGuy::try_activate() { // Don't activate if player is dying auto player = get_nearest_player(); if (!player) return; if (!is_offscreen()) { set_state(STATE_ACTIVE); if (!m_is_initialized) { // if starting direction was set to AUTO, this is our chance to re-orient the badguy if (m_start_dir == Direction::AUTO) { auto player_ = get_nearest_player(); if (player_ && (player_->get_bbox().get_left() > m_col.m_bbox.get_right())) { m_dir = Direction::RIGHT; } else { m_dir = Direction::LEFT; } } initialize(); m_is_initialized = true; } activate(); } }
void Bullet::draw(DrawingContext& context) { //Draw the Sprite. sprite->draw(context, get_pos(), LAYER_OBJECTS); //Draw the light if fire and dark if(type == FIRE_BONUS){ context.get_light( get_bbox().get_middle(), &light ); if (light.red + light.green < 2.0){ context.push_target(); context.set_target(DrawingContext::LIGHTMAP); sprite->draw(context, get_pos(), LAYER_OBJECTS); lightsprite->draw(context, get_bbox().get_middle(), 0); context.pop_target(); } } }
void Player::position_grabbed_object() { MovingObject* moving_object = dynamic_cast<MovingObject*>(grabbed_object); assert(moving_object); // Position where we will hold the lower-inner corner Vector pos(get_bbox().get_left() + get_bbox().get_width()/2, get_bbox().get_top() + get_bbox().get_height()*0.66666); // Adjust to find the grabbed object's upper-left corner if (dir == LEFT) pos.x -= moving_object->get_bbox().get_width(); pos.y -= moving_object->get_bbox().get_height(); grabbed_object->grab(*this, pos, dir); }
void Player::collision_solid(const CollisionHit& hit) { if(hit.bottom) { if(physic.get_velocity_y() > 0) physic.set_velocity_y(0); on_ground_flag = true; floor_normal = hit.slope_normal; // Butt Jump landed if (does_buttjump) { does_buttjump = false; physic.set_velocity_y(-300); on_ground_flag = false; Sector::current()->add_object(std::make_shared<Particles>( Vector(get_bbox().p2.x, get_bbox().p2.y), 270+20, 270+40, Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f, LAYER_OBJECTS+1)); Sector::current()->add_object(std::make_shared<Particles>( Vector(get_bbox().p1.x, get_bbox().p2.y), 90-40, 90-20, Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f, LAYER_OBJECTS+1)); Sector::current()->camera->shake(.1f, 0, 5); } } else if(hit.top) { if(physic.get_velocity_y() < 0) physic.set_velocity_y(.2f); } if(hit.left || hit.right) { physic.set_velocity_x(0); } // crushed? if(hit.crush) { if(hit.left || hit.right) { kill(true); } else if(hit.top || hit.bottom) { kill(false); } } }
void Block::start_bounce(GameObject* hitter) { if(original_y == -1){ original_y = bbox.p1.y; } bouncing = true; bounce_dir = -BOUNCY_BRICK_SPEED; bounce_offset = 0; MovingObject* hitter_mo = dynamic_cast<MovingObject*>(hitter); if (hitter_mo) { float center_of_hitter = hitter_mo->get_bbox().get_middle().x; float offset = (get_bbox().get_middle().x - center_of_hitter)*2 / get_bbox().get_width(); sprite->set_angle(BUMP_ROTATION_ANGLE*offset); } }
/**************************************************************************** * PSDRV_WriteSetDownloadFont * * Write setfont for download font. * */ BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev) { char *ps_name; LPOUTLINETEXTMETRICA potm; DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL); DOWNLOAD *pdl; assert(physDev->font.fontloc == Download); potm = HeapAlloc(GetProcessHeap(), 0, len); GetOutlineTextMetricsA(physDev->hdc, len, potm); get_download_name(physDev, potm, &ps_name); if(physDev->font.fontinfo.Download == NULL) { RECT bbox; UINT emsize; if (!get_bbox(physDev, &bbox, &emsize)) { HeapFree(GetProcessHeap(), 0, potm); return FALSE; } if(!is_room_for_font(physDev)) PSDRV_EmptyDownloadList(physDev, TRUE); pdl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pdl)); pdl->ps_name = HeapAlloc(GetProcessHeap(), 0, strlen(ps_name)+1); strcpy(pdl->ps_name, ps_name); pdl->next = NULL; if(physDev->pi->ppd->TTRasterizer == RO_Type42) { pdl->typeinfo.Type42 = T42_download_header(physDev, ps_name, &bbox, emsize); pdl->type = Type42; } if(pdl->typeinfo.Type42 == NULL) { pdl->typeinfo.Type1 = T1_download_header(physDev, ps_name, &bbox, emsize); pdl->type = Type1; } pdl->next = physDev->downloaded_fonts; physDev->downloaded_fonts = pdl; physDev->font.fontinfo.Download = pdl; if(pdl->type == Type42) { char g_name[MAX_G_NAME + 1]; get_glyph_name(physDev->hdc, 0, g_name); T42_download_glyph(physDev, pdl, 0, g_name); } } PSDRV_WriteSetFont(physDev, ps_name, physDev->font.size, physDev->font.escapement); HeapFree(GetProcessHeap(), 0, ps_name); HeapFree(GetProcessHeap(), 0, potm); return TRUE; }
HitResponse Block::collision(GameObject& other, const CollisionHit& ) { auto player = dynamic_cast<Player*> (&other); if(player) { if(player->get_bbox().get_top() > bbox.get_bottom() - SHIFT_DELTA) { hit(*player); } } // only interact with other objects if... // 1) we are bouncing // 2) the object is not portable (either never or not currently) // 3) the object is being hit from below (baguys don't get killed for activating boxes) auto portable = dynamic_cast<Portable*> (&other); auto moving_object = dynamic_cast<MovingObject*> (&other); auto bomb = dynamic_cast<Bomb*> (&other); bool is_portable = ((portable != 0) && portable->is_portable()); bool is_bomb = (bomb != 0); // bombs need to explode, although they are considered portable bool hit_mo_from_below = ((moving_object == 0) || (moving_object->get_bbox().get_bottom() < (bbox.get_top() + SHIFT_DELTA))); if(bouncing && (!is_portable || is_bomb) && hit_mo_from_below) { // Badguys get killed auto badguy = dynamic_cast<BadGuy*> (&other); if(badguy) { badguy->kill_fall(); } // Coins get collected auto coin = dynamic_cast<Coin*> (&other); if(coin) { coin->collect(); } //Eggs get jumped auto growup = dynamic_cast<GrowUp*> (&other); if(growup) { growup->do_jump(); } } return FORCE_MOVE; }