void Ant::turn(bool left) { int newDir = left ? (getFacing() - 1 + 4) % 4 : (getFacing() + 1 + 4) % 4; setFacing((Ant::Facing) newDir); moves++; }
int Cat::getRX() const { if ( current_animation ){ if ( getFacing() == FACING_LEFT ){ return Object::getRX() - current_animation->getOffsetX(); } else { return Object::getRX() + current_animation->getOffsetX(); } } return Object::getRX(); }
bool CSObject::isFacing(vector3df targetposition, float window) { vector3df lookat = getFacing(targetposition); if ( ((getAbsoluteRotation().Y > lookat.Y - window) && (getAbsoluteRotation().Y < lookat.Y + window)) || ((lookat.Y > getAbsoluteRotation().Y - window) && (lookat.Y < getAbsoluteRotation().Y + window)) ) return true; else return false; }
AttackObject* HeroKnight::createAttackObject() { std::string strAttID=getArmature()->getAnimation()->getCurrentMovementID(); auto actionMode=getActionFileMode(); //创建攻击对象 int attack=getHeroModel()->Attack; auto att=AttackObject::create(); att->setAttackObject(this); //默认是普通攻击距离 float attDist=getHeroModel()->AttackDist; if (strAttID==actionMode->ActionAttackName1) { att->setRepelPower(20); }else if (strAttID==actionMode->ActionAttackName2) { att->setRepelPower(10); }else if (strAttID==actionMode->ActionAttackName3) { att->setRepelPower(35); } //技能攻击距离 if (strAttID==actionMode->SkillName1){ attDist=skills[0].AttackDist; //加血 int addHp=skills[0].CurrAttack + attack / 4; HeroBase::addHp(addHp); return nullptr; }else if (strAttID==actionMode->SkillName2){ attack=skills[1].CurrAttack + attack / 4; att->setRepelPower(180); attDist=skills[1].AttackDist; }else if (strAttID==actionMode->SkillName3){ attack=skills[2].CurrAttack + attack / 4; att->setRepelPower(290); attDist=skills[2].AttackDist; }else if (strAttID==actionMode->SkillName4){ attack=skills[3].CurrAttack + attack / 4; attDist=skills[3].AttackDist; } att->setAttack(attack); //攻击范围 Vec2 pos=this->getPosition(); float attStartPos=getPositionX(); if (!getFacing()) { attStartPos-=attDist; } Rect attRect=Rect(attStartPos,getPositionY(),attDist, 200); att->setAttRange(attRect); return att; }
void Cat::draw( Graphics::Bitmap * work, int rel_x, int rel_y ){ if ( getFacing() == Object::FACING_RIGHT ){ current_animation->Draw(getRX() - rel_x, getRY(), NULL, work); } else { current_animation->DrawFlipped(getRX() - rel_x, getRY(), NULL, work); } if (Util::rnd(2000) == 0){ int distance = 1000 - fabs((double)getRX() - rel_x) / 2; double volume = distance < 0 ? 0.1 : (double) distance / 1000.0; int pan = 128 + (getRX() - rel_x) / 50; meow.play(volume, pan); } }
void Player::updateFlashlightPosition() { const float offsetX = 50.0f; float offsetY = 95.0f; float bodyOffsetX = 0.0f; if (anime.getAnimation() == mWalking) { offsetY = 106.0f; } if (anime.getAnimation() == mJump) { offsetY = 83.0f; } sf::Vector2f pos = Convert::b2ToSfml(body->GetPosition()); sf::Texture* mask = nullptr; pos.y += offsetY; switch (getFacing()) { case LEFT: pos.x -= offsetX; bodyOffsetX += FLASHLIGHT_SIZE.x / 4.0f; mask = maskLeft; break; case RIGHT: default: pos.x += offsetX; mask = maskRight; break; } flashLight->setPosition(pos); flashLight->setMask(mask); pos.x -= bodyOffsetX; flashLightBody->SetTransform(Convert::sfmlToB2(pos), 0.0f); }
void Player::update(sf::Time deltaTime) { float maxVel = 3.0f; const b2Vec2& vel = body->GetLinearVelocity(); if(hitTimer.getElapsedTime().asSeconds() <= 3.0f) { leftHitCollision->setActive(false); rightHitCollision->setActive(false); } else { leftHitCollision->setActive(true); rightHitCollision->setActive(true); } if(rightHitCollision->isHitColliding() && rightHitCollision->isActive()) { setFacing(RIGHT); hitTimer.restart(); damaged(); } if(leftHitCollision->isHitColliding()&& leftHitCollision->isActive()) { setFacing(LEFT); hitTimer.restart(); damaged(); } if(shadeCollision->isHitColliding()&&!groundCallBack->isColliding() && state != GRABBING) { //For funtimes ;) //body->SetFixedRotation(false); if(getFacing() == LEFT) { body->ApplyForce(b2Vec2(knockForce,0.1f),b2Vec2(0.0f,0.0f),true); } else if(getFacing() == RIGHT) { body->ApplyForce(b2Vec2(-knockForce,0.1f),b2Vec2(0.0f,0.0f),true); } else{body->ApplyForce(b2Vec2(knockForce,0.1f),b2Vec2(0.0f,0.0f),true);} setState(KNOCKEDBACKED); } if (flashLight->isEnabled()) { Shade* shade = flashLightCallBack->getClosestShade(flashLight->getPosition()); if (shade) { Facing dir = (getFacing() == Facing::LEFT) ? RIGHT : LEFT; shade->increaseTimeInFlashLight(deltaTime.asSeconds()); shade->setFacing(dir); } } switch(state) { case NORMAL: if ((!rightButton && !leftButton) || (rightButton && leftButton)) { body->SetLinearVelocity(b2Vec2(0,vel.y)); } else if (rightButton) { if (!rightSideCollision->isColliding() && vel.x < maxVel) { //body->SetLinearVelocity(b2Vec2(SPEED, vel.y)); body->ApplyLinearImpulse(b2Vec2(0.8f,0.0f),b2Vec2(body->GetWorldCenter()),true); } setFacing(Entity::RIGHT); } else if (leftButton) { if (!leftSideCollision->isColliding() && vel.x > -maxVel) { //body->SetLinearVelocity(b2Vec2(-SPEED, vel.y)); body->ApplyLinearImpulse(b2Vec2(-0.8f,0.0f),b2Vec2(body->GetWorldCenter()),true); } setFacing(Entity::LEFT); } //Check for grabbing if we are not flying upwards. if (!groundCallBack->isColliding() && vel.y >= 0) { if (leftGrabCallBack->isColliding() && !leftAntiGrabCallBack->isColliding() && getFacing() == Facing::LEFT) { this->setState(PLAYER_STATE::GRABBING); const sf::FloatRect& bounds = leftGrabCallBack->getGrabbedFixtureBounds(); body->SetTransform(Convert::sfmlToB2(sf::Vector2f(bounds.left + bounds.width + (bodyBounds.width / 2.0f), bounds.top)), 0); } else if (rightGrabCallBack->isColliding() && !rightAntiGrabCallBack->isColliding() && getFacing() == Facing::RIGHT) { this->setState(PLAYER_STATE::GRABBING); const sf::FloatRect& bounds = rightGrabCallBack->getGrabbedFixtureBounds(); body->SetTransform(Convert::sfmlToB2(sf::Vector2f(bounds.left-(bodyBounds.width/2.0f), bounds.top)), 0); } } break; case GRABBING: //Check if we should just drop down //Jumping while grabbing is handled in Player::jump() and not here. if (downButton || (rightButton && getFacing() == Facing::LEFT) || (leftButton && getFacing() == Facing::RIGHT)) { const float pushDistance = 12.0f; //If we are facing right, push the player a bit left if (getFacing() == Facing::RIGHT) { sf::Vector2f pos = Convert::b2ToSfml(body->GetPosition()); pos.x -= pushDistance; body->SetTransform(Convert::sfmlToB2(pos), 0.0f); setFacing(Entity::LEFT); } //Else just push the player a bit right. else if (getFacing() == Facing::LEFT) { sf::Vector2f pos = Convert::b2ToSfml(body->GetPosition()); pos.x += pushDistance; body->SetTransform(Convert::sfmlToB2(pos), 0.0f); setFacing(Entity::RIGHT); } setState(PLAYER_STATE::NORMAL); } break; case DAMAGED: anime.setLooped(false); if(!anime.isFinished()) { body->SetLinearVelocity(b2Vec2(0,0)); } if(anime.isFinished()) { setState(NORMAL); anime.setLooped(true); } if(mStats.health <=0) { setState(DYING); } break; case KNOCKEDBACKED: if(mStats.health <=0){setState(DYING);} else if (knockedbackClock.getElapsedTime().asSeconds() > 1) { setState(NORMAL); } break; case DYING: mPlatformState.getOverlay(PlatformState::DEATH_SCREEN).setEnabled(true); std::cout<<"Waaaaaaaaaaaah"<<std::endl; std::cout<<"---------Player Dead----------"<<std::endl; break; default: break; } updateAnimation(); updateSound(); anime.update(deltaTime); updateFlashlightPosition(); }
void NounShip::inflictDamage( dword nWhen, Noun * pFrom, int damage, dword type, const Vector3 & direction ) { if ( isDestroyed() ) // don't bother if ship is already destroyed! return; // only increase timer if an enemy is attacking us - we don't want to promote griefing if ( isEnemy( pFrom ) ) setOutOfCombat(); // update combat timer // if we are not the server, then halve the damage applied to avoid over estimatation the damage we are // inflicting on another ship.. if (! isServer() ) damage = damage * CLIENT_SIDE_DAMAGE; Facing eFacing = getFacing( atan2( direction.x, direction.z ), false ); // apply any damage modifiers damage = damage * calculateModifier( MT_DAMAGE_REDUCTION, true ); LOG_DEBUG_LOW( "NounShip", CharString().format("Damaged inflicted, When: %u, From: %s, Damage: %d, Type: 0x%X, Facing: %u", nWhen, pFrom != NULL ? pFrom->name() : "NULL", damage, type, eFacing) ); // callback so AI controlled ships can receive notification that they have been damaged by someone onAttacked( pFrom, damage, type ); // calculate the points we're going to award to the attacker now before shields/armor reduce // the damage applied to the hull. float fDamagePoints = float( damage ) / DAMAGE_POINTS_DIV; // check shields if( damage > 0 ) { for(int i=0;i<m_Shields.size();i++) damage = m_Shields[i]->deflect( type, damage, eFacing, direction ); } // check armor if ( damage > 0 ) { for(int i=0;i<m_Armor.size();i++) damage = m_Armor[i]->deflect( type, damage, eFacing ); } int internalDamage = damage; // inflict internal damage if hull is 50% or less int halfHull = maxDamage() >> 1; if ( damage > 0 && m_Damage > halfHull && (type & DAMAGE_EMP) == 0 ) { // once hull is under 50%, start causing internal damage type |= DAMAGE_EMP; // scale internal damage up based on how much under 50% the hull internalDamage = (damage * (m_Damage - halfHull)) / halfHull; } if ( damage > 0 && (type & (DAMAGE_EMP|DAMAGE_ELF)) ) { // get the radius of this ship float myRadius = radius(); ASSERT( myRadius > 0.0f ); // calculate the hit position in object space of this ship Vector3 hitPosition( direction ); hitPosition.normalize(); // direction is not normalized, it's the delta from the projectile/explosion, to the center of the ship hitPosition *= -(myRadius * 0.5f); // flip the direction so it goes away from the center of the ship if ( isServer() && m_Gadgets.size() > 0 ) { // seed with the time-stamp of the damage so we get the same gadget damaged // on all clients. srand( nWhen ); int nPicked = rand() % m_Gadgets.size(); NounGadget * pDamageGadget = m_Gadgets[ nPicked ]; if ( pDamageGadget != NULL ) { float fDistance = (pDamageGadget->position() - hitPosition).magnitude(); float fScale = (1.0f - (fDistance / myRadius)); if ( fScale > 0.0f ) pDamageGadget->inflictDamage( nWhen, pFrom, fScale * internalDamage, type, direction ); } } } if ( damage > 0 && (type & DAMAGE_ELF) ) { // drain energy from main energy bank int drained = Min( energy(), damage ); setEnergy( energy() - drained ); // give energy to attacking ship if ( WidgetCast<NounShip>( pFrom ) ) ((NounShip *)pFrom)->setEnergy( ((NounShip *)pFrom)->energy() + drained ); } // update the stats if it is another ship - NOTE this needs to happen before the DestroyShip // code below otherwise a player who is damaging this ship may not get credit/loot. if ( WidgetCast<NounShip>( pFrom ) ) { NounShip * pFromShip = (NounShip *)pFrom; ASSERT( pFromShip ); // set combat timer on attacking ship pFromShip->setOutOfCombat(); // non-hull damages gives a lessor percentage of points.. if ( damage <= 0 ) fDamagePoints *= NOHULL_DAMAGE_POINTS_SCALE; if (! isFriend( pFrom ) ) { // if the attacking ship is destroyed, then treat this as kamikaze points if ( pFromShip->isDestroyed() ) gameContext()->gameUser()->onKamikaze( pFrom, 1.0f ); else gameContext()->gameUser()->onDamageShip( pFrom, fDamagePoints, this); } else { gameContext()->gameUser()->onFriendlyFire( pFrom, fDamagePoints ); } } if ( damage > 0 && (type & (DAMAGE_KINETIC|DAMAGE_ENERGY)) ) { ASSERT( context() ); // cap the damage, damage = Min( maxDamage() - m_Damage, damage ); // add the damage to the hull m_Damage = Min( m_Damage + damage, maxDamage() ); // update the damage bits updateDamageBits(); // check if the ship was destroyed if ( isServer() && isDestroyed() ) { // ship is destroyed, send out verb to destroy this ship to all local clients Verb::Ref( new VerbDestroyShip( this, pFrom, false ) ); } } }
Facing NounShip::getFacing( const Vector3 & vWorld ) { Vector3 vDirection( worldFrame() * (vWorld - worldPosition()) ); vDirection.normalize(); return getFacing( atan2( vDirection.x, vDirection.z ), false ); }
AttackObject* HeroBow::createAttackObject() { std::string strAttID=getArmature()->getAnimation()->getCurrentMovementID(); auto actionMode=getActionFileMode(); //获取方向 bool facing=getFacing(); float attackDist=getHeroModel()->AttackDist; //攻击距离 //创建子弹 auto bullet=BulletObject::create(); bullet->setAttackType(1); bullet->setAttackObject(this); if (strAttID==actionMode->ActionAttackName1 || strAttID==actionMode->ActionAttackName2 || strAttID==actionMode->ActionAttackName3 || strAttID==actionMode->ActionAttackName4) { bullet->setRepelPower(8.0); float bulletX=GameBLL::instance()->getMaxMapWidth(); if(!facing){ bulletX*=-1; } auto b=Sprite::createWithSpriteFrameName("v_arrow_1.png"); b->setFlippedX(!facing); bullet->setSprite(b); bullet->setPosition(getPosition()+vShootPos); bullet->setTargetPos(getPosition()+Vec2(bulletX,vShootPos.y), 3000); bullet->setAttack(getHeroModel()->Attack); BulletBLL::getInstance()->addBullet(bullet); } //技能1 if (strAttID==actionMode->SkillName1) { bullet->setPenetrateAttack(true); bullet->setRepelPower(32); attackDist=skills[0].AttackDist; float width=1280.0; float rota=21.24; //旋转角度 if(!facing){ attackDist*=-1; rota*=-1; width*=-1; } auto bulletStartPos=getPosition() + Vec2(0, 255); auto b=Sprite::createWithSpriteFrameName("v_arrow_2.png"); b->setFlippedX(!facing); bullet->setSprite(b); bullet->setPosition(bulletStartPos); //bullet->setTargetPos(pos+Vec2(attackDist,0), 2000); bullet->setIsDone(true); bullet->setRotation(rota); int attack=skills[0].CurrAttack + getHeroModel()->Attack / 4; bullet->setAttack(attack); BulletBLL::getInstance()->addBullet(bullet); auto call=CallFunc::create(CC_CALLBACK_0(HeroBow::bulletCallback, this, bullet)); ccBezierConfig bc; bc.endPosition=Vec2(bulletStartPos.x + width, bulletStartPos.y); if(!facing){ bc.controlPoint_1 = Vec2(bulletStartPos.x - width * 0.2, bulletStartPos.y - 300); bc.controlPoint_2 = Vec2(bc.endPosition.x + width * 0.2, bulletStartPos.y - 300); }else{ bc.controlPoint_1 = Vec2(bulletStartPos.x + width * 0.2, bulletStartPos.y - 300); bc.controlPoint_2 = Vec2(bc.endPosition.x - width * 0.2, bulletStartPos.y - 300); } //子弹动作 auto bez=BezierTo::create(0.5, bc); auto seq=Sequence::create(bez,call, NULL); bullet->runAction(APRotateWithAction::create(seq)); }else if (strAttID==actionMode->SkillName2){ float bAngle=345; if(!facing){ bAngle=215; } auto bulletPos=getPosition() + Vec2(0, 272); int attack=skills[1].CurrAttack + getHeroModel()->Attack / 4; for (int i=0; i<3; i++) { auto targetPos=APTools::getRoundPoint(bulletPos, bAngle - (i * 10), 1700); float rotation=APTools::getAngle(bulletPos, targetPos); auto b=Sprite::createWithSpriteFrameName("v_arrow_3.png"); b->setFlippedX(!facing); //创建子弹 auto newbullet=BulletObject::create(); newbullet->setRepelPower(8.0); newbullet->setAttackType(1); newbullet->setPenetrateAttack(true); newbullet->setAttackObject(this); newbullet->setSprite(b); newbullet->setPosition(bulletPos); newbullet->setTargetPos(targetPos, 2000); newbullet->setRotation(rotation); newbullet->setAttack(attack); BulletBLL::getInstance()->addBullet(newbullet); } }else if (strAttID==actionMode->SkillName3){ attackDist=skills[2].AttackDist; //创建攻击对象 int attack=skills[2].CurrAttack + getHeroModel()->Attack / 4; auto att=AttackObject::create(); att->setAttack(attack); att->setRepelPower(280); att->setAttackObject(this); //是否被击倒 att->setIsHitDown(true); //攻击范围 Vec2 pos=this->getPosition(); float attStartPosX=getPositionX(); if (!facing) { attStartPosX-=attackDist; } Rect attRect=Rect(attStartPosX,getPositionY(),attackDist, 100); att->setAttRange(attRect); return att; }else if (strAttID==actionMode->SkillName4){ attackDist=skills[3].AttackDist; //创建攻击对象 int attack=skills[3].CurrAttack + getHeroModel()->Attack / 4; auto att=AttackObject::create(); att->setAttack(attack); att->setRepelPower(120); att->setAttackObject(this); //是否被击倒 att->setIsHitDown(false); //攻击范围 Vec2 pos=this->getPosition(); auto worldPos=this->getParent()->convertToWorldSpace(pos); float attDist=1280-worldPos.x; float attStartPosX=pos.x; if (!facing) { attDist=worldPos.x; attStartPosX-=attDist; } Rect attRect=Rect(attStartPosX,getPositionY(),attDist, 100); att->setAttRange(attRect); return att; } return nullptr; }