|
This thread is locked; no one can reply to it. |
1
2
|
Basic Turret Defense Game |
Mark Oates
Member #1,146
March 2001
|
Wuh!?Original idea from this thread OK, the tank idea was cool but it eventually turned into a a turret game. The tank moving/aiming controls didn't work so well in a single player, a little slow, so I turned the tanks into turrets and did a turret-defense type game. The game is bare-bones. It's for testing the "robustness" of my little framework thing I'm working on. Technically, the game came together quickly! If I feel like it, I might add damage to the turrets, shields (shields are drawn but they serve no purpose), power-ups, etc. Screenshot{"name":"600036","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/9\/09fc3b48d9ef600f6449dde51a2f5ba7.png","w":626,"h":491,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/9\/09fc3b48d9ef600f6449dde51a2f5ba7"} DownloadInstructions
Questions
-- |
Malinus
Member #11,332
September 2009
|
1. First attempt, with not even one that manged to get by my furious burst of fire. 2. None (2ghz laptop) |
Slartibartfast
Member #8,789
June 2007
|
So you expect me to boot into windows just to see your game? ---- |
Dario ff
Member #10,065
August 2008
|
1) I never winned. I tried twice. I suck at double coordination games. I like the idea of your framework(I red your other post). Maybe I'll start a fresh one after CH. It'd be so much cleaner than the mess I have actually TranslatorHack 2010, a human translation chain in a.cc. |
Trent Gamblin
Member #261
April 2000
|
Slart: There's been a screenshot there since he started the thread
|
Matthew Leverton
Supreme Loser
January 1999
|
Is the sourcecode in the screenshot? |
Trent Gamblin
Member #261
April 2000
|
Oh, the meaning of NSND changed? I didn't get the memo.
|
MiquelFire
Member #3,110
January 2003
|
It changed for this topic at least. --- |
Slartibartfast
Member #8,789
June 2007
|
It changed for the scope of my posts in this thread. ---- |
Dario ff
Member #10,065
August 2008
|
What's the Einstein image in the data folder used for? TranslatorHack 2010, a human translation chain in a.cc. |
BAF
Member #2,981
December 2002
|
Holy shit, when did Allegro become bloated with 10+ dlls? Anyway, I didn't win, only tried a few times though. Ran smoothly, ran fine. The bursts were weird, and the game was difficult at spots where you'd have a bunch of dots bunched together but can only shoot 4 bullets (also, the bullets slowing down near their destination seemed really weird at first). |
Trent Gamblin
Member #261
April 2000
|
1) only tried once, was pretty hard with a trackpad (especially since it only has one button!)
|
MiquelFire
Member #3,110
January 2003
|
BAF said: Holy shit, when did Allegro become bloated with 10+ dlls? You haven't been paying attention to Allegro 5's development, have you? --- |
Mark Oates
Member #1,146
March 2001
|
Quote: So you expect me to boot into windows just to see your game? Either that or buy a copy if Windows if you don't have it. Quote: NSND; No Source No Download. No download then. My source code is still top secret. Not to say that I don't support Linux, just not for this purpose. If I were to make a real game then I'd look into providing some kind of support for the other platforms. Apart from the framework code, here's the code I wrote for the actual game: 1Object tank1;
2Object turret1;
3
4Object tank2;
5Object turret2;
6
7Object bullet1;
8Object bullet2;
9Object bullet3;
10Object bullet4;
11
12Object title_text;
13
14Object sheild1;
15Object sheild2;
16
17#define TURRET_ROTATION_SPEED 0.01f
18
19
20int tank_strength = 5;
21
22
23float sheild_max_scale = 1.2;
24float sheild_min_scale = 0.9;
25
26
27
28Object win_notification;
29Object win_notification_2;
30
31
32Object fail_notification;
33Object fail_notification_2;
34
35
36
37enum { GAME_STATE_PLAYING, GAME_STATE_WIN, GAME_STATE_FAIL };
38int game_state = GAME_STATE_PLAYING;
39
40
41
42vector<Object *> enemies;
43
44
45
46void init_bullet_position(Object *bullet)
47{
48 bullet->position(-300, -300);
49}
50
51
52void initialize()
53{
54 tank1.set_image("data/images/tank.png");
55 tank1.position(100, screen_h-160);
56 tank1.align(ALIGN_CENTER, ALIGN_MIDDLE);
57 tank1.scale_x = 0.75;
58 tank1.scale_y = 0.75;
59 tank1.position_z = 2;
60
61 tank2.set_image("data/images/tank.png");
62 tank2.position(screen_w-100, screen_h-160);
63 tank2.align(ALIGN_CENTER, ALIGN_MIDDLE);
64 tank2.scale_x = 0.75;
65 tank2.scale_y = 0.75;
66 tank2.position_z = 2;
67
68 turret1.set_image("data/images/turret.png");
69 turret1.position(screen_w/2, screen_h/2);
70 turret1.align(ALIGN_CENTER, 0.75);
71 turret1.position_z = 3;
72
73 turret2.set_image("data/images/turret.png");
74 turret2.position(screen_w/2, screen_h/2);
75 turret2.align(ALIGN_CENTER, 0.75);
76 turret2.position_z = 3;
77
78 bullet1.set_image("data/images/bullet.png");
79 bullet1.align(ALIGN_CENTER, ALIGN_MIDDLE);
80 bullet1.opacity = 0.0;
81 init_bullet_position(&bullet1);
82
83 bullet2.set_image("data/images/bullet.png");
84 bullet2.align(ALIGN_CENTER, ALIGN_MIDDLE);
85 bullet2.opacity = 0.0;
86 init_bullet_position(&bullet2);
87
88 bullet3.set_image("data/images/bullet.png");
89 bullet3.align(ALIGN_CENTER, ALIGN_MIDDLE);
90 bullet3.opacity = 0.0;
91 init_bullet_position(&bullet3);
92
93 bullet4.set_image("data/images/bullet.png");
94 bullet4.align(ALIGN_CENTER, ALIGN_MIDDLE);
95 bullet4.opacity = 0.0;
96 init_bullet_position(&bullet4);
97
98
99
100 sheild1.set_image("data/images/sheild.png");
101 sheild1._blending_mode = BLENDER_ADDITIVE;
102 sheild1.align(ALIGN_CENTER, ALIGN_MIDDLE);
103 sheild1.opacity = 0.3;
104 sheild1.position_z = 4;
105 sheild1.scale_x = sheild_min_scale;
106 sheild1.scale_y = sheild_min_scale;
107
108
109 sheild2.set_image("data/images/sheild.png");
110 sheild2._blending_mode = BLENDER_ADDITIVE;
111 sheild2.align(ALIGN_CENTER, ALIGN_MIDDLE);
112 sheild2.opacity = 0.3;
113 sheild2.position_z = 4;
114 sheild2.scale_x = sheild_min_scale;
115 sheild2.scale_y = sheild_min_scale;
116
117
118
119
120 title_text.set_image(get_text_render("data/fonts/StencilStd.otf", -110, "TANK"));
121 title_text.position(screen_w/2, screen_h/2);
122 title_text.align(ALIGN_CENTER, ALIGN_MIDDLE);
123 title_text.hide(0);
124
125 title_text.show(0.4, ANIMATION_CURVE_DOUBLE_SLOW);
126
127
128
129 win_notification.set_image(get_text_render("data/fonts/StencilStd.otf", -200, "WIN"));
130 win_notification.align_center();
131 win_notification.align_middle();
132 win_notification.tint = al_color_name("green");
133 win_notification.position(screen_w/2, screen_h/2);
134 win_notification.hide(0);
135 win_notification.bring_to_top();
136
137 win_notification_2.set_image(get_text_render("data/fonts/StencilStd.otf", -40, "That's all for now folks!"));
138 win_notification_2.align_center();
139 win_notification_2.align_middle();
140 win_notification_2.tint = al_color_name("green");
141 win_notification_2.position(screen_w/2, screen_h/3*2);
142 win_notification_2.hide(0);
143 win_notification_2.bring_to_top();
144
145
146
147 fail_notification.set_image(get_text_render("data/fonts/StencilStd.otf", -200, "FAIL"));
148 fail_notification.align_center();
149 fail_notification.align_middle();
150 fail_notification.tint = al_color_name("red");
151 fail_notification.position(screen_w/2, screen_h/2);
152 fail_notification.hide(0);
153 fail_notification.bring_to_top();
154
155 fail_notification_2.set_image(get_text_render("data/fonts/StencilStd.otf", -40, "The ESC key is your only way out."));
156 fail_notification_2.align_center();
157 fail_notification_2.align_middle();
158 fail_notification_2.tint = al_color_name("red");
159 fail_notification_2.position(screen_w/2, screen_h/3*2);
160 fail_notification_2.hide(0);
161 fail_notification_2.bring_to_top();
162
163
164
165 Object *obj;
166 int multiplier = 5;
167 for (int i=0; i<20*multiplier; i++)
168 {
169 enemies.push_back(new Object());
170 obj = enemies[enemies.size()-1];
171 obj->position_x = random_int(100, screen_w-100);
172 obj->position_y = random_int(-1500*multiplier, 0);
173 obj->set_image("data/images/enemy_bullet.png");
174 obj->align_center();
175 obj->align_middle();
176 }
177}
178
179
180
181
182void win_game()
183{
184 if (game_state != GAME_STATE_PLAYING) return;
185 game_state = GAME_STATE_WIN;
186 win_notification.show();
187 win_notification_2.show();
188}
189
190
191void lose_game()
192{
193 if (game_state != GAME_STATE_PLAYING) return;
194 game_state = GAME_STATE_FAIL;
195 fail_notification.show();
196 fail_notification_2.show();
197}
198
199
200
201#define BULLET_VELOCITY 350.0
202
203void fire_bullet(Object &gun)
204{
205 Object *obj = NULL;
206 if (!bullet1.visible()) obj = &bullet1;
207 else if (!bullet2.visible()) obj = &bullet2;
208 else if (!bullet3.visible()) obj = &bullet3;
209 else if (!bullet4.visible()) obj = &bullet4;
210
211 if (!obj) return;
212
213 obj->opacity.animate(0.0, 1.0, 0.0, 0.2, ANIMATION_CURVE_DOUBLE_FAST);
214 obj->opacity.animate(1.0, 0.0, 0.6, 0.4, ANIMATION_CURVE_SLOW);
215 obj->position(gun._position_x, gun._position_y);
216 obj->rotation = gun._rotation;
217
218 vec2d destination = PolarCoords(gun._rotation - ALLEGRO_PI/2, BULLET_VELOCITY);
219
220 obj->position_x.animate(gun._position_x, gun._position_x+destination.x, 0.0, 1.0, ANIMATION_CURVE_FAST);
221 obj->position_y.animate(gun._position_y, gun._position_y+destination.y, 0.0, 1.0, ANIMATION_CURVE_FAST);
222}
223
224
225
226
227void update_shield_animation(Object &sheild)
228{
229 if (sheild._scale_x == sheild_max_scale)
230 {
231 sheild.scale_x.animate(sheild_max_scale, sheild_min_scale, 0.0, 0.5, ANIMATION_CURVE_SLOW_IN_OUT);
232 sheild.scale_y.animate(sheild_max_scale, sheild_min_scale, 0.0, 0.5, ANIMATION_CURVE_SLOW_IN_OUT);
233 }
234 else if (sheild._scale_x == sheild_min_scale)
235 {
236 sheild.scale_x.animate(sheild_min_scale, sheild_max_scale, 0.0, 0.5, ANIMATION_CURVE_SLOW_IN_OUT);
237 sheild.scale_y.animate(sheild_min_scale, sheild_max_scale, 0.0, 0.5, ANIMATION_CURVE_SLOW_IN_OUT);
238 }
239}
240
241
242
243
244float enemy_falling_speed = 1.0f;
245float enemy_falling_accel = 0.0005;
246
247
248
249void detonate_enemy(Object *obj)
250{
251 obj->opacity.animate(1.0, 0.0, 0.0, 0.5, ANIMATION_CURVE_FAST);
252 obj->tint.animate(al_color_name("white"), al_color_name("red"), 0.1, 0.5, ANIMATION_CURVE_DOUBLE_FAST);
253 obj->scale_x.animate(1.001, 20.0, 0.0, 0.5, ANIMATION_CURVE_DOUBLE_FAST);
254 obj->scale_y.animate(1.001, 20.0, 0.0, 0.5, ANIMATION_CURVE_DOUBLE_FAST);
255}
256
257
258
259void detonate_bullet(Object *bullet)
260{
261 bullet->opacity = 0.0;
262 init_bullet_position(bullet);
263 bullet->clear_animations();
264}
265
266
267
268void update_enemy_positions()
269{
270 Object *obj;
271 for (int i=0; i<(int)enemies.size(); i++)
272 {
273 obj = enemies<i>;
274 obj->position_y += enemy_falling_speed;
275 if (obj->_position_y > screen_h)
276 {
277 if (obj->_scale_x == 1.0)
278 {
279 detonate_enemy(obj);
280 tank_strength -= 1;
281 if (tank_strength <= 0) { tank_strength = 0; lose_game(); }
282 }
283 }
284 }
285}
286
287
288
289
290void test_bullet_collision(Object *obj, Object *bullet)
291{
292 if (!obj->visible_on_screen()) return;
293 if (obj->_opacity == 1.0 && bullet->_opacity != 0.0 && collides(*obj, *bullet))
294 {
295 detonate_enemy(obj);
296 detonate_bullet(bullet);
297 }
298}
299
300
301int num_active;
302
303int test_win_condition()
304{
305 int num_visible = (int)enemies.size();
306 for (int i=0; i<(int)enemies.size(); i++)
307 {
308 if (!enemies<i>->visible()) num_visible--;
309 }
310 if (num_visible == 0) win_game();
311 return num_visible;
312}
313
314
315
316void test_bullet_enemy_collisions()
317{
318 Object *obj;
319 for (int i=0; i<(int)enemies.size(); i++)
320 {
321 obj = enemies<i>;
322
323 test_bullet_collision(obj, &bullet1);
324 test_bullet_collision(obj, &bullet2);
325 test_bullet_collision(obj, &bullet3);
326 test_bullet_collision(obj, &bullet4);
327 }
328}
329
330
331
332#define TANK_VELOCITY 1.0
333
334void update_logic()
335{
336 if (game_state == GAME_STATE_PLAYING)
337 {
338 update_enemy_positions();
339 test_bullet_enemy_collisions();
340 enemy_falling_speed += enemy_falling_accel;
341 }
342
343 vec2d mouse_pos = vec2d(mouse_x(), mouse_y());
344 vec2d tank1_pos = vec2d(tank1._position_x, tank1._position_y);
345 vec2d tank2_pos = vec2d(tank2._position_x, tank2._position_y);
346
347 tank1._rotation = (mouse_pos-tank1_pos).GetAngle() + ALLEGRO_PI /2;
348 tank2._rotation = (mouse_pos-tank2_pos).GetAngle() + ALLEGRO_PI /2;
349
350 turret1.rotation = tank1._rotation;
351 turret1.position(tank1._position_x, tank1._position_y);
352 turret1.position(tank1._position_x, tank1._position_y);
353 sheild1.position(tank1._position_x, tank1._position_y);
354
355 turret2.rotation = tank2._rotation;
356 turret2.position(tank2._position_x, tank2._position_y);
357 turret2.position(tank2._position_x, tank2._position_y);
358 sheild2.position(tank2._position_x, tank2._position_y);
359
360 update_shield_animation(sheild1);
361 update_shield_animation(sheild2);
362
363 if (just_pressed(MOUSE_B1)) fire_bullet(tank1);
364 if (just_pressed(MOUSE_B2)) fire_bullet(tank2);
365
366 num_active = test_win_condition();
367}
368
369
370
371void draw()
372{
373 //draw("data/images/einstein.png", 50, 50);
374
375 object_manager.draw_all();
376
377 font_manager.use_font("data/fonts/lacuna.ttf", -40);
378 print("Energy", 30, screen_h-100);
379 string energy_string = "";
380
381 for (int i=0; i<tank_strength; i++) energy_string += ".";
382
383 font_manager.use_font("data/fonts/lacuna.ttf", -130);
384 print(energy_string, 30, screen_h-140);
385
386
387 //font_manager.destroy_text_render("data/fonts/lacuna.ttf", -130, tostring(num_active-1));
388 font_manager.use_font("data/fonts/lacuna.ttf", -16);
389 print(tostring(num_active), 30, 30);
390
391
392 draw("data/images/crosshair.png", mouse_x(), mouse_y(), ALIGN_CENTER);
393 al_hide_mouse_cursor();
394
395 draw("data/images/vignette2.png", 0, 0);
396}
397}
Quote: Anyway, I didn't win, only tried a few times though. Ran smoothly, ran fine. The bursts were weird, and the game was difficult at spots where you'd have a bunch of dots bunched together but can only shoot 4 bullets (also, the bullets slowing down near their destination seemed really weird at first). I agree. Game balance is pretty much non-existent in this demo. If anyone can beat it, I don't believe them, unless they can post a screenshot of the win screen Quote: Probably too many dlls Yea, I think half of them don't even get used. I wish I could dump them in a folder or something so the EXE is the only file in the root of the folder. So from what I hear, no technical problems? Awesome! While making it, I noticed some slowdown when I went to about 80 enemies and 4 bullets on the screen. That's 320 separating-axis tests, so I limited the collisions tests to on-screen objects and it fixed it. Quote: What's the Einstein image in the data folder used for? Ah, just forgot to take it out. -- |
BAF
Member #2,981
December 2002
|
The more I play it, the more I grow to hate your bullet acceleration/deceleration. It throws me off shooting thingies that are further away. |
Dario ff
Member #10,065
August 2008
|
I Won! TranslatorHack 2010, a human translation chain in a.cc. |
Mark Oates
Member #1,146
March 2001
|
Here you go Baf, an EXE with linear bullet trajectory. Nice dario. I haven't even beat it, yet. -- |
Matthew Leverton
Supreme Loser
January 1999
|
Is the game for "Now Folks," or is it a direct address? |
Mark Oates
Member #1,146
March 2001
|
both. -- |
Dario ff
Member #10,065
August 2008
|
Malinus said: 1. First attempt, with not even one that manged to get by my furious burst of fire. I don't believe him. But how can he prove it? He could easily copy my screenshot. TranslatorHack 2010, a human translation chain in a.cc. |
Fishcake
Member #8,704
June 2007
|
The game runs without any problem for me. I couldn't win the game though.
|
blargmob
Member #8,356
February 2007
|
Sorry Oates, but your lack for OOP makes me want to cry --- |
Matthew Leverton
Supreme Loser
January 1999
|
{"name":"600044","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb1bccf96ee6a62d14a47f2dff6269cd.png","w":791,"h":598,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb1bccf96ee6a62d14a47f2dff6269cd"} I won too! |
Trent Gamblin
Member #261
April 2000
|
I beat it twice in a row!! {"name":"fb1bccf96ee6a62d14a47f2dff6269cd.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb1bccf96ee6a62d14a47f2dff6269cd.png","w":791,"h":598,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb1bccf96ee6a62d14a47f2dff6269cd"} {"name":"fb1bccf96ee6a62d14a47f2dff6269cd.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb1bccf96ee6a62d14a47f2dff6269cd.png","w":791,"h":598,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/b\/fb1bccf96ee6a62d14a47f2dff6269cd"}
|
Mark Oates
Member #1,146
March 2001
|
blargmob said: your lack for OOP makes me want to cry You'll be OK. All the OOP is under the hood in this example. Matthew, your kerning is a mess. Hey everybody, try the version with linear bullet trajectories. It's easier. I find the trick is to aim with the cursor and shoot below the bullets. -- |
|
1
2
|