Problem with Sprite
Marcin Piwko

In my program there is an icon of player and icon of enemy. Player can move using ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_DOWN,ALLEGRO_KEY_RIGHT, ALLEGRO_KEY_LEFT. To create AI I used srand(time(NULL)); function, then:

1if (events.timer.source == enemy1TypeTimer) 2{ 3 enemy.choDir = rand() % 3; 4}

program generates 3 random numbers: 0,1 and 2. If 1- the following direction will be chosen : Right or Left, if 2- Top or Bottom.

I create another condition to chose between right and left, top or bottom:

2if (enemy.choDir == 1){ 3 if (enemy.y<player.y) 4 { 5 enemy.y += enemy.moveSpeed; 6 enemy.dir = DOWN; 7 } 8 else 9 { 10 enemy.y -= enemy.moveSpeed; 11 enemy.dir = UP; 12 } 13 } 14 if (enemy.choDir == 2) 15 { 16 if (enemy.x<player.x) 17 { 18 enemy.x += enemy.moveSpeed; 19 enemy.dir = RIGHT; 20 } 21 else 22 { 23 enemy.x -= enemy.moveSpeed; 24 enemy.dir = LEFT; 25 } 26 }

AI logic works well; when I start the program, enemy go in my direction. BUUUT don't know why the sprite effect doesn't work well. It works only with direction left and right. The graphic looks like that:

Can someone tell me what to do to create working correctly sprite effect? I'm trying to solve this problem all day and I don't have any ideas what's wrong.. Please help!

Here is my full source code:

3#include<allegro5\allegro5.h> 4#include<allegro5\allegro_native_dialog.h> 5#include<allegro5\allegro_image.h> 6#include<vector> 7#include<iostream> 8using namespace std; 9 10int ScreenWidth = 800, ScreenHeight = 600; 11bool done = false; 12 13enum Direction{ DOWN, LEFT, RIGHT, UP }; 14 15struct Player 16{ 17 float x = 10; 18 float y = 10; 19 float moveSpeed = 5; 20 21 bool draw = true; 22 bool active = false; 23 24 int dir = DOWN; 25 int sourceX=32; 26 int sourceY=0; 27}; 28struct Enemy{ 29 float x = 10; 30 float y = 10; 31 float moveSpeed = 5; 32 33 bool draw = true; 34 bool active = false; 35 36 int dir = DOWN; 37 int sourceX = 32; 38 int sourceY = 0; 39 40 int choDir= 0; //choose direction horizontal or upright 41}; 42 43void PlayerInitialConditions(Player& player,float StartXPosition,float StartYPostition, float StartMoveSpeed)//in next Updates add health, timer, bullets etc. 44{ 45 player.x = StartXPosition; 46 player.y = StartYPostition; 47 player.moveSpeed = StartMoveSpeed; 48} 49void EnemyInitialConditions(Enemy &enemy, float StartXPosition, float StartYPostition, float StartMoveSpeed) 50{ 51 enemy.x = StartXPosition; 52 enemy.y = StartYPostition; 53 enemy.moveSpeed = StartMoveSpeed; 54} 55 56void InitialConditions(Player& player, Enemy &enemy) 57{ 58 PlayerInitialConditions(player, 10, 10, 5); 59 EnemyInitialConditions(enemy, 200, 200, 3); 60} 61 62int main(){ 63 64 const float FPS = 60; 65 const float frameFPS = 15;//1) 66 67 if (!al_init()) 68 { 69 al_show_native_message_box(NULL, "ERROR", NULL, "Could not initialize Allegro 5", NULL, NULL); 70 return -1; 71 } 72 73 al_set_new_display_flags(ALLEGRO_WINDOWED); 74 ALLEGRO_DISPLAY *display = al_create_display(ScreenWidth, ScreenHeight);//creating window with dimensions: 800:600 px 75 al_set_window_position(display, 200, 200);//place from left top positioning the frame of display 76 al_set_window_title(display, "Marcin Piwko RLZ"); 77 78 if (!display)//show this message if sth wrong with display 79 { 80 al_show_native_message_box(display, "Sample Title", "Display Settings", "Display window was not created succesfully", NULL, ALLEGRO_MESSAGEBOX_ERROR); 81 return -1; 82 } 83 84 al_install_keyboard(); 85 al_init_image_addon(); 86 ALLEGRO_BITMAP *playerBMP = al_load_bitmap("PlayerImage1.png"); 87 ALLEGRO_BITMAP *enemy1TypeBMP = al_load_bitmap("enemy1.png"); 88 89 90 ALLEGRO_KEYBOARD_STATE keyState;//pokazuje jaki klawisz został aktualnie wciśniety 91 92 ALLEGRO_TIMER *timer = al_create_timer(3.0 / FPS);//predkosc ruchu gracza 93 ALLEGRO_TIMER *frameTimer = al_create_timer(0.5 / frameFPS);//2) 94 ALLEGRO_TIMER *enemy1TypeTimer = al_create_timer(5.0 / FPS); 95 96 97 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue(); 98 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 99 al_register_event_source(event_queue, al_get_timer_event_source(frameTimer)); 100 al_register_event_source(event_queue, al_get_timer_event_source(enemy1TypeTimer)); 101 102 al_register_event_source(event_queue, al_get_display_event_source(display)); 103 al_register_event_source(event_queue, al_get_keyboard_event_source()); 104 105 Player player; 106 Enemy enemy; 107 108 InitialConditions(player, enemy); 109 110 srand(time(NULL)); 111 al_start_timer(timer); 112 al_start_timer(frameTimer); 113 al_start_timer(enemy1TypeTimer); 114 115 while (!done) 116 { 117 ALLEGRO_EVENT events; 118 al_wait_for_event(event_queue, &events); 119 al_get_keyboard_state(&keyState); 120 if (events.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 121 { 122 done = true; 123 } 124 125 //Implementation of AI 126 if (events.timer.source == enemy1TypeTimer) 127 { 128 enemy.choDir = rand() % 3; 129 } 130 131 else if (events.type == ALLEGRO_EVENT_TIMER) 132 { 133 if (events.timer.source == timer)//5 134 { 135 player.active = true; 136 if (al_key_down(&keyState, ALLEGRO_KEY_DOWN)) 137 { 138 player.y += player.moveSpeed; 139 player.dir = DOWN; 140 } 141 else if (al_key_down(&keyState, ALLEGRO_KEY_UP)) 142 { 143 player.y -= player.moveSpeed; 144 player.dir = UP; 145 } 146 else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT)) 147 { 148 player.x += player.moveSpeed; 149 player.dir = RIGHT; 150 } 151 else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT)) 152 { 153 player.x -= player.moveSpeed; 154 player.dir = LEFT; 155 } 156 else 157 player.active = false; 158 159 //Artificial inteligence used: 160 enemy.active = true; 161 if (enemy.choDir == 1){ 162 if (enemy.y<player.y) 163 { 164 enemy.y += enemy.moveSpeed; 165 enemy.dir = DOWN; 166 } 167 else 168 { 169 enemy.y -= enemy.moveSpeed; 170 enemy.dir = UP; 171 } 172 } 173 if (enemy.choDir == 2) 174 { 175 if (enemy.x<player.x) 176 { 177 enemy.x += enemy.moveSpeed; 178 enemy.dir = RIGHT; 179 } 180 else 181 { 182 enemy.x -= enemy.moveSpeed; 183 enemy.dir = LEFT; 184 } 185 } 186 //********************************************** 187 else 188 enemy.active = false; 189 190 191 } 192 193 if (events.timer.source = frameTimer)//6) 194 { 195 if (player.active == true) 196 player.sourceX += al_get_bitmap_width(playerBMP) / 3; 197 else 198 player.sourceX = 32; 199 200 if (player.sourceX >= al_get_bitmap_width(playerBMP)) 201 player.sourceX = 0; 202 203 player.sourceY = player.dir; 204 } 205 player.draw = true; 206 207 208 209 if (events.timer.source = frameTimer)//6) 210 { 211 if (enemy.active== true) 212 enemy.sourceX += al_get_bitmap_width(enemy1TypeBMP) / 3; 213 else 214 enemy.sourceX = 32; 215 216 if (enemy.sourceX >= al_get_bitmap_width(enemy1TypeBMP)) 217 enemy.sourceX = 0; 218 219 enemy.sourceY = enemy.dir; 220 } 221 enemy.draw = true; 222 223 224 } 225 226 227 228 229 230 231 if (player.draw||enemy.draw){ 232 al_draw_bitmap_region(playerBMP, player.sourceX, player.sourceY * al_get_bitmap_height(playerBMP) / 4, 32, 32, 233 player.x, player.y, NULL); 234 al_draw_bitmap_region(enemy1TypeBMP, enemy.sourceX, enemy.sourceY * al_get_bitmap_height(enemy1TypeBMP) / 4, 32, 32, 235 enemy.x, enemy.y, NULL); 236 al_flip_display(); 237 al_clear_to_color(al_map_rgb(0, 0, 0)); 238 } 239 } 240 241 al_destroy_display(display); 242 al_destroy_timer(timer); 243 al_destroy_bitmap(playerBMP); 244 al_destroy_bitmap(enemy1TypeBMP); 245 al_destroy_event_queue(event_queue); 246 return 0; 247}

Trent Gamblin

You need to use "else if" here:

```        else if (enemy.choDir == 2)
```

Otherwise anytime choDir is 1, the else following this gets executed, setting the enemy to inactive.

Gideon Weems

Trent's right. Also, you've got a couple assignments in your if statements:

if (events.timer.source = frameTimer)//6)

In addition, this block seems to be redundant.

That's a cool, little sprite you've got there.

Marcin Piwko

I can't believe that the answer is so simple! Thx you both!!! It works!!