demo/snake/snake.c

changeset 288
8796f03aac26
parent 287
359eaf2a8bd2
equal deleted inserted replaced
287:359eaf2a8bd2 288:8796f03aac26
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();

mercurial