source: soft/giet_vm/applications/raycast/game.c @ 708

Last change on this file since 708 was 708, checked in by alain, 9 years ago

Adapt the following application to the POSIX threads API

  • convol
  • classif
  • raycast
  • coproc
  • display
  • gameoflife
  • transpose
  • shell
File size: 7.6 KB
Line 
1#include "game.h"
2#include "disp.h"
3#include "ctrl.h"
4#include <math.h>
5#include <stdio.h>
6
7//////////////////////////////
8// Game Maps
9//////////////////////////////
10
11static Map map[] =
12{
13    { // map0
14        .tile =
15        {
16            {1, 0, 0, 0, 0, 1, 0, 0, 1, 1},
17            {0, 0, 0, 0, 0, 1, 0, 0, 0, 2},
18            {0, 0, 0, 0, 1, 0, 0, 0, 1, 1},
19            {0, 0, 0, 1, 3, 0, 3, 0, 0, 0},
20            {0, 0, 0, 1, 3, 0, 3, 0, 0, 1},
21            {0, 0, 0, 1, 3, 0, 3, 0, 0, 0},
22            {0, 0, 0, 1, 1, 0, 3, 0, 0, 1},
23            {4, 0, 0, 0, 0, 0, 1, 0, 0, 0},
24            {4, 0, 0, 0, 0, 0, 1, 0, 0, 1},
25            {0, 4, 4, 4, 4, 0, 0, 0, 1, 0}
26        },
27        .w = 10,
28        .h = 10,
29        .startX = 2.f,
30        .startY = 3.f,
31        .startDir = 70.f * M_PI / 180.f
32    },
33    { // map1
34        .tile =
35        {
36            {0, 1, 0, 1, 0, 3, 0, 0, 0, 0},
37            {0, 1, 0, 0, 0, 3, 0, 0, 0, 0},
38            {0, 0, 0, 1, 0, 3, 0, 0, 0, 0},
39            {1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
40            {4, 2, 4, 1, 3, 0, 3, 3, 3, 0},
41            {4, 0, 0, 1, 3, 3, 3, 0, 0, 0},
42            {4, 0, 0, 1, 3, 0, 0, 0, 3, 3},
43            {4, 0, 0, 0, 0, 0, 4, 0, 0, 3},
44            {4, 0, 0, 0, 0, 0, 4, 0, 0, 0},
45            {4, 4, 4, 4, 4, 4, 4, 0, 1, 0}
46        },
47        .w = 10,
48        .h = 10,
49        .startX = 0.5f,
50        .startY = 0.5f,
51        .startDir = 90.f * M_PI / 180.f
52    },
53    { // map2
54        .tile =
55        {
56            {4, 4, 4, 4, 4, 4, 4, 0, 0, 0},
57            {0, 0, 0, 0, 0, 0, 0, 0, 3, 0},
58            {3, 0, 0, 0, 4, 4, 4, 0, 0, 0},
59            {3, 0, 0, 4, 0, 0, 0, 1, 1, 0},
60            {3, 0, 4, 2, 0, 0, 0, 0, 0, 0},
61            {3, 0, 4, 2, 0, 0, 0, 0, 0, 0},
62            {3, 0, 0, 4, 0, 0, 0, 1, 1, 0},
63            {3, 0, 0, 0, 4, 4, 4, 0, 0, 0},
64            {0, 0, 0, 0, 0, 0, 0, 0, 3, 0},
65            {4, 4, 4, 4, 4, 4, 4, 0, 0, 0}
66        },
67        .w = 10,
68        .h = 10,
69        .startX = 4.5f,
70        .startY = 5.f,
71        .startDir = 0.f * M_PI / 180.f
72    },
73};
74
75////////////////////////////
76// extern variables
77////////////////////////////
78
79extern Game         game;
80
81//////////////////////
82// Local functions
83//////////////////////
84
85////////////////////////////////////
86static void gameOnBlockHit(int type)
87{
88    giet_tty_printf("\n[RAYCAST] Fatal collision, killed...\n");
89    game.exit = 1;
90}
91
92///////////////////////////////////////////////
93static void gameCollision(float opx, float opy)
94{
95    static unsigned int collided_x = 0;
96    static unsigned int collided_y = 0;
97
98    float               px = game.player.x;
99    float               py = game.player.y;
100    int                 fpx = floor(px);
101    int                 fpy = floor(py);
102    unsigned int        colliding_x = 0;
103    unsigned int        colliding_y = 0;
104    int                 collide_type_x = 0;
105    int                 collide_type_y = 0;
106    int                 type;
107
108    // Check for x axis collisions
109    if      ((type = gameLocate(floor(px + COLLIDE_GAP), fpy))) 
110    {
111        colliding_x = 1, collide_type_x = type;
112        game.player.x = fpx - COLLIDE_GAP + 1;
113    }
114    else if ((type = gameLocate(floor(px - COLLIDE_GAP), fpy))) 
115    {
116        colliding_x = 1, collide_type_x = type;
117        game.player.x = fpx + COLLIDE_GAP;
118    }
119
120    // Check for y axis collisions
121    if      ((type = gameLocate(fpx, floor(py + COLLIDE_GAP)))) 
122    {
123        colliding_y = 1, collide_type_y = type;
124        game.player.y = fpy - COLLIDE_GAP + 1;
125    }
126    else if ((type = gameLocate(fpx, floor(py - COLLIDE_GAP)))) 
127    {
128        colliding_y = 1, collide_type_y = type;
129        game.player.y = fpy + COLLIDE_GAP;
130    }
131
132    // Check if we're inside a wall
133    if ((type = gameLocate(fpx, fpy))) 
134    {
135        colliding_x   = 1   , collide_type_x = type;
136        colliding_y   = 1   , collide_type_y = type;
137        game.player.x = opx , game.player.y = opy;
138    }
139
140    // Take action when the player hits a block
141    if (colliding_x && !collided_x)
142        gameOnBlockHit(collide_type_x);
143    if (colliding_y && !collided_y)
144        gameOnBlockHit(collide_type_y);
145
146    collided_x = colliding_x;
147    collided_y = colliding_y;
148}
149
150/////////////////////////
151// Exported functions
152/////////////////////////
153
154///////////////
155void gameInit()
156{
157    game.mapId      = 0;
158    game.map        = &map[0];
159    game.player.x   = game.map->startX;
160    game.player.y   = game.map->startY;
161    game.player.dir = game.map->startDir;
162    game.timeLeft   = TIME_TOTAL;
163    game.exit       = 0;
164}
165
166//////////////////
167void gameControl()
168{
169    // Only six commands are accepted:
170    // - key Q         : quit game
171    // - key UP        : forward move
172    // - key DOWN      : backward move
173    // - key RIGHT     : right move
174    // - key LEFT      : left move
175    // - any other key : continue
176    // several moves can be made before continue
177
178    char c;
179    unsigned int state = 0;
180    unsigned int done  = 0;
181
182    // display prompt
183    giet_tty_printf("\n[RAYCAST] > " );
184
185    // get one command
186    while ( done == 0 )
187    {
188        // get one character       
189        giet_tty_getc( &c );
190
191        if (state == 0) // first character
192        {
193            if      (c == 0x1B)         // ESCAPE : possible player move 
194            {
195                state = 1;
196            }
197            else if (c == 0x71)         // quit game
198            {
199                game.exit = 1;
200                done = 1;
201                giet_tty_printf("QUIT\n");
202            }
203            else                        // continue
204            {
205                done = 1;
206                giet_tty_printf("\n");
207            }
208        } 
209        else if (state == 1) // previous character was ESCAPE
210        {
211            if      (c == 0x5B)        // BRAKET : possible player move
212            {
213                state = 2;
214            }
215            else                       // continue
216            {
217                done = 1;
218                giet_tty_printf("\n");
219            }
220        }
221        else  // previous characters were ESCAPE,BRACKET
222        {
223            if      (c == 0x41)        // UP arrow <=> forward move
224            {
225                game.player.x += PLAYER_MOVE * cos(game.player.dir);
226                game.player.y += PLAYER_MOVE * sin(game.player.dir);
227                giet_tty_printf("GO ");
228                state = 0;
229            }
230            else if (c == 0x42)        // DOWN arrow <=> backward move
231            {
232                game.player.x -= PLAYER_MOVE * cos(game.player.dir);
233                game.player.y -= PLAYER_MOVE * sin(game.player.dir);
234                giet_tty_printf("BACK ");
235                state = 0;
236            }
237            else if (c == 0x43)        // RIGHT arrow <=> turn right     
238            {
239                game.player.dir += PLAYER_ROT;
240                giet_tty_printf("RIGHT ");
241                state = 0;
242            }
243            else if (c == 0x44)        // LEFT arrow <=> turn left     
244            {
245                game.player.dir -= PLAYER_ROT;
246                giet_tty_printf("LEFT ");
247                state = 0;
248            }
249            else                       // continue
250            {
251                done = 1;
252                giet_tty_printf("\n");
253            }
254        }
255    }  // end while
256   
257    // check new position
258    int hit = gameLocate( game.player.x , game.player.y );
259    if ( hit )  gameOnBlockHit( hit );
260}
261
262////////////////////////////
263int gameLocate(int x, int y)
264{
265    if ((x < 0 || x >= game.map->w) ||
266        (y < 0 || y >= game.map->h)) 
267    {
268        // Outside the map bounds
269        return 1;
270    }
271
272    return game.map->tile[y][x];
273}
274
275///////////////
276void gameTick()
277{
278    game.timeLeft--;
279
280    if (game.timeLeft == 0) 
281    {
282        game.exit = 1;
283    }
284}
285
Note: See TracBrowser for help on using the repository browser.