test/snake/snake.c

changeset 206
26726b7a89a7
parent 205
d1e44c861426
equal deleted inserted replaced
205:d1e44c861426 206:26726b7a89a7
42 #define TEXTURE_BACKDROP &tex2d[TEX_BACKDROP] 42 #define TEXTURE_BACKDROP &tex2d[TEX_BACKDROP]
43 43
44 #define BACKDROP_SCENE asc_window_scene(0) 44 #define BACKDROP_SCENE asc_window_scene(0)
45 #define MAIN_SCENE asc_window_scene(1) 45 #define MAIN_SCENE asc_window_scene(1)
46 46
47 static void destroy_textures(void) {
48 asc_texture_destroy(tex2d, TEX2D_COUNT);
49 }
50
51 static void init_textures(void) {
52 asc_texture_init_2d(tex2d, TEX2D_COUNT);
53 asc_texture_from_file(TEXTURE_SHIP, "ship.png");
54 asc_texture_from_file(TEXTURE_BACKDROP, "backdrop.png");
55 asc_gl_context_add_cleanup_func(asc_active_glctx, destroy_textures);
56 }
57
58 static void update_fps_counter(AscBehavior *behavior) {
59 asc_ptr_cast(AscText, node, behavior->node);
60 static float last_fps = 0.f;
61 if (fabsf(asc_context.frame_rate - last_fps) > 1) {
62 last_fps = asc_context.frame_rate;
63 asc_text_printf(node, "%.2f FPS", asc_context.frame_rate);
64 }
65 }
66
67 static void tie_fps_counter_to_corner(AscBehavior *behavior) {
68 // TODO: this should be replaced with some sort of UI layout manager
69 AscSceneNode *node = behavior->node;
70 if (asc_test_flag(node->flags, ASC_SCENE_NODE_GRAPHICS_UPDATED) || asc_active_window->resized) {
71 asc_vec2u bottom_right = asc_active_window->dimensions;
72 asc_vec2u text_size = ((AscText*)node)->dimension;
73 asc_node_set_position2f(node, ASC_VEC2F(
74 (int) bottom_right.x - (int) text_size.width - 10,
75 (int) bottom_right.y - (int) text_size.height - 10
76 ));
77 }
78 }
79
80 static void scale_backdrop(AscBehavior *behavior) {
81 // scale the backdrop to the size of the window
82 if (asc_active_window->resized) {
83 asc_ptr_cast(AscSprite, sprite, behavior->node);
84 asc_vec2u window_size = asc_active_window->dimensions;
85 asc_sprite_set_size(sprite, window_size);
86 }
87 }
88
89 static void create_backdrop(void) {
90 AscSceneNode *node = asc_sprite(
91 .texture = TEXTURE_BACKDROP,
92 .texture_scale_mode = ASC_TEXTURE_SCALE_REPEAT
93 );
94 asc_behavior_add(node, .func = scale_backdrop);
95 asc_scene_add_node(BACKDROP_SCENE, node);
96 }
97
98 static void create_fps_counter(void) {
99 asc_font(ASC_FONT_REGULAR, 12);
100 asc_ink_rgb(255, 255, 255);
101 AscSceneNode *node = asc_text(.name = "FPS Counter");
102 asc_behavior_add(node, .func = update_fps_counter, .interval = asc_seconds(1));
103 asc_behavior_add(node, tie_fps_counter_to_corner);
104 asc_ui_add_node(node);
105 }
106
107 static void create_score_counter(void) {
108 asc_font(ASC_FONT_BOLD, 16);
109 asc_ink_rgb(0, 255, 0);
110 AscSceneNode *node = asc_text(
111 .name = "Score Counter",
112 .x = 10, .y = 10,
113 .text = "Score: 0"
114 );
115 asc_ui_add_node(node);
116 }
117
118 enum MoveDirection { 47 enum MoveDirection {
119 MOVE_UP, 48 MOVE_UP,
120 MOVE_LEFT, 49 MOVE_LEFT,
121 MOVE_DOWN, 50 MOVE_DOWN,
122 MOVE_RIGHT 51 MOVE_RIGHT
124 53
125 static asc_transform rotations[4]; 54 static asc_transform rotations[4];
126 static asc_vec2f directions[4]; 55 static asc_vec2f directions[4];
127 56
128 typedef struct { 57 typedef struct {
129 AscSceneNode *sprite;
130 enum MoveDirection direction; 58 enum MoveDirection direction;
131 } Spaceship; 59 } Spaceship;
132 60
133 static void turn_left(Spaceship *spaceship) { 61 static void init_globals(void) {
134 spaceship->direction = (spaceship->direction + 1) % 4;
135 asc_node_set_rotation(spaceship->sprite, rotations[spaceship->direction]);
136 }
137
138 static void turn_right(Spaceship *spaceship) {
139 spaceship->direction = (spaceship->direction + 3) % 4;
140 asc_node_set_rotation(spaceship->sprite, rotations[spaceship->direction]);
141 }
142
143 static Spaceship *create_spaceship(void) {
144 // TODO: this all belongs somewhere else, this is just quickly hacked into here for testing
145 asc_transform_identity(rotations[MOVE_UP]); 62 asc_transform_identity(rotations[MOVE_UP]);
146 asc_transform_roll(rotations[MOVE_LEFT], asc_rad(-90)); 63 asc_transform_roll(rotations[MOVE_LEFT], asc_rad(-90));
147 asc_transform_roll(rotations[MOVE_RIGHT], asc_rad(90)); 64 asc_transform_roll(rotations[MOVE_RIGHT], asc_rad(90));
148 asc_transform_roll(rotations[MOVE_DOWN], asc_rad(180)); 65 asc_transform_roll(rotations[MOVE_DOWN], asc_rad(180));
149 directions[MOVE_UP] = ASC_VEC2F(0, -1); 66 directions[MOVE_UP] = ASC_VEC2F(0, -1);
150 directions[MOVE_LEFT] = ASC_VEC2F(-1, 0); 67 directions[MOVE_LEFT] = ASC_VEC2F(-1, 0);
151 directions[MOVE_DOWN] = ASC_VEC2F(0, 1); 68 directions[MOVE_DOWN] = ASC_VEC2F(0, 1);
152 directions[MOVE_RIGHT] = ASC_VEC2F(1, 0); 69 directions[MOVE_RIGHT] = ASC_VEC2F(1, 0);
70 }
71
72 static void destroy_textures(void) {
73 asc_texture_destroy(tex2d, TEX2D_COUNT);
74 }
75
76 static void init_textures(void) {
77 asc_texture_init_2d(tex2d, TEX2D_COUNT);
78 asc_texture_from_file(TEXTURE_SHIP, "ship.png");
79 asc_texture_from_file(TEXTURE_BACKDROP, "backdrop.png");
80 asc_gl_context_add_cleanup_func(asc_active_glctx, destroy_textures);
81 }
82
83 static void update_fps_counter(AscBehavior *behavior) {
84 asc_ptr_cast(AscText, node, behavior->node);
85 static float last_fps = 0.f;
86 if (fabsf(asc_context.frame_rate - last_fps) > 1) {
87 last_fps = asc_context.frame_rate;
88 asc_text_printf(node, "%.2f FPS", asc_context.frame_rate);
89 }
90 }
91
92 static void tie_fps_counter_to_corner(AscBehavior *behavior) {
93 // TODO: this should be replaced with some sort of UI layout manager
94 AscSceneNode *node = behavior->node;
95 if (asc_test_flag(node->flags, ASC_SCENE_NODE_GRAPHICS_UPDATED) || asc_active_window->resized) {
96 asc_vec2u bottom_right = asc_active_window->dimensions;
97 asc_vec2u text_size = ((AscText*)node)->dimension;
98 asc_scene_node_set_position2f(node, ASC_VEC2F(
99 (int) bottom_right.x - (int) text_size.width - 10,
100 (int) bottom_right.y - (int) text_size.height - 10
101 ));
102 }
103 }
104
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) {
124 asc_font(ASC_FONT_REGULAR, 12);
125 asc_ink_rgb(255, 255, 255);
126 AscSceneNode *node = asc_text(.name = "FPS Counter");
127 asc_behavior_add(node, .func = update_fps_counter, .interval = asc_seconds(1));
128 asc_behavior_add(node, tie_fps_counter_to_corner);
129 asc_ui_add_node(node);
130 }
131
132 static void create_score_counter(void) {
133 asc_font(ASC_FONT_BOLD, 16);
134 asc_ink_rgb(0, 255, 0);
135 AscSceneNode *node = asc_text(
136 .name = "Score Counter",
137 .x = 10, .y = 10,
138 .text = "Score: 0"
139 );
140 asc_ui_add_node(node);
141 }
142
143 static void move_spaceship(AscBehavior *behavior) {
144 AscSceneNode *node = behavior->node;
145 Spaceship *spaceship = node->user_data;
146 float speed = 32.f * asc_context.frame_factor;
147 asc_vec2f movement = asc_vec2f_scale(directions[spaceship->direction], speed);
148 asc_scene_node_move2f(node, movement);
149 asc_scene_node_set_rotation(node, rotations[spaceship->direction]);
150 }
151
152 static Spaceship *create_spaceship(void) {
153 AscSceneNode *sprite = asc_sprite( 153 AscSceneNode *sprite = asc_sprite(
154 .name = "Player", 154 .name = "Player",
155 .texture = TEXTURE_SHIP, 155 .texture = TEXTURE_SHIP,
156 .x = 250, 156 .x = 250,
157 .y = 300, 157 .y = 300,
158 .width = 64, 158 .width = 32,
159 .height = 64, 159 .height = 32,
160 .origin_x = 32, 160 .origin_x = 16,
161 .origin_y = 32, 161 .origin_y = 16,
162 ); 162 );
163 asc_scene_add_node(MAIN_SCENE, sprite); 163 asc_scene_add_node(MAIN_SCENE, sprite);
164 // TODO: this is never freed at the moment 164 asc_scene_node_allocate_data(sprite, sizeof(Spaceship));
165 Spaceship *ship = cxZallocDefault(sizeof(Spaceship)); 165 asc_behavior_add(sprite, move_spaceship);
166 ship->sprite = sprite; 166 return sprite->user_data;
167 return ship;
168 } 167 }
169 168
170 static asc_rect update_viewport_for_window_resize(asc_vec2u window_size) { 169 static asc_rect update_viewport_for_window_resize(asc_vec2u window_size) {
171 // Compute scaling and offsets 170 // Compute scaling and offsets
172 unsigned viewport_size, offset_x = 0, offset_y = 0; 171 unsigned viewport_size, offset_x = 0, offset_y = 0;
195 asc_set_font_path("../../fonts"); 194 asc_set_font_path("../../fonts");
196 asc_set_shader_path("../../shader"); 195 asc_set_shader_path("../../shader");
197 asc_set_texture_path("../../test/snake/textures"); 196 asc_set_texture_path("../../test/snake/textures");
198 #endif 197 #endif
199 198
199 // initialize globals
200 init_globals();
201
200 // create window 202 // create window
201 AscWindowSettings settings; 203 AscWindowSettings settings;
202 asc_window_settings_init_defaults(&settings); 204 asc_window_settings_init_defaults(&settings);
203 settings.title = "Snake"; 205 settings.title = "Snake";
204 asc_window_initialize(0, &settings); 206 asc_window_initialize(0, &settings);
206 208
207 // load textures 209 // load textures
208 init_textures(); 210 init_textures();
209 211
210 // initialize the scenes 212 // initialize the scenes
211 const int game_field_size = 500; 213 const int game_field_size = 512;
212 asc_scene_init(BACKDROP_SCENE, 214 asc_scene_init(BACKDROP_SCENE,
213 .type = ASC_CAMERA_ORTHO, 215 .type = ASC_CAMERA_ORTHO,
214 .projection_update_func = asc_camera_ortho_update_size 216 .projection_update_func = asc_camera_ortho_update_size
215 ); 217 );
216 asc_ink_rgb(0, 128, 90); 218 asc_ink_rgb(0, 128, 90);
242 asc_context_quit(); 244 asc_context_quit();
243 } 245 }
244 246
245 // player rotation 247 // player rotation
246 if (asc_key_pressed(ASC_KEY(LEFT))) { 248 if (asc_key_pressed(ASC_KEY(LEFT))) {
247 turn_left(spaceship); 249 if (spaceship->direction != MOVE_RIGHT) {
250 spaceship->direction = MOVE_LEFT;
251 }
248 } 252 }
249 if (asc_key_pressed(ASC_KEY(RIGHT))) { 253 if (asc_key_pressed(ASC_KEY(RIGHT))) {
250 turn_right(spaceship); 254 if (spaceship->direction != MOVE_LEFT) {
255 spaceship->direction = MOVE_RIGHT;
256 }
257 }
258 if (asc_key_pressed(ASC_KEY(UP))) {
259 if (spaceship->direction != MOVE_DOWN) {
260 spaceship->direction = MOVE_UP;
261 }
262 }
263 if (asc_key_pressed(ASC_KEY(DOWN))) {
264 if (spaceship->direction != MOVE_UP) {
265 spaceship->direction = MOVE_DOWN;
266 }
251 } 267 }
252 268
253 // debug-key for clearing the shader registry 269 // debug-key for clearing the shader registry
254 if (asc_key_pressed(ASC_KEY(S))) { 270 if (asc_key_pressed(ASC_KEY(S))) {
255 asc_shader_clear_registry(); 271 asc_shader_clear_registry();

mercurial