-
Notifications
You must be signed in to change notification settings - Fork 0
/
GameMap.h
218 lines (174 loc) · 6.6 KB
/
GameMap.h
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#ifndef MAIN_Gmap_H
#define MAIN_Gmap_H
#include <vector>
#include <map>
#include <string>
#include "General.h"
#include "Image.h"
#include "RandImage.h"
struct GameMap;
#include "Item.h"
#include "Enemy.h"
struct Door
{
Point pos;
bool open;
E_Dir dir;
Door(Point _pos, E_Dir _dir): pos(_pos), open(false), dir(_dir){}
Door(Point _pos, bool _open, E_Dir _dir): pos(_pos), open(_open), dir(_dir) {}
bool IsRectIn(Point p, Size sz)
{
if (open)return false;
int w = TILE_SZ;
int h = TILE_SZ;
int p_x = pos.x * TILE_SZ + (TILE_SZ - w) / 2;
int p_y = pos.y * TILE_SZ + (TILE_SZ - h) / 2;
if (p.x < p_x && p.x + sz.w < p_x)return false;
if (p.x > p_x && p.x > p_x + w)return false;
if (p.y < p_y && p.y + sz.h < p_y)return false;
if (p.y > p_y && p.y > p_y + h)return false;
return true;
}
};
struct MapObj
{
MapObj(GameMap &_parent) : items(), parent(_parent) {};
//void AddItem(Point pos, int rarity);
void AddKey(Point pos);
void AddItem(Point pos, int lvl);
void AddEnemy(Point pos, int type);
void AddDoor(Point pos, E_Dir dir, bool open = false) { doors.emplace_back(pos, open, dir); };
void PressE();
void AfterLoad(int tile_w, int tile_h);
void EnemiesMove(Point player_pos);
void DrawItems(Image &canvas);
void DrawEnemies(Image &canvas);
std::vector<Item> &GetItems() { return items; }
bool CanStay(Point pos, int enemy_id);
bool TryAttack(Point pos, int dmg);
private:
std::vector<Item> items {};
std::vector<Enemy> enemies {};
std::vector<Door> doors {};
GameMap &parent;
int ind_E = -1;
int ind_D = -1;
};
struct GameMap
{
private: static GameMap *cur_map;
public:
static GameMap *GetCur() { return cur_map; }
enum class E_MapPos
{
Center,
};
enum class E_TileType
{
Floor,
Wall,
Empty,
Nothing
};
enum class E_CanStayType
{
Right,
Left,
Up,
Down
};
GameMap();
bool CheckWin();
bool CheckChangeMap();
void EnemiesMove(Point player_pos) { now_room->map_objects.EnemiesMove(player_pos); }
bool CanStay(E_CanStayType stay_type, Point pos, Size obj_sz, bool empty_can, int enemy_id)
{
Point LD {.x = pos.x, .y = pos.y};
Point LU {.x = pos.x, .y = pos.y + obj_sz.h - 1};
Point RU {.x = pos.x + obj_sz.w - 1, .y = pos.y + obj_sz.h - 1};
Point RD {.x = pos.x + obj_sz.w - 1, .y = pos.y};
Point R_UD {.x = pos.x + obj_sz.w - 1, .y = pos.y + obj_sz.h / 2};
Point L_UD {.x = pos.x, .y = pos.y + obj_sz.h / 2};
Point LR_U {.x = pos.x + obj_sz.w / 2, .y = pos.y + obj_sz.h - 1};
Point LR_D {.x = pos.x + obj_sz.w / 2, .y = pos.y};
switch (stay_type) {
case GameMap::E_CanStayType::Right:
return CanPointStay(RU, empty_can, enemy_id) && CanPointStay(RD, empty_can, enemy_id) && now_room->map_objects.CanStay(R_UD, enemy_id);
case GameMap::E_CanStayType::Left:
return CanPointStay(LD, empty_can, enemy_id) && CanPointStay(LU, empty_can, enemy_id) && now_room->map_objects.CanStay(L_UD, enemy_id);
case GameMap::E_CanStayType::Up:
return CanPointStay(LU, empty_can, enemy_id) && CanPointStay(RU, empty_can, enemy_id) && now_room->map_objects.CanStay(LR_U, enemy_id);
case GameMap::E_CanStayType::Down:
return CanPointStay(LD, empty_can, enemy_id) && CanPointStay(RD, empty_can, enemy_id) && now_room->map_objects.CanStay(LR_D, enemy_id);
default: error("wrong enum state"); return false;
}
}
bool CanPointStay(Point pos, bool empty_can, int enemy_id) const;
GameMap::E_TileType PointType(Point pos) const { return now_room->gri.TileType(pos.x / TILE_SZ, pos.y / TILE_SZ); }
Point GetPos(E_MapPos map_pos, Size obj_sz);
void Draw(Image &canvas);
void Draw_E(Image &canvas, Point p)
{
key_E_img.Draw(canvas, {.x = p.x * TILE_SZ + (TILE_SZ - key_E_img.Width()) / 2, .y = (p.y + 1) * TILE_SZ}, true);
}
int PixWidth()const { return now_room->gri.map_width * TILE_SZ; }
int PixHeight()const { return now_room->gri.map_height * TILE_SZ; }
template <typename T> void DrawOn(T &img_for_draw, Point map_pos, Image &canvas)
{
int map_x = map_pos.x;
int map_y = map_pos.y;
img_for_draw.Draw(canvas, {.x = map_x * TILE_SZ + (TILE_SZ - img_for_draw.Width()) / 2, .y = map_y * TILE_SZ + (TILE_SZ - img_for_draw.Height()) / 2}, true);
}
void PressE() { now_room->map_objects.PressE(); }
bool TryAttack(Point pos, int dmg) { return now_room->map_objects.TryAttack(pos, dmg); }
std::vector<Item> &GetItems() { return now_room->map_objects.GetItems(); }
bool CanThrowItem(Point pos);
private:
void load_room(int x, int y);
struct GameRoomInfo // general, lfrom that you need copy data into other class, that changeble it's staitc info!
{
static constexpr int U = 0;
static constexpr int L = 1;
static constexpr int R = 2;
static constexpr int D = 3;
static constexpr Point BAD_IN = Point {-1, -1};
static constexpr Point NOT_WIN_POINT = Point {-32, -128};
GameRoomInfo(char room_type);
std::vector<std::vector<GameMap::E_TileType>> tile_type{};
std::vector<std::pair<Point, int>> enemies{}; // point - pos, int - type
std::vector<Point> door_pos{}; // point - pos
std::vector< std::pair<Point, int>> items{}; // point - pos, int - rarity
std::vector<Point> keys_pos{}; // point - pos
Point win_point = NOT_WIN_POINT;
int map_width = -1;
int map_height = -1;
std::vector<Point> point_in {};
GameMap::E_TileType TileType(int x, int y) const
{
if (x < 0 || map_width <= x)return GameMap::E_TileType::Nothing;
if (y < 0 || map_height <= y)return GameMap::E_TileType::Nothing;
return tile_type[map_height - y - 1][x];
}
};
struct GameRoom
{
std::vector<std::vector<int>> map_ids{};
GameMap::GameRoomInfo &gri;
Image room_holst;
GameRoom(GameMap::GameRoomInfo &_gri, GameMap &_parent);
MapObj map_objects;
private:
GameMap &parent;
};
std::vector<std::string> room_map {};
std::map<Point, GameRoom> loaded_room{};
std::map<char, GameRoomInfo> loaded_room_info {};
RandImage floor_img;
Image empty_img;
Image wall_img;
Sprite key_E_img;
GameMap::GameRoom *now_room = nullptr;
int now_x = 0;
int now_y = 0;
};
#endif