Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Experimento con emscripten y SDL

1178 views
1
#include "engine.h"
2
3
void snake_render_handler(actor *a)
4
{
5
snake_actor *sn = (snake_actor *)a;
6
7
int i;
8
for (i = 0; i < sn->num_segments; i++) {
9
sprite_render(&(sn->snake_sprites[i]));
10
}
11
}
12
13
void snake_direction_to_vector(snake_actor *sn, int *r)
14
{
15
switch (sn->direction) {
16
case DIRECTION_N:
17
r[0] = 0;
18
r[1] = -1;
19
break;
20
case DIRECTION_E:
21
r[0] = 1;
22
r[1] = 0;
23
break;
24
case DIRECTION_S:
25
r[0] = 0;
26
r[1] = 1;
27
break;
28
case DIRECTION_W:
29
r[0] = -1;
30
r[1] = 0;
31
break;
32
}
33
}
34
35
SPRITES_DECALS snake_get_neck_decal(snake_actor *sn, DIRECTION old_direction)
36
{
37
switch (sn->direction) {
38
case DIRECTION_N:
39
switch (old_direction) {
40
case DIRECTION_W:
41
return BODY_NE;
42
case DIRECTION_E:
43
return BODY_NW;
44
default:
45
return BODY_N;
46
}
47
case DIRECTION_E:
48
switch (old_direction) {
49
case DIRECTION_N:
50
return BODY_SE;
51
case DIRECTION_S:
52
return BODY_NE;
53
default:
54
return BODY_E;
55
}
56
case DIRECTION_S:
57
switch (old_direction) {
58
case DIRECTION_W:
59
return BODY_SE;
60
case DIRECTION_E:
61
return BODY_SW;
62
default:
63
return BODY_N;
64
}
65
return BODY_N;
66
case DIRECTION_W:
67
switch (old_direction) {
68
case DIRECTION_N:
69
return BODY_SW;
70
case DIRECTION_S:
71
return BODY_NW;
72
default:
73
return BODY_E;
74
}
75
}
76
return BODY_N;
77
}
78
79
SPRITES_DECALS snake_get_head_decal(snake_actor *sn)
80
{
81
switch (sn->direction) {
82
case DIRECTION_N:
83
return HEAD_N;
84
case DIRECTION_E:
85
return HEAD_E;
86
case DIRECTION_S:
87
return HEAD_S;
88
case DIRECTION_W:
89
return HEAD_W;
90
}
91
return HEAD_N;
92
}
93
94
SPRITES_DECALS snake_get_tail_decal(snake_actor *sn)
95
{
96
unsigned int next_to_tail_index = (sn->tail_index + 1) % sn->num_segments;
97
98
if (sn->snake_sprites[next_to_tail_index].r[0] > sn->snake_sprites[sn->tail_index].r[0]) {
99
if (sn->snake_sprites[next_to_tail_index].r[0] - sn->snake_sprites[sn->tail_index].r[0] > sn->segment_w) {
100
return TAIL_W;
101
}
102
return TAIL_E;
103
}
104
105
if (sn->snake_sprites[next_to_tail_index].r[0] < sn->snake_sprites[sn->tail_index].r[0]) {
106
if (sn->snake_sprites[sn->tail_index].r[0] - sn->snake_sprites[next_to_tail_index].r[0] > sn->segment_w) {
107
return TAIL_E;
108
}
109
return TAIL_W;
110
}
111
112
if (sn->snake_sprites[next_to_tail_index].r[1] > sn->snake_sprites[sn->tail_index].r[1]) {
113
if (sn->snake_sprites[next_to_tail_index].r[1] - sn->snake_sprites[sn->tail_index].r[1] > sn->segment_h) {
114
return TAIL_N;
115
}
116
return TAIL_S;
117
}
118
119
if (sn->snake_sprites[sn->tail_index].r[1] - sn->snake_sprites[next_to_tail_index].r[1] > sn->segment_h) {
120
return TAIL_S;
121
}
122
return TAIL_N;
123
}
124
125
sprite *snake_get_head_sprite(snake_actor *sn)
126
{
127
int head_index = ((sn->tail_index - 1 + sn->num_segments) % sn->num_segments);
128
return &sn->snake_sprites[head_index];
129
}
130
131
void snake_apple_collision_detect(snake_actor *sn)
132
{
133
sprite *snake_head = snake_get_head_sprite(sn);
134
if (snake_head->r[0] == eng.apple_actor.sprite.r[0]
135
&& snake_head->r[1] == eng.apple_actor.sprite.r[1]) {
136
apple_replace(&eng.apple_actor);
137
sn->needs_to_grow = true;
138
eng.score += 1;
139
background_actor_update_scoreboard(&eng.background_actor);
140
141
float seconds_per_update = INITIAL_SNAKE_SECONDS_PER_UPDATE
142
- (float)eng.score * SNAKE_SECONDS_PER_UPDATE_INCREMENT;
143
if (seconds_per_update < MINIMUM_SNAKE_SECONDS_PER_UPDATE)
144
{
145
seconds_per_update = MINIMUM_SNAKE_SECONDS_PER_UPDATE;
146
}
147
148
sn->snake_frame_ratio = eng.fps * seconds_per_update;
149
}
150
}
151
152
void snake_grow(snake_actor *sn)
153
{
154
sn->num_segments += 1;
155
sprite_init(
156
&(sn->snake_sprites[sn->num_segments - 1]),
157
sn->segment_w,
158
sn->segment_h,
159
&(eng.sprites_decals[BODY_N]));
160
161
sprite *new_segment = &(sn->snake_sprites[sn->num_segments - 1]);
162
163
int i;
164
for (i = sn->num_segments - 1; i > sn->tail_index; i--) {
165
sn->snake_sprites[i].r[0] = sn->snake_sprites[i-1].r[0];
166
sn->snake_sprites[i].r[1] = sn->snake_sprites[i-1].r[1];
167
sprite_set_decal(&sn->snake_sprites[i], sn->snake_sprites[i-1].d);
168
}
169
170
unsigned int grid_x = new_segment->r[0] / TILE_DIMENSION;
171
unsigned int grid_y = new_segment->r[1] / TILE_DIMENSION - STATUS_BAR_HEIGHT;
172
eng.occupied_gridpoints[grid_x + eng.grid_width * grid_y] = true;
173
174
}
175
176
void snake_logic_handler(actor *a)
177
{
178
snake_actor * sn = (snake_actor *)a;
179
if (eng.current_frame % sn->snake_frame_ratio == 0) {
180
DIRECTION old_direction = sn->direction;
181
182
if (is_state_active(GS_N)) {
183
deactivate_state(GS_N);
184
if (sn->direction != DIRECTION_S)
185
{
186
sn->direction = DIRECTION_N;
187
}
188
} else if (is_state_active(GS_E)) {
189
deactivate_state(GS_E);
190
if (sn->direction != DIRECTION_W)
191
{
192
sn->direction = DIRECTION_E;
193
}
194
} else if (is_state_active(GS_S)) {
195
deactivate_state(GS_S);
196
if (sn->direction != DIRECTION_N)
197
{
198
sn->direction = DIRECTION_S;
199
}
200
} else if (is_state_active(GS_W)) {
201
deactivate_state(GS_W);
202
203
if (sn->direction != DIRECTION_E)
204
{
205
sn->direction = DIRECTION_W;
206
}
207
}
208
209
if (sn->needs_to_grow && sn->num_segments < MAX_SNAKE_SEGMENTS) {
210
snake_grow(sn);
211
sn->needs_to_grow = false;
212
}
213
214
sprite *old_head = snake_get_head_sprite(sn);
215
SPRITES_DECALS decal = snake_get_neck_decal(sn, old_direction);
216
sprite_set_decal(old_head, &(eng.sprites_decals[decal]));
217
218
int new_head_index = sn->tail_index;
219
sprite *new_head = &sn->snake_sprites[new_head_index];
220
221
int old_grid_coords[2];
222
engine_get_grid_coord(new_head->r, old_grid_coords);
223
224
int snake_direction[2];
225
snake_direction_to_vector(sn, snake_direction);
226
227
int new_grid_coords[2];
228
engine_get_grid_coord(old_head->r, new_grid_coords);
229
new_grid_coords[0] += snake_direction[0];
230
new_grid_coords[1] += snake_direction[1];
231
engine_apply_boundary_conditions(new_grid_coords);
232
233
engine_get_pixel_coord(new_grid_coords, new_head->r);
234
235
if (eng.occupied_gridpoints[new_grid_coords[0] + eng.grid_width * new_grid_coords[1]]) {
236
engine_reset();
237
return;
238
}
239
eng.occupied_gridpoints[old_grid_coords[0] + eng.grid_width * old_grid_coords[1]] = false;
240
eng.occupied_gridpoints[new_grid_coords[0] + eng.grid_width * new_grid_coords[1]] = true;
241
242
decal = snake_get_head_decal(sn);
243
sprite_set_decal(new_head, &(eng.sprites_decals[decal]));
244
245
sn->tail_index = (sn->tail_index + 1) % sn->num_segments;
246
247
decal = snake_get_tail_decal(sn);
248
sprite_set_decal(&sn->snake_sprites[sn->tail_index], &(eng.sprites_decals[decal]));
249
250
snake_apple_collision_detect(sn);
251
}
252
}
253
254
snake_actor *snake_actor_init(snake_actor *sn)
255
{
256
sn->num_segments = 3;
257
sn->segment_w = TILE_DIMENSION;
258
sn->segment_h = TILE_DIMENSION;
259
sn->needs_to_grow = false;
260
261
actor_init(&(sn->a), snake_render_handler, snake_logic_handler);
262
int i;
263
SPRITES_DECALS snake_init_config[] = {TAIL_E, BODY_E, HEAD_E};
264
int tail_pos[2];
265
int tail_grid_pos[2] = {4,4};
266
engine_get_pixel_coord(tail_grid_pos, tail_pos);
267
268
for (i = 0; i < sn->num_segments; i++) {
269
sprite_init(
270
&(sn->snake_sprites[i]),
271
sn->segment_w,
272
sn->segment_h,
273
&(eng.sprites_decals[snake_init_config[i]]));
274
sn->snake_sprites[i].r[0] = tail_pos[0] + i * sn->segment_w;
275
sn->snake_sprites[i].r[1] = tail_pos[1];
276
277
unsigned int grid_x = sn->snake_sprites[i].r[0] / TILE_DIMENSION;
278
unsigned int grid_y = sn->snake_sprites[i].r[1] / TILE_DIMENSION - STATUS_BAR_HEIGHT;
279
eng.occupied_gridpoints[grid_x + eng.grid_width * grid_y] = true;
280
}
281
sn->direction = DIRECTION_E;
282
283
float seconds_per_update = INITIAL_SNAKE_SECONDS_PER_UPDATE;
284
sn->snake_frame_ratio = eng.fps * seconds_per_update;
285
286
sn->tail_index = 0;
287
return sn;
288
}
289
290