test/snake/snake.c

changeset 260
2649d04f0287
parent 257
67d7b79997df
equal deleted inserted replaced
259:1315ac4d1368 260:2649d04f0287
42 42
43 #define SHADER_ID_PLAYER 1 43 #define SHADER_ID_PLAYER 1
44 44
45 #define BACKDROP_SCENE asc_window_scene(0) 45 #define BACKDROP_SCENE asc_window_scene(0)
46 #define MAIN_SCENE asc_window_scene(1) 46 #define MAIN_SCENE asc_window_scene(1)
47
48 #define HUD_WIDTH 400 47 #define HUD_WIDTH 400
49 48
50 enum MoveDirection { 49 enum MoveDirection {
51 MOVE_UP, 50 MOVE_UP,
52 MOVE_LEFT, 51 MOVE_LEFT,
165 asc_active_window->dimensions.y - ((AscText*)node)->dimension.height - 10 164 asc_active_window->dimensions.y - ((AscText*)node)->dimension.height - 10
166 )); 165 ));
167 } 166 }
168 } 167 }
169 168
170 static void fps_counter_create(void) { 169 static AscSceneNode *fps_counter_create(void) {
171 AscSceneNode *node = asc_text( 170 AscSceneNode *node = asc_text(
172 .name = "FPS Counter", 171 .name = "FPS Counter",
173 .color = ASC_RGB(1, 1, 1), 172 .color = ASC_RGB(1, 1, 1),
174 .font = asc_font(ASC_FONT_REGULAR, 12), 173 .font = asc_font(ASC_FONT_REGULAR, 12),
175 ); 174 );
176 asc_behavior_add(node, .func = fps_counter_update, .interval = asc_seconds(1)); 175 asc_behavior_add(node, .func = fps_counter_update, .interval = asc_seconds(1));
177 asc_behavior_add(node, fps_counter_tie_to_corner); 176 asc_behavior_add(node, fps_counter_tie_to_corner);
178 asc_ui_add_node(node); 177 asc_ui_add_node(node);
178 return node;
179 } 179 }
180 180
181 181
182 static GameField *game_field; 182 static GameField *game_field;
183 183
194 } 194 }
195 int new_owner = game_field->tile_data[x][y] & GAME_FIELD_TILE_OWNER_MASK; 195 int new_owner = game_field->tile_data[x][y] & GAME_FIELD_TILE_OWNER_MASK;
196 return old_owner != new_owner; 196 return old_owner != new_owner;
197 } 197 }
198 198
199 static void game_field_create() { 199 static GameField *game_field_create() {
200 // TODO: create a more interesting map than just a basic grid 200 // TODO: create a more interesting map than just a basic grid
201 AscSceneNode *node = asc_scene_node_empty(); 201 AscSceneNode *node = asc_scene_node_empty();
202 game_field = asc_scene_node_allocate_data(node, sizeof(GameField)); 202 game_field = asc_scene_node_allocate_data(node, sizeof(GameField));
203 for (unsigned x = 0; x < GAME_FIELD_SIZE; x++) { 203 for (unsigned x = 0; x < GAME_FIELD_SIZE; x++) {
204 for (unsigned y = 0; y < GAME_FIELD_SIZE; y++) { 204 for (unsigned y = 0; y < GAME_FIELD_SIZE; y++) {
215 asc_scene_node_link(node, tile); 215 asc_scene_node_link(node, tile);
216 } 216 }
217 } 217 }
218 asc_scene_node_set_zindex(node, -2); 218 asc_scene_node_set_zindex(node, -2);
219 asc_scene_add_node(MAIN_SCENE, node); 219 asc_scene_add_node(MAIN_SCENE, node);
220 return game_field;
220 } 221 }
221 222
222 static asc_vec2u game_field_tile_at_position(asc_vec3f position) { 223 static asc_vec2u game_field_tile_at_position(asc_vec3f position) {
223 return ASC_VEC2U((int)position.x / GAME_FIELD_TILE_SIZE, (int)position.y / GAME_FIELD_TILE_SIZE); 224 return ASC_VEC2U((int)position.x / GAME_FIELD_TILE_SIZE, (int)position.y / GAME_FIELD_TILE_SIZE);
224 } 225 }
344 } 345 }
345 } 346 }
346 } 347 }
347 } 348 }
348 349
350 static void player_controls(Player *player) {
351 if (asc_key_pressed(ASC_KEY(LEFT))) {
352 if (player->direction != MOVE_RIGHT) {
353 player->target_direction = MOVE_LEFT;
354 }
355 }
356 if (asc_key_pressed(ASC_KEY(RIGHT))) {
357 if (player->direction != MOVE_LEFT) {
358 player->target_direction = MOVE_RIGHT;
359 }
360 }
361 if (asc_key_pressed(ASC_KEY(UP))) {
362 if (player->direction != MOVE_DOWN) {
363 player->target_direction = MOVE_UP;
364 }
365 }
366 if (asc_key_pressed(ASC_KEY(DOWN))) {
367 if (player->direction != MOVE_UP) {
368 player->target_direction = MOVE_DOWN;
369 }
370 }
371 }
372
349 static void player_position(Player *pl, int x, int y) { 373 static void player_position(Player *pl, int x, int y) {
350 pl->new_position.x = x; 374 pl->new_position.x = x;
351 pl->new_position.y = y; 375 pl->new_position.y = y;
352 pl->reset_position = true; 376 pl->reset_position = true;
353 } 377 }
413 437
414 // Set the viewport to the scaled and centered region 438 // Set the viewport to the scaled and centered region
415 return ASC_RECT(offset_x, offset_y, viewport_size, viewport_size); 439 return ASC_RECT(offset_x, offset_y, viewport_size, viewport_size);
416 } 440 }
417 441
442 #define GAME_STATE_MENU 0
443 #define GAME_STATE_PLAYING 1
444 #define GAME_STATE_GAME_OVER 2
445
446 typedef struct {
447 int state;
448 GameField *field;
449 Player *players[4];
450 } GameState;
451
418 int main(void) { 452 int main(void) {
419 asc_context_initialize(); 453 asc_context_initialize();
420 if (asc_has_error()) { 454 if (asc_has_error()) {
421 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, 455 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
422 "Fatal Error",asc_get_error(), NULL); 456 "Fatal Error",asc_get_error(), NULL);
451 ), 485 ),
452 .viewport_clear = true, 486 .viewport_clear = true,
453 .clear_color = ASC_RGBi(0, 32, 16), 487 .clear_color = ASC_RGBi(0, 32, 16),
454 .viewport_update_func = main_scene_viewport_update 488 .viewport_update_func = main_scene_viewport_update
455 ); 489 );
456
457 // backdrop for letterbox/pillarbox
458 backdrop_create(); 490 backdrop_create();
459 491
460 // the game field 492 // create the fps counter
461 game_field_create(); 493 AscSceneNode *fps_counter = fps_counter_create();
462 494 asc_scene_node_hide(fps_counter);
463 // create UI elements 495
464 fps_counter_create(); 496 // create the game state
465 497 GameState game = {0};
466 // create player 498 // TODO: add a main menu and start with the menu
467 Player *player = player_create(); 499 game.state = GAME_STATE_PLAYING;
500 game.field = game_field_create();
501 game.players[0] = player_create();
468 502
469 // Main Loop 503 // Main Loop
470 do { 504 do {
471 // quit application on any error 505 // quit application on any error
472 if (asc_has_error()) { 506 if (asc_has_error()) {
475 asc_active_window->window); 509 asc_active_window->window);
476 asc_clear_error(); 510 asc_clear_error();
477 asc_context_quit(); 511 asc_context_quit();
478 } 512 }
479 513
480 // player rotation 514 // game states
481 if (asc_key_pressed(ASC_KEY(LEFT))) { 515 if (game.state == GAME_STATE_PLAYING) {
482 if (player->direction != MOVE_RIGHT) { 516 // TODO: implement hot seat 1on1 multiplayer
483 player->target_direction = MOVE_LEFT; 517 player_controls(game.players[0]);
484 }
485 }
486 if (asc_key_pressed(ASC_KEY(RIGHT))) {
487 if (player->direction != MOVE_LEFT) {
488 player->target_direction = MOVE_RIGHT;
489 }
490 }
491 if (asc_key_pressed(ASC_KEY(UP))) {
492 if (player->direction != MOVE_DOWN) {
493 player->target_direction = MOVE_UP;
494 }
495 }
496 if (asc_key_pressed(ASC_KEY(DOWN))) {
497 if (player->direction != MOVE_UP) {
498 player->target_direction = MOVE_DOWN;
499 }
500 } 518 }
501 519
502 // debug-key for clearing the shader registry 520 // debug-key for clearing the shader registry
503 if (asc_key_pressed(ASC_KEY(S))) { 521 if (asc_key_pressed(ASC_KEY(S))) {
504 asc_shader_clear_registry(); 522 asc_shader_clear_registry();
505 asc_dprintf("Shader cache cleared."); 523 asc_dprintf("Shader cache cleared.");
506 } 524 }
507 525
526 // show/hide the FPS counter
527 if (asc_key_pressed(ASC_KEY(F2))) {
528 asc_scene_node_toggle_visibility(fps_counter);
529 }
530
508 // quit application on ESC key press 531 // quit application on ESC key press
509 if (asc_key_pressed(ASC_KEY(ESCAPE))) { 532 if (asc_key_pressed(ASC_KEY(ESCAPE))) {
510 asc_context_quit(); 533 asc_context_quit();
511 } 534 }
512 } while (asc_loop_next()); 535 } while (asc_loop_next());

mercurial