예제 #1
0
void Simulation::setVelocity(const Vec3f& v1) {
  setVelocity(v1, Vec3f(0,0,0));
}
예제 #2
0
void Ball::increaseVelocity() {
  auto body = getPhysicsBody();
  body->setVelocity(body->getVelocity() * VELOCITY_INCREASE);
}
예제 #3
0
void GiantSlimeEntity::animate(float delay)
{
  slimeTimer -= delay;
  if (slimeTimer <= 0.0f)
  {
    slimeTypeEnum slimeType = SlimeTypeStandard;
    if (game().isAdvancedLevel())
    {
      slimeType =  (slimeTypeEnum)(slimeType + rand() % 3);
    }
    switch (slimeCounter)
    {
    case 0:
      new SlimeEntity(TILE_WIDTH * 1.5f, TILE_HEIGHT * 1.5f, slimeType, true);
      break;
    case 1:
      new SlimeEntity(TILE_WIDTH * (MAP_WIDTH - 2) + TILE_WIDTH * 0.5f, TILE_HEIGHT * 1.5f, slimeType, true);
      break;
    case 2:
      new SlimeEntity(TILE_WIDTH * (MAP_WIDTH - 2) + TILE_WIDTH * 0.5f, TILE_HEIGHT * (MAP_HEIGHT - 2) + TILE_HEIGHT * 0.5f, slimeType, true);
      break;
    case 3:
      new SlimeEntity(TILE_WIDTH * 1.5f, TILE_HEIGHT * (MAP_HEIGHT - 2) + TILE_HEIGHT * 0.5f, slimeType, true);
      break;
    }
    slimeTimer = 7.0f;
    slimeCounter ++;
    if (slimeCounter == 4) slimeCounter = 0;
  }

  if (age <= 0.0f)
  {
    age += delay;
    return;
  }
  EnemyEntity::animate(delay);
  if (specialState[SpecialStateIce].active) delay *= specialState[SpecialStateIce].param1;

  timer -= delay;
  if (timer <= 0.0f)
  {
    if (state == 0) // walking
    {
      counter--;
      if (counter >= 0)
      {
        timer = 0.5f;
        if (hp <= hpMax / 4)
          creatureSpeed = GIANT_SLIME_SPEED * 1.4f;
        if (hp <= hpMax / 2)
          creatureSpeed = GIANT_SLIME_SPEED * 1.2f;
        else
          creatureSpeed = GIANT_SLIME_SPEED;

        setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), GIANT_SLIME_SPEED ));
      }
      else
      {
        int r = rand() % 3;
        if (r == 0) changeToState(1);
        else if (r == 1) changeToState(3);
        else changeToState(5);
      }
    }
    else if (state == 1) // waiting for jumping
    {
      changeToState(2);
    }
    else if (state == 2) // jumping
    {
      changeToState(8);
    }
    else if (state == 3)
    {
      changeToState(4);
    }
    else if (state == 4) // walking
    {
      counter--;
      if (counter >= 0)
      {
        if (hp <= hpMax / 4)
          timer = missileDelay * 0.6f;
        if (hp <= hpMax / 2)
          timer = missileDelay * 0.8f;
        else
          timer = missileDelay;
        fire();
      }
      else
      {
        changeToState(8);
      }
    }
    else if (state == 5)
    {
      changeToState(6);
    }
    else if (state == 6)  // jump
    {
      changeToState(7); // fall
    }
    else if (state == 7)  // jump
    {
    }
    else if (state == 8)  // jump
    {
      changeToState(0); // fall
    }
  }

  if (state == 0) // walking
  {
    frame = ((int)(age * 2.0f)) % 2;
  }
  else if (state == 1 || state == 5) // waiting to jump
  {
    if (timer < 0.25f)
      frame = 1;
    else
      frame = 0;
  }
  else if (state == 2)  // jumping
  {
    hVelocity -= 700.0f * delay;

    h += hVelocity * delay;

    if (h <= 0.0f)
    {
      if (hp <= 0)
        dying();
      else
      {
        h = 0.0f;
        if (isFirstJumping)
        {
          isFirstJumping = false;
          hVelocity = 160.0f;
          SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT);
        }
        else
        {
          SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT_WEAK);
          viscosity = 0.96f;
          changeToState(0);
        }
      }
    }
    if (hVelocity > 0.0f) frame = 2;
    else frame = 0;
  }
  else if (state == 6) // ultra jump
  {
    if (h < 2000)
      h += hVelocity * delay;
  }
  else if (state == 7) // ultra jump
  {
    if (!isFalling && timer <= 2.2f)
    {
      isFalling = true;
      x = game().getPlayer()->getX();
      y = game().getPlayer()->getY();
      // to prevent collisions
      float x0 = TILE_WIDTH + 1;
      float xf = TILE_WIDTH * (MAP_WIDTH - 1) - 1;
      float y0 = TILE_HEIGHT + 1;
      float yf = TILE_HEIGHT * (MAP_HEIGHT - 1) - 1;

      calculateBB();

      if (boundingBox.left < x0) x += (x0 - boundingBox.left);
      else if (boundingBox.left + boundingBox.width > xf) x -= (boundingBox.left + boundingBox.width - xf);

      if (boundingBox.top < y0) y += (y0 - boundingBox.top);
      else if (boundingBox.top + boundingBox.height > yf) y -= (boundingBox.top + boundingBox.height - yf);
    }
    if (timer < 2.3f)
    {
      h += hVelocity * delay;
      if (h <= 0)
      {
        h = 0;
        changeToState(8);
        game().makeShake(0.8f);
        SoundManager::getInstance().playSound(SOUND_CYCLOPS_IMPACT);
      }
    }
  }

  if (state == 6 && timer < 0.5f)
  {
    int fade = timer * 512;
    if (fade < 0) fade = 0;
    sprite.setColor(sf::Color(255, 255, 255, fade));
  }
  else if (state == 7 && timer < 1.5f)
    sprite.setColor(sf::Color(255, 255, 255, 255));
  else if (state == 7 && timer < 2.0f)
    sprite.setColor(sf::Color(255, 255, 255, (2.0f - timer) * 512));
  else if (state == 7)
    sprite.setColor(sf::Color(255, 255, 255, 0));

  isMirroring = (frame == 2) && (velocity.x < 0.0f);
  z = y + 26;
}
예제 #4
0
void Robot::setRandDirection()
{
	int randAngle = rand() % 360;
	setVelocity(Vector3(1, 0, 0).GetRotatedY(randAngle));
  setRotation(Vector3(0, -randAngle+90.f, 0));
}
void SimpleWalkingMonster::update()
{
	switch(mState)
	{
	case State_Walking:
		{
			mVelocity.y += 6.0f;
			mVelocity.x = 20.0f * ((mFacing==Facing_Left)?-1:1);

			setVelocity(mVelocity);
			int bumps = moveWithCollision();

			if ((bumps & (Direction_Up | Direction_Down)) != 0) 
			{
				mVelocity.y = 0;
			}

			if ((bumps & (Direction_Left)) != 0)
			{
				mFacing = Facing_Right;
			}

			if ((bumps & (Direction_Right)) != 0)
			{
				mFacing = Facing_Left;
			}


			int offsetX = (mState==Facing_Right)?-getHalfSize().x-2:getHalfSize().x+2;
			int offsetY = getHalfSize().y+2;
		
			float2 position = getPosition();

			int x = (position.x+offsetX) / (float)mRoom->getTileWidth();
			int y = (position.y+offsetY) / (float)mRoom->getTileHeight();

			if (!mRoom->isCollidable(x, y))
			{
				if (mFacing == Facing_Left)
				{
					mFacing = Facing_Right;
				}
				else
				{
					mFacing = Facing_Left;
				}
			}

			if (mRand.getFloat(1.0f) < WALK_TO_IDLE_CHANCE)
			{
				mState = State_Idling;
			}
		}

		break;
	case State_Idling:

		if (mRand.getFloat(1.0f) < IDLE_TO_WALK_CHANCE)
		{
			if (mRand.getFloat(1.0f) > 0.5)
			{
				mFacing = Facing_Left;
			}
			else
			{
				mFacing = Facing_Right;
			}
			mState = State_Walking;
		}

		break;
	}

	Hero* hero = mRoom->getHero();
	if (Collides(hero->getCollisionRect(), getCollisionRect()))
	{
		hero->kill();
	}

	mFrame++;
}
예제 #6
0
bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    this->isGameOver = false;
    
    visibleSize = Director::getInstance()->getVisibleSize();
    
    // Ground setup
    groundSprite0 = Sprite::create("ground.png");
    this->addChild(groundSprite0);
    groundSprite0->setPosition(Vec2(groundSprite0->getContentSize().width/2.0 , groundSprite0->getContentSize().height/2));
    
    groundSprite1 = Sprite::create("ground.png");
    this->addChild(groundSprite1);
    groundSprite1->setPosition(Vec2(visibleSize.width + groundSprite1->getContentSize().width/2.0 -10, groundSprite1->getContentSize().height/2));
    
    auto groundbody0 = PhysicsBody::createBox(groundSprite0->getContentSize());
    groundbody0->setDynamic(false);
    groundbody0->setContactTestBitmask(true);
    groundSprite0->setPhysicsBody(groundbody0);
    auto groundbody1 = PhysicsBody::createBox(groundSprite1->getContentSize());
    groundbody1->setDynamic(false);
    groundbody1->setContactTestBitmask(true);
    groundSprite1->setPhysicsBody(groundbody1);
    
    // SkyGround setup
    Sprite *skySprite0 = Sprite::create("flappy_background.png");
    Sprite *skySprite1 = Sprite::create("flappy_background.png");
    Sprite *skySprite2 = Sprite::create("flappy_background.png");
    this->addChild(skySprite0);
    this->addChild(skySprite1);
    this->addChild(skySprite2);
    skySprite0->setPosition(visibleSize.width/2, 168 + 200);
    skySprite1->setPosition(visibleSize.width/2 - skySprite1->getContentSize().width, 168 + 200);
    skySprite2->setPosition(visibleSize.width/2 + skySprite1->getContentSize().width, 168 + 200);
    
    // bird setup
    /*
    Sprite *birdSprite = Sprite::create("flappybird1.png");
    this->addChild(birdSprite);
    birdSprite->setPosition(visibleSize.width/2, visibleSize.height/2 + 120);
    */

    SpriteFrameCache* cache = SpriteFrameCache::getInstance();
    cache->addSpriteFramesWithFile("bird.plist");
    
    auto flyAnim = Animation::create();
    for (int i = 1; i < 4; i++) {
        SpriteFrame * frame = cache->getSpriteFrameByName("flappybird" + to_string(i) + ".png");
        flyAnim->addSpriteFrame(frame);
    }
    auto birdSprite = Sprite::createWithSpriteFrameName("flappybird1.png");

    flyAnim->setDelayPerUnit(0.2f);
    
    auto action = Animate::create(flyAnim);
    auto animation = RepeatForever::create(action);
    birdSprite->runAction(animation);
    
    birdSprite->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2 + 80));
    this->addChild(birdSprite);

    auto birdBody = PhysicsBody::createCircle(17.0);
    birdBody->setDynamic(true);
    birdBody->setMass(1.0f);
    birdBody->setVelocity(Vec2(4.0f, 2.0f));
    birdBody->setVelocityLimit(50);
    birdBody->setContactTestBitmask(true);
    birdSprite->setPhysicsBody(birdBody);
    
    //pipe setup
    topPipeSprite = Sprite::create("top_pipe.png");
    bottomPipeSprite = Sprite::create("bottom_pipe.png");
    topPipeSprite->setPosition(visibleSize.width + topPipeSprite->getContentSize().width/2, 600);
    
    auto pipebody0 = PhysicsBody::createBox(topPipeSprite->getContentSize());
    pipebody0->setDynamic(false);
    topPipeSprite->setPhysicsBody(pipebody0);
    pipebody0->setContactTestBitmask(true);
    auto pipebody1 = PhysicsBody::createBox(bottomPipeSprite->getContentSize());
    pipebody1->setDynamic(false);
    pipebody1->setContactTestBitmask(true);
    bottomPipeSprite->setPhysicsBody(pipebody1);
    
    this->positionBottomPipe();
    this->addChild(topPipeSprite);
    this->addChild(bottomPipeSprite);
    
    //setup touch listener
    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);

    listener->onTouchBegan = [=](Touch *touch, Event *event){
        if (!this->isGameOver) {
            birdBody->applyImpulse(Vec2(0, 90.0f));
        }
        log("touch detected!");
        return true;
    };
    
    //setup collision listener
    auto plistener = EventListenerPhysicsContact::create();
    plistener->onContactBegin = [=](PhysicsContact &contact){
        log("collision detected!");
        auto gameOverSprite = Sprite::create("game_over.png");
        gameOverSprite->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
        this->addChild(gameOverSprite);
        this->isGameOver = true;
        
        auto restartListner = EventListenerTouchOneByOne::create();
        restartListner->setSwallowTouches(true);
        restartListner->onTouchBegan = [](Touch *touch, Event* event){
            Director::getInstance()->replaceScene(HelloWorld::createScene());
            return true;
        };
        Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(restartListner, gameOverSprite);
        return true;
    };
    
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(plistener, this);
    this->scheduleUpdate();
    
    return true;
}
예제 #7
0
void BouncyLogo::initSpeed()
{
    const double speed = 4.0;
    double d = (double)(rand()%1024) / 1024.0;
    setVelocity( d*speed*2-speed, (1-d)*speed*2-speed );
}
	void Listener::setVelocity(const Ogre::Vector3& vec)
	{
		setVelocity(vec.x, vec.y, vec.z);
	}
예제 #9
0
bool SFXSound::_allocVoice( SFXDevice* device )
{
   // We shouldn't have any existing voice!
   AssertFatal( !mVoice, "SFXSound::_allocVoice() - Already had a voice!" );

   // Must not assign voice to source that isn't playing.
   AssertFatal( getLastStatus() == SFXStatusPlaying,
      "SFXSound::_allocVoice() - Source is not playing!" );

   // The buffer can be lost when the device is reset 
   // or changed, so initialize it if we have to.  If
   // that fails then we cannot create the voice.
   
   if( mBuffer.isNull() )
   {
      SFXProfile* profile = getProfile();
      if( profile != NULL )
      {
         SFXBuffer* buffer = profile->getBuffer();
         if( buffer )
            _setBuffer( buffer );
      }

      if( mBuffer.isNull() )
         return false;
   }

   // Ask the device for a voice based on this buffer.
   mVoice = device->createVoice( is3d(), mBuffer );
   if( !mVoice )
      return false;
            
   // Set initial properties.
   
   mVoice->setVolume( mPreAttenuatedVolume );
   mVoice->setPitch( mEffectivePitch );
   mVoice->setPriority( mEffectivePriority );
   if( mDescription->mRolloffFactor != -1.f )
      mVoice->setRolloffFactor( mDescription->mRolloffFactor );
      
   // Set 3D parameters.
   
   if( is3d() )
   {
      // Scatter the position, if requested.  Do this only once so
      // we don't change position when resuming from virtualized
      // playback.
      
      if( !mTransformScattered )
         _scatterTransform();
      
      // Set the 3D attributes.

      setTransform( mTransform );
      setVelocity( mVelocity );
      _setMinMaxDistance( mMinDistance, mMaxDistance );
      _setCone( mConeInsideAngle, mConeOutsideAngle, mConeOutsideVolume );
   }
   
   // Set reverb, if enabled.

   if( mDescription->mUseReverb )
      mVoice->setReverb( mDescription->mReverb );
   
   // Update the duration... it shouldn't have changed, but
   // its probably better that we're accurate if it did.
   mDuration = mBuffer->getDuration();

   // If virtualized playback has been started, we transfer its position to the
   // voice and stop virtualization.

   const U32 playTime = mPlayTimer.getPosition();
   
   if( playTime > 0 )
   {
      const U32 pos = mBuffer->getFormat().getSampleCount( playTime );
      mVoice->setPosition( pos);
   }

   mVoice->play( isLooping() );
   
   #ifdef DEBUG_SPEW
   Platform::outputDebugString( "[SFXSound] allocated voice for source '%i' (pos=%i, 3d=%i, vol=%f)",
      getId(), playTime, is3d(), mPreAttenuatedVolume );
   #endif
   
   return true;
}
예제 #10
0
void Player::setVelocity(float dx, float dy)
{
	setVelocity(Vector(dx, dy));
}
예제 #11
0
void Player::update(float dt)
{
	if(mStunnedCounter > 0.0f)
		mStunnedCounter -= dt;
	else
		mStunned = false;

	// Update the animation
	mAnimation->animate(dt);

	// Update the head rotation
	updateHead();

	// Update the weapon
	if(mWeapon != NULL)	{
		mWeapon->updatePosition(getPosition());
		mWeapon->incrementCooldownCounter(dt);
	}

	/* Update the velocity */

	// Strafing sideways
	if(gDInput->keyDown(DIK_A) && !mStunned && getVelocity().x > -mMaxVelocity)	{	// Left
		getBody()->ApplyForce(Vector(-mAcceleration, 0), getPosition());
		setFacingDirection(LEFT);

		if(mWeapon != NULL)
			mWeapon->setFlipped(true);

		// If the player is on the ground, continue the animation
		if(!mInAir)	
			mAnimation->resume();
	}
	else if(gDInput->keyDown(DIK_D) && !mStunned && getVelocity().x < mMaxVelocity)	{	// Right
		getBody()->ApplyForce(Vector(mAcceleration, 0), getPosition());
		setFacingDirection(RIGHT);

		if(mWeapon != NULL)
			mWeapon->setFlipped(false);

		// If the player is on the ground, continue the animation
		if(!mInAir)	
			mAnimation->resume();
	}
	
	// If A or D is released set the frame to 0 if the player not is in the air
	if(gDInput->keyReleased(DIK_A) || gDInput->keyReleased(DIK_D))	{
		mAnimation->pause();

		if(!mInAir)
			mAnimation->setFrame(0);
	}

	// Jump if the player is on the ground
	if(gDInput->keyDown(DIK_SPACE) && !mInAir)	{
		setVelocity(getVelocity() + Vector(0, -500));
		getBody()->Move(0, -1);		// Move it out of collision (:HACK:)
		mAnimation->setFrame(7);	// Set the jumping frame
		mAnimation->pause();		// Pause the animation
		mInAir = true;				// The player is now in the air
	}

	// Shooting with the left mouse button
	if(gDInput->mouseButtonDown(0))	{
		if(mWeapon != NULL)	{
			if(mWeapon->isReady())	{
				mWeapon->attack();
				mWeapon->setCooldownCounter(0.0f);
				mWeapon->setAttacking(true);
			}
		}
	}

	// Drop the equipped weapon if the drop button was pressed
	if(gDInput->keyPressed(DIK_G))
		dropWeapon();

	// Loot
	if(gDInput->keyPressed(DIK_E))
		checkLoot();
}
예제 #12
0
	void loop() {
		
		//Variable Initialization
		
        time ++;
		api.getMyZRState(myState);
        api.getOtherZRState(otherState);
		phase = game.getCurrentPhase();
		fuel = game.getFuelRemaining();
		myScore = game.getScore();
		otherScore = game.getOtherScore();
		dust = game.getRemainingMaterial();
		chg = game.getCharge();
		
		if (time < 2) {
			red = statePos(myState)[0] < floatZero;
		}
		
		//Debug Console
		
		DEBUG(("\nDevilTech Message Screen: Fall 2012\n"));
#if printDebug
		DEBUG(("Debug Info\n"));
		DEBUG(("\tTime (s)\t%d\tPhase\t%d\tPlayer\t%s\n", time, phase, (red ? "Red" : "Blue")));
		DEBUG(("\tFuel\t%.3f\tDust\t%.3f\tChg\t%d\n", fuel, dust, chg));
		DEBUG(("\tScore\t%.2f\tOther Score\t%.2f\n", myScore, otherScore));
		DEBUG(("\tOther Message\t%u\n", otherMessage));
		printVec("\tMy Pos (m)", statePos(myState));
		printVec("\tMy Vel (m/s)", stateVel(myState));
		printVec("\tMy Att (unitvec)", stateAtt(myState));
		printVec("\tMy AngVel (rad/s)", stateAngVel(myState));
		printVec("\tOther Pos (m)", statePos(otherState));
		printVec("\tOther Vel (m/s)", stateVel(otherState));
		printVec("\tOther Att (unitvec)", stateAtt(otherState));
		printVec("\tOther AngVel (rad/s)", stateAngVel(otherState));
#endif
		
		vec att = {floatZero, -1.0f, floatZero};
		if (!obsCreated) {
			if (makeObs(red ? -0.17f : 0.17f, -0.63f)) obsCreated ++;
		}
		else if (obsCreated == 1) {
			if (makeObs(red ? -0.47f : 0.47f, -0.03f)) obsCreated ++;
		}
		else if (phase == 1) {
			vec temp = {norm((red ? -0.45f : 0.45f) - myState[0], 0.015f), 0.05f, floatZero};
			setVelocity(temp);
			//api.setAttitudeTarget(att);
		}
		else {
			if (!game.haveObject(0)) getItem(0);
			else if (!game.haveObject(1) && !game.otherHasObject(1)) getItem(1);
            else if (!game.haveObject(2) && !game.otherHasObject(2) && !game.haveObject(1)) getItem(2);
            else {
				if (game.haveObject(1) || game.haveObject(2)) {
                    api.setAttitudeTarget(att);
				}
                vec temp = {floatZero, floatZero, floatZero};
                if (phase == 2) {
                    vec temp2 = {(red ? 0.04f : -0.04f), 0.09f, floatZero};
                    attToTarget(myState, temp2, temp);
                    vecScale(temp, 0.057f);
                    temp[2] = maintainZ();
                    setVelocity(temp);
                }
                else {
                    if (!alreadySet) {
                        alreadySet = true;
                        top = myState[2] > floatZero;
                    }
                    if (myState[1] > -0.4f) {
						remDust();
                        temp[0] = norm((red ? 0.045f : -0.045f) - myState[0], 0.015f);
                        temp[1] = -0.051f;
                        temp[2] = maintainZ();
                    }
                    else if (myState[1] > -0.6f) {
						temp[0] = norm((red ? 0.045f : -0.045f) - myState[0], 0.015f);
                        temp[1] = -0.022f;
                        temp[2] = maintainZ();
                    }
                    else {
						temp[0] = norm((red ? 0.045f : -0.045f) - myState[0], 0.015f);
                        temp[1] = floatZero;
                        temp[2] = (top ? -0.055f : 0.055f);
                        DEBUG(("Top:\t%d\t%.3f\n", top, temp[2]));
                    }
                    setVelocity(temp);
                }
            }
        }
	}
예제 #13
0
	void Physics::shock(cg::Vector2d collisionPoint, double Force) {
		cg::Vector2d collisionVector = cg::Vector2d(_position[0] - collisionPoint[0], _position[1] - collisionPoint[1]);
			collisionVector /= length(collisionVector);
			setVelocity(Force*collisionVector[0]/_mass + _velocity[0],Force*collisionVector[1]/_mass + _velocity[1]);
	}
예제 #14
0
    void Physics::decelerate(double step, double limit) {
        _velocity = _velocity -  _velocity/step;
		if (length(_velocity) < limit)
            setVelocity(0,0);
    }
예제 #15
0
파일: sprites.cpp 프로젝트: Camelek/qtmoko
/*!
  The advance function does quite a lot for the ship sprite.
  In \a phase 0, if the ship is marked dead, just return. If
  not, move the ship using its current position and velocity.
  Then get the list of all collisions with the ship and run
  through the list.

  If the ship collides with a rock, then if the shield is
  up, destroy the rock. If the shiled is down (normal), mark
  the ship dead and return.

  If the ship collides with a powerup, then if the shield is
  up, mark the powerup destroyed. If the shield is not up,
  apply the powerup to the ship.

  In phase 1, if the ship is marked dead, explode the ship,
  delete it, and return. Otherwise, handle ship rotation,
  breaking, ship velocity, an teleporting. also update the
  image if the ship is rotating, and the exhaust image, if
  the engine is on. If the shiled is up, handle its image
  and age. Finally, in phase one, handle the firing of the
  missiles.
  \internal
 */
void KShip::advance(int phase)
{
    if (phase == 0) {
	if (dying())
	    markDead();
	if (isDead() || teleport_)
	    return;
	KSprite::advance(phase);
	QList<QGraphicsItem*> hits = ship_->collidingItems();
	QList<QGraphicsItem*>::Iterator i;
	for (i=hits.begin(); i!=hits.end(); ++i) {
	    if ((*i)->type() <= ID_Base)
		continue;
	    KSprite* sprite = (KSprite*)(*i);
	    if (sprite->isRock()) {
		if (shield_->isUp()) {
		    /*
		      The ship hit a rock with the shield up.
		      The rock is marked for death, which will
		      cause it to break up or just disappear in
		      in phase 1.

		      The shield's strength is reduced by an
		      amount commensurate with the rock size.
		      If the strength goes to 0, the shield
		      will be dropped in phase 1.
		     */
		    sprite->markDead();
		    int s = 1;
		    if (sprite->isLargeRock())
			s = 3;
		    else if (sprite->isMediumRock())
			s = 2;
		    int pl = s * (SHIELD_HIT_COST - (shield_->strength()*2));
		    shield_->reduceStrength(s);
		    reducePowerLevel(pl);
		}
		else {
		    /*
		      The ship hit a rock with the shield down.
		      Mark the ship dead and return. The ship
		      will be exploded in phase 1.
		     */
                    view_->setCanPause(false);
		    markDead();
		    shield_->markDead();
		    return;
		}
	    }
	    else if (sprite->isPowerup()) {
		if (shield_->isUp()) {
		    sprite->markDead();
		}
		else {
		    /*
		      The ship hit a powerup with the shield down.
		      Mark the powerup for apply. It will be applied
		      to the ship in phase 1, if the ship survives.
		      Also mark the powerup dead, ie consumed.
		     */
		    sprite->markApply();
		    sprite->markDead();
		    return;
		}
	    }
            else if (powerLevel() <= EMPTY_SHIP_POWER_LEVEL) {
                ship_->markDead();
                shield_->markDead();
            }
	}
    }
    else { // phase 1
	if (isDead() || dying()) {
	    explode(); // shatters the ship into spinning fragments.
	    delete this;
	    return;
	}
	if (rotateSlow_)
	    rotateSlow_--;

	if (rotateLeft_) {
	    angleIndex_ -= rotateSlow_ ? 1 : rotationRate_;
	    if (angleIndex_ < 0)
		angleIndex_ = SHIP_STEPS-1;
	    angle_ = angleIndex_ * PI_X_2 / SHIP_STEPS;
	    cosangle_ = cos(angle_);
	    sinangle_ = sin(angle_);
	}

	if (rotateRight_) {
	    angleIndex_ += rotateSlow_ ? 1 : rotationRate_;
	    if (angleIndex_ >= SHIP_STEPS)
		angleIndex_ = 0;
	    angle_ = angleIndex_ * PI_X_2 / SHIP_STEPS;
	    cosangle_ = cos(angle_);
	    sinangle_ = sin(angle_);
	}

	if (isBraking()) {
	    stopEngine();
	    stopRotation();
	    if ((fabs(dx_) < 2.5) && (fabs(dy_) < 2.5)) {
		dx_ = 0.0;
		dy_ = 0.0;
		setVelocity(dx_,dy_);
		releaseBrakes();
	    }
	    else {
		double motionAngle = atan2(-dy_,-dx_);
		if (angle_ > M_PI)
		    angle_ -= PI_X_2;
		double angleDiff = angle_ - motionAngle;
		if (angleDiff > M_PI)
		    angleDiff = PI_X_2 - angleDiff;
		else if (angleDiff < -M_PI)
		    angleDiff = PI_X_2 + angleDiff;
		double fdiff = fabs(angleDiff);
		if (fdiff > 0.08) {
		    if (angleDiff > 0)
			rotateLeft_ = true;
		    else if (angleDiff < 0)
			rotateRight_ = true;
		    if (fdiff > 0.6)
			rotationRate_ = brakeForce() + 1;
		    else if (fdiff > 0.4)
			rotationRate_ = 2;
		    else
			rotationRate_ = 1;

		    if (rotationRate_ > 5)
			rotationRate_ = 5;
		}
		else if ((fabs(dx_)>1) || (fabs(dy_)>1)) {
		    startEngine();
		    // we'll make braking a bit faster
		    dx_ += cosangle_/6 * (brakeForce() - 1);
		    dy_ += sinangle_/6 * (brakeForce() - 1);
		    reducePowerLevel(BRAKE_ON_COST);
		    KExhaust::add(ship_->x() + 10 - cosangle_*11,
				  ship_->y() + 10 - sinangle_*11,
				  dx_-cosangle_,
				  dy_-sinangle_,
				  brakeForce()+1);
		}
	    }
	}
	else if (engineIsOn()) {
	    /*
	      The ship has a terminal velocity, but trying
	      to go faster still uses fuel (can go faster
	      diagonally - don't care).
	    */
	    double thrustx = cosangle_/8;
	    double thrusty = sinangle_/8;
	    if (fabs(dx_ + thrustx) < MAX_SHIP_SPEED)
		dx_ += thrustx;
	    if (fabs(dy_ + thrusty) < MAX_SHIP_SPEED)
		dy_ += thrusty;
	    setVelocity(dx_,dy_);
	    reducePowerLevel(5);
	    KExhaust::add(x() + 10 - cosangle_*10,
			  y() + 10 - sinangle_*10,
			  dx_-cosangle_,
			  dy_-sinangle_,
			  3);
	}

	setImage(angleIndex_ >> 1);

	if (teleport_) {
	    int ra = rand() % 10;
	    if(ra == 0)
		ra += rand() % 20;
	    int xra = ra * 60 + ((rand() % 20) * (rand() % 20));
	    int yra = ra * 50 - ((rand() % 20) * (rand() % 20));
	    setPos(xra,yra);
	    teleport_ = false;
	    if (teleportCount_ > 0) {
		--teleportCount_;
		view_->markVitalsChanged();
	    }
	    wrap();
	}

	if (shield_->isUp()) {
	    /*
	      The shield's position always depends on the
	      ship's position.
	     */
	    static int sf = 0;
	    sf++;
	    if (sf % 2)
		shield_->advanceImage();
	    shield_->setPos(x()-5,y()-5);
	    shield_->show();
	}

	if (isShooting()) {
	    int maxMissiles = firePower_ + 2;
	    if (canShoot() && (KMissile::missiles() < maxMissiles)) {
		KMissile* missile = new KMissile();
		missile->setMaximumAge(12);
		missile->setPos(11 + x() + cosangle_ * 11,
				11 + y() + sinangle_ * 11);
		missile->setVelocity(dx_ + cosangle_ * MISSILE_SPEED,
				     dy_ + sinangle_ * MISSILE_SPEED);
		missile->show();
		reducePowerLevel(1);
		view_->reportMissileFired();
		int delay = 5 - firePower_;
		if (delay < 0)
		    delay = 0;
		delayShooting(delay); // delay firing next missile.
	    }
	    decrementNextShotDelay();
	}
    }
}
예제 #16
0
void Pod::init() {
    setVelocity(0, -1);

}
예제 #17
0
파일: sprites.cpp 프로젝트: Camelek/qtmoko
/*!
  Create an exhaust sprite at position \a x, \a y with
  velocity \a dx, \a dy.
 */
KExhaust::KExhaust(double x, double y, double dx, double dy)
    : KAgingSprite(1)
{
    setPos(x + 2 - randDouble()*4, y + 2 - randDouble()*4);
    setVelocity(dx,dy);
}
예제 #18
0
void SlimePetEntity::animate(float delay)
{
    if (age < 0.0f)
    {
        age += delay;
    }
    else
    {

        attackDelay -= delay;

        if (isJumping)
        {
            hVelocity -= 700.0f * delay;

            h += hVelocity * delay;

            bool firstTimeGround = false;

            if (h <= 0.0f)
            {
                h = 0.0f;
                if (isFalling())
                {
                    fall();
                }
                else
                {
                    if (isFirstJumping)
                    {
                        isFirstJumping = false;
                        firstTimeGround = true;
                        hVelocity = 160.0f;
                        SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT);
                    }
                    else
                    {
                        jumpingDelay = 0.3f + 0.1f * (rand() % 15);
                        isJumping = false;
                        SoundManager::getInstance().playSound(SOUND_SLIME_IMAPCT_WEAK);
                    }
                }
            }
            if (firstTimeGround) frame = 0;
            else if (hVelocity > -190.0f) frame = 2;
            else frame = 1;
        }
        else if (isFalling())
        {
            fall();
        }
        else
        {
            jumpingDelay -= delay;
            if (jumpingDelay < 0.0f)
            {
                SoundManager::getInstance().playSound(SOUND_SLIME_JUMP);
                hVelocity = 300.0f + rand() % 250;
                isJumping = true;
                isFirstJumping = true;

                float randVel = 250.0f + rand() % 250;

                setVelocity(Vector2D(x, y).vectorTo(game().getPlayerPosition(), randVel ));
            }
            else if (jumpingDelay < 0.1f)
                frame = 1;
            else frame = 0;
        }

        BaseCreatureEntity::animate(delay);
        if (canCollide()) testSpriteCollisions();
    }

    z = y + 14;
}
예제 #19
0
파일: Entity.cpp 프로젝트: ELMERzark/JVGS
        void Entity::loadData(TiXmlElement *element)
        {
            PropertyMap::loadData(element);

            /* Get id. */
            if(element->Attribute("id"))
                setId(element->Attribute("id"));

            /* Load basic data. */
            Vector2D position = getPosition();
            Vector2D::fromXML(element->FirstChildElement("position"),
                    &position);
            setPosition(position);

            Vector2D velocity = getVelocity();
            Vector2D::fromXML(element->FirstChildElement("velocity"),
                    &velocity);
            setVelocity(velocity);

            Vector2D::fromXML(element->FirstChildElement("radius"), &radius);

            queryBoolAttribute(element, "collisionchecker", &collisionChecker);

            float speed = getSpeed();;
            element->QueryFloatAttribute("speed", &speed);
            setSpeed(speed);

            /* Load controller. */
            TiXmlElement *controllerElement =
                    element->FirstChildElement("controller");
            if(controllerElement) {
                string type = controllerElement->Attribute("type");
                map<string, AffectorFactory<Controller>*>::iterator
                        controllerFactory = controllerFactories.find(type);
                if(controllerFactory != controllerFactories.end())
                    controller = controllerFactory->second->create(this,
                            controllerElement);
                else
                    LogManager::getInstance()->error("No controller: %s",
                            type.c_str());
            }

            /* Load positioner. */
            TiXmlElement *positionerElement =
                    element->FirstChildElement("positioner");
            if(positionerElement) {
                string type = positionerElement->Attribute("type");
                map<string, AffectorFactory<Positioner>*>::iterator
                        positionerFactory = positionerFactories.find(type);
                if(positionerFactory != positionerFactories.end())
                    positioner = positionerFactory->second->create(this,
                            positionerElement);
                else
                    LogManager::getInstance()->error("No positioner: %s",
                            type.c_str());
            }

            /* Load sprite. */
            TiXmlElement *spriteElement = element->FirstChildElement("sprite");
            sprite = spriteElement ? new Sprite(spriteElement) : sprite;

            /* Load script. */
            script = element->Attribute("script") ?
                    element->Attribute("script") : script;
        }
예제 #20
0
void AudioSource::setVelocity(float x, float y, float z)
{
    setVelocity(Vector3(x, y, z));
}
예제 #21
0
void BouncyLogo::advance(int stage)
{
    switch ( stage ) {
      case 0: {
	double vx = xVelocity();
	double vy = yVelocity();

	if ( vx == 0.0 && vy == 0.0 ) {
	    // stopped last turn
	    initSpeed();
	    vx = xVelocity();
	    vy = yVelocity();
	}

	double nx = x() + vx;
	double ny = y() + vy;

	if ( nx < 0 || nx >= canvas()->width() )
	    vx = -vx; // 換反方向
	if ( ny < 0 || ny >= canvas()->height() )
	    vy = -vy; // 換反方向

	for (int bounce=0; bounce<4; bounce++) {
	    QCanvasItemList l=collisions(FALSE); // 沒有那麼精準的傳回所有有碰撞的canvas item
	    for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
		QCanvasItem *hit = *it;
		if ( hit->rtti()==logo_rtti && hit->collidesWith(this) ) {
		    switch ( bounce ) {
		      case 0:
			vx = -vx;
			break;
		      case 1:
			vy = -vy;
			vx = -vx;
			break;
		      case 2:
			vx = -vx;
			break;
		      case 3:
			// Stop for this turn
			vx = 0;
			vy = 0;
			break;
		    }
		    setVelocity(vx,vy);
		    break;
		}
	    }
	}

	if ( x()+vx < 0 || x()+vx >= canvas()->width() )
	    vx = 0;
	if ( y()+vy < 0 || y()+vy >= canvas()->height() )
	    vy = 0;

	setVelocity(vx,vy);
      } break;
      case 1:
	QCanvasItem::advance(stage);
	break;
    }
}
예제 #22
0
int setup(){
	/* setup communications to the device */
	memset(out,0,64);
        memset(in,0,64);


	/* setup gpio */

	evgpioinit();
        evsetddr(81,0);
        evsetddr(82,0);
	evsetddr(83,1);
        evsetdata(61,0);

	
        int i;
        for(i=36;i<41;i++){
                evsetmask(i,1);
                evgetin(i);
        }

        sleep(.1);
        evclrwatch();
	
	/* current values */
	/* the following needs to be added to the status routine
	int x;
	for(x=36; x<41; x++) {
        	int value = evgetin((int)x);
                printf("%d\t",value);
        }
	printf("\n");
	*/

        if(!fnPerformaxComGetNumDevices(&num))
        {
                printf("error in fnPerformaxComGetNumDevices\n");
                return -1;
        }
        if(num<1)
        {
                printf( "No motor found\n");
                return -1;
        }

        if(!fnPerformaxComOpen(0,&Handle))
        {
                printf( "Error opening device\n");
                return -1;
        }

        if(!fnPerformaxComSetTimeouts(500,500))
        {
                printf("Error setting timeouts\n");
                return -1;
        }
        if(!fnPerformaxComFlush(Handle))
        {
                printf("Error flushing the coms\n");
                return -1;
        }

	printf("Setting Up Device\n");

	/* return the motor information */
        strcpy(out, "ID"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {       
                printf("Could not send\n");
                return -1;
        }
        
        printf("Arcus Product: %s\n",in);
        
        strcpy(out, "DN"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {       
                printf("Could not send\n");
                return -1;
        }
        
        printf("Device Number: %s\n",in);
        
        strcpy(out, "ABS"); //read current 
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {       
                printf("Could not send\n");
                return -1;
        }
        
        printf("Set move mode to absolute: %s\n",in);
        
        
        strcpy(out, "DOBOOT=0"); //read current 
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {       
                printf("Could not send\n");
                return -1;
        }
        
        printf("Disable Output, DOBOOT: %s\n",in);
        
        
        strcpy(out, "EDIO=0"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {       
                printf("Could not send\n");
                return -1;
        }
        
        printf("Disable DIO, EDIO: %s\n",in);

 	strcpy(out, "POL=4"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }

        printf("Set Limit Polarity: %s\n",in);

                strcpy(out, "POL=6"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }

        printf("Set Latch Polarity: %s\n",in);

        strcpy(out, "POL=1"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }

        printf("Set Directional Polarity: %s\n",in);


        strcpy(out, "SCV=0"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }

        printf("S-Curve Ramp Enabled: %s\n",in);



        strcpy(out, "IERR=1"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }

        printf("Ignore Error Enabled: %s\n",in);

	strcpy(out, "MST"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }

        printf("Motor Status, MST: %s\n",in);



        strcpy(out, "RR"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }
        sleep(2.5);//RR requires a 2 second minimum
        printf("Read Drive Parameters, RR: %s\n",in);

        strcpy(out, "DRVRC=1500"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }
        sleep(.1);
        printf("Set Drive Current, 1.5A, DRVRC: %s\n",in);


        strcpy(out, "RW"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }

	printf("Write Motor Parameters, RW: %s\n",in);


        sleep(1);
        strcpy(out, "SL=1"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }       
        
        printf("Write SL Parameters, SNL: %s\n",in);


	 sleep(1);

        strcpy(out, "SLR=25"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }       

        printf("Write SNL Parameters, SNL: %s\n",in);


        sleep(2.5);

        strcpy(out, "CLR"); //read current
        if(!fnPerformaxComSendRecv(Handle, out, 64,64, in))
        {
                printf("Could not send\n");
                return -1;
        }
        printf("Clear Errors: %s\n",in);
	setVelocity();

	return 1;	
}
void ofxBox2dBaseShape::setVelocity(ofVec2f p) {
	setVelocity(p.x, p.y);
}
예제 #24
0
void Enemy::update()
{
	setCurrentFrame(int(((SDL_GetTicks() / 100) % 6)));
	setVelocity(1, 1, 0);
	SDLGameObject::update();
}
예제 #25
0
U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
										  void **user_data,
										  U32 block_num, EObjectUpdateType update_type,
										  LLDataPacker *dp)
{
	// Do base class updates...
	U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);

	if (  (getVelocity().lengthSquared() > 0.f)
		||(getAcceleration().lengthSquared() > 0.f)
		||(getAngularVelocity().lengthSquared() > 0.f))
	{
		llinfos << "ACK! Moving tree!" << llendl;
		setVelocity(LLVector3::zero);
		setAcceleration(LLVector3::zero);
		setAngularVelocity(LLVector3::zero);
	}

	if (update_type == OUT_TERSE_IMPROVED)
	{
		// Nothing else needs to be done for the terse message.
		return retval;
	}

	// 
	//  Load Instance-Specific data 
	//
	if (mData)
	{
		mSpecies = ((U8 *)mData)[0];
	}
	
	if (!sSpeciesTable.count(mSpecies))
	{
		if (sSpeciesTable.size())
		{
			SpeciesMap::const_iterator it = sSpeciesTable.begin();
			mSpecies = (*it).first;
		}
	}

	//
	//  Load Species-Specific data 
	//
	mTreeImagep = gImageList.getImage(sSpeciesTable[mSpecies]->mTextureID);
	if (mTreeImagep)
	{
		gGL.getTexUnit(0)->bind(mTreeImagep.get());
	}
	mBranchLength = sSpeciesTable[mSpecies]->mBranchLength;
	mTrunkLength = sSpeciesTable[mSpecies]->mTrunkLength;
	mLeafScale = sSpeciesTable[mSpecies]->mLeafScale;
	mDroop = sSpeciesTable[mSpecies]->mDroop;
	mTwist = sSpeciesTable[mSpecies]->mTwist;
	mBranches = sSpeciesTable[mSpecies]->mBranches;
	mDepth = sSpeciesTable[mSpecies]->mDepth;
	mScaleStep = sSpeciesTable[mSpecies]->mScaleStep;
	mTrunkDepth = sSpeciesTable[mSpecies]->mTrunkDepth;
	mBillboardScale = sSpeciesTable[mSpecies]->mBillboardScale;
	mBillboardRatio = sSpeciesTable[mSpecies]->mBillboardRatio;
	mTrunkAspect = sSpeciesTable[mSpecies]->mTrunkAspect;
	mBranchAspect = sSpeciesTable[mSpecies]->mBranchAspect;
	
	// position change not caused by us, etc.  make sure to rebuild.
	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);

	return retval;
}
예제 #26
0
bool  GameSceneQuattro::onTouchBegan(Touch *touch, Event *unused_event){


	   cocos2d::log("onTouchBegan.......   ");
	   Size visibleSize = Director::getInstance()->getVisibleSize();
	   Vec2 origin = Director::getInstance()->getVisibleOrigin();
	   cocos2d::log("position = (%f,%f)",touch->getLocation().x,touch->getLocation().y);

    // _player1->runAction((CCAction *) _rotateSprite->copy()->autorelease());

    auto actionTo = SkewTo::create(2, 37.2f, -37.2f);
    auto actionToBack = SkewTo::create(2, 0, 0);
    auto actionBy = SkewBy::create(2, 0.0f, -90.0f);
    auto actionBy2 = SkewBy::create(2, 45.0f, 45.0f);
    auto actionByBack = actionBy->reverse();

    Vec2  offset = Vec2(_gugutAnimato->getPosition().x-touch->getLocation().x,_gugutAnimato->getPosition().y-touch->getLocation().y );
    float   ratio     = offset.y/offset.x;
    int     targetX   = _gugutAnimato->getContentSize().width/2 +  visibleSize.width;
    int     targetY   = (targetX*ratio) + _gugutAnimato->getPosition().y;

    Vec2 targetPositionProiettileTo = Vec2(targetX,targetY);

    auto *proiettile = _pietre->at( _nextPietra);
	   // auto *proiettile = CCSprite::create("pietra.png");

    _nextPietra++;

	  	if ( _nextPietra >= _pietre->size())
            _nextPietra = 0;

    proiettile->setPosition(Vec2(_gugutAnimato->getPosition().x,_gugutAnimato->getPosition().y+(_gugutAnimato->getContentSize().height)*0.3));
    proiettile->setVisible(true);

    auto spriteBody = PhysicsBody::createBox( proiettile->getContentSize( ), PhysicsMaterial( 0, 1, 0 ) );

    //spriteBody->applyImpulse( Vect( 400, 700 ) );

    proiettile->setPhysicsBody( spriteBody );
    spriteBody->setTag(PIETRA_TAG);//Tag del PhysicsBody
    spriteBody->setCollisionBitmask(5);
    spriteBody->setContactTestBitmask(true);

    spriteBody->setVelocity(targetPositionProiettileTo);


    ///addChild(proiettile, 9); in ios dava problemi perche aggiunto prima

 /*   auto moveToTargetPosition = MoveTo::create(1.2, targetPositionProiettileTo);


    auto seq2 = Sequence::create(moveToTargetPosition, NULL);

    proiettile->runAction(
                          Sequence::create(moveToTargetPosition,
                                           CallFuncN::create(CC_CALLBACK_1(GameSceneQuattro::setInvisible, this)),
                                           NULL )
                          );

   */

    return true;

}
예제 #27
0
Particle::Particle() {
    setup(ofColor(0), ofPoint(0,0), 0);
    setVelocity(ofPoint(0,0));
}
예제 #28
0
void PhysXRigidBody::addVelocity(const dim::vector3df &Direction)
{
    setVelocity(getVelocity() + Direction);
}
예제 #29
0
void GiantSlimeEntity::changeToState(int n)
{
  if (n == 0) // walking
  {
    state = 0;
    counter = 8 + rand() % 7;
    timer = -1.0f;
    viscosity = 1.0f;
  }
  else if (n == 1 || n == 3 || n == 5 || n == 8) // waiting
  {
    state = n;
    timer = 1.2f;
    setVelocity(Vector2D(0.0f, 0.0f));
  }
  else if (n == 2) // jumping
  {
    state = 2;
    timer = 4.0f;

    viscosity = 0.991f;

    SoundManager::getInstance().playSound(SOUND_SLIME_JUMP);
    hVelocity = 420.0f + rand() % 380;

    isFirstJumping = true;

    float randVel = 350.0f + rand() % 200;

    if (rand() % 2 == 0)
    {
      float tan = (game().getPlayer()->getX() - x) / (game().getPlayer()->getY() - y);
      float angle = atan(tan);

      if (game().getPlayer()->getY() > y)
        setVelocity(Vector2D(sin(angle) * randVel,
                             cos(angle) * randVel));
      else
        setVelocity(Vector2D(-sin(angle) * randVel,
                             -cos(angle) * randVel));
    }
    else
      velocity = Vector2D(randVel);
  }
  else if (n == 4) // walking
  {
    state = 4;
    if (hp <= hpMax / 4)
      counter = 26;
    if (hp <= hpMax / 2)
      counter = 18;
    else
      counter = 12;
    timer = GIANT_SLIME_MISSILE_DELAY;
  }
  else if (n == 6) // jumping
  {
    state = 6;
    timer = 1.2f;

    viscosity = 1.0f;

    SoundManager::getInstance().playSound(SOUND_SLIME_JUMP);
    hVelocity = GIANT_SLIME_ULTRA_JUMP_VELOCITY;
  }
  else if (n == 7) // falling
  {
    isFalling = false;
    state = 7;
    timer = GIANT_SLIME_ULTRA_JUMP_TIMER;

    hVelocity = GIANT_SLIME_ULTRA_FALL_VELOCITY;
    h = 1500;
  }
}
예제 #30
0
void ConstraintsNode::applyConstrainedTranslation(osg::Vec3 v)
{
    osg::Vec3 localPos = this->getTranslation();
    osg::ref_ptr<ReferencedNode> hitNode;
    ReferencedNode *testNode;

    // with really big velocities (or small enclosures), and if the surface
    // doesn't damp the velocity, it's possible to get see an infinite recursion
    // occur. So, we keep a recursionCounter, and stop prevent this occurrence:
    if (++recursionCounter > 10) return;

    /*
    std::cout << std::endl << "checking for collisions" << std::endl;
    std::cout << "start =  " << localPos.x()<<","<<localPos.y()<<","<<localPos.z() << std::endl;
    std::cout << "v =      " << v.x()<<","<<v.y()<<","<<v.z() << std::endl;
    */

    osg::ref_ptr<ReferencedNode> targetNode = dynamic_cast<ReferencedNode*>(_target->s_thing);

    if (targetNode.valid())
    {
        // get current position (including offset from previous bounces)
        osg::Matrix thisMatrix = osg::computeLocalToWorld(this->currentNodePath);
        osg::Vec3 worldPos = thisMatrix.getTrans();

        // set up intersector:
        osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(worldPos, worldPos + v);
        osgUtil::IntersectionVisitor iv(intersector.get());

        // apply intersector:
        targetNode->accept(iv);

        if (intersector->containsIntersections())
        {
            osgUtil::LineSegmentIntersector::Intersections intersections;
            osgUtil::LineSegmentIntersector::Intersections::iterator itr;

            intersections = intersector->getIntersections();

            for (itr = intersections.begin(); itr != intersections.end(); ++itr)
            {
                //std::cout << "testing intersection with " << (*itr).nodePath[0]->getName() << std::endl;

                // first check if the hit is with our target (should be first in
                // the nodepath):

                testNode = dynamic_cast<ReferencedNode*>((*itr).nodePath[0]);
                if (testNode!=targetNode) continue;

                // The intersection has a nodepath that we have to walk down to
                // see which exact node has been hit. It's possible that there
                // are other SPIN nodes in the targetNode's subgraph that are
                // the real source of intersection:

                hitNode = 0;
                testNode = 0;
                for (unsigned int i=0; i<(*itr).nodePath.size(); i++)
                {
                    testNode = dynamic_cast<ReferencedNode*>((*itr).nodePath[i]);
                    if (testNode) hitNode = testNode;
                }

                if (hitNode.valid())
                {

                    //std::cout << id->s_name << " collision!!! with " << (*itr).drawable->getName() << "[" << (*itr).primitiveIndex << "] @ " << std::endl;
                    //std::cout << "localHitPoint:\t" << localHitPoint.x()<<","<<localHitPoint.y()<<","<<localHitPoint.z() << std::endl;
                    //std::cout << "localHitNormal:\t" << localHitNormal.x()<<","<<localHitNormal.y()<<","<<localHitNormal.z() << std::endl;


                    // For BOUNCE mode, we need to check if we've intersected
                    // with the same primitive again. This may occur since we
                    // do recursive translations after repositioning the node at
                    // the bounce point (and there may be numerical imprecision)
                    // If so, we skip this intersection:
                    if ((_mode==BOUNCE) &&
                            (lastDrawable.get()==(*itr).drawable.get()) &&
                            (lastPrimitiveIndex==(int)(*itr).primitiveIndex))
                    {
                        //std::cout << "... skipping" << std::endl;
                        continue;
                    }
                    else
                    {
                        lastDrawable=(*itr).drawable;
                        lastPrimitiveIndex=(*itr).primitiveIndex;
                    }


                    osg::Vec3 localHitPoint = (*itr).getWorldIntersectPoint();
                    osg::Vec3 localHitNormal = (*itr).getWorldIntersectNormal();
                    localHitNormal.normalize();


                    // current direction vector:
                    osg::Vec3 dirVec = v;
                    dirVec.normalize();

                    // Find the rotation between the direction vector and the
                    // surface normal at the hit point:
                    osg::Quat rot;
                    rot.makeRotate(dirVec, localHitNormal);
                    //std::cout << "rot =     " << rot.x()<<","<<rot.y()<<","<<rot.z()<<","<<rot.w() << " ... angle=" << acos(rot.w())*2 << ", indegrees=" << osg::RadiansToDegrees(acos(rot.w()))*2 << std::endl;

                    // the surface normal may be in the opposite direction
                    // from us. If so, we need to flip it:
                    if (acos(rot.w()) * 2 > osg::PI_2)
                    {
                        localHitNormal *= -1;
                        rot.makeRotate(dirVec, localHitNormal);
                        //std::cout << "flipped = " << rot.x()<<","<<rot.y()<<","<<rot.z()<<","<<rot.w() << " ... angle=" << acos(rot.w())*2 << ", indegrees=" << osg::RadiansToDegrees(acos(rot.w()))*2 << std::endl;
                    }


                    osg::Vec3 rotEulers = QuatToEuler(rot);
                    //std::cout << "newHitNormal:\t" << localHitNormal.x()<<","<<localHitNormal.y()<<","<<localHitNormal.z() << std::endl;


                    if ((_mode==COLLIDE)||(_mode==COLLIDE_THRU)||(_mode==STICK))
                    {
                        // Let the collisionPoint be just a bit before the real
                        // hitpoint (to avoid numerical imprecision placing the
                        // node behind the plane):
                        osg::Vec3 collisionPoint = localHitPoint - (localHitNormal * 0.01);

                        // place the node at the collision point
                        setTranslation(collisionPoint.x(), collisionPoint.y(), collisionPoint.z());

                        BROADCAST(this, "ssfff", "collide", hitNode->id->s_name, osg::RadiansToDegrees(rotEulers.x()), osg::RadiansToDegrees(rotEulers.y()), osg::RadiansToDegrees(rotEulers.z()));


                        if (_mode==COLLIDE)
                        {
                            // SLIDE along the hit plane with the left over energy:
                            // ie, project the remaining vector onto the surface we
                            // just intersected with.
                            //
                            // using:
                            //   cos(theta) = distToSurface / remainderVector length
                            //
                            double cosTheta = (dirVec * -localHitNormal) ; // dot product
                            osg::Vec3 remainderVector = (localPos + v) - localHitPoint;
                            double distToSurface = cosTheta * remainderVector.length();
                            osg::Vec3 slideVector = remainderVector + (localHitNormal * distToSurface);

                            // pseudo-recursively apply remainder of bounce:
                            applyConstrainedTranslation( slideVector );
                        }
                        else if (_mode==COLLIDE_THRU)
                        {
                            // allow the node to pass thru (ie, just apply the
                            // translation):
                            //setTranslation(v.x(), v.y(), v.z());
                            osg::Vec3 newPos = localPos + v;
                            setTranslation(newPos.x(), newPos.y(), newPos.z());
                        }

                        return;
                    }


                    else if (_mode==BOUNCE)
                    {
                        // bounce returns a translation mirrored about the hit
                        // normal to the surface



                        // the new direction vector is a rotated version
                        // of the original, about the localHitNormal:
                        //osg::Vec3 newDir = (rot * 2.0) * -dirVec;
                        osg::Vec3 newDir = (rot * (rot * -dirVec));
                        newDir.normalize();
                        //std::cout << "newDir = " << newDir.x()<<","<<newDir.y()<<","<<newDir.z() << std::endl;


                        // amount of distance still to travel after bounce:
                        double dist = v.length() - (localHitPoint-localPos).length();
                        //std::cout << "dist =   " << dist << std::endl;



                        // in node is translating (ie, changing position
                        // independently from it's orientatino), then we need to
                        // flip the velocity vector.
                        if (_velocityMode == GroupNode::TRANSLATE)
                        {
                            osg::Vec3 newVel = newDir * _velocity.length();
                            setVelocity(newVel.x(), newVel.y(), newVel.z());
                        }

                        // if the node is moving along it's orientation vector,
                        // we need to update the orientation of so that it
                        // points in 'bounced' direction
                        else if (_velocityMode == GroupNode::MOVE)
                        {
                            osg::Quat newQuat;
                            newQuat.makeRotate(osg::Vec3(0,1,0),  newDir);
                            osg::Vec3 newRot = Vec3inDegrees(QuatToEuler(newQuat));
                            //std::cout << "newrot = " << newRot.x()<<","<<newRot.y()<<","<<newRot.z() << std::endl;
                            setOrientation(newRot.x(), newRot.y(), newRot.z());

                        }

                        // the new position will be just a hair before hitpoint
                        // (because numerical imprecision may place the hitpoint
                        // slightly beyond the surface, and when we bounce the
                        // node, we don't want to  intersect with the same
                        // surface again)
                        double HAIR = 0.0000001;
                        setTranslation(localHitPoint.x()-dirVec.x()*HAIR, localHitPoint.y()-dirVec.y()*HAIR, localHitPoint.z()-dirVec.z()*HAIR);
                        //setTranslation(localHitPoint.x(), localHitPoint.y(), localHitPoint.z());

                        //std::cout << "rotEulers = " << osg::RadiansToDegrees(rotEulers.x())<<","<<osg::RadiansToDegrees(rotEulers.y())<<","<<osg::RadiansToDegrees(rotEulers.z()) << std::endl;
                        BROADCAST(this, "ssfff", "bounce", hitNode->id->s_name, osg::RadiansToDegrees(rotEulers.x()), osg::RadiansToDegrees(rotEulers.y()), osg::RadiansToDegrees(rotEulers.z()));

                        // pseudo-recursively apply remainder of bounce:
                        applyConstrainedTranslation(newDir*dist);

                        return;

                    }
                }
            }
        } //else std::cout << "no intersections" << std::endl;
    }


    // no intersections, so just do regular translation:
    osg::Vec3 newPos = localPos + v;
    setTranslation(newPos.x(), newPos.y(), newPos.z());
}