Advertisement
Guest User

Untitled

a guest
Apr 7th, 2020
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.40 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "Player.h"
  3. #include "ServiceLocator.h"
  4. #include "InputWrapper.h"
  5. #include "AnimationFactory.h"
  6. #include "Time.h"
  7. #include "Collider.h"
  8. #include "BurstObject.h"
  9. #include "Map.h"
  10. #include "SoundManager.h"
  11. #include "SpriteFactory.h"
  12. #include "BurstArrow.h"
  13. #include "Tile.h"
  14. #include "Locator.h"
  15.  
  16. #include <tga2d/math/common_math.h>
  17. #include <CommonUtilities/Macros.h>
  18. #ifndef _RETAIL
  19. #include <imgui.h>
  20. #endif // !_RETAIL
  21. #include <string>
  22.  
  23. void Player::OnInit()
  24. {
  25.     InitAnimations();
  26.     myCurrentAnimation = myAnimations[State::Idle];
  27.     myCurrentAnimation->SetShouldRender(true);
  28.  
  29.     myJsonReader.Init(*this);
  30.     myStateMachine.Init(std::static_pointer_cast<Player>(shared_from_this()), State::Idle);
  31.  
  32.     myPosition = { 200, 30 };
  33.     myBurstArrow = Entity::Instantiate<BurstArrow>().lock();
  34. }
  35.  
  36. void Player::Update()
  37. {
  38.     myAcceleration = { 0, 0 };
  39.     myStateMachine.Update();
  40.  
  41.     myIsGrounded = false; // We reset IsGrounded every frame to detect running off edges. CheckCollisions() will set it to true.
  42.     myTileCollider->CheckCollision(myPosition);
  43.  
  44.     myCurrentAnimation->Update(Time::GetInstance()->GetTimeDelta());
  45. }
  46.  
  47. void Player::InitAnimations()
  48. {
  49.     myAnimations[State::Idle] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_idle.dds");
  50.     myAnimations[State::Jumping] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_jump.dds");
  51.     myAnimations[State::DoubleJumping] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_dubbleJump.dds");
  52.     myAnimations[State::Running] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_walk.dds");
  53.     myAnimations[State::Falling] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_inAir.dds");
  54.     myAnimations[State::Bursting] = ServiceLocator::Get<AnimationFactory>()->Create(weak_from_this(), "Assets/Animations/Character/Polaris_bash.dds");
  55.  
  56.     for (auto anim : myAnimations)
  57.     {
  58.         anim.second->SetShouldRender(false);
  59.     }
  60. }
  61.  
  62. void Player::SetState(State aState)
  63. {
  64.     if (myState == aState)
  65.         return;
  66.     myState = aState;
  67.     myCurrentAnimation->SetShouldRender(false);
  68.     myCurrentAnimation = myAnimations[myState];
  69.     myCurrentAnimation->SetShouldRender(true);
  70.     myCurrentAnimation->Reset();
  71. }
  72.  
  73. void Player::Jump()
  74. {
  75.     myIsGrounded = false;
  76.     myVelocity.y = -myJumpSpeed;
  77. }
  78.  
  79. void Player::MoveGrounded()
  80. {
  81.     myPosition += myVelocity * Time::GetInstance()->GetTimeDelta();
  82. }
  83.  
  84. void Player::MoveAirBorne()
  85. {
  86.     float timeDelta = Time::GetInstance()->GetTimeDelta();
  87.     myVelocity.y += myGravity * timeDelta;
  88.     myVelocity += myAcceleration * timeDelta;
  89.     myPosition += myVelocity * timeDelta;
  90.  
  91.     if (myAcceleration.x == 0)
  92.     {
  93.         myVelocity.x *= myXVelocityFallOff;
  94.     }
  95.  
  96.     float maxSpeedX = myHasBursted ? myMaxSpeedAfterBurst : myMaxSpeed;
  97.     float maxSpeedY = myHasBursted ? myMaxSpeedAfterBurst : myMaxFallSpeed;
  98.     myVelocity.x = CLAMP(myVelocity.x, -maxSpeedX, maxSpeedX);
  99.     myVelocity.y = CLAMP(myVelocity.y, -maxSpeedY, maxSpeedY);
  100. }
  101.  
  102. void Player::Burst(const VECTOR2F& aDirection)
  103. {
  104.     myVelocity = aDirection * GetBurstSpeed();
  105.     myHasBursted = true;
  106. }
  107.  
  108. void Player::InitCollider(Map* aMap)
  109. {
  110.     VECTOR2UI size = { static_cast<UINT>(myCurrentAnimation->GetSize().x), static_cast<UINT>(myCurrentAnimation->GetSize().y) };
  111.     myTileCollider = std::make_shared<TileCollider>(size, VECTOR2F{ 0.f, 0.f }, aMap);
  112.  
  113.     const int tileWidth = aMap->GetTileWidth();
  114.     const int tileHeight = aMap->GetTileHeight();
  115.  
  116.     auto footCollisionCallback = [&](const Tile& aCollidedTile, const Locator& aLocator)
  117.     {
  118.         myHasBursted = false;
  119.         bool isMovingDownwards = myVelocity.y >= 0;
  120.         if (isMovingDownwards)
  121.         {
  122.             myIsGrounded = true;
  123.             myVelocity.y = 0;
  124.         }
  125.  
  126.         if (!HandleSlopes(aCollidedTile, aLocator))
  127.         {
  128.             myPosition.y = aCollidedTile.myPosition.y - aLocator.GetRelativePosition().y;
  129.         }
  130.     };
  131.  
  132.     auto rightSideCollisionCallback = [&](const Tile& aCollidedTile, const Locator& aLocator)
  133.     {
  134.         myHasBursted = false;
  135.         myPosition.x = aCollidedTile.myPosition.x - aLocator.GetRelativePosition().x;
  136.     };
  137.  
  138.     auto leftSideCollisionCallback = [&, tileWidth](const Tile& aCollidedTile, const Locator& aLocator)
  139.     {
  140.         myHasBursted = false;
  141.         int tileX = aCollidedTile.myPosition.x + tileWidth - aLocator.GetRelativePosition().x;
  142.         myPosition.x = tileX;
  143.     };
  144.  
  145.     auto headCollisionCallback = [&, tileHeight](const Tile& aCollidedTile, const Locator& aLocator)
  146.     {
  147.         bool isMovingUpwards = myVelocity.y <= 0;
  148.         if (isMovingUpwards) // NOTE(jens): This condition prevents wonky changes in velocity if we touch a roof while falling.
  149.         {
  150.             myHasBursted = false;
  151.             myVelocity.y = 0;
  152.         }
  153.         myPosition.y = aCollidedTile.myPosition.y + tileHeight - aLocator.GetRelativePosition().y;
  154.     };
  155.  
  156.     myTileCollider->AddLocator({ 6, 0 }, rightSideCollisionCallback);  //right
  157.     myTileCollider->AddLocator({ 6, 12 }, rightSideCollisionCallback); //right
  158.     myTileCollider->AddLocator({ -6, 0 }, leftSideCollisionCallback);  //left
  159.     myTileCollider->AddLocator({ -6, 12 }, leftSideCollisionCallback); //left
  160.     myTileCollider->AddLocator({ 5, 16 }, footCollisionCallback);      // foot
  161.     myTileCollider->AddLocator({ -5, 16 }, footCollisionCallback);     // foot
  162.     myTileCollider->AddLocator({ 0, -10 }, headCollisionCallback);     //head
  163.  
  164. }
  165.  
  166. void Player::CheckCollision(const std::vector<std::shared_ptr<Entity>>& aList)
  167. {
  168.     // TODO: Temporary solution
  169.     const auto rect = GetRect();
  170.     myInRangeForBurst = false;
  171.  
  172.     for (const auto obj : aList)
  173.     {
  174.         if (obj->IsInBurstRange(rect))
  175.         {
  176.             myInRangeForBurst = true;
  177.         }
  178.     }
  179. }
  180.  
  181. void Player::AimArrow(const float aRotation, bool aSetActive)
  182. {
  183.     myBurstArrow->SetActive(aSetActive);
  184.     myBurstArrow->SetPosition(myPosition); // TODO: Use targets position instead of myPosition instead.
  185.     if (aSetActive)
  186.     {
  187.         myBurstArrow->SetRotation(aRotation);
  188.     }
  189. }
  190.  
  191. bool Player::CanBurst() const
  192. {
  193.     return myInRangeForBurst;
  194. }
  195.  
  196. const TileCollider& Player::GetTileCollider() const
  197. {
  198.     return *myTileCollider;
  199. }
  200.  
  201. State Player::GetState() const
  202. {
  203.     return myState;
  204. }
  205.  
  206. bool Player::IsGrounded() const
  207. {
  208.     return myIsGrounded;
  209. }
  210.  
  211. int Player::GetCoyoteFrames() const
  212. {
  213.     return myCoyoteFrames;
  214. }
  215.  
  216. void Player::SetVelocity(const VECTOR2F& aVelocity)
  217. {
  218.     myVelocity = aVelocity;
  219. }
  220.  
  221. float Player::GetSpeed() const
  222. {
  223.     return mySpeed;
  224. }
  225.  
  226. float Player::GetMaxSpeed() const
  227. {
  228.     return myMaxSpeed;
  229. }
  230.  
  231. float Player::GetGravity() const
  232. {
  233.     return myGravity;
  234. }
  235.  
  236. float Player::GetAirControl() const
  237. {
  238.     return myAirControl;
  239. }
  240.  
  241. float Player::GetBurstSpeed() const
  242. {
  243.     return myBurstSpeed;
  244.  
  245. }
  246.  
  247. VECTOR2F& Player::GetVelocity()
  248. {
  249.     return myVelocity;
  250. }
  251.  
  252. VECTOR2F& Player::GetAcceleration()
  253. {
  254.     return myAcceleration;
  255. }
  256.  
  257.  
  258. const VECTOR2F& Player::GetPosition() const
  259. {
  260.     return myPosition;
  261. }
  262.  
  263. CommonUtilities::RectInt Player::GetRect() const
  264. {
  265.     const auto& size = myCurrentAnimation->GetSize();
  266.     const int offset = size.x * 0.5f; // only works with square sprite
  267.     const int x = myPosition.x - offset;
  268.     const int y = myPosition.y - offset;
  269.     return  { x, y, size.x, size.y };
  270. }
  271.  
  272. void Player::Accept(EntityVisitor& aVisitor)
  273. {
  274.     aVisitor.Visit(*this);
  275. }
  276.  
  277. bool Player::HandleSlopes(const Tile& aCollidedTile, const Locator& aLocator)
  278. {
  279.     VECTOR2F pos = myPosition + myVelocity;
  280.     if (aCollidedTile.myData == 0)
  281.     {
  282.         return false;
  283.     }
  284.     if (aCollidedTile.myAngle == 0.f)
  285.     {
  286.         return false;
  287.     }
  288.  
  289.     float slopeRatio = tan(aCollidedTile.myAngle);
  290.     int tileWidth = myTileCollider->GetTileWidth();
  291.     int tileHeight = myTileCollider->GetTileHeight();
  292.     //int mapWidth = myTileCollider->GetMapWidth();
  293.     //int mapHeight = myTileCollider->GetMapHeight();
  294.  
  295.     float horPos = (pos.x - aCollidedTile.myPosition.x) / tileWidth;
  296.     float vertPos = (pos.y - aCollidedTile.myPosition.y + tileHeight) / tileHeight;
  297.  
  298.     float ratio = (1 - vertPos) / horPos;
  299.     if (slopeRatio < 0.f)
  300.     {
  301.         if (ratio > slopeRatio)
  302.         {
  303.             myPosition.y = aCollidedTile.myPosition.y - slopeRatio * horPos * tileHeight - aLocator.GetRelativePosition().y;
  304.             myVelocity.y = 0;
  305.             myAcceleration.y = 0;
  306.         }
  307.     }
  308.     else
  309.     {
  310.         if (ratio < slopeRatio)
  311.         {
  312.             myPosition.y = aCollidedTile.myPosition.y + tileHeight - slopeRatio * horPos * tileHeight - aLocator.GetRelativePosition().y;
  313.             myVelocity.y = 0;
  314.             myAcceleration.y = 0;
  315.         }
  316.     }
  317.  
  318.     return true;
  319. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement