A 2D tile-based sandbox game.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

PlayerEntity.cc 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "PlayerEntity.h"
  2. #include <cmath>
  3. #include "ItemStackEntity.h"
  4. PlayerEntity::PlayerEntity(const Swan::Context &ctx, Swan::Vec2 pos):
  5. PlayerEntity(ctx) {
  6. body_.pos = pos;
  7. }
  8. PlayerEntity::PlayerEntity(const Swan::Context &ctx, const PackObject &obj):
  9. PlayerEntity(ctx) {
  10. deserialize(ctx, obj);
  11. }
  12. void PlayerEntity::draw(const Swan::Context &ctx, Cygnet::Renderer &rnd) {
  13. Cygnet::Mat3gf mat;
  14. // Currently, there is no sprite for running left.
  15. // Running left is just running right but flipped.
  16. if (state_ == State::RUNNING_L) {
  17. mat.translate({-0.5, 0}).scale({-1, 1}).translate({0.5, 0});
  18. }
  19. anims_[(int)state_].draw(rnd, mat.translate(
  20. body_.pos - Swan::Vec2{0.2, 0.1}));
  21. rnd.drawRect(mouseTile_, {1, 1});
  22. rnd.drawRect(body_.pos, body_.size);
  23. rnd.drawLight(1, body_.topMid() + Swan::Vec2{0, 0.3});
  24. }
  25. void PlayerEntity::update(const Swan::Context &ctx, float dt) {
  26. State oldState = state_;
  27. state_ = State::IDLE;
  28. mouseTile_ = ctx.game.getMouseTile();
  29. ctx.plane.debugBox(mouseTile_);
  30. jumpTimer_.tick(dt);
  31. placeTimer_.tick(dt);
  32. // Break block
  33. if (ctx.game.isMousePressed(SDL_BUTTON_LEFT))
  34. ctx.plane.breakTile(mouseTile_);
  35. // Place block
  36. if (ctx.game.isMousePressed(SDL_BUTTON_RIGHT) && placeTimer_.periodic(0.50)) {
  37. if (ctx.plane.getTileID(mouseTile_) == ctx.world.getTileID("@::air")) {
  38. ctx.plane.setTile(mouseTile_, "core::torch");
  39. }
  40. }
  41. // Move left
  42. if (ctx.game.isKeyPressed(SDL_SCANCODE_A) || ctx.game.isKeyPressed(SDL_SCANCODE_LEFT)) {
  43. physics_.force += Swan::Vec2(-MOVE_FORCE, 0);
  44. state_ = State::RUNNING_L;
  45. }
  46. // Move right
  47. if (ctx.game.isKeyPressed(SDL_SCANCODE_D) || ctx.game.isKeyPressed(SDL_SCANCODE_RIGHT)) {
  48. physics_.force += Swan::Vec2(MOVE_FORCE, 0);
  49. if (state_ == State::RUNNING_L)
  50. state_ = State::IDLE;
  51. else
  52. state_ = State::RUNNING_R;
  53. }
  54. bool jumpPressed = ctx.game.isKeyPressed(SDL_SCANCODE_SPACE);
  55. // Jump
  56. if (physics_.onGround && jumpPressed && jumpTimer_.periodic(0.5)) {
  57. physics_.vel.y = -JUMP_VEL;
  58. }
  59. // Fall down faster than we went up
  60. if (!physics_.onGround && (!jumpPressed || physics_.vel.y > 0))
  61. physics_.force += Swan::Vec2(0, DOWN_FORCE);
  62. if (state_ != oldState)
  63. anims_[(int)state_].reset();
  64. anims_[(int)state_].tick(dt);
  65. physics(ctx, dt, { .mass = MASS });
  66. }
  67. void PlayerEntity::tick(const Swan::Context &ctx, float dt) {
  68. for (ItemStackEntity *ent: ctx.plane.getEntsOfType<ItemStackEntity>()) {
  69. float squared_dist =
  70. (body_.bottomMid() - ent->get(Swan::BodyTrait::Tag{}).center())
  71. .squareLength();
  72. if (squared_dist < 0.5 * 0.5) {
  73. // TODO: Pick up
  74. }
  75. }
  76. }
  77. void PlayerEntity::deserialize(const Swan::Context &ctx, const PackObject &obj) {
  78. //body_.deserialize(obj["body"]);
  79. }
  80. Swan::Entity::PackObject PlayerEntity::serialize(const Swan::Context &ctx, msgpack::zone &zone) {
  81. return {};
  82. /*
  83. return Swan::MsgPackObject{
  84. { "body", body_.serialize(w) },
  85. };
  86. */
  87. }