void Player::FireBullet() { // nalicz opłatę za wystrzelenie pocisków PayForBullet(); if (IsTwinShotEnabled()) { PayForBullet(); } // GetX() oraz GetY() zwracają położenie lewego dolnego // narożnika postaci. W zależności od prędkości i stanu // postaci dodajemy pocisk po odpowiedniej stronie. double x, xvel; const double eps = 0.0001; // jakakolwiek prędkość if (m_state == PS::TurnLeft) { x = GetX() - .3; xvel = -eps; } else if (m_state == PS::TurnRight) { x = GetX() + .7; xvel = eps; } else { x = GetXVelocity() < 0 ? GetX() - .3 : GetX() + .7; xvel = GetXVelocity(); } const double y = GetY() + .5; AddCreator(CreatorPtr(new PlayerBulletCreator(x, y, xvel, 0))); if (IsTwinShotEnabled()) { double twin_xvel = xvel + 2 * (xvel>0?1:-1); // zwiększamy prędkość w zależności od zwrotu wektora prędkości AddCreator(CreatorPtr(new PlayerBulletCreator(x, y + .5, twin_xvel, 0))); } }
//----------------------------------------------------------------------------- // Purpose: Constructor for ship debris after explosion //----------------------------------------------------------------------------- CShipDebris::CShipDebris( IGameEngine *pGameEngine, float xPos, float yPos, DWORD dwDebrisColor ) : CSpaceWarEntity( pGameEngine, 0, true ) { AddLine( 0.0f, 0.0f, 16.0f, 0.0f, dwDebrisColor ); // Random rotation between 0 and 360 degrees (6.28 radians) float flRotation = (float)(rand()%628)/100.0f; SetRotationDeltaNextFrame( flRotation ); // Rotation to apply per second int nRandRotation = rand()%(157*2) - (157); m_flRotationPerInterval = nRandRotation/100.0f; float sinvalue = (float)sin( flRotation ); float cosvalue = (float)cos( flRotation ); float xVelocity = GetXVelocity() + ( sinvalue * 80 ); float yVelocity = GetYVelocity() - ( cosvalue * 80 ); // Offset out a bit from the center of the ship compensating for rotation float offset = (rand()%12)-6.0f; float xOffset = xPos + (cosvalue*-offset - sinvalue*-offset); float yOffset = yPos + (cosvalue*-offset + sinvalue*-offset); // Set velocity SetVelocity( xVelocity, yVelocity ); // Set position SetPosition( xOffset, yOffset ); }
//----------------------------------------------------------------------------- // Purpose: Build the update data to send from server to clients //----------------------------------------------------------------------------- void CShip::BuildServerUpdate( ServerShipUpdateData_t *pUpdateData ) { pUpdateData->SetDisabled( BIsDisabled() ); pUpdateData->SetExploding( BIsExploding() ); pUpdateData->SetXAcceleration( GetXAccelerationLastFrame() ); pUpdateData->SetYAcceleration( GetYAccelerationLastFrame() ); pUpdateData->SetXPosition( GetXPos()/(float)m_pGameEngine->GetViewportWidth() ); pUpdateData->SetYPosition( GetYPos()/(float)m_pGameEngine->GetViewportHeight() ); pUpdateData->SetXVelocity( GetXVelocity() ); pUpdateData->SetYVelocity( GetYVelocity() ); pUpdateData->SetRotation( GetAccumulatedRotation() ); pUpdateData->SetRotationDeltaLastFrame( GetRotationDeltaLastFrame() ); pUpdateData->SetForwardThrustersActive( m_bForwardThrustersActive ); pUpdateData->SetReverseThrustersActive( m_bReverseThrustersActive ); BuildServerPhotonBeamUpdate( pUpdateData ); }
void State::SetYVelocity(double y) { SetVelocity(GetXVelocity(), y); }
//----------------------------------------------------------------------------- // Purpose: Run a frame for the ship //----------------------------------------------------------------------------- void CShip::RunFrame() { if ( m_bDisabled ) return; const uint64 ulCurrentTickCount = m_pGameEngine->GetGameTickCount(); // Look for expired photon beams int nNextAvailablePhotonBeamSlot = -1; // Track next available slot for use spawning new beams below for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i ) { if ( m_rgPhotonBeams[i] ) { if ( m_rgPhotonBeams[i]->BIsBeamExpired() ) { delete m_rgPhotonBeams[i]; m_rgPhotonBeams[i] = NULL; } } if ( !m_rgPhotonBeams[i] && nNextAvailablePhotonBeamSlot == -1 ) nNextAvailablePhotonBeamSlot = i; } // run all the photon beams we have outstanding for( int i=0; i < MAX_PHOTON_BEAMS_PER_SHIP; ++i ) { if ( m_rgPhotonBeams[i] ) m_rgPhotonBeams[i]->RunFrame(); } // run all the space debris { std::list<CShipDebris *>::iterator iter; for( iter = m_ListDebris.begin(); iter != m_ListDebris.end(); ++iter ) (*iter)->RunFrame(); } if ( m_bIsLocalPlayer ) { m_SpaceWarClientUpdateData.SetTurnLeftPressed( false ); m_SpaceWarClientUpdateData.SetTurnRightPressed( false ); if ( m_pGameEngine->BIsKeyDown( m_dwVKLeft ) ) { m_SpaceWarClientUpdateData.SetTurnLeftPressed( true ); } if ( m_pGameEngine->BIsKeyDown( m_dwVKRight ) ) { m_SpaceWarClientUpdateData.SetTurnRightPressed( true ); } } else if ( m_bIsServerInstance ) { // Server side float flRotationDelta = 0.0f; if ( m_SpaceWarClientUpdateData.GetTurnLeftPressed() ) { flRotationDelta += (PI_VALUE/2.0f) * -1.0f * (float)m_pGameEngine->GetGameTicksFrameDelta()/400.0f; } if ( m_SpaceWarClientUpdateData.GetTurnRightPressed() ) { flRotationDelta += (PI_VALUE/2.0f) * (float)m_pGameEngine->GetGameTicksFrameDelta()/400.0f; } SetRotationDeltaNextFrame( flRotationDelta ); } // Compute acceleration if ( m_bIsLocalPlayer ) { // client side m_SpaceWarClientUpdateData.SetReverseThrustersPressed( false ); m_SpaceWarClientUpdateData.SetForwardThrustersPressed( false ); if ( m_pGameEngine->BIsKeyDown( m_dwVKForwardThrusters ) || m_pGameEngine->BIsKeyDown( m_dwVKReverseThrusters ) ) { if ( m_pGameEngine->BIsKeyDown( m_dwVKReverseThrusters ) ) { m_SpaceWarClientUpdateData.SetReverseThrustersPressed( true ); } else { m_SpaceWarClientUpdateData.SetForwardThrustersPressed( true ); } } } else if ( m_bIsServerInstance ) { // Server side float xThrust = 0; float yThrust = 0; m_bReverseThrustersActive = false; m_bForwardThrustersActive = false; if ( m_SpaceWarClientUpdateData.GetReverseThrustersPressed() || m_SpaceWarClientUpdateData.GetForwardThrustersPressed() ) { float flSign = 1.0f; if ( m_SpaceWarClientUpdateData.GetReverseThrustersPressed() ) { m_bReverseThrustersActive = true; flSign = -1.0f; } else { m_bForwardThrustersActive = true; } if ( m_ulLastThrustStartedTickCount == 0 ) m_ulLastThrustStartedTickCount = ulCurrentTickCount; // You have to hold the key for a second to reach maximum thrust float factor = MIN( ((float)(ulCurrentTickCount - m_ulLastThrustStartedTickCount) / 500.0f) + 0.2f, 1.0f ); xThrust = flSign * (float)(MAXIMUM_SHIP_THRUST * factor * sin( GetAccumulatedRotation() ) ); yThrust = flSign * -1.0f * (float)(MAXIMUM_SHIP_THRUST * factor * cos( GetAccumulatedRotation() ) ); } else { m_ulLastThrustStartedTickCount = 0; } SetAcceleration( xThrust, yThrust ); } // We'll use these values in a few places below to compute positions of child objects // appropriately given our rotation float sinvalue = (float)sin( GetAccumulatedRotation() ); float cosvalue = (float)cos( GetAccumulatedRotation() ); if ( m_bIsLocalPlayer ) { // client side if ( m_pGameEngine->BIsKeyDown( m_dwVKFire ) ) { m_SpaceWarClientUpdateData.SetFirePressed( true ); } } else if ( m_bIsServerInstance ) { // server side if ( nNextAvailablePhotonBeamSlot != -1 && !m_bExploding && m_SpaceWarClientUpdateData.GetFirePressed() && ulCurrentTickCount - PHOTON_BEAM_FIRE_INTERVAL_TICKS > m_ulLastPhotonTickCount ) { m_ulLastPhotonTickCount = ulCurrentTickCount; float xVelocity = GetXVelocity() + ( sinvalue * 275 ); float yVelocity = GetYVelocity() - ( cosvalue * 275 ); // Offset 12 points up from the center of the ship, compensating for rotation float xPos = GetXPos() - sinvalue*-12.0f; float yPos = GetYPos() + cosvalue*-12.0f; m_rgPhotonBeams[nNextAvailablePhotonBeamSlot] = new CPhotonBeam( m_pGameEngine, xPos, yPos, m_dwShipColor, GetAccumulatedRotation(), xVelocity, yVelocity ); } } CSpaceWarEntity::RunFrame(); // Finally, update the thrusters ( we do this after the base class call as they rely on our data being fully up-to-date) m_ForwardThrusters.RunFrame(); m_ReverseThrusters.RunFrame(); }