Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "Player.h"
- #include "ServiceLocator.h"
- #include "InputWrapper.h"
- #include "AnimationFactory.h"
- #include "Time.h"
- #include "Collider.h"
- #include "BurstObject.h"
- #include "Map.h"
- #include "SoundManager.h"
- #include "SpriteFactory.h"
- #include "BurstArrow.h"
- #include "Tile.h"
- #include "Locator.h"
- #include <tga2d/math/common_math.h>
- #include <CommonUtilities/Macros.h>
- #ifndef _RETAIL
- #include <imgui.h>
- #endif // !_RETAIL
- #include <string>
- void Player::OnInit()
- {
- InitAnimations();
- myCurrentAnimation = myAnimations[State::Idle];
- myCurrentAnimation->SetShouldRender(true);
- myJsonReader.Init(*this);
- myStateMachine.Init(std::static_pointer_cast<Player>(shared_from_this()), State::Idle);
- myPosition = { 200, 30 };
- myBurstArrow = Entity::Instantiate<BurstArrow>().lock();
- }
- void Player::Update()
- {
- myAcceleration = { 0, 0 };
- myStateMachine.Update();
- myIsGrounded = false; // We reset IsGrounded every frame to detect running off edges. CheckCollisions() will set it to true.
- myTileCollider->CheckCollision(myPosition);
- myCurrentAnimation->Update(Time::GetInstance()->GetTimeDelta());
- }
- void Player::InitAnimations()
- {
- myAnimations[State::Idle] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_idle.dds");
- myAnimations[State::Jumping] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_jump.dds");
- myAnimations[State::DoubleJumping] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_dubbleJump.dds");
- myAnimations[State::Running] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_walk.dds");
- myAnimations[State::Falling] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_inAir.dds");
- myAnimations[State::Bursting] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_bash.dds");
- for (auto anim : myAnimations)
- {
- anim.second->SetShouldRender(false);
- }
- }
- void Player::SetState(State aState)
- {
- if (myState == aState)
- return;
- myState = aState;
- myCurrentAnimation->SetShouldRender(false);
- myCurrentAnimation = myAnimations[myState];
- myCurrentAnimation->SetShouldRender(true);
- myCurrentAnimation->Reset();
- }
- void Player::Jump()
- {
- myIsGrounded = false;
- myVelocity.y = -myJumpSpeed;
- }
- void Player::MoveGrounded()
- {
- myPosition += myVelocity * Time::GetInstance()->GetTimeDelta();
- }
- void Player::MoveAirBorne()
- {
- float timeDelta = Time::GetInstance()->GetTimeDelta();
- myVelocity.y += myGravity * timeDelta;
- myVelocity += myAcceleration * timeDelta;
- myPosition += myVelocity * timeDelta;
- if (myAcceleration.x == 0)
- {
- myVelocity.x *= myXVelocityFallOff;
- }
- float maxSpeedX = myHasBursted ? myMaxSpeedAfterBurst : myMaxSpeed;
- float maxSpeedY = myHasBursted ? myMaxSpeedAfterBurst : myMaxFallSpeed;
- myVelocity.x = CLAMP(myVelocity.x, -maxSpeedX, maxSpeedX);
- myVelocity.y = CLAMP(myVelocity.y, -maxSpeedY, maxSpeedY);
- }
- void Player::Burst(const VECTOR2F& aDirection)
- {
- myVelocity = aDirection * GetBurstSpeed();
- myHasBursted = true;
- }
- void Player::InitCollider(Map* aMap)
- {
- VECTOR2UI size = { static_cast<UINT>(myCurrentAnimation->GetSize().x), static_cast<UINT>(myCurrentAnimation->GetSize().y) };
- myTileCollider = std::make_shared<TileCollider>(size, VECTOR2F{ 0.f, 0.f }, aMap);
- const int tileWidth = aMap->GetTileWidth();
- const int tileHeight = aMap->GetTileHeight();
- auto footCollisionCallback = [&](const Tile& aCollidedTile, const Locator& aLocator)
- {
- myHasBursted = false;
- bool isMovingDownwards = myVelocity.y >= 0;
- if (isMovingDownwards)
- {
- myIsGrounded = true;
- myVelocity.y = 0;
- }
- if (!HandleSlopes(aCollidedTile, aLocator))
- {
- myPosition.y = aCollidedTile.myPosition.y - aLocator.GetRelativePosition().y;
- }
- };
- auto rightSideCollisionCallback = [&](const Tile& aCollidedTile, const Locator& aLocator)
- {
- myHasBursted = false;
- myPosition.x = aCollidedTile.myPosition.x - aLocator.GetRelativePosition().x;
- };
- auto leftSideCollisionCallback = [&, tileWidth](const Tile& aCollidedTile, const Locator& aLocator)
- {
- myHasBursted = false;
- int tileX = aCollidedTile.myPosition.x + tileWidth - aLocator.GetRelativePosition().x;
- myPosition.x = tileX;
- };
- auto headCollisionCallback = [&, tileHeight](const Tile& aCollidedTile, const Locator& aLocator)
- {
- bool isMovingUpwards = myVelocity.y <= 0;
- if (isMovingUpwards) // NOTE(jens): This condition prevents wonky changes in velocity if we touch a roof while falling.
- {
- myHasBursted = false;
- myVelocity.y = 0;
- }
- myPosition.y = aCollidedTile.myPosition.y + tileHeight - aLocator.GetRelativePosition().y;
- };
- myTileCollider->AddLocator({ 6, 0 }, rightSideCollisionCallback); //right
- myTileCollider->AddLocator({ 6, 12 }, rightSideCollisionCallback); //right
- myTileCollider->AddLocator({ -6, 0 }, leftSideCollisionCallback); //left
- myTileCollider->AddLocator({ -6, 12 }, leftSideCollisionCallback); //left
- myTileCollider->AddLocator({ 5, 16 }, footCollisionCallback); // foot
- myTileCollider->AddLocator({ -5, 16 }, footCollisionCallback); // foot
- myTileCollider->AddLocator({ 0, -10 }, headCollisionCallback); //head
- }
- void Player::CheckCollision(const std::vector<std::shared_ptr<Entity>>& aList)
- {
- // TODO: Temporary solution
- const auto rect = GetRect();
- myInRangeForBurst = false;
- for (const auto obj : aList)
- {
- if (obj->IsInBurstRange(rect))
- {
- myInRangeForBurst = true;
- }
- }
- }
- void Player::AimArrow(const float aRotation, bool aSetActive)
- {
- myBurstArrow->SetActive(aSetActive);
- myBurstArrow->SetPosition(myPosition); // TODO: Use targets position instead of myPosition instead.
- if (aSetActive)
- {
- myBurstArrow->SetRotation(aRotation);
- }
- }
- bool Player::CanBurst() const
- {
- return myInRangeForBurst;
- }
- const TileCollider& Player::GetTileCollider() const
- {
- return *myTileCollider;
- }
- State Player::GetState() const
- {
- return myState;
- }
- bool Player::IsGrounded() const
- {
- return myIsGrounded;
- }
- int Player::GetCoyoteFrames() const
- {
- return myCoyoteFrames;
- }
- void Player::SetVelocity(const VECTOR2F& aVelocity)
- {
- myVelocity = aVelocity;
- }
- float Player::GetSpeed() const
- {
- return mySpeed;
- }
- float Player::GetMaxSpeed() const
- {
- return myMaxSpeed;
- }
- float Player::GetGravity() const
- {
- return myGravity;
- }
- float Player::GetAirControl() const
- {
- return myAirControl;
- }
- float Player::GetBurstSpeed() const
- {
- return myBurstSpeed;
- }
- VECTOR2F& Player::GetVelocity()
- {
- return myVelocity;
- }
- VECTOR2F& Player::GetAcceleration()
- {
- return myAcceleration;
- }
- const VECTOR2F& Player::GetPosition() const
- {
- return myPosition;
- }
- CommonUtilities::RectInt Player::GetRect() const
- {
- const auto& size = myCurrentAnimation->GetSize();
- const int offset = size.x * 0.5f; // only works with square sprite
- const int x = myPosition.x - offset;
- const int y = myPosition.y - offset;
- return { x, y, size.x, size.y };
- }
- void Player::Accept(EntityVisitor& aVisitor)
- {
- aVisitor.Visit(*this);
- }
- bool Player::HandleSlopes(const Tile& aCollidedTile, const Locator& aLocator)
- {
- VECTOR2F pos = myPosition + myVelocity;
- if (aCollidedTile.myData == 0)
- {
- return false;
- }
- if (aCollidedTile.myAngle == 0.f)
- {
- return false;
- }
- float slopeRatio = tan(aCollidedTile.myAngle);
- int tileWidth = myTileCollider->GetTileWidth();
- int tileHeight = myTileCollider->GetTileHeight();
- //int mapWidth = myTileCollider->GetMapWidth();
- //int mapHeight = myTileCollider->GetMapHeight();
- float horPos = (pos.x - aCollidedTile.myPosition.x) / tileWidth;
- float vertPos = (pos.y - aCollidedTile.myPosition.y + tileHeight) / tileHeight;
- float ratio = (1 - vertPos) / horPos;
- if (slopeRatio < 0.f)
- {
- if (ratio > slopeRatio)
- {
- myPosition.y = aCollidedTile.myPosition.y - slopeRatio * horPos * tileHeight - aLocator.GetRelativePosition().y;
- myVelocity.y = 0;
- myAcceleration.y = 0;
- }
- }
- else
- {
- if (ratio < slopeRatio)
- {
- myPosition.y = aCollidedTile.myPosition.y + tileHeight - slopeRatio * horPos * tileHeight - aLocator.GetRelativePosition().y;
- myVelocity.y = 0;
- myAcceleration.y = 0;
- }
- }
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement