1#include <allegro5/allegro.h>
2#include <allegro5/allegro_native_dialog.h>
3#include <allegro5/allegro_font.h>
4#include <allegro5/allegro_ttf.h>
5#include <allegro5/allegro_image.h>
6#include <allegro5/allegro_primitives.h>
7#include <allegro5/allegro_physfs.h>
8#include <physfs.h>
9
10#include <cstdio>
11#include <vector>
12
13typedef enum
14{
15 GAME_STATE_MENU,
16 GAME_STATE_PLAY
17} GAME_STATE
;
18
19struct GameStruct
20{
21 ALLEGRO_DISPLAY* display
;
22 ALLEGRO_TIMER* timer
;
23 ALLEGRO_EVENT_QUEUE* queue
;
24 ALLEGRO_EVENT event
;
25 GAME_STATE state
;
26 int menu_select
;
27 ALLEGRO_FONT* font;
28 bool quit
;
29 bool ticked
;
30 float gravity
;
31} game
;
32
33struct GFXStruct
34{
35 ALLEGRO_BITMAP* menu_bg
;
36 ALLEGRO_BITMAP* player
;
37 ALLEGRO_BITMAP* platform
;
38} gfx
;
39
40struct PlayerStruct
41{
42 float x
;
43 float y
;
44 float vspeed
;
45} player
;
46
47struct PlatformStruct
48{
49 float x
;
50 float y
;
51};
52
53bool keys
[ ALLEGRO_KEY_MAX
];
54std::vector
<PlatformStruct> platform
;
55
56void error
( const char* format, ...
)
57{
58 char message
[100];
59
60 va_list vl
;
61 va_start
( vl, format
);
62 vsprintf( message, format, vl
);
63 va_end
( vl
);
64
65 al_show_native_message_box( game.display,
"Error", NULL, message, NULL, ALLEGRO_MESSAGEBOX_ERROR
);
66 exit( EXIT_FAILURE
);
67}
68
69void update_events
()
70{
71 ALLEGRO_TIMEOUT timeout
;
72 al_init_timeout( &timeout,
0.
1 );
73
74 al_wait_for_event_until( game.queue,
&game.event,
&timeout
);
75
76 switch ( game.event.type
)
77 {
78 case ALLEGRO_EVENT_DISPLAY_CLOSE:
79 game.quit
= true;
80 break;
81
82 case ALLEGRO_EVENT_TIMER:
83 game.ticked
= true;
84 break;
85
86 case ALLEGRO_EVENT_KEY_DOWN:
87 keys
[ game.event.keyboard.keycode
] = true;
88 break;
89
90 case ALLEGRO_EVENT_KEY_UP:
91 keys
[ game.event.keyboard.keycode
] = false;
92 break;
93 }
94}
95
96ALLEGRO_BITMAP* load_image
( const char* filename
)
97{
98 ALLEGRO_BITMAP* temp
= al_load_bitmap( filename
);
99 if ( !temp
)
100 error
( "Error loading image %s.", filename
);
101
102 return temp
;
103}
104
105void init
()
106{
107 al_init();
108
109 if ( !al_install_keyboard() )
110 error
( "Error installing the keyboard." );
111
112 for ( int i
=0; i
<ALLEGRO_KEY_MAX
; i
++ )
113 keys
[i
] = false;
114
115 //al_set_new_display_flags( ALLEGRO_FULLSCREEN );
116
117 game.display
= al_create_display( 640,
480 );
118 if ( !game.display
)
119 error
( "Error creating display." );
120
121 al_set_window_title( game.display,
"Jump Pacman" );
122
123 game.timer
= al_create_timer( ALLEGRO_BPS_TO_SECS( 60 ) );
124 if ( !game.timer
)
125 error
( "Error creating timer." );
126
127 game.queue
= al_create_event_queue();
128 if ( !game.queue
)
129 error
( "Error creating event queue." );
130
131 al_register_event_source( game.queue,
al_get_keyboard_event_source() );
132 al_register_event_source( game.queue,
al_get_display_event_source( game.display
) );
133 al_register_event_source( game.queue,
al_get_timer_event_source( game.timer
) );
134
135 al_init_font_addon();
136
137 al_hide_mouse_cursor( game.display
);
138
139 if ( !al_init_ttf_addon() )
140 error
( "Error initialize ttf addon." );
141
142 if ( !al_init_image_addon() )
143 error
( "Error initialize image addon." );
144
145 if ( !al_init_primitives_addon() )
146 error
( "Error initalizing primitives addon." );
147
148 al_set_physfs_file_interface();
149
150 if ( !PHYSFS_init
( NULL
) )
151 error
( "Error with PHYSFS_init()." );
152
153 if ( !PHYSFS_addToSearchPath
( "data.dat",
0 ) )
154 error
( "Error with PHYSFS_addToSearchPath()." );
155
156 game.font
= al_load_font( "AltamonteNF.ttf",
20,
0 );
157 if ( !game.font
)
158 error
( "Failed to load font verdanab.ttf" );
159
160 gfx.menu_bg
= load_image
( "gfx/menu_bg.png" );
161 gfx.player
= load_image
( "gfx/player.png" );
162 gfx.platform
= load_image
( "gfx/platform.png" );
163
164 game.gravity
= 0.
3;
165
166 player.x
= 130; // 304
167 player.y
= 220; // 400
168 player.vspeed
= 0;
169
170 PlatformStruct platform_data
;
171 platform_data.x
= 100;
172 platform_data.y
= 250;
173 platform.push_back
( platform_data
);
174
175 platform_data.x
= 400;
176 platform_data.y
= 200;
177 platform.push_back
( platform_data
);
178
179 al_start_timer( game.timer
);
180
181 game.state
= GAME_STATE_MENU
;
182 game.menu_select
= 0;
183 game.quit
= false;
184 game.ticked
= true;
185}
186
187void draw_text
( float x,
float y,
const char* text
)
188{
189 al_draw_text( game.font,
al_map_rgb( 0,
0,
0 ), x
+1, y
+1, ALLEGRO_ALIGN_CENTRE, text
);
190 al_draw_text( game.font,
al_map_rgb( 255,
255,
255 ), x, y, ALLEGRO_ALIGN_CENTRE, text
);
191}
192
193float check_collision
()
194{
195 for ( unsigned int i
=0; i
<platform.size
(); i
++ )
196 {
197 // 91x31
198 if ( player.x
+34 > platform
[i
].x
&& player.x
< platform
[i
].x
+91 &&
199 player.y
+player.vspeed
+36 > platform
[i
].y
&& player.y
+player.vspeed
< platform
[i
].y
+5 )
200 {
201 return 1;
202 }
203 }
204
205 return 0;
206}
207
208bool key_down
= false;
209void loop
()
210{
211 while ( !game.quit
)
212 {
213 update_events
();
214
215 if ( game.ticked
)
216 {
217 al_set_target_bitmap( al_get_backbuffer(game.display
) );
218 al_clear_to_color( al_map_rgb( 0,
128,
255 ) );
219
220 switch ( game.state
)
221 {
222 case GAME_STATE_MENU:
223 {
224 al_draw_bitmap( gfx.menu_bg,
0,
0,
0 );
225
226 int menu_pos
= 190;
227 int menu_select_x
= 195;
228
229 if ( !key_down
)
230 {
231 if ( keys
[ ALLEGRO_KEY_UP
] && game.menu_select
> 0 )
232 {
233 game.menu_select--
;
234 key_down
= true;
235 }
236
237 if ( keys
[ ALLEGRO_KEY_DOWN
] && game.menu_select
< 3 )
238 {
239 game.menu_select
++;
240 key_down
= true;
241 }
242 }
243 else if ( !keys
[ ALLEGRO_KEY_UP
] && !keys
[ ALLEGRO_KEY_DOWN
] )
244 key_down
= false;
245
246 if ( keys
[ ALLEGRO_KEY_ENTER
] )
247 {
248 if ( game.menu_select
== 0 )
249 game.state
= GAME_STATE_PLAY
;
250
251 if ( game.menu_select
== 3 )
252 game.quit
= true;
253 }
254
255 int menu_select_y
= menu_pos
+ ( 30 * game.menu_select
);
256
257 al_draw_bitmap( gfx.platform, platform
[0].x, platform
[0].y,
0 );
258 al_draw_bitmap( gfx.platform, platform
[1].x, platform
[1].y,
0 );
259
260 // Begin Physics.
261 float offset
= check_collision
();
262 if ( offset
> 0 )
263 {
264 player.vspeed
= -11;
265 player.y
+= offset
;
266 }
267
268 player.vspeed
+= game.gravity
;
269
270 if ( player.vspeed
> 8 )
271 player.vspeed
= 8;
272
273 player.y
+= player.vspeed
;
274 // End Physics.
275
276 if ( keys
[ ALLEGRO_KEY_LEFT
] )
277 player.x
-= 4;
278
279 if ( keys
[ ALLEGRO_KEY_RIGHT
] )
280 player.x
+= 4;
281
282 al_draw_bitmap( gfx.player, player.x, player.y,
0 );
283
284 al_set_blender( ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA
);
285 al_draw_filled_rounded_rectangle( menu_select_x, menu_select_y, menu_select_x
+250, menu_select_y
+30,
7,
7,
al_map_rgba( 255,
255,
255,
100 ) );
286
287 draw_text
( 320, menu_pos,
"Play Game" );
288 draw_text
( 320, menu_pos
+30,
"Dificulty [Normal]" );
289 draw_text
( 320, menu_pos
+60,
"Options" );
290 draw_text
( 320, menu_pos
+90,
"Exit Game" );
291
292 draw_text
( 320,
450,
"(c) Desmond Taylor 2011" );
293 }
294 break;
295
296 case GAME_STATE_PLAY:
297 {
298 if ( keys
[ ALLEGRO_KEY_ESCAPE
] )
299 game.state
= GAME_STATE_MENU
;
300
301 al_draw_bitmap( gfx.player, player.x, player.y,
0 );
302
303 al_draw_bitmap( gfx.platform,
10,
10,
0 );
304 }
305 break;
306 }
307
308 al_flip_display();
309 }
310 }
311}
312
313void cleanup
()
314{
315 PHYSFS_deinit
();
316
317 al_uninstall_keyboard();
318 al_destroy_timer( game.timer
);
319 al_destroy_display( game.display
);
320
321 if ( gfx.menu_bg
)
322 al_destroy_bitmap( gfx.menu_bg
);
323
324 if ( gfx.player
)
325 al_destroy_bitmap( gfx.player
);
326
327 if ( gfx.platform
)
328 al_destroy_bitmap( gfx.platform
);
329
330 al_shutdown_image_addon();
331 al_shutdown_primitives_addon();
332}
333
334int main
( int argc,
char** argv
)
335{
336 init
();
337
338 loop
();
339
340 cleanup
();
341
342 return EXIT_SUCCESS
;
343}