コード例 #1
0
ファイル: ScnViewComponent.cpp プロジェクト: Psybrus/Psybrus
//////////////////////////////////////////////////////////////////////////
// getDepth
BcU32 ScnViewComponent::getDepth( const MaVec3d& WorldPos ) const
{
	MaVec4d ScreenSpace = MaVec4d( WorldPos, 1.0f ) * ViewUniformBlock_.ClipTransform_;
	BcF32 Depth = 1.0f - BcClamp( ScreenSpace.z() / ScreenSpace.w(), 0.0f, 1.0f );

	return BcU32( Depth * BcF32( 0xffffff ) );
}
コード例 #2
0
//////////////////////////////////////////////////////////////////////////
// setBehaviourMove
void GaGameUnit::setBehaviourMove( const BcFixedVec2d& Target, BcBool IsAttackMove, BcBool DrawDebug )
{
	if( Health_ > 0.0f )
	{
		Behaviour_ = BEHAVIOUR_MOVE;
		MoveTargetPosition_ = Target;
		IsAttackMove_ = IsAttackMove;

		// Hacky clamp.
		BcFixed HW = ( 1280.0f * 0.5f ) / 32.0f - 1.0f;
		BcFixed HH = ( 720.0f * 0.5f ) / 32.0f - 1.0f;
		MoveTargetPosition_.x( BcClamp( MoveTargetPosition_.x(), -HW, HW ) );
		MoveTargetPosition_.y( BcClamp( MoveTargetPosition_.y(), -HH, HH ) );
		
		if( DrawDebug )
		{
			pSimulator_->addDebugPoint( Target, 0.5f, IsAttackMove ? RsColour::RED : RsColour::GREEN );
		}
	}
}
コード例 #3
0
ファイル: GaRobotComponent.cpp プロジェクト: neilogd/LD31Game
//////////////////////////////////////////////////////////////////////////
// update
//virtual
void GaRobotComponent::update( BcF32 Tick )
{
	if( Health_ <= 0.0f )
	{
		return;
	}

	CurrentOpTimer_ -= Tick;
	if( CurrentOpTimer_ < 0.0f )
	{
		CurrentOpTimer_ += CurrentOpTime_;

		// Handle robot program.
		BcBool ExecutedCode = BcFalse;
		if( Program_.size() > 0 )
		{
			CurrentOp_ = NextOp_;
			const auto& Op = Program_[ CurrentOp_ ];
			if( Op.State_ == CurrentState_ )
			{
				auto Condition = ProgramFunctionMap_[ Op.Condition_ ];
				if( Condition != nullptr )
				{
					if( Condition( this, Op.ConditionVar_ ) )
					{
						auto Operation = ProgramFunctionMap_[ Op.Operation_ ];
						if( Operation == nullptr )
						{
							BcPrintf( "No operation \"%s\"\n", Op.Operation_.c_str() );
						}
						else
						{
							auto RetVal = Operation( this, Op.OperationVar_ );
							if( RetVal != BcErrorCode )
							{
								CurrentState_ = RetVal;
							}
						}
					}
				}
				ExecutedCode = BcTrue;
			}

			// Advance to next valid op.
			if( ExecutedCode )
			{
				for( BcU32 Idx = 0; Idx < Program_.size(); ++Idx )
				{
					NextOp_ = ( NextOp_ + 1 ) % Program_.size();
					if( Program_[ NextOp_ ].State_ == CurrentState_ )
					{
						break;
					}
				}
			}

			// Did we fail to run code? If so, reset to op 0 and the state of op 0.
			if( ExecutedCode == BcFalse )
			{
				NextOp_ = 0;
				CurrentState_ = Program_[ NextOp_ ].State_;
			}
		}
	}

	// Grab entity + position.
	auto Entity = getParentEntity();
	auto LocalPosition = Entity->getLocalPosition();

	// Move if we need to move towards our target position.
	if( ( TargetPosition_ - LocalPosition ).magnitudeSquared() > ( TargetDistance_ * TargetDistance_ ) )
	{
		if( MoveTimer_ <= 0.0f )
		{
			Velocity_ +=  ( TargetPosition_ - LocalPosition ).normal() * MaxVelocity_;
		}
	}
	else
	{
		BcF32 SlowDownTick = BcClamp( Tick * 50.0f, 0.0f, 1.0f );
		Velocity_ -= ( Velocity_ * SlowDownTick );
	}

	// TODO LATER: Do rotation.
	if( Velocity_.magnitudeSquared() > 0.1f )
	{
		auto Angle = std::atan2( Velocity_.z(), Velocity_.x() ) + BcPIDIV2;

		MaMat4d RotMat;
		RotMat.rotation( MaVec3d( 0.0f, Angle, 0.0f ) );
		Base_->setLocalMatrix( RotMat );
	}

	// TODO LATER: Do rotation.
	auto Robots = getRobots( 1 - Team_ );
	if( Robots.size() > 0 )
	{
		auto Robot = Robots[ 0 ];
		auto RobotPosition = Robot->getParentEntity()->getLocalPosition();
		auto VectorTo = RobotPosition - LocalPosition;

		// Push out of away.
		if( VectorTo.magnitude() < 3.0f )
		{
			BcF32 Factor = ( 3.0f - VectorTo.magnitude() ) / 3.0f;
			BcF32 InvFactor = 1.0f - Factor;

			Velocity_ = ( -( VectorTo.normal() * MaxVelocity_ ) * Factor * 3.0f ) + ( Velocity_ * InvFactor );
		}

		// Face turret.
		auto Angle = std::atan2( VectorTo.z(), VectorTo.x() ) + BcPIDIV2;

		MaMat4d RotMat;
		RotMat.rotation( MaVec3d( 0.0f, Angle, 0.0f ) );
		Turret_->setLocalMatrix( RotMat );
	}

	LocalPosition += Velocity_ * Tick;

	// Slow down velocity.
	BcF32 SlowDownTick = BcClamp( Tick * 10.0f, 0.0f, 1.0f );
	Velocity_ -= ( Velocity_ * SlowDownTick );

	if( Velocity_.magnitude() > MaxVelocity_ )
	{
		Velocity_ = Velocity_.normal() * MaxVelocity_;
	}

	// Set local position.
	Entity->setLocalPosition( LocalPosition );

	// Handle health + energy.
	Health_ = BcClamp( Health_, 0.0f, 100.0f );
	Energy_ = BcClamp( Energy_ + ( EnergyChargeRate_ * Tick ), 0.0f, 100.0f );

	// Weapon timers.
	WeaponATimer_ = BcMax( WeaponATimer_ - Tick, -1.0f );
	WeaponBTimer_ = BcMax( WeaponBTimer_ - Tick, -1.0f );

	MoveTimer_ = BcMax( MoveTimer_ - Tick, -1.0f );

	// Health/energy bars.
	OsClient* Client = OsCore::pImpl()->getClient( 0 );
	BcF32 Width = BcF32( Client->getWidth() ) * 0.5f;
	BcF32 Height = BcF32( Client->getHeight() ) * 0.5f;
	MaMat4d Projection;
	Projection.orthoProjection( -Width, Width, Height, -Height, -1.0f, 1.0f );
	Canvas_->pushMatrix( Projection );

	Canvas_->setMaterialComponent( Material_ );

	auto ScreenPos = View_->getScreenPosition( getParentEntity()->getWorldPosition() );
	ScreenPos -= MaVec2d( 0.0f, Height / 8.0f );
	auto TLPos = ScreenPos - MaVec2d( Width / 16.0f, Height / 64.0f );
	auto BRPos = ScreenPos + MaVec2d( Width / 16.0f, Height / 64.0f );

	// Draw background.
	Canvas_->drawBox( TLPos, BRPos, RsColour::BLACK, 0 );

	// Draw inner bars.
	TLPos += MaVec2d( 1.0f, 1.0f );
	BRPos -= MaVec2d( 1.0f, 1.0f );

	auto HealthTL = MaVec2d(
		TLPos.x(),
		TLPos.y() );	
	auto HealthBR = MaVec2d( 
		TLPos.x() + ( BRPos.x() - TLPos.x() ) * ( Health_ / 100.0f ),
		( TLPos.y() + BRPos.y() ) * 0.5f );

	auto EnergyTL = MaVec2d(
		TLPos.x(),
		( TLPos.y() + BRPos.y() ) * 0.5f );
	auto EnergyBR = MaVec2d( 
		TLPos.x() + ( BRPos.x() - TLPos.x() ) * ( Energy_ / 100.0f ),
		BRPos.y() );

	Canvas_->drawBox( HealthTL, HealthBR, RsColour::GREEN, 0 );
	Canvas_->drawBox( EnergyTL, EnergyBR, RsColour::BLUE, 0 );

	Canvas_->popMatrix( );

	ScnDebugRenderComponent::pImpl()->drawLine(
		LocalPosition,
		TargetPosition_,
		RsColour::WHITE,
		0 );

	Super::update( Tick );
}
コード例 #4
0
ファイル: OsClientWindows.cpp プロジェクト: Psybrus/Psybrus
//////////////////////////////////////////////////////////////////////////
// update
void OsClientWindows::update()
{
	// Update mouse if we're in focus.
	if( ::GetActiveWindow() == hWnd_ )
	{
		POINT MousePosition;
		POINT WindowPosition;
		RECT Rect;

		// Get window rect in screen space.
		::GetWindowRect( hWnd_, &Rect );
		
		// Screen space cood of the client area.
		WindowPosition.x = 0;
		WindowPosition.y = 0;
		::ClientToScreen( hWnd_, &WindowPosition );
		
		// Get the cursor position
		::GetCursorPos( &MousePosition );

		const BcS32 WX = ( Rect.right - Rect.left );
		const BcS32 WY = ( Rect.bottom - Rect.top );
		MouseDelta_.x( BcF32( MousePosition.x - ( Rect.left + ( WX / 2 ) ) ) );
		MouseDelta_.y( BcF32( MousePosition.y - ( Rect.top + ( WY / 2 ) ) ) );

		MousePos_ += MouseDelta_;
		MousePos_.x( BcClamp( MousePos_.x(), 0.0f, BcF32( WX ) ) );
		MousePos_.y( BcClamp( MousePos_.y(), 0.0f, BcF32( WY ) ) );

		// Smooth out delta
		const MaVec2d TempOld = MouseDelta_;
		MouseDelta_ = ( MousePrevDelta_ + MouseDelta_ ) * 0.5f;
		MousePrevDelta_ = TempOld;

		// Lock to centre of screen if we're in focus.
		if( MouseLocked_ )
		{
			::SetCursorPos( Rect.left + ( WX / 2 ), Rect.top + ( WY / 2 ) );
		}

		// Send event if moved.
		if( MouseDelta_.magnitude() > 0.5f )
		{
			OsEventInputMouse Event;
			Event.DeviceID_ = 0;
			Event.MouseX_ = (BcS16)MousePosition.x - (BcS16)WindowPosition.x;
			Event.MouseY_ = (BcS16)MousePosition.y - (BcS16)WindowPosition.y;
			Event.MouseDX_ = MouseDelta_.x();
			Event.MouseDY_ = MouseDelta_.y();
			Event.NormalisedX_ = BcF32( (BcS32)Event.MouseX_ - ( (BcS32)getWidth() / 2 ) ) / BcF32( (BcS32)getWidth() / 2 );
			Event.NormalisedY_ = BcF32( (BcS32)Event.MouseY_ - ( (BcS32)getHeight() / 2 ) ) / BcF32( (BcS32)getHeight() / 2 );

			// Legacy...
			PrevMouseX_ = Event.MouseX_;
			PrevMouseY_ = Event.MouseY_;

			Event.ButtonCode_ = 0;
			OsCore::pImpl()->publish( osEVT_INPUT_MOUSEMOVE, Event ); // TODO: REMOVE OLD!
			EvtPublisher::publish( osEVT_INPUT_MOUSEMOVE, Event );
		}
	}
}
コード例 #5
0
//////////////////////////////////////////////////////////////////////////
// tickState
void GaGameUnit::tickState( BcFixed Delta )
{
	PrevState_ = CurrState_;
	NextState_ = CurrState_;

	//if( NextState_.Velocity_.magnitudeSquared() > 0.0f )
	{
		NextState_.Position_ += NextState_.Velocity_ * Delta;

		if( Behaviour_ != BEHAVIOUR_DAMAGE )
		{
			// Check new state is valid.
			BcFixedVec2d Min( NextState_.Position_ - ( Desc_.Size_ * 0.9f ) );
			BcFixedVec2d Max( NextState_.Position_ + ( Desc_.Size_ * 0.9f ) );
			
			GaGameUnitIDList FoundUnits;
			
			pSimulator_->findUnits( FoundUnits, Min, Max, ID_, 0x3 );

			// Move unit away from it's nearest one.
			if( FoundUnits.size() != 0 )
			{
				BcU32 NearestUnit = pSimulator_->findNearestUnit( CurrState_.Position_, ID_, 0x3 );
				GaGameUnit* pGameUnit = pSimulator_->getUnit( NearestUnit );

				if( pGameUnit != NULL )
				{
					BcFixedVec2d Direction = ( CurrState_.Position_ - pGameUnit->CurrState_.Position_ ).normal();

					if( Direction.dot( NextState_.Velocity_.normal() ) > 0.0f || NextState_.Velocity_.magnitudeSquared() == 0.0f )
					{
						BcFixedVec2d RandomOffset( (int)( pSimulator_->rand() % 64 ), (int)( pSimulator_->rand() % 64 ) );
						NextState_ = CurrState_;
						NextState_.Velocity_ = NextState_.Velocity_ * 0.4f + ( Direction * Desc_.MoveSpeed_ ) * 0.6f;
						NextState_.Position_ += NextState_.Velocity_ * Delta + ( RandomOffset / 4096.0f );
					}
				}
				else
				{
					NextState_ = CurrState_;
				}
			}
		}
	}

	//
	WalkTimer_ -= NextState_.Velocity_.magnitude() * Delta;

	if( WalkTimer_ < 0.0f )
	{
		GaTopState::pImpl()->playSound( "Walk", getPosition() );
		WalkTimer_ += ( Desc_.MoveSpeed_ + (BcAbs( BcRandom::Global.randReal() ) * 0.02f ) ) * 0.2f;
	}

	// Clamp position and move away.
	BcFixed HW = ( 1280.0f * 0.5f ) / 32.0f - 1.0f;
	BcFixed HH = ( 720.0f * 0.5f ) / 32.0f - 1.0f;
	BcFixedVec2d ClampedPosition;
	ClampedPosition.x( BcClamp( NextState_.Position_.x(), -HW, HW ) );
	ClampedPosition.y( BcClamp( NextState_.Position_.y(), -HH, HH ) );
	if( NextState_.Position_ != ClampedPosition )
	{
		BcFixedVec2d RandomOffset( (int)( pSimulator_->rand() % 64 ), (int)( pSimulator_->rand() % 64 ) );
		NextState_.Velocity_ += RandomOffset / 4096.0f;
		NextState_.Position_ = ClampedPosition;
	}
}
コード例 #6
0
//////////////////////////////////////////////////////////////////////////
// onMouseEvent
eEvtReturn GaGameComponent::onMouseEvent( EvtID ID, const OsEventInputMouse& Event )
{
	// Convert to rendering space.
	OsClient* pClient = OsCore::pImpl()->getClient( 0 );
	BcReal HW = static_cast< BcReal >( pClient->getWidth() ) / 2.0f;
	BcReal HH = static_cast< BcReal >( pClient->getHeight() ) / 2.0f;
	CursorPosition_.set( Event.MouseX_ - HW, Event.MouseY_ - HH );
	GameCursorPosition_ = CursorPosition_ / 32.0f;
	EndGameCursorPosition_ = GameCursorPosition_;

	if( MouseDown_ && ( StartGameCursorPosition_ - EndGameCursorPosition_ ).magnitudeSquared() > BcFixed( 8.0f ) )
	{
		BoxSelection_ = BcTrue;
	}

	if( ID == osEVT_INPUT_MOUSEDOWN )
	{
		StartGameCursorPosition_ = GameCursorPosition_;
		MouseDown_ = BcTrue;
		BoxSelection_ = BcFalse;
	}
	else if( ID == osEVT_INPUT_MOUSEUP )
	{
		EndGameCursorPosition_ = GameCursorPosition_;
		MouseDown_ = BcFalse;
		GaGameUnitIDList FoundUnits;

		if( BoxSelection_ )
		{
			pSimulator_->findUnits( FoundUnits, StartGameCursorPosition_, EndGameCursorPosition_, BcErrorCode, 1 << TeamID_ );
		}
		else
		{
			pSimulator_->findUnits( FoundUnits, GameCursorPosition_, 0.8f, BcErrorCode, 1 << TeamID_ );
			while( FoundUnits.size() > 1 )
			{
				FoundUnits.pop_back();
			}
		}

		// If we found units, then set selection.
		if( FoundUnits.size() > 0 )
		{
			UnitSelection_ = FoundUnits;
		}
		else
		{
			// If we aren't box selection do action.
			if( BoxSelection_ == BcFalse )
			{
				BcU32 TargetUnitID = BcErrorCode;

				// Determine if it's an attack move or not.
				pSimulator_->findUnits( FoundUnits, GameCursorPosition_, 0.8f, BcErrorCode, 1 << ( 1 - TeamID_ ) );
				while( FoundUnits.size() > 1 )
				{
					FoundUnits.pop_back();
				}

				if( FoundUnits.size() == 1 )
				{
					TargetUnitID = FoundUnits[ 0 ];
				}

				// Otherwise, tell found units to move.
				BcFixedVec2d CentralPosition;
				BcFixed Divisor;
				for( BcU32 Idx = 0; Idx < UnitSelection_.size(); ++Idx )
				{
					GaGameUnit* pGameUnit( pSimulator_->getUnit( UnitSelection_[ Idx ] ) );
					if( pGameUnit != NULL )
					{
						CentralPosition += pGameUnit->getPosition();
						Divisor += 1.0f;
					}
				}

				if( UnitSelection_.size() > 0 && Divisor > 0.0f )
				{
					CentralPosition /= Divisor;

					GameCursorPosition_ = BcFixedVec2d( ( GameCursorPosition_.x() ), ( GameCursorPosition_.y() ) );

					BcFixed PlayfieldHW = 1280.0f * 0.5f / 32.0f;
					BcFixed PlayfieldHH = 720.0f * 0.5f / 32.0f;

					for( BcU32 Idx = 0; Idx < UnitSelection_.size(); ++Idx )
					{
						GaGameUnit* pGameUnit( pSimulator_->getUnit( UnitSelection_[ Idx ] ) );
						if( pGameUnit != NULL )
						{
							if( TargetUnitID == BcErrorCode )
							{
								GaGameUnitMoveEvent Event;
								Event.UnitID_ = pGameUnit->getID();
								Event.Position_ = ( ( pGameUnit->getPosition() - CentralPosition ) * 0.0f ) + GameCursorPosition_;

								Event.Position_.x( BcClamp( Event.Position_.x(), -PlayfieldHW, PlayfieldHW ) );
								Event.Position_.y( BcClamp( Event.Position_.y(), -PlayfieldHH, PlayfieldHH ) );

								Event.IsAttackMove_ = AttackMove_;
								
								pSimulator_->publish( gaEVT_UNIT_MOVE, Event );
							}
							else
							{
								GaGameUnitAttackEvent Event;
								Event.UnitID_ = pGameUnit->getID();
								Event.TargetUnitID_ = TargetUnitID;
								pSimulator_->publish( gaEVT_UNIT_ATTACK, Event );
							}
						}
					}
				}

				// Toggle off attack move.
				AttackMove_ = BcFalse;
			}
			else
			{
				// If we were box selecting clear selection.
				UnitSelection_.clear();
			}
		}

		BoxSelection_ = BcFalse;
	}
	
	return evtRET_PASS;
}
コード例 #7
0
ファイル: BcRandom.cpp プロジェクト: Psybrus/Psybrus
//////////////////////////////////////////////////////////////////////////
// randRange
BcS32 BcRandom::randRange( BcS32 Min, BcS32 Max )
{
	return BcClamp( ( Min + ( rand() % ( 1 + Max - Min ) ) ), Min, Max );
}