66 float speed; |
66 float speed; |
67 asc_vec2i new_position; |
67 asc_vec2i new_position; |
68 bool reset_position; |
68 bool reset_position; |
69 } Player; |
69 } Player; |
70 |
70 |
71 static const unsigned game_field_size = 32; |
71 #define GAME_FIELD_SIZE 32 |
72 static const unsigned game_field_tile_size = 32; |
72 #define GAME_FIELD_TILE_SIZE 32 |
|
73 |
|
74 /** The bit in the tile data indicating if the tile exists. */ |
|
75 #define GAME_FIELD_TILE_EXISTS_FLAG 0x80 |
|
76 /** The bits in the tile data that identify the owner. */ |
|
77 #define GAME_FIELD_TILE_OWNER_MASK 0xF |
|
78 |
|
79 typedef struct { |
|
80 AscSceneNode *nodes[GAME_FIELD_SIZE][GAME_FIELD_SIZE]; |
|
81 int8_t tile_data[GAME_FIELD_SIZE][GAME_FIELD_SIZE]; |
|
82 } GameField; |
73 |
83 |
74 static void globals_init(void) { |
84 static void globals_init(void) { |
75 asc_transform_identity(rotations[MOVE_UP]); |
85 asc_transform_identity(rotations[MOVE_UP]); |
76 asc_transform_roll(rotations[MOVE_LEFT], asc_rad(-90)); |
86 asc_transform_roll(rotations[MOVE_LEFT], asc_rad(-90)); |
77 asc_transform_roll(rotations[MOVE_RIGHT], asc_rad(90)); |
87 asc_transform_roll(rotations[MOVE_RIGHT], asc_rad(90)); |
205 |
215 |
206 // check if the position is set programmatically |
216 // check if the position is set programmatically |
207 if (player->reset_position) { |
217 if (player->reset_position) { |
208 asc_scene_node_set_position2f(node, |
218 asc_scene_node_set_position2f(node, |
209 ASC_VEC2F( |
219 ASC_VEC2F( |
210 game_field_tile_size * player->new_position.x, |
220 GAME_FIELD_TILE_SIZE * player->new_position.x, |
211 game_field_tile_size * player->new_position.y)); |
221 GAME_FIELD_TILE_SIZE * player->new_position.y)); |
212 player->reset_position = false; |
222 player->reset_position = false; |
213 return; |
223 return; |
214 } |
224 } |
215 |
225 |
216 // normal movement |
226 // normal movement |
217 const int ts = (int) game_field_tile_size; |
227 const int ts = (int) GAME_FIELD_TILE_SIZE; |
218 const float fts = (float) ts; |
228 const float fts = (float) ts; |
219 const float speed = fts * player->speed * asc_context.frame_factor; |
229 const float speed = fts * player->speed * asc_context.frame_factor; |
220 const asc_vec2i dir = directions[player->direction]; |
230 const asc_vec2i dir = directions[player->direction]; |
221 const asc_vec2f movement = asc_vec2f_scale(asc_vec2_itof(dir), speed); |
231 const asc_vec2f movement = asc_vec2f_scale(asc_vec2_itof(dir), speed); |
222 // check if we are supposed to change the direction |
232 // check if we are supposed to change the direction |
259 } |
269 } |
260 |
270 |
261 static Player *player_create(void) { |
271 static Player *player_create(void) { |
262 AscSceneNode *sprite = asc_sprite( |
272 AscSceneNode *sprite = asc_sprite( |
263 .name = "Player", |
273 .name = "Player", |
264 .width = game_field_tile_size, |
274 .width = GAME_FIELD_TILE_SIZE, |
265 .height = game_field_tile_size, |
275 .height = GAME_FIELD_TILE_SIZE, |
266 .origin_x = game_field_tile_size / 2, |
276 .origin_x = GAME_FIELD_TILE_SIZE / 2, |
267 .origin_y = game_field_tile_size / 2, |
277 .origin_y = GAME_FIELD_TILE_SIZE / 2, |
268 ); |
278 ); |
269 asc_scene_add_node(MAIN_SCENE, sprite); |
279 asc_scene_add_node(MAIN_SCENE, sprite); |
270 Player *player = asc_scene_node_allocate_data(sprite, sizeof(Player)); |
280 Player *player = asc_scene_node_allocate_data(sprite, sizeof(Player)); |
271 player_position(player, 12, 8); |
281 player_position(player, 12, 8); |
272 player->speed = 3.f; // start with 3 tiles/sec |
282 player->speed = 3.f; // start with 3 tiles/sec |
276 return player; |
286 return player; |
277 } |
287 } |
278 |
288 |
279 static void gamefield_create() { |
289 static void gamefield_create() { |
280 // TODO: create a proper data structure and a more interesting map than just a basic grid |
290 // TODO: create a proper data structure and a more interesting map than just a basic grid |
281 AscSceneNode *gamefield = asc_scene_node_empty(); |
291 AscSceneNode *node = asc_scene_node_empty(); |
282 for (unsigned x = 1; x <= game_field_size; x++) { |
292 GameField *data = asc_scene_node_allocate_data(node, sizeof(GameField)); |
283 for (unsigned y = 1; y <= game_field_size; y++) { |
293 for (unsigned x = 0; x < GAME_FIELD_SIZE; x++) { |
|
294 for (unsigned y = 0; y < GAME_FIELD_SIZE; y++) { |
284 AscSceneNode *tile = asc_rectangle( |
295 AscSceneNode *tile = asc_rectangle( |
285 .x = x*game_field_tile_size, .y = y*game_field_tile_size, .filled = true, .thickness = 2, |
296 .x = (x+1)*GAME_FIELD_TILE_SIZE, .y = (y+1)*GAME_FIELD_TILE_SIZE, .filled = true, .thickness = 2, |
286 .origin_x = game_field_tile_size / 2, .origin_y = game_field_tile_size / 2, |
297 .origin_x = GAME_FIELD_TILE_SIZE / 2, .origin_y = GAME_FIELD_TILE_SIZE / 2, |
287 .width = game_field_tile_size, .height = game_field_tile_size, |
298 .width = GAME_FIELD_TILE_SIZE, .height = GAME_FIELD_TILE_SIZE, |
288 .color = ASC_RGB(16, 50, 160), |
299 .color = ASC_RGB(16, 50, 160), |
289 .border_color = ASC_RGB(20, 84, 128), |
300 .border_color = ASC_RGB(20, 84, 128), |
290 ); |
301 ); |
291 asc_scene_node_link(gamefield, tile); |
302 |
292 } |
303 data->tile_data[x][y] = GAME_FIELD_TILE_EXISTS_FLAG; |
293 } |
304 data->nodes[x][y] = tile; |
294 asc_scene_node_set_zindex(gamefield, -2); |
305 |
295 asc_scene_add_node(MAIN_SCENE, gamefield); |
306 asc_scene_node_link(node, tile); |
|
307 } |
|
308 } |
|
309 asc_scene_node_set_zindex(node, -2); |
|
310 asc_scene_add_node(MAIN_SCENE, node); |
296 } |
311 } |
297 |
312 |
298 static asc_rect main_scene_viewport_update(asc_vec2u window_size) { |
313 static asc_rect main_scene_viewport_update(asc_vec2u window_size) { |
299 |
314 |
300 // margins |
315 // margins |
361 .projection_update_func = asc_camera_ortho_update_size |
376 .projection_update_func = asc_camera_ortho_update_size |
362 ); |
377 ); |
363 asc_scene_init(MAIN_SCENE, "main", |
378 asc_scene_init(MAIN_SCENE, "main", |
364 .type = ASC_CAMERA_ORTHO, |
379 .type = ASC_CAMERA_ORTHO, |
365 .ortho.rect = ASC_RECT(0, 0, |
380 .ortho.rect = ASC_RECT(0, 0, |
366 (game_field_size+1)*game_field_tile_size, |
381 (GAME_FIELD_SIZE+1)*GAME_FIELD_TILE_SIZE, |
367 (game_field_size+1)*game_field_tile_size |
382 (GAME_FIELD_SIZE+1)*GAME_FIELD_TILE_SIZE |
368 ), |
383 ), |
369 .viewport_clear = true, |
384 .viewport_clear = true, |
370 .clear_color = ASC_RGB(0, 32, 16), |
385 .clear_color = ASC_RGB(0, 32, 16), |
371 .viewport_update_func = main_scene_viewport_update |
386 .viewport_update_func = main_scene_viewport_update |
372 ); |
387 ); |