void LVL_Npc::transformTo_x(long id) { if(_isInited) { if(data.id==(unsigned)abs(id)) return; if(!ConfigManager::lvl_npc_indexes.contains(id)) return; setup = &ConfigManager::lvl_npc_indexes[id]; } data.id=id; double targetZ = 0; if(setup->foreground) targetZ = LevelScene::Z_npcFore; else if(setup->background) targetZ = LevelScene::Z_npcBack; else targetZ = LevelScene::Z_npcStd; z_index += targetZ; LevelScene::zCounter += 0.00000001; z_index += LevelScene::zCounter; long tID = ConfigManager::getNpcTexture(data.id); if( tID >= 0 ) { texId = ConfigManager::level_textures[tID].texture; texture = ConfigManager::level_textures[tID]; animated = ((setup->frames>1) || (setup->framestyle>0)); animator_ID = setup->animator_ID; } warpFrameW = texture.w; warpFrameH = texture.h; setSize(setup->width, setup->height); if(data.generator) { isGenerator=true; generatorDirection=data.generator_direct; generatorTimeLeft= data.generator_period*100; generatorType = data.generator_type; deActivatable = true; activationTimeout= 150; collide_npc=COLLISION_NONE; collide_player=COLLISION_NONE; disableBlockCollision=true; setGravityScale(0.0f); return; } deActivatable = ((setup->deactivation)||(setup->scenery)); activationTimeout= setup->deactivetionDelay; disableBlockCollision=!setup->collision_with_blocks; disableNpcCollision = setup->no_npc_collions; setDirection(_direction); frameSize.setSize(setup->gfx_w, setup->gfx_h); animator.construct(texture, *setup); setDefaults(); setGravityScale(setup->gravity ? 1.0f : 0.f); if(setup->block_player) collide_player = COLLISION_ANY; else if(setup->block_player_top) collide_player = COLLISION_TOP; else collide_player = COLLISION_NONE; if(setup->block_npc) collide_npc = COLLISION_ANY; else if(setup->block_npc_top) collide_npc = COLLISION_TOP; else collide_npc = COLLISION_NONE; if(setup->no_npc_collions) collide_npc=COLLISION_NONE; if(_isInited) { int leftHealth=setup->health-(setup->health-health); health=(leftHealth>0)? leftHealth : 1; } else health=(setup->health>0)?setup->health : 1; }
void LVL_Player::solveCollision(PGE_Phys_Object *collided) { if(!collided) return; switch(collided->type) { case PGE_Phys_Object::LVLBlock: { LVL_Block *blk= static_cast<LVL_Block*>(collided); if(blk) { if(blk->destroyed) { #ifdef COLLIDE_DEBUG qDebug() << "Destroyed!"; #endif break; } } else { #ifdef COLLIDE_DEBUG qDebug() << "Wrong cast"; #endif break; } if( ((!forceCollideCenter)&&(!collided->posRect.collideRect(posRect)))|| ((forceCollideCenter)&&(!collided->posRect.collideRectDeep(posRect, 1.0, -3.0))) ) { #ifdef COLLIDE_DEBUG qDebug() << "No, is not collidng"; #endif break; } #ifdef COLLIDE_DEBUG qDebug() << "Collided item! "<<collided->type<<" " <<collided->posRect.center().x()<<collided->posRect.center().y(); #endif if((bumpUp||bumpDown)&&(!forceCollideCenter)) { #ifdef COLLIDE_DEBUG qDebug() << "Bump? U'r dumb!"; #endif break; } // PGE_PointF c1 = posRect.center(); // PGE_RectF &r1 = posRect; // PGE_PointF cc = collided->posRect.center(); // PGE_RectF rc = collided->posRect; switch(collided->collide_player) { case COLLISION_TOP: { if(isCollideFloorToponly(collided)) { if(blk->isHidden) break; collided_bottom[(intptr_t)collided]=collided;//bottom of player if(blk->setup->lava) kill(DEAD_burn); else if(blk->setup->danger==2||blk->setup->danger==-3||blk->setup->danger==4) harm(1); #ifdef COLLIDE_DEBUG qDebug() << "Top of block"; #endif } } break; case COLLISION_ANY: { #ifdef COLLIDE_DEBUG bool found=false; #endif //*****************************Feet of player****************************/ if( (( (blk->shape==LVL_Block::shape_rect)|| (blk->shape==LVL_Block::shape_tr_bottom_left)|| (blk->shape==LVL_Block::shape_tr_bottom_right) ) && isCollideFloor(collided))|| ((blk->shape==LVL_Block::shape_tr_top_right)&&isCollideSlopeFloor(collided, SLOPE_RIGHT)) || ((blk->shape==LVL_Block::shape_tr_top_left)&&isCollideSlopeFloor(collided, SLOPE_LEFT)) ){ if(blk->isHidden) break; collided_bottom[(intptr_t)collided]=collided;//bottom of player if(blk->setup->lava) kill(DEAD_burn); else if(blk->setup->danger==2||blk->setup->danger==-3||blk->setup->danger==4) harm(1); } //*****************************Head of player****************************/ else if( (( (blk->shape==LVL_Block::shape_rect)|| (blk->shape==LVL_Block::shape_tr_top_left)|| (blk->shape==LVL_Block::shape_tr_top_right)) && isCollideCelling(collided, _heightDelta, forceCollideCenter))|| ((blk->shape==LVL_Block::shape_tr_bottom_right)&&isCollideSlopeCelling(collided, SLOPE_RIGHT)) || ((blk->shape==LVL_Block::shape_tr_bottom_left)&&isCollideSlopeCelling(collided, SLOPE_LEFT)) ) { collided_top[(intptr_t)collided]=collided;//top of player if(blk->setup->lava) kill(DEAD_burn); else if(blk->setup->danger==-2||blk->setup->danger==-3||blk->setup->danger==4) harm(1); } //*****************************Left****************************/ else if( (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_rect))|| (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_tr_top_left) &&(posRect.bottom()>=(collided->posRect.top()+SL_HeightTopRight(collided)+1.0)))|| (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_tr_bottom_left) &&(posRect.top()<=(collided->posRect.bottom()-SL_HeightTopRight(collided)-1.0))) ) { if(blk->isHidden) break; collided_left[(intptr_t)collided]=collided;//right of player if(blk->setup->lava) kill(DEAD_burn); else if(blk->setup->danger==-1||blk->setup->danger==3||blk->setup->danger==4) harm(1); } //*****************************Right****************************/ else if( (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_rect))|| (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_tr_top_right) &&(posRect.bottom()>=(collided->posRect.top()+SL_HeightTopLeft(collided)+1.0)))|| (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_tr_bottom_right) &&(posRect.top()<=(collided->posRect.bottom()-SL_HeightTopLeft(collided)-1.0))) ) { if(blk->isHidden) break; collided_right[(intptr_t)collided]=collided;//left of player if(blk->setup->lava) kill(DEAD_burn); else if(blk->setup->danger==1||blk->setup->danger==3||blk->setup->danger==4) harm(1); } float c=forceCollideCenter? 0.0f : 1.0f; //*****************************Center****************************/ if( ((!forceCollideCenter && blk->shape==LVL_Block::shape_rect)||(forceCollideCenter)) && blk->posRect.collideRectDeep(posRect, fabs(_velocityX_prev+_velocityX_add)*c+c*2.0, fabs(_velocityY_prev+_velocityY_add)*c+c*2.0) ) { if(blk->isHidden && !forceCollideCenter) break; collided_center[(intptr_t)collided]=collided; } break; } default: break; } break; } case PGE_Phys_Object::LVLWarp: { contactedWarp = static_cast<LVL_Warp*>(collided); if(contactedWarp) contactedWithWarp=true; break; } case PGE_Phys_Object::LVLBGO: { LVL_Bgo *bgo= static_cast<LVL_Bgo*>(collided); if(bgo) { if(bgo->setup->climbing) { bool set=climbable_map.isEmpty(); climbable_map[(intptr_t)collided]=collided; if(set) climbableHeight=collided->posRect.top(); else if(collided->top()<climbableHeight) climbableHeight=collided->top(); } } break; } case PGE_Phys_Object::LVLNPC: { LVL_Npc *npc= static_cast<LVL_Npc*>(collided); if(npc) { if(npc->isKilled()) break; if(!npc->data.msg.isEmpty()) { collided_talkable_npc=npc; } if(npc->data.friendly) break; if(npc->isGenerator) break; if(npc->setup->climbable) { bool set=climbable_map.isEmpty(); climbable_map[(intptr_t)collided]=collided; if(set) climbableHeight=collided->posRect.top(); else if(collided->top()<climbableHeight) climbableHeight=collided->top(); } if((!npc->data.friendly)&&(npc->setup->takable)) { collided_talkable_npc=NULL; npc->doHarm(LVL_Npc::DAMAGE_TAKEN); kill_npc(npc, LVL_Player::NPC_Taked_Coin); } if( ((!forceCollideCenter)&&(!collided->posRect.collideRect(posRect)))|| ((forceCollideCenter)&&(!collided->posRect.collideRectDeep(posRect, 1.0, -3.0))) ) { break; } if((bumpUp||bumpDown)&&(!forceCollideCenter)) break; if(!npc->isActivated) break; //PGE_PointF c1 = posRect.center(); //PGE_RectF &r1 = posRect; //PGE_PointF cc = collided->posRect.center(); //PGE_RectF rc = collided->posRect; switch(collided->collide_player) { case COLLISION_TOP: { if(isCollideFloorToponly(collided)) { collided_bottom[(intptr_t)collided]=collided;//bottom of player #ifdef COLLIDE_DEBUG qDebug() << "Top of block"; #endif } else { if( npc->posRect.collideRect(posRect)) { if(npc->setup->hurt_player & !npc->setup->kill_on_jump) harm(1); } } } break; case COLLISION_ANY: { #ifdef COLLIDE_DEBUG bool found=false; #endif //double xSpeed = Maths::max(fabs(speedX()+_velocityX_add), fabs(_velocityX_prev+_velocityX_add)) * Maths::sgn(speedX()+_velocityX_add); //double ySpeed = Maths::max(fabs(speedY()+_velocityY_add), fabs(_velocityY_prev+_velocityY_add)) * Maths::sgn(speedY()+_velocityY_add); //*****************************Feet of player****************************/ if(isCollideFloor(collided)) { collided_bottom[(intptr_t)collided]=collided;//bottom of player #ifdef COLLIDE_DEBUG qDebug() << "Top of block"; found=true; #endif } //*****************************Head of player****************************/ else if( isCollideCelling(collided, _heightDelta, forceCollideCenter) ) { collided_top[(intptr_t)collided]=collided;//top of player if(npc->setup->hurt_player) harm(1); #ifdef COLLIDE_DEBUG qDebug() << "Bottom of block"; found=true; #endif } //*****************************Left****************************/ else if( isCollideLeft(collided) ) { collided_left[(intptr_t)collided]=collided;//right of player if(npc->setup->hurt_player) harm(1); #ifdef COLLIDE_DEBUG qDebug() << "Right of block"; #endif } //*****************************Right****************************/ else if( isCollideRight(collided) ) { collided_right[(intptr_t)collided]=collided;//left of player if(npc->setup->hurt_player) harm(1); #ifdef COLLIDE_DEBUG qDebug() << "Left of block"; found=true; #endif } float c=forceCollideCenter? 0.0f : 1.0f; //*****************************Center****************************/ #ifdef COLLIDE_DEBUG qDebug() << "block" <<posRect.top()<<":"<<blk->posRect.bottom() << "block" <<posRect.bottom()<<":"<<blk->posRect.top()<<" collide?"<< blk->posRect.collideRectDeep(posRect, fabs(_velocityX_prev)*c+c*2.0, fabs(_velocityY_prev)*c+c*2.0) << "depths: "<< fabs(_velocityX_prev)*c+c*2.0 << fabs(_velocityY_prev)*c+c; #endif if( npc->posRect.collideRectDeep(posRect, fabs(_velocityX_prev)*c+c*2.0, fabs(_velocityY_prev)*c+c*2.0) ) { if(npc->setup->hurt_player) harm(1); if(!forceCollideCenter) break; collided_center[(intptr_t)collided]=collided; #ifdef COLLIDE_DEBUG qDebug() << "Center of block"; found=true; #endif } #ifdef COLLIDE_DEBUG qDebug() << "---checked---" << (found?"and found!": "but nothing..." )<< r1.left()<< "<="<< rc.right()<<"+"<<xSpeed ; #endif break; } case COLLISION_NONE: { //Detect top of stompable NPC! if(!npc->setup->kill_on_jump) { if( npc->posRect.collideRect(posRect)) { if(npc->setup->hurt_player) harm(1); } break; } // PGE_RectF &r1=posRect; // PGE_RectF rc = collided->posRect; // float summSpeedY=(speedY()+_velocityY_add)-(collided->speedY()+collided->_velocityY_add); // float summSpeedYprv=_velocityY_prev-collided->_velocityY_prev; if(isCollideFloorToponly(collided)) // ( // (summSpeedY >= 0.0) // && // (r1.bottom() < rc.top()+summSpeedYprv) // && // ( // (r1.left()<rc.right()-1 ) && // (r1.right()>rc.left()+1 ) // ) // ) // || // (r1.bottom() <= rc.top()) // ) { npc->doHarm(LVL_Npc::DAMAGE_STOMPED); this->bump(true); //Reset floating state floating_timer = floating_maxtime; if(floating_isworks) { floating_isworks=false; setGravityScale(climbing?0:physics_cur.gravity_scale); } kill_npc(npc, NPC_Stomped); } else { if( npc->posRect.collideRect(posRect)) { //The second half of this "if" statement is there to fix a bug with falling collisions, //and should NOT remain here because it is not how we should handle this! //The bug occurs when the player is moving fast enough when they land on an enemy that they //partially enter the enemy before the collision is resolved, causing the engine to think //that the player is INSIDE the NPC, when they are actually only JUMPING on the NPC. if(npc->setup->hurt_player & (!npc->setup->kill_on_jump || colliding_ySpeed > -1.0f)) harm(1); } } break; }//case COLLISION_NONE default: break; } } break; } case PGE_Phys_Object::LVLPhysEnv: { LVL_PhysEnv *env= static_cast<LVL_PhysEnv*>(collided); if(env) { if(env) environments_map[(intptr_t)env]=env->env_type; } break; } default: break; } }
void LVL_Player::update(float ticks) { if(isLocked) return; if(!_isInited) return; if(!camera) return; LVL_Section* section = sct(); if(!section) return; event_queue.processEvents(ticks); if((isWarping) || (!isAlive)) { animator.tickAnimation(ticks); updateCamera(); return; } _onGround = !foot_contacts_map.isEmpty(); on_slippery_surface = !foot_sl_contacts_map.isEmpty(); bool climbableUp = !climbable_map.isEmpty(); bool climbableDown= climbableUp && !_onGround; climbing = (climbableUp && climbing && !_onGround && (posRect.center().y()>=(climbableHeight-physics_cur.velocity_climb_y_up)) ); if(_onGround) { phys_setup.decelerate_x = (fabs(speedX())<=physics_cur.MaxSpeed_walk)? (on_slippery_surface?physics_cur.decelerate_stop/physics_cur.slippery_c : physics_cur.decelerate_stop): (on_slippery_surface?physics_cur.decelerate_run/physics_cur.slippery_c : physics_cur.decelerate_run); if(physics_cur.strict_max_speed_on_ground) { if((speedX()>0)&&(speedX()>phys_setup.max_vel_x)) setSpeedX(phys_setup.max_vel_x); else if((speedX()<0)&&(speedX()<phys_setup.min_vel_x)) setSpeedX(phys_setup.min_vel_x); } } else phys_setup.decelerate_x = physics_cur.decelerate_air; if(doKill) { doKill=false; isAlive = false; setPaused(true); LvlSceneP::s->checkPlayers(); return; } if(climbing) { PGE_Phys_Object* climbableItem = static_cast<PGE_Phys_Object*>((void*)(intptr_t)climbable_map[climbable_map.keys().first()]); if(climbableItem) { _velocityX_add=climbableItem->speedX(); _velocityY_add=climbableItem->speedY(); } else { _velocityX_add=0.0f; _velocityY_add=0.0f; } if(gscale_Backup != 1) { setGravityScale(0); gscale_Backup = 1; } } else { if(gscale_Backup != 0.f) { setGravityScale(physics_cur.gravity_scale); gscale_Backup = 0.f; } } if(climbing) { setSpeed(0,0); } if(environments_map.isEmpty()) { if(last_environment!=section->getPhysicalEnvironment() ) { environment = section->getPhysicalEnvironment(); } } else { int newEnv = section->getPhysicalEnvironment(); foreach(int x, environments_map) { newEnv = x; } if(last_environment != newEnv) { qDebug()<<"Enter to environment" << newEnv; environment = newEnv; } } refreshEnvironmentState(); if(_onGround) { if(!floating_isworks) { floating_timer=floating_maxtime; } } //Running key if(keys.run) { if(!_isRunning) { phys_setup.max_vel_x = physics_cur.MaxSpeed_run; phys_setup.min_vel_x = -physics_cur.MaxSpeed_run; _isRunning=true; } } else { if(_isRunning) { phys_setup.max_vel_x = physics_cur.MaxSpeed_walk; phys_setup.min_vel_x = -physics_cur.MaxSpeed_walk; _isRunning=false; } } if((physics_cur.ground_c_max!=1.0f)) { phys_setup.max_vel_x = fabs(_isRunning ? physics_cur.MaxSpeed_run : physics_cur.MaxSpeed_walk) *(_onGround?physics_cur.ground_c_max:1.0f); phys_setup.min_vel_x = -fabs(_isRunning ? physics_cur.MaxSpeed_run : physics_cur.MaxSpeed_walk) *(_onGround?physics_cur.ground_c_max:1.0f); } if(keys.alt_run) { if(attack_enabled && !attack_pressed && !climbing) { attack_pressed=true; if(keys.up) attack(Attack_Up); else if(keys.down) attack(Attack_Down); else { attack(Attack_Forward); PGE_Audio::playSoundByRole(obj_sound_role::PlayerTail); animator.playOnce(MatrixAnimator::RacoonTail, _direction, 75, true, true, 1); } } } else { if(attack_pressed) attack_pressed=false; } //if if(!keys.up && !keys.down && !keys.left && !keys.right) { if(wasEntered) { wasEntered = false; wasEnteredTimeout=0; } } //Reset state if(wasEntered) { wasEnteredTimeout-=ticks; if(wasEnteredTimeout<0) { wasEnteredTimeout=0; wasEntered=false; } } if(keys.up) { if(climbableUp&&(jumpTime<=0)) { setDuck(false); climbing=true; floating_isworks=false;//!< Reset floating on climbing start } if(climbing) { if(posRect.center().y() >= climbableHeight) setSpeedY(-physics_cur.velocity_climb_y_up); } } if(keys.down) { if( climbableDown && (jumpTime<=0) ) { setDuck(false); climbing=true; floating_isworks=false;//!< Reset floating on climbing start } else { if((duck_allow & !ducking)&&( (animator.curAnimation()!=MatrixAnimator::RacoonTail) ) ) { setDuck(true); } } if(climbing) { setSpeedY(physics_cur.velocity_climb_y_down); } } else { if(ducking) setDuck(false); } if( (!keys.left) || (!keys.right) ) { bool turning=(((speedX()>0)&&(_direction<0))||((speedX()<0)&&(_direction>0))); float force = turning? physics_cur.decelerate_turn : (fabs(speedX())>physics_cur.MaxSpeed_walk)?physics_cur.run_force : physics_cur.walk_force; if(on_slippery_surface) force=force/physics_cur.slippery_c; else if((_onGround)&&(physics_cur.ground_c!=1.0f)) force=force*physics_cur.ground_c; if(keys.left) _direction=-1; if(keys.right) _direction=1; if(!ducking || !_onGround) { //If left key is pressed if(keys.right && collided_right.isEmpty()) { if(climbing) setSpeedX(physics_cur.velocity_climb_x); else applyAccel(force, 0); } //If right key is pressed if(keys.left && collided_left.isEmpty()) { if(climbing) setSpeedX(-physics_cur.velocity_climb_x); else applyAccel(-force, 0); } } } if( keys.alt_jump ) { //Temporary it is ability to fly up! if(!bumpDown && !bumpUp) { setSpeedY(-physics_cur.velocity_jump); } } if( keys.jump ) { if(!JumpPressed) { if(environment!=LVL_PhysEnv::Env_Water) { if(climbing || _onGround || (environment==LVL_PhysEnv::Env_Quicksand)) PGE_Audio::playSoundByRole(obj_sound_role::PlayerJump); } else PGE_Audio::playSoundByRole(obj_sound_role::PlayerWaterSwim); } if((environment==LVL_PhysEnv::Env_Water)||(environment==LVL_PhysEnv::Env_Quicksand)) { if(!JumpPressed) { if(environment==LVL_PhysEnv::Env_Water) { if(!ducking) animator.playOnce(MatrixAnimator::SwimUp, _direction, 75); } else if(environment==LVL_PhysEnv::Env_Quicksand) { if(!ducking) animator.playOnce(MatrixAnimator::JumpFloat, _direction, 64); } JumpPressed=true; jumpTime = physics_cur.jump_time; jumpVelocity=physics_cur.velocity_jump; floating_timer = floating_maxtime; setSpeedY(speedY()-jumpVelocity); } } else if(!JumpPressed) { JumpPressed=true; if(_onGround || climbing) { climbing=false; jumpTime=physics_cur.jump_time; jumpVelocity=physics_cur.velocity_jump; floating_timer = floating_maxtime; setSpeedY(-jumpVelocity-fabs(speedX()/physics_cur.velocity_jump_c)); } else if((floating_allow)&&(floating_timer>0)) { floating_isworks=true; //if true - do floating with sin, if false - do with cos. floating_start_type=(speedY()<0); setSpeedY(0); setGravityScale(0); } } else { if(jumpTime>0) { jumpTime -= ticks; setSpeedY(-jumpVelocity-fabs(speedX()/physics_cur.velocity_jump_c)); } if(floating_isworks) { floating_timer -= ticks; if(floating_start_type) setSpeedY( state_cur.floating_amplitude*(-cos(floating_timer/80.0)) ); else setSpeedY( state_cur.floating_amplitude*(cos(floating_timer/80.0)) ); if(floating_timer<=0) { floating_timer=0; floating_isworks=false; setGravityScale(climbing?0:physics_cur.gravity_scale); } } } } else { jumpTime=0; if(JumpPressed) { JumpPressed=false; if(floating_allow) { if(floating_isworks) { floating_timer=0; floating_isworks=false; setGravityScale(climbing?0:physics_cur.gravity_scale); } } } } refreshAnimation(); animator.tickAnimation(ticks); PGE_RectF sBox = section->sectionLimitBox(); //Return player to start position on fall down if( posY() > sBox.bottom()+_height ) { kill(DEAD_fall); } if(bumpDown) { bumpDown=false; jumpTime=0; setSpeedY(bumpVelocity); } else if(bumpUp) { bumpUp=false; if(keys.jump) { jumpTime=bumpJumpTime; jumpVelocity=bumpJumpVelocity; } setSpeedY( (keys.jump ? (-fabs(bumpJumpVelocity)-fabs(speedX()/physics_cur.velocity_jump_c)): -fabs(bumpJumpVelocity)) ); } //Connection of section opposite sides if(isExiting) // Allow walk offscreen if exiting { if((posX() < sBox.left()-_width-1 )||(posX() > sBox.right() + 1 )) { setGravityScale(0.0);//Prevent falling [we anyway exited from this level, isn't it?] setSpeedY(0.0); } if(keys.left||keys.right) { if((environment==LVL_PhysEnv::Env_Water)||(environment==LVL_PhysEnv::Env_Quicksand)) { keys.run=true; if(_exiting_swimTimer<0 && !keys.jump) keys.jump=true; else if(_exiting_swimTimer<0 && keys.jump) { keys.jump=false; _exiting_swimTimer=(environment==LVL_PhysEnv::Env_Quicksand)? 1 : 500; } _exiting_swimTimer-= ticks; } else keys.run=false; } } else if(section->isWarp()) { if(posX() < sBox.left()-_width-1 ) setPosX( sBox.right()+1 ); else if(posX() > sBox.right() + 1 ) setPosX( sBox.left()-_width-1 ); } else { if(section->ExitOffscreen()) { if(section->RightOnly()) { if( posX() < sBox.left()) { setPosX( sBox.left() ); setSpeedX(0.0); } } if((posX() < sBox.left()-_width-1 ) || (posX() > sBox.right() + 1 )) { setLocked(true); _no_render=true; LvlSceneP::s->setExiting(1000, LvlExit::EXIT_OffScreen); return; } } else { //Prevent moving of player away from screen if( posX() < sBox.left()) { setPosX(sBox.left()); setSpeedX(0.0); } else if( posX()+_width > sBox.right()) { setPosX(sBox.right()-_width); setSpeedX(0.0); } } } if(_stucked) { posRect.setX(posRect.x()-_direction*2); applyAccel(0, 0); } processWarpChecking(); if(_doSafeSwitchCharacter) setCharacter(characterID, stateID); try { lua_onLoop(); } catch (luabind::error& e) { LvlSceneP::s->getLuaEngine()->postLateShutdownError(e); } updateCamera(); }
Block::Block(int index, Game *game, const TileParam &tileParam) : Body(Body::BodyType::Block, game, tileParam) , mGravityScale(2.f) , mMinimumHitImpulse(0) { mName = Name; mMinimumHitImpulse = mTileParam.minimumHitImpulse; setScore(mTileParam.score); setEnergy(mTileParam.minimumKillImpulse); setGravityScale(mTileParam.gravityScale); const sf::Texture &texture = mGame->level()->tileParam(index).texture; sf::Image img; img.create(texture.getSize().x + 2 * TextureMargin, texture.getSize().y + 2 * TextureMargin, sf::Color(0, 0, 0, 0)); img.copy(texture.copyToImage(), TextureMargin, TextureMargin, sf::IntRect(0, 0, 0, 0), true); mTexture.loadFromImage(img); setSmooth(mTileParam.smooth); setHalfTextureSize(texture); mSprite.setTexture(mTexture); mSprite.setOrigin(.5f * mTexture.getSize().x, .5f * mTexture.getSize().y); if (gLocalSettings().useShaders()) { mShader.loadFromFile(ShadersDir + "/fallingblock.fs", sf::Shader::Fragment); mShader.setParameter("uAge", 0.f); mShader.setParameter("uBlur", 0.f); mShader.setParameter("uColor", sf::Color(255U, 255U, 255U, 255U)); mShader.setParameter("uResolution", float(mTexture.getSize().x), float(mTexture.getSize().y)); } const unsigned int W = texture.getSize().x; const unsigned int H = texture.getSize().y; b2BodyDef bd; bd.type = b2_dynamicBody; bd.angle = .0f; bd.linearDamping = mTileParam.linearDamping.isValid() ? mTileParam.linearDamping.get() : DefaultLinearDamping; bd.angularDamping = mTileParam.angularDamping.isValid() ? mTileParam.angularDamping.get() : DefaultAngularDamping; bd.gravityScale = .0f; bd.allowSleep = true; bd.awake = false; bd.fixedRotation = false; bd.bullet = false; bd.userData = this; mBody = game->world()->CreateBody(&bd); b2PolygonShape polygon; const float32 hs = .5f * Game::InvScale; const float32 hh = hs * H; const float32 xoff = hs * (W - H); polygon.SetAsBox(xoff, hh); const float32 density = mTileParam.density.isValid() ? mTileParam.density.get() : DefaultDensity; const float32 friction = mTileParam.friction.isValid() ? mTileParam.friction.get() : DefaultFriction; const float32 restitution = mTileParam.restitution.isValid() ? mTileParam.restitution.get() : DefaultRestitution; b2FixtureDef fdBox; fdBox.shape = &polygon; fdBox.density = density; fdBox.friction = friction; fdBox.restitution = restitution; fdBox.userData = this; mBody->CreateFixture(&fdBox); b2CircleShape circleL; circleL.m_p.Set(-xoff, 0.f); circleL.m_radius = hh; b2FixtureDef fdCircleL; fdCircleL.shape = &circleL; fdCircleL.density = density; fdCircleL.friction = friction; fdCircleL.restitution = restitution; fdCircleL.userData = this; mBody->CreateFixture(&fdCircleL); b2CircleShape circleR; circleR.m_p.Set(xoff, 0.f); circleR.m_radius = hh; b2FixtureDef fdCircleR; fdCircleR.shape = &circleR; fdCircleR.density = density; fdCircleR.friction = friction; fdCircleR.restitution = restitution; fdCircleR.userData = this; mBody->CreateFixture(&fdCircleR); }