summary refs log tree commit diff stats
path: root/src/transform_system.cpp
blob: ad7947f7d9d48fca238c4ec4f8b3f62f0487bb16 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "transform_system.h"
#include "game.h"
#include "map.h"

void TransformSystem::initSprite(int spriteId, vec2i loc) {
  Sprite& sprite = game_.getSprite(spriteId);
  sprite.loc = loc;
  spritesByY_.emplace(loc.y(), spriteId);
}

void TransformSystem::moveSprite(int spriteId, vec2i newLoc) {
  Sprite& sprite = game_.getSprite(spriteId);
  bool changedY = (sprite.loc.y() != newLoc.y());
  if (changedY) {
    spritesByY_.erase(std::make_tuple(sprite.loc.y(), spriteId));
  }
  sprite.loc = newLoc;
  if (changedY) {
    spritesByY_.emplace(newLoc.y(), spriteId);
  }
}

CollisionResult TransformSystem::checkCollision(int spriteId, vec2i newLoc, Direction dir) {
  CollisionResult result;

  Sprite& sprite = game_.getSprite(spriteId);

  const Map& map = game_.getMap();
  bool blocked = false;

  const vec2i UL_COL_BOX = { 8, 8 };
  const vec2i DR_COL_BOX = { 4, 0 };
  vec2i oldColPosUL = (sprite.loc - UL_COL_BOX) / map.getTileSize();
  vec2i newColPosUL = (newLoc - UL_COL_BOX) / map.getTileSize();
  vec2i oldColPosDR = (sprite.loc + DR_COL_BOX) / map.getTileSize();
  vec2i newColPosDR = (newLoc + DR_COL_BOX) / map.getTileSize();

  if (dirHasDir(sprite.dir, Direction::right) &&
      newColPosDR.x() > oldColPosDR.x()) {
    for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
      if (map.isBlocked(newColPosDR.x(), y)) {
        result.horiz.blocked = true;
        result.horiz.dir = Direction::right;

        break;
      }
    }
  }

  if (dirHasDir(sprite.dir, Direction::left) &&
      newColPosUL.x() < oldColPosUL.x()) {
    for (int y = newColPosUL.y(); y <= newColPosDR.y(); y++) {
      if (map.isBlocked(newColPosUL.x(), y)) {
        result.horiz.blocked = true;
        result.horiz.dir = Direction::left;

        break;
      }
    }
  }

  if (dirHasDir(sprite.dir, Direction::down) &&
      newColPosDR.y() > oldColPosDR.y()) {
    for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
      if (map.isBlocked(x, newColPosDR.y())) {
        result.vert.blocked = true;
        result.vert.dir = Direction::down;

        break;
      }
    }
  }

  if (dirHasDir(sprite.dir, Direction::up) &&
      newColPosUL.y() < oldColPosUL.y()) {
    for (int x = newColPosUL.x(); x <= newColPosDR.x(); x++) {
      if (map.isBlocked(x, newColPosUL.y())) {
        result.vert.blocked = true;
        result.vert.dir = Direction::up;

        break;
      }
    }
  }

  return result;
}