test/snake/snake.c

changeset 213
3d252dbd7c8e
parent 206
26726b7a89a7
child 214
9d460888a83e
equal deleted inserted replaced
212:90bbacb97cb6 213:3d252dbd7c8e
54 static asc_transform rotations[4]; 54 static asc_transform rotations[4];
55 static asc_vec2f directions[4]; 55 static asc_vec2f directions[4];
56 56
57 typedef struct { 57 typedef struct {
58 enum MoveDirection direction; 58 enum MoveDirection direction;
59 /**
60 * The speed in tiles per second.
61 */
62 float speed;
59 } Spaceship; 63 } Spaceship;
64
65 static const unsigned game_field_size = 512;
66 static const unsigned game_field_tile_size = 32;
60 67
61 static void init_globals(void) { 68 static void init_globals(void) {
62 asc_transform_identity(rotations[MOVE_UP]); 69 asc_transform_identity(rotations[MOVE_UP]);
63 asc_transform_roll(rotations[MOVE_LEFT], asc_rad(-90)); 70 asc_transform_roll(rotations[MOVE_LEFT], asc_rad(-90));
64 asc_transform_roll(rotations[MOVE_RIGHT], asc_rad(90)); 71 asc_transform_roll(rotations[MOVE_RIGHT], asc_rad(90));
76 static void init_textures(void) { 83 static void init_textures(void) {
77 asc_texture_init_2d(tex2d, TEX2D_COUNT); 84 asc_texture_init_2d(tex2d, TEX2D_COUNT);
78 asc_texture_from_file(TEXTURE_SHIP, "ship.png"); 85 asc_texture_from_file(TEXTURE_SHIP, "ship.png");
79 asc_texture_from_file(TEXTURE_BACKDROP, "backdrop.png"); 86 asc_texture_from_file(TEXTURE_BACKDROP, "backdrop.png");
80 asc_gl_context_add_cleanup_func(asc_active_glctx, destroy_textures); 87 asc_gl_context_add_cleanup_func(asc_active_glctx, destroy_textures);
88 }
89
90 static void scale_backdrop(AscBehavior *behavior) {
91 // scale the backdrop to the size of the window
92 if (asc_active_window->resized) {
93 asc_ptr_cast(AscSprite, sprite, behavior->node);
94 asc_vec2u window_size = asc_active_window->dimensions;
95 asc_sprite_set_size(sprite, window_size);
96 }
97 }
98
99 static void create_backdrop(void) {
100 AscSceneNode *node = asc_sprite(
101 .texture = TEXTURE_BACKDROP,
102 .texture_scale_mode = ASC_TEXTURE_SCALE_REPEAT
103 );
104 asc_behavior_add(node, .func = scale_backdrop);
105 asc_scene_add_node(BACKDROP_SCENE, node);
81 } 106 }
82 107
83 static void update_fps_counter(AscBehavior *behavior) { 108 static void update_fps_counter(AscBehavior *behavior) {
84 asc_ptr_cast(AscText, node, behavior->node); 109 asc_ptr_cast(AscText, node, behavior->node);
85 static float last_fps = 0.f; 110 static float last_fps = 0.f;
100 (int) bottom_right.y - (int) text_size.height - 10 125 (int) bottom_right.y - (int) text_size.height - 10
101 )); 126 ));
102 } 127 }
103 } 128 }
104 129
105 static void scale_backdrop(AscBehavior *behavior) {
106 // scale the backdrop to the size of the window
107 if (asc_active_window->resized) {
108 asc_ptr_cast(AscSprite, sprite, behavior->node);
109 asc_vec2u window_size = asc_active_window->dimensions;
110 asc_sprite_set_size(sprite, window_size);
111 }
112 }
113
114 static void create_backdrop(void) {
115 AscSceneNode *node = asc_sprite(
116 .texture = TEXTURE_BACKDROP,
117 .texture_scale_mode = ASC_TEXTURE_SCALE_REPEAT
118 );
119 asc_behavior_add(node, .func = scale_backdrop);
120 asc_scene_add_node(BACKDROP_SCENE, node);
121 }
122
123 static void create_fps_counter(void) { 130 static void create_fps_counter(void) {
124 asc_font(ASC_FONT_REGULAR, 12); 131 asc_font(ASC_FONT_REGULAR, 12);
125 asc_ink_rgb(255, 255, 255); 132 asc_ink_rgb(255, 255, 255);
126 AscSceneNode *node = asc_text(.name = "FPS Counter"); 133 AscSceneNode *node = asc_text(.name = "FPS Counter");
127 asc_behavior_add(node, .func = update_fps_counter, .interval = asc_seconds(1)); 134 asc_behavior_add(node, .func = update_fps_counter, .interval = asc_seconds(1));
141 } 148 }
142 149
143 static void move_spaceship(AscBehavior *behavior) { 150 static void move_spaceship(AscBehavior *behavior) {
144 AscSceneNode *node = behavior->node; 151 AscSceneNode *node = behavior->node;
145 Spaceship *spaceship = node->user_data; 152 Spaceship *spaceship = node->user_data;
146 float speed = 32.f * asc_context.frame_factor; 153 float speed = 32.f * spaceship->speed * asc_context.frame_factor;
147 asc_vec2f movement = asc_vec2f_scale(directions[spaceship->direction], speed); 154 asc_vec2f movement = asc_vec2f_scale(directions[spaceship->direction], speed);
148 asc_scene_node_move2f(node, movement); 155 asc_scene_node_move2f(node, movement);
149 asc_scene_node_set_rotation(node, rotations[spaceship->direction]); 156 asc_scene_node_set_rotation(node, rotations[spaceship->direction]);
150 } 157 }
151 158
152 static Spaceship *create_spaceship(void) { 159 static Spaceship *create_spaceship(void) {
153 AscSceneNode *sprite = asc_sprite( 160 AscSceneNode *sprite = asc_sprite(
154 .name = "Player", 161 .name = "Player",
155 .texture = TEXTURE_SHIP, 162 .texture = TEXTURE_SHIP,
156 .x = 250, 163 // TODO: introduce a function to set the position of a space ship
157 .y = 300, 164 .x = game_field_tile_size * 8 - game_field_tile_size / 2,
158 .width = 32, 165 .y = game_field_tile_size * 12 - game_field_tile_size / 2,
159 .height = 32, 166 .width = game_field_tile_size,
160 .origin_x = 16, 167 .height = game_field_tile_size,
161 .origin_y = 16, 168 .origin_x = game_field_tile_size / 2,
169 .origin_y = game_field_tile_size / 2,
162 ); 170 );
163 asc_scene_add_node(MAIN_SCENE, sprite); 171 asc_scene_add_node(MAIN_SCENE, sprite);
164 asc_scene_node_allocate_data(sprite, sizeof(Spaceship)); 172 Spaceship *ship = asc_scene_node_allocate_data(sprite, sizeof(Spaceship));
173 ship->speed = 2.f; // start with 2 tiles/sec
165 asc_behavior_add(sprite, move_spaceship); 174 asc_behavior_add(sprite, move_spaceship);
166 return sprite->user_data; 175 return sprite->user_data;
176 }
177
178 static void create_gamefield() {
179 // TODO: create a proper data structure and a more interesting map than just a basic grid
180 AscSceneNode *gamefield = asc_scene_node_empty();
181 for (unsigned x = 0; x < game_field_size; x+=game_field_tile_size) {
182 for (unsigned y = 0; y < game_field_size; y+=game_field_tile_size) {
183 asc_ink_rgb(0, 128, 255);
184 AscSceneNode *tile = asc_rectangle(
185 .x = x, .y = y, .filled = true, .thickness = 1,
186 .width = game_field_tile_size, .height = game_field_tile_size,
187 .border_color = ASC_RGB(64, 196, 255),
188 );
189 asc_scene_node_link(gamefield, tile);
190 }
191 }
192 asc_scene_node_set_zindex(gamefield, -2);
193 asc_scene_add_node(MAIN_SCENE, gamefield);
167 } 194 }
168 195
169 static asc_rect update_viewport_for_window_resize(asc_vec2u window_size) { 196 static asc_rect update_viewport_for_window_resize(asc_vec2u window_size) {
170 // Compute scaling and offsets 197 // Compute scaling and offsets
171 unsigned viewport_size, offset_x = 0, offset_y = 0; 198 unsigned viewport_size, offset_x = 0, offset_y = 0;
201 228
202 // create window 229 // create window
203 AscWindowSettings settings; 230 AscWindowSettings settings;
204 asc_window_settings_init_defaults(&settings); 231 asc_window_settings_init_defaults(&settings);
205 settings.title = "Snake"; 232 settings.title = "Snake";
233 settings.dimensions = ASC_VEC2U(800, 800);
206 asc_window_initialize(0, &settings); 234 asc_window_initialize(0, &settings);
207 asc_ui_scale_auto(); 235 asc_ui_scale_auto();
208 236
209 // load textures 237 // load textures
210 init_textures(); 238 init_textures();
211 239
212 // initialize the scenes 240 // initialize the scenes
213 const int game_field_size = 512;
214 asc_scene_init(BACKDROP_SCENE, 241 asc_scene_init(BACKDROP_SCENE,
215 .type = ASC_CAMERA_ORTHO, 242 .type = ASC_CAMERA_ORTHO,
216 .projection_update_func = asc_camera_ortho_update_size 243 .projection_update_func = asc_camera_ortho_update_size
217 ); 244 );
218 asc_ink_rgb(0, 128, 90); 245 asc_ink_rgb(0, 128, 90);
219 asc_scene_init(MAIN_SCENE, 246 asc_scene_init(MAIN_SCENE,
220 .type = ASC_CAMERA_ORTHO, 247 .type = ASC_CAMERA_ORTHO,
221 .ortho.rect = ASC_RECT(0, 0, game_field_size, game_field_size), 248 .ortho.rect = ASC_RECT(
249 -game_field_tile_size/2,
250 -game_field_tile_size/2,
251 game_field_size+game_field_tile_size,
252 game_field_size+game_field_tile_size
253 ),
222 .viewport_clear = true, 254 .viewport_clear = true,
223 .viewport_update_func = update_viewport_for_window_resize 255 .viewport_update_func = update_viewport_for_window_resize
224 ); 256 );
225 257
226 // backdrop for letterbox/pillarbox 258 // backdrop for letterbox/pillarbox
227 create_backdrop(); 259 create_backdrop();
260
261 // the game field
262 create_gamefield();
228 263
229 // create UI elements 264 // create UI elements
230 create_fps_counter(); 265 create_fps_counter();
231 create_score_counter(); 266 create_score_counter();
232 267

mercurial