A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PlayerEntity.cc 2.9KB

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, Swan::Win &win) {
  13. body_.outline(win);
  14. anims_[(int)state_].draw(body_.pos - Swan::Vec2(0.2, 0.1), win);
  15. }
  16. void PlayerEntity::update(const Swan::Context &ctx, float dt) {
  17. State oldState = state_;
  18. state_ = State::IDLE;
  19. mouseTile_ = ctx.game.getMouseTile();
  20. ctx.plane.debugBox(mouseTile_);
  21. jumpTimer_.tick(dt);
  22. placeTimer_.tick(dt);
  23. // Break block
  24. if (ctx.game.isMousePressed(SDL_BUTTON_LEFT))
  25. ctx.plane.breakTile(mouseTile_);
  26. // Place block
  27. if (ctx.game.isMousePressed(SDL_BUTTON_RIGHT) && placeTimer_.periodic(0.50)) {
  28. if (ctx.plane.getTileID(mouseTile_) == ctx.world.getTileID("@::air")) {
  29. ctx.plane.setTile(mouseTile_, "core::torch");
  30. }
  31. }
  32. // Move left
  33. if (ctx.game.isKeyPressed(SDL_SCANCODE_A) || ctx.game.isKeyPressed(SDL_SCANCODE_LEFT)) {
  34. physics_.force += Swan::Vec2(-MOVE_FORCE, 0);
  35. state_ = State::RUNNING_L;
  36. }
  37. // Move right
  38. if (ctx.game.isKeyPressed(SDL_SCANCODE_D) || ctx.game.isKeyPressed(SDL_SCANCODE_RIGHT)) {
  39. physics_.force += Swan::Vec2(MOVE_FORCE, 0);
  40. if (state_ == State::RUNNING_L)
  41. state_ = State::IDLE;
  42. else
  43. state_ = State::RUNNING_R;
  44. }
  45. bool jumpPressed = ctx.game.isKeyPressed(SDL_SCANCODE_SPACE);
  46. // Jump
  47. if (physics_.onGround && jumpPressed && jumpTimer_.periodic(0.5)) {
  48. physics_.vel.y = -JUMP_VEL;
  49. }
  50. // Fall down faster than we went up
  51. if (!physics_.on_ground && (!jumpPressed || physics_.vel.y > 0))
  52. physics_.force += Swan::Vec2(0, DOWN_FORCE);
  53. if (state_ != oldState)
  54. anims_[(int)state_].reset();
  55. anims_[(int)state_].tick(dt);
  56. physics(ctx, dt, { .mass = MASS });
  57. // Do this after moving so that it's not behind
  58. Swan::Vec2 headPos = body_.topMid() + Swan::Vec2(0, 0.5);
  59. Swan::TilePos tilePos = Swan::Vec2i(floor(headPos.x), floor(headPos.y));
  60. if (!placedLight_) {
  61. ctx.plane.addLight(tilePos, LIGHT_LEVEL);
  62. placedLight_ = true;
  63. lightTile_ = tilePos;
  64. } else if (tilePos != lightTile_) {
  65. ctx.plane.removeLight(lightTile_, LIGHT_LEVEL);
  66. ctx.plane.addLight(tilePos, LIGHT_LEVEL);
  67. lightTile_ = tilePos;
  68. }
  69. }
  70. void PlayerEntity::tick(const Swan::Context &ctx, float dt) {
  71. for (ItemStackEntity *ent: ctx.plane.getEntsOfType<ItemStackEntity>()) {
  72. float squared_dist =
  73. (body_.bottomMid() - ent->get(Swan::BodyTrait::Tag{}).center())
  74. .squareLength();
  75. if (squared_dist < 0.5 * 0.5) {
  76. // TODO: Pick up
  77. }
  78. }
  79. }
  80. void PlayerEntity::deserialize(const Swan::Context &ctx, const PackObject &obj) {
  81. //body_.deserialize(obj["body"]);
  82. }
  83. Swan::Entity::PackObject PlayerEntity::serialize(const Swan::Context &ctx, msgpack::zone &zone) {
  84. return {};
  85. /*
  86. return Swan::MsgPackObject{
  87. { "body", body_.serialize(w) },
  88. };
  89. */
  90. }