| 56 |
56 |
| 57 static asc_transform rotations[4]; |
57 static asc_transform rotations[4]; |
| 58 static asc_vec2i directions[4]; |
58 static asc_vec2i directions[4]; |
| 59 |
59 |
| 60 typedef struct { |
60 typedef struct { |
| |
61 AscSceneNode *node; |
| 61 asc_color color; |
62 asc_color color; |
| 62 enum MoveDirection direction; |
63 enum MoveDirection direction; |
| 63 enum MoveDirection target_direction; |
64 enum MoveDirection target_direction; |
| |
65 /** |
| |
66 * The number of tiles this player can look. |
| |
67 */ |
| |
68 float view_distance; |
| 64 /** |
69 /** |
| 65 * The speed in tiles per second. |
70 * The speed in tiles per second. |
| 66 */ |
71 */ |
| 67 float speed; |
72 float speed; |
| 68 /** |
73 /** |
| 471 .origin_x = GAME_FIELD_TILE_SIZE / 2, |
476 .origin_x = GAME_FIELD_TILE_SIZE / 2, |
| 472 .origin_y = GAME_FIELD_TILE_SIZE / 2, |
477 .origin_y = GAME_FIELD_TILE_SIZE / 2, |
| 473 ); |
478 ); |
| 474 asc_scene_add_node(MAIN_SCENE, node); |
479 asc_scene_add_node(MAIN_SCENE, node); |
| 475 Player *player = asc_scene_node_allocate_data(node, sizeof(Player)); |
480 Player *player = asc_scene_node_allocate_data(node, sizeof(Player)); |
| |
481 player->node = node; |
| |
482 player->view_distance = 7.f; // start with 7 tiles |
| 476 player->speed = 3.f; // start with 3 tiles/sec |
483 player->speed = 3.f; // start with 3 tiles/sec |
| 477 player->number = 1; |
484 player->number = 1; |
| 478 player->health = 100; |
485 player->health = 100; |
| 479 player->color = ASC_RGB(1, 0, 0); |
486 player->color = ASC_RGB(1, 0, 0); |
| 480 player->trace = cxLinkedListCreateSimple(sizeof(asc_vec2u)); |
487 player->trace = cxLinkedListCreateSimple(sizeof(asc_vec2u)); |
| 489 asc_behavior_disable_all_while_hidden(node); |
496 asc_behavior_disable_all_while_hidden(node); |
| 490 |
497 |
| 491 return player; |
498 return player; |
| 492 } |
499 } |
| 493 |
500 |
| 494 static asc_rect main_scene_viewport_update(asc_vec2u window_size) { |
501 static void main_scene_viewport_update(AscCamera *camera, asc_vec2u window_size) { |
| 495 |
|
| 496 // margins |
502 // margins |
| 497 const unsigned margin = 16; |
503 const unsigned margin = 16; |
| 498 |
504 |
| 499 // space for score, power-ups, etc. |
505 // space for score, power-ups, etc. |
| 500 const unsigned left_area = (unsigned) (asc_active_window->ui_scale*HUD_WIDTH); |
506 const unsigned left_area = (unsigned) (asc_active_window->ui_scale*HUD_WIDTH); |
| 503 const unsigned rw = 2*margin + left_area; |
509 const unsigned rw = 2*margin + left_area; |
| 504 const unsigned rh = 2*margin; |
510 const unsigned rh = 2*margin; |
| 505 |
511 |
| 506 // check if there is still a viewport left and chicken out when not |
512 // check if there is still a viewport left and chicken out when not |
| 507 if (window_size.width < rw || window_size.height < rh) { |
513 if (window_size.width < rw || window_size.height < rh) { |
| 508 return ASC_RECT(0, 0, 0, 0); |
514 camera->viewport = ASC_RECT(0, 0, 0, 0); |
| |
515 return; |
| 509 } |
516 } |
| 510 window_size.width -= rw; |
517 window_size.width -= rw; |
| 511 window_size.height -= rh; |
518 window_size.height -= rh; |
| 512 |
519 |
| 513 // Compute scaling and offsets |
520 // Compute scaling and offsets |
| 523 } |
530 } |
| 524 offset_x += left_area + margin; |
531 offset_x += left_area + margin; |
| 525 offset_y += margin; |
532 offset_y += margin; |
| 526 |
533 |
| 527 // Set the viewport to the scaled and centered region |
534 // Set the viewport to the scaled and centered region |
| 528 return ASC_RECT(offset_x, offset_y, viewport_size, viewport_size); |
535 camera->viewport = ASC_RECT(offset_x, offset_y, viewport_size, viewport_size); |
| |
536 } |
| |
537 |
| |
538 static void main_scene_camera_update(AscCamera *camera) { |
| |
539 // follow the player |
| |
540 // TODO: for hot seat / split screen updates we need to attach custom data to the camera |
| |
541 // s.t. the camera knows which player to follow |
| |
542 const Player *player = game.players[0]; |
| |
543 |
| |
544 const AscSceneNode *player_node = player->node; |
| |
545 const float view_distance = player->view_distance; |
| |
546 const float cam_view_distance = (1+view_distance) * GAME_FIELD_TILE_SIZE; |
| |
547 const float proj_size = 2 * cam_view_distance; |
| |
548 |
| |
549 // TODO: create camera API to avoid direct access to the matrices |
| |
550 |
| |
551 // update the projection matrix |
| |
552 asc_mat4f_ortho_update_size(camera->projection, proj_size, proj_size); |
| |
553 |
| |
554 // update the view matrix |
| |
555 asc_vec2f pos = asc_scene_node_get_position2f(player_node); |
| |
556 pos.x = -pos.x + cam_view_distance; |
| |
557 pos.y = -pos.y + cam_view_distance; |
| |
558 asc_transform_translate2f(camera->view, pos); |
| 529 } |
559 } |
| 530 |
560 |
| 531 int main(void) { |
561 int main(void) { |
| 532 asc_context_initialize(); |
562 asc_context_initialize(); |
| 533 if (asc_has_error()) { |
563 if (asc_has_error()) { |
| 551 |
581 |
| 552 // initialize backdrop scene |
582 // initialize backdrop scene |
| 553 AscCamera backdrop_camera; |
583 AscCamera backdrop_camera; |
| 554 asc_camera_init(&backdrop_camera, |
584 asc_camera_init(&backdrop_camera, |
| 555 .type = ASC_CAMERA_ORTHO, |
585 .type = ASC_CAMERA_ORTHO, |
| 556 .projection_update_func = asc_camera_ortho_update_size |
586 .viewport_update_func = asc_camera_ortho_update_size |
| 557 ); |
587 ); |
| 558 asc_scene_init(BACKDROP_SCENE, "backdrop", &backdrop_camera); |
588 asc_scene_init(BACKDROP_SCENE, "backdrop", &backdrop_camera); |
| 559 backdrop_create(); |
589 backdrop_create(); |
| 560 |
590 |
| 561 // Initialize the main scene |
591 // Initialize the main scene |
| 562 const unsigned initial_view_distance = 10; |
|
| 563 AscCamera main_camera; |
592 AscCamera main_camera; |
| 564 asc_camera_init(&main_camera, |
593 asc_camera_init(&main_camera, |
| 565 .type = ASC_CAMERA_ORTHO, |
594 .type = ASC_CAMERA_ORTHO, |
| 566 .ortho.rect = ASC_RECT(0, 0, |
|
| 567 initial_view_distance*2*GAME_FIELD_TILE_SIZE, |
|
| 568 initial_view_distance*2*GAME_FIELD_TILE_SIZE |
|
| 569 ), |
|
| 570 .viewport_clear = true, |
595 .viewport_clear = true, |
| 571 .clear_color = ASC_RGBi(0, 32, 16), |
596 .clear_color = ASC_RGBi(0, 32, 16), |
| 572 .viewport_update_func = main_scene_viewport_update |
597 .viewport_update_func = main_scene_viewport_update, |
| |
598 .update_func = main_scene_camera_update |
| 573 ); |
599 ); |
| 574 asc_scene_init(MAIN_SCENE, "main", &main_camera); |
600 asc_scene_init(MAIN_SCENE, "main", &main_camera); |
| 575 |
601 |
| 576 // create the fps counter |
602 // create the fps counter |
| 577 AscSceneNode *fps_counter = fps_counter_create(); |
603 AscSceneNode *fps_counter = fps_counter_create(); |