Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Help shooting left and right.

This thread is locked; no one can reply to it. rss feed Print
Help shooting left and right.
DJLad16
Member #14,857
January 2013

First of all, this a something I've tried to do since day 1 proper development. I want the character to shoot left when he facing left, and shoot right when he's facing right. My problem is when I was facing left or right, it was shooting left or right. But if I shot right, and then turned left, the arrow would change its direction. I could clearly see what the problem was, however I couldn't fix. And I have run out of ideas on how to fix it. I've tried have a second arrow instance, some boolean variables, having updateArrow2 etc. But everything I tried wouldn't work, I was hoping I could solve this on my, but I can't. Its probably one of the most simple things to do as well. (Removed some unnecessary code)

#SelectExpand
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_primitives.h> 6#include <allegro5/allegro_image.h> 7#include <allegro5/allegro_audio.h> 8#include <allegro5/allegro_acodec.h> 9#include <time.h> 10#include <cmath> 11#include "objects.h" 12 13#define ScreenWidth 800 14#define ScreenHeight 600 15 16 17////////////////////////////////////// 18// SORT OUT ARROW PROBLEM // 19////////////////////////////////////// 20 21 22//Prototpyes 23void initPlayer(Player &player); 24 25void initEnemy(Enemy &enemy, int x, int y); 26void drawEnemy(Enemy &enemy, ALLEGRO_BITMAP *image); 27void updateEnemy(Enemy &enemy, int posX, int posX2); 28bool collideArrow(Enemy &enemy, Arrow &arrow); 29 30void initCoin(Coin &coin, int x, int y); 31void drawCoin(Coin &coin, ALLEGRO_BITMAP *image); 32bool coinCollide(Coin &coin,Player &player ,int cX, int cY, int cWidth, int cHeight, int pWidth, int pHeight, bool live, int coinCount); 33 34void initArrow(Arrow &arrow); 35void drawArrow(Arrow &arrow, ALLEGRO_BITMAP *image, ALLEGRO_BITMAP *image1); 36void fireArrow(Arrow &arrow, Player &player, ALLEGRO_SAMPLE *bowShot); 37void updateArrow(Arrow &arrow); 38 39void initKey(Key &key); 40void drawKey(Key &key, ALLEGRO_BITMAP *image); 41 42bool collision(Player &player, int ex, int ey, int eWidth, int eHeight, int pWidth, int pHeight); 43 44void cameraUpdate(float *cameraPosition,Player &player, float width, float height); 45 46//Global Variables 47enum direction {LEFT, RIGHT}; 48enum GameStaes {MENU, PLAYING, DEATH}; 49int gamestate = MENU; 50int dir = LEFT; 51const int NUM_ENEMY = 10; 52int arrowCount = 10; 53bool fired = false; 54int firedR = 0, firedL = 0; 55bool coinLive = false; 56bool left, right = false; 57const float gravity = 1; 58 59int main() 60{ 61 ALLEGRO_DISPLAY *display; 62 63 if(!al_init()) 64 { 65 al_show_native_message_box(0, 0, "Error", "Falied to initialize allegro", 0, 0); 66 return -1; 67 } 68 69 display = al_create_display(ScreenWidth, ScreenHeight); 70 71 if(!display) 72 { 73 al_show_native_message_box(0, 0, "Error", "Falied to initialize the display", 0, 0); 74 return -1; 75 } 76 77 Player player; 78 Enemy enemy; 79 Enemy enemy2; 80 Enemy enemy3; 81 Enemy enemy4; 82 Coin coin; 83 Coin coin2; 84 Arrow arrow; 85 Key key; 86 int groundHeight = 535; 87 bool done = false, active = false, draw = true; 88 bool jump = false; 89 bool gotKey = false; 90 int sourceX = 32, sourceY = 0; 91 int coinCount = 0; 92 const float FPS = 60.0; 93 const float frameFPS = 15.0; 94 float jumpSpeed = 15.0; 95 float velX = 0, velY = 0; 96 97 float cameraPosition[2] = {0,0}; 98 99 100 101 al_init_image_addon(); 102 al_init_primitives_addon(); 103 al_install_keyboard(); 104 al_init_font_addon(); 105 al_init_ttf_addon(); 106 al_install_audio(); 107 al_init_acodec_addon(); 108 109 initPlayer(player); 110 initEnemy(enemy, 86, 391); 111 initEnemy(enemy2, 1167, 333); 112 initEnemy(enemy3, 378, 473); 113 initEnemy(enemy4, 649, 473); 114 initArrow(arrow); 115 initCoin(coin, 550, 480); 116 initCoin(coin2, 120, 398); 117 initKey(key); 118 119 ALLEGRO_KEYBOARD_STATE keystate; 120 ALLEGRO_TRANSFORM camera; 121 ALLEGRO_TRANSFORM identity; 122 ALLEGRO_SAMPLE *coinCollect = al_load_sample("Files/coin collect sound.wav"); 123 ALLEGRO_SAMPLE *bowShot = al_load_sample("Files/bow sound effect.wav"); 124 ALLEGRO_SAMPLE *bgSong = al_load_sample("Files/Background song 2.wav"); 125 ALLEGRO_SAMPLE *keyCollection = al_load_sample("Files/key collection.wav"); 126 ALLEGRO_SAMPLE *crocSound = al_load_sample("Files/Crocodile sound effect.wav"); 127 ALLEGRO_SAMPLE_INSTANCE *songInstance = al_create_sample_instance(bgSong); 128 ALLEGRO_BITMAP *enemyImg = al_load_bitmap("Files/enemy.png"); 129 ALLEGRO_BITMAP *background2 = al_load_bitmap("Files/Background 2.png"); 130 ALLEGRO_BITMAP *character = al_load_bitmap("Files/spritesheet(Bow & left + right).png"); 131 ALLEGRO_BITMAP *arrow_r = al_load_bitmap("Files/Arrow(RIGHT).png"); 132 ALLEGRO_BITMAP *arrow_l = al_load_bitmap("Files/Arrow(LEFT).png"); 133 ALLEGRO_BITMAP *coinImg = al_load_bitmap("Files/coin2.png"); 134 ALLEGRO_BITMAP *keyImg = al_load_bitmap("Files/key.png"); 135 ALLEGRO_BITMAP *ground = al_load_bitmap("Files/Ground.png"); 136 ALLEGRO_BITMAP *icon = al_load_bitmap("Files/game icon.png"); 137 ALLEGRO_BITMAP *menu = al_load_bitmap("Files/menu.png"); 138 ALLEGRO_FONT *font = al_load_font("Files/JUNGBN__.TTF", 23, 0); 139 ALLEGRO_TIMER *timer = al_create_timer(1.0/FPS); 140 ALLEGRO_TIMER *frameTimer = al_create_timer(1.0/frameFPS); 141 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue(); 142 143 al_reserve_samples(5); //Respresents how many audio clips I have in the game 144 al_set_display_icon(display, icon); 145 146 147 while(!done) 148 { 149 ALLEGRO_EVENT event; 150 al_wait_for_event(event_queue, &event); 151 al_get_keyboard_state(&keystate); 152 153 if(al_key_down(&keystate, ALLEGRO_KEY_ESCAPE)) 154 { 155 done = true; 156 } 157 else if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 158 { 159 done = true; 160 } 161 162 163 else if(event.type == ALLEGRO_EVENT_TIMER) 164 { 165 if(event.timer.source == timer) 166 { 167 active = true; 168 updateArrow(arrow); 169 updateEnemy(enemy, 238, 78); 170 updateEnemy(enemy2, 1236, 1167); 171 updateEnemy(enemy3, 660, 378); 172 updateEnemy(enemy4, 660, 378); 173 if(al_key_down(&keystate, ALLEGRO_KEY_SPACE)) 174 { 175 fireArrow(arrow, player, bowShot); 176 } 177 if(al_key_down(&keystate, ALLEGRO_KEY_D)) 178 { 179 velX = player.speed; 180 dir = RIGHT; 181 182 } 183 else if(al_key_down(&keystate, ALLEGRO_KEY_A)) 184 { 185 velX = -player.speed; 186 dir = LEFT; 187 } 188 else 189 { 190 velX = 0; 191 active = false; 192 } 193 if(al_key_down(&keystate, ALLEGRO_KEY_W) && jump) 194 { 195 velY = -jumpSpeed; 196 jump = false; 197 } 198 } 199 else if(event.timer.source = frameTimer) 200 { 201 if(active) 202 { 203 sourceX += al_get_bitmap_width(character) / 3; 204 } 205 else 206 { 207 sourceX = 32; 208 } 209 if(sourceX >= al_get_bitmap_width(character)) 210 { 211 sourceX = 0; 212 } 213 sourceY = dir; 214 215 216 } 217 218 if(!jump) 219 velY += gravity; 220 else 221 velY = 0; 222 player.x += velX; 223 player.y += velY; 224 225 jump = (player.y >= groundHeight); 226 227 if(jump) 228 { 229 player.y = groundHeight; 230 } draw = true; 231 232 233 cameraUpdate(cameraPosition, player, 32, 32); 234 al_identity_transform(&camera); 235 al_translate_transform(&camera, -cameraPosition[0], -cameraPosition[1]); 236 al_use_transform(&camera); 237 238 } 239 240 241 if(draw && al_is_event_queue_empty(event_queue)) 242 { 243 draw = false; 244 if(gamestate == MENU) 245 { 246 247 } 248 al_draw_bitmap(background2, 0, 0, 0); 249 al_draw_bitmap_region(character, sourceX, sourceY * al_get_bitmap_height(character) / 2, 32, 32, player.x, player.y, 0); 250 drawKey(key, keyImg); 251 drawArrow(arrow, arrow_r, arrow_l); 252 drawCoin(coin, coinImg); 253 drawCoin(coin2, coinImg); 254 drawEnemy(enemy, enemyImg); 255 drawEnemy(enemy2, enemyImg); 256 drawEnemy(enemy3, enemyImg); 257 drawEnemy(enemy4, enemyImg); 258 al_identity_transform(&identity); 259 al_use_transform(&identity); 260 al_draw_textf(font, al_map_rgb(252,209, 22), 10, 10, 0, "Arrows: %i", arrowCount); 261 al_draw_textf(font, al_map_rgb(252, 209, 22), 10, 50, 0, "Coins: %i", coinCount); 262 al_draw_textf(font, al_map_rgb(252, 209, 22), 110, 10, 0, "Lives: %i", player.lives); 263 //al_draw_textf(fps, al_map_rgb(252, 209, 22), 110, 50, 0, "FPS: %i", FPS); 264 al_flip_display(); 265 al_clear_to_color(al_map_rgb(255, 255, 255)); 266 267 } 268 } 269 270 al_destroy_bitmap(character); 271 al_destroy_bitmap(ground); 272 al_destroy_bitmap(coinImg); 273 al_destroy_bitmap(background2); 274 al_destroy_bitmap(arrow_l); 275 al_destroy_bitmap(arrow_r); 276 al_destroy_bitmap(keyImg); 277 al_destroy_sample(coinCollect); 278 al_destroy_sample(bowShot); 279 al_destroy_sample(bgSong); 280 al_destroy_sample(keyCollection); 281 al_destroy_sample_instance(songInstance); 282 al_destroy_font(font); 283 al_destroy_display(display); 284 al_destroy_event_queue(event_queue); 285 al_destroy_timer(timer); 286 return 0; 287} 288void initArrow(Arrow &arrow) 289{ 290 arrow.speed = 4.0; 291 arrow.live = false; 292 arrow.width = 16; 293 arrow.height = 5; 294} 295void drawArrow(Arrow &arrow, ALLEGRO_BITMAP *image, ALLEGRO_BITMAP *image2) 296{ 297 if(arrow.live && dir == RIGHT) 298 { 299 al_draw_bitmap(image, arrow.x, arrow.y, 0); 300 } 301 if(arrow.live && dir == LEFT) 302 { 303 al_draw_bitmap(image2, arrow.x, arrow.y, 0); 304 } 305 306} 307void fireArrow(Arrow &arrow, Player &player, ALLEGRO_SAMPLE *bowShot) 308{ 309 if(!arrow.live) 310 { 311 --arrowCount; 312 arrow.live = true; 313 arrow.x = player.x + 17; 314 arrow.y = player.y + 22; 315 fired = true; 316 al_play_sample(bowShot, 1.0, 0.0, 1.0, ALLEGRO_PLAYMODE_ONCE, 0); 317 } 318 319} 320void updateArrow(Arrow &arrow) 321{ 322 if(arrow.live && fired) 323 { 324 if(dir == RIGHT) 325 { 326 arrow.x += arrow.speed; 327 if(arrow.x >= 2990) 328 { 329 arrow.live = false; 330 } 331 } 332 if(dir == LEFT) 333 { 334 arrow.x -= arrow.speed; 335 if(arrow.x <= 5) 336 { 337 arrow.live = false; 338 } 339 } 340 341 if(arrowCount <= 0) 342 { 343 fired = false; 344 } 345 } 346}

Aaron Bolyard
Member #7,537
July 2006
avatar

The global direction variable is shared between the player and the arrow. That's no good.

What you need to do is have a member of the Arrow object called dir and use that instead of the global direction. Each arrow will then use its local direction variable, instead of the one that affects the player.

Samuel Henderson
Member #3,757
August 2003
avatar

Hi DJLad16!

Basically what is happening is that your arrow object and player object are sharing the same direction global variable. So when the player object switches direction so does the arrow.

This is a very good reason why global variables can sometimes get you into trouble.

What you could try doing is adding a dir member to your player object and arrow objects, then when you press the space bar (or whatever you make your 'shoot arrow' key) pass the direction the player object is facing into the 'fireArrow()' function. This way your player will be able to modify it's own direction variable willy nilly while the arrow will remain fixed in the direction it was fired from.

Edit:
Beaten! Oh well.

=================================================
Paul whoknows: Why is this thread still open?
Onewing: Because it is a pthread: a thread for me to pee on.

bamccaig
Member #7,536
July 2006
avatar

You should never use global variables (unless you really really have a reason to).

video

You're also ignoring a ton of return values. I would recommend you read this.

DJLad16
Member #14,857
January 2013

Doesn't matter - got it! Thanks, guys really appreciate it. Never experienced problems with global variables before so I just used them willy nilly. But now I know other wise. And bamccaig, I've taken into consideration what you said and edit my code with the return values.
However, one other problem I have is that you can only shoot if there is no arrow that it moving. And I cannot see anywhere in my code that will be causing this.

pkrcel
Member #14,001
February 2012

I see only one instance of Arrow object, named arrow....how are you supposed to fire more than one?

It is unlikely that Google shares your distaste for capitalism. - Derezo
If one had the eternity of time, one would do things later. - Johan Halmén

DJLad16
Member #14,857
January 2013

Ah.. I see. Well crap. When I was first learning how to make bullets, I did it through class arrays, and I was able to shoot one after another.

Schyfis
Member #9,752
May 2008
avatar

So why don't you do the same thing for arrows?

________________________________________________________________________________________________________
[freedwill.us]
[unTied Games]

Go to: