summary refs log tree commit diff stats
path: root/src/mapview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mapview.cpp')
-rw-r--r--src/mapview.cpp319
1 files changed, 319 insertions, 0 deletions
diff --git a/src/mapview.cpp b/src/mapview.cpp new file mode 100644 index 0000000..f524d46 --- /dev/null +++ b/src/mapview.cpp
@@ -0,0 +1,319 @@
1#include "mapview.h"
2
3// Initialize jump physics
4double jump_height = TILE_HEIGHT*3;
5double jump_length = 0.25 * FRAMES_PER_SECOND;
6double jump_velocity = -2 * jump_height / jump_length;
7double jump_gravity = -1 * jump_velocity / jump_length;
8
9MapView::MapView(Map* first, int x, int y)
10{
11 // Initialize player data
12 player = new mob_t();
13 player->x = x;
14 player->y = y;
15 player->x_vel = 0;
16 player->y_vel = 0;
17 player->x_accel = 0;
18 player->y_accel = jump_gravity;
19 player->w = 10;
20 player->h = 14;
21
22 loadMap(first);
23}
24
25MapView::~MapView()
26{
27 destroyTexture(bg);
28
29 delete player;
30}
31
32void MapView::loadMap(Map* m)
33{
34 curMap = m;
35
36 left_collisions.clear();
37 right_collisions.clear();
38 up_collisions.clear();
39 down_collisions.clear();
40
41 add_collision(-6, 0, GAME_WIDTH, left, (m->getLeftMap() == NULL) ? 1 : 2);
42 add_collision(GAME_WIDTH+6, 0, GAME_WIDTH, right, (m->getRightMap() == NULL) ? 1 : 2);
43
44 if (bg == NULL)
45 {
46 bg = createTexture(GAME_WIDTH, GAME_HEIGHT);
47 }
48
49 fillTexture(bg, NULL, 0, 0, 0);
50
51 const char* mapbuf = m->mapdata();
52
53 for (int i=0; i<MAP_WIDTH*(MAP_HEIGHT-1); i++)
54 {
55 int x = i % MAP_WIDTH;
56 int y = i / MAP_WIDTH;
57 Rectangle dst(x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT);
58 //Rectangle src;
59
60 switch (mapbuf[i])
61 {
62 case ' ': break;
63 case 'X': fillTexture(bg, &dst, 255, 85, 85); break;
64 case 'P': fillTexture(bg, &dst, 85, 255, 255); break;
65 }
66
67 //blitTexture(tiles, bg, &src, &dst);
68
69 if (mapbuf[i] == 'X')
70 {
71 if ((x != 0) && (mapbuf[i-1] != 'X'))
72 {
73 add_collision(x*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, right, 0);
74 }
75
76 if ((x != 39) && (mapbuf[i+1] != 'X'))
77 {
78 add_collision((x+1)*TILE_WIDTH, y*TILE_HEIGHT, (y+1)*TILE_HEIGHT, left, 0);
79 }
80
81 if ((y != 0) && (mapbuf[i-MAP_WIDTH] != 'X'))
82 {
83 add_collision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, down, 0);
84 }
85
86 if ((y != 23) && (mapbuf[i+MAP_WIDTH] != 'X'))
87 {
88 add_collision((y+1)*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, up, 0);
89 }
90 } else if (mapbuf[i] == 'P')
91 {
92 add_collision(y*TILE_HEIGHT, x*TILE_WIDTH, (x+1)*TILE_WIDTH, down, 0);
93 }
94 }
95
96 Texture* font = loadTextureFromBMP("../res/font.bmp");
97 const char* map_name = m->title();
98 int start_x = (40/2) - (strlen(map_name)/2);
99 for (size_t i=0; i<strlen(map_name); i++)
100 {
101 Rectangle srcRect(map_name[i] % 16 * 8, map_name[i] / 16 * 8, 8, 8);
102 Rectangle dstRect((start_x + i)*8, 24*8, 8, 8);
103 blitTexture(font, bg, &srcRect, &dstRect);
104 }
105
106 destroyTexture(font);
107}
108
109void MapView::input(int key, int action)
110{
111 if (action == GLFW_PRESS)
112 {
113 switch (key)
114 {
115 case GLFW_KEY_LEFT: holding_left = true; break;
116 case GLFW_KEY_RIGHT: holding_right = true; break;
117 case GLFW_KEY_UP: player->y_vel = jump_velocity; break;
118 }
119 } else if (action == GLFW_RELEASE)
120 {
121 switch (key)
122 {
123 case GLFW_KEY_LEFT: holding_left = false; break;
124 case GLFW_KEY_RIGHT: holding_right = false; break;
125 }
126 }
127}
128
129void MapView::tick()
130{
131 if (holding_left && player->x_vel >= 0)
132 {
133 player->x_vel = -2;
134 } else if (holding_right && player->x_vel <= 0)
135 {
136 player->x_vel = 2;
137 } else if (!holding_left && !holding_right) {
138 player->x_vel = 0;
139 }
140
141 player->x_vel += player->x_accel;
142 if (player->x_vel < -16) player->x_vel = -16;
143 if (player->x_vel > 16) player->x_vel = 16;
144 int playerx_next = player->x + player->x_vel;
145
146 player->y_vel += player->y_accel;
147 if (player->y_vel > 16) player->y_vel = 16; // Terminal velocity
148 if (player->y_vel < -16) player->y_vel = -16;
149 int playery_next = player->y + player->y_vel;
150
151 check_collisions(player, playerx_next, playery_next);
152}
153
154void MapView::render(Texture* tex)
155{
156 // Draw the background
157 blitTexture(bg, tex, NULL, NULL);
158
159 // Draw the player
160 Rectangle dst_rect(player->x, player->y, player->w, player->h);
161 fillTexture(tex, &dst_rect, 255, 255, 255);
162}
163
164void MapView::add_collision(int axis, int lower, int upper, direction_t dir, int type)
165{
166 //printf("added collision\n");
167 list<collision_t>::iterator it;
168
169 switch (dir)
170 {
171 case up:
172 it = up_collisions.begin();
173 for (; it!=up_collisions.end(); it++)
174 {
175 if (it->axis < axis) break;
176 }
177
178 up_collisions.insert(it, {axis, lower, upper, type});
179
180 break;
181 case down:
182 it = down_collisions.begin();
183 for (; it!=down_collisions.end(); it++)
184 {
185 if (it->axis > axis) break;
186 }
187
188 down_collisions.insert(it, {axis, lower, upper, type});
189
190 break;
191 case left:
192 it = left_collisions.begin();
193 for (; it!=left_collisions.end(); it++)
194 {
195 if (it->axis < axis) break;
196 }
197
198 left_collisions.insert(it, {axis, lower, upper, type});
199
200 break;
201 case right:
202 it = right_collisions.begin();
203 for (; it!=right_collisions.end(); it++)
204 {
205 if (it->axis > axis) break;
206 }
207
208 right_collisions.insert(it, {axis, lower, upper, type});
209
210 break;
211 }
212}
213
214void MapView::check_collisions(mob_t* mob, int x_next, int y_next)
215{
216 if (x_next < mob->x)
217 {
218 for (list<collision_t>::iterator it=left_collisions.begin(); it!=left_collisions.end(); it++)
219 {
220 if (it->axis > mob->x) continue;
221 if (it->axis < x_next) break;
222
223 if ((mob->y+mob->h > it->lower) && (mob->y < it->upper))
224 {
225 // We have a collision!
226 if (it->type == 0)
227 {
228 x_next = it->axis;
229 mob->x_vel = 0;
230 } else if (it->type == 1)
231 {
232 x_next = GAME_WIDTH-mob->w/2;
233 } else if (it->type == 2)
234 {
235 x_next = GAME_WIDTH-mob->w/2;
236 loadMap(curMap->getLeftMap());
237 }
238
239 break;
240 }
241 }
242 } else if (x_next > mob->x)
243 {
244 for (list<collision_t>::iterator it=right_collisions.begin(); it!=right_collisions.end(); it++)
245 {
246 if (it->axis < mob->x+mob->w) continue;
247 if (it->axis > x_next+mob->w) break;
248
249 if ((mob->y+mob->h > it->lower) && (mob->y < it->upper))
250 {
251 // We have a collision!
252 if (it->type == 0)
253 {
254 x_next = it->axis - mob->w;
255 mob->x_vel = 0;
256 } else if (it->type == 1)
257 {
258 x_next = -mob->w/2;
259 } else if (it->type == 2)
260 {
261 x_next = -mob->w/2;
262 loadMap(curMap->getRightMap());
263 }
264
265 break;
266 }
267 }
268 }
269
270 mob->x = x_next;
271
272 if (y_next < mob->y)
273 {
274 for (list<collision_t>::iterator it=up_collisions.begin(); it!=up_collisions.end(); it++)
275 {
276 if (it->axis > mob->y) continue;
277 if (it->axis < y_next) break;
278
279 if ((mob->x+mob->w > it->lower) && (mob->x < it->upper))
280 {
281 // We have a collision!
282 if (it->type == 0)
283 {
284 y_next = it->axis;
285 mob->y_vel = 0;
286 } else if (it->type == 1)
287 {
288 y_next = GAME_HEIGHT-mob->h/2-1;
289 }
290
291 break;
292 }
293 }
294 } else if (y_next > mob->y)
295 {
296 for (list<collision_t>::iterator it=down_collisions.begin(); it!=down_collisions.end(); it++)
297 {
298 if (it->axis < mob->y+mob->h) continue;
299 if (it->axis > y_next+mob->h) break;
300
301 if ((mob->x+mob->w > it->lower) && (mob->x < it->upper))
302 {
303 // We have a collision!
304 if (it->type == 0)
305 {
306 y_next = it->axis - mob->h;
307 mob->y_vel = 0;
308 } else if (it->type == 1)
309 {
310 y_next = 1 - mob->h/2;
311 }
312
313 break;
314 }
315 }
316 }
317
318 mob->y = y_next;
319}