Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Randomness-ish

This thread is locked; no one can reply to it. rss feed Print
Randomness-ish
Specter Phoenix
Member #1,425
July 2001
avatar

I'm trying to do finishing touches on a simple game for a competition and I hit a snag I hadn't put any thought into until now. I have the random number generator:

srand(time(NULL));
int iSecret = rand() % 608 + 16;

My plan was to do aiShip.setCoords(iSecret, -20);, but I don't know how to make iSecret continuously generate random numbers so the ship redraws itself on different parts of the screen. I have to do this for a few ships so that you have more than one ship on screen, and plan to make a second variable to randomize the velocity of each ship between say 1 and 5.

Arthur Kalliokoski
Second in Command
February 2005
avatar

You're not using srand() prior to every rand() call, are you? You'll only get a different result once per second if you do. Call srand() once at the beginning of the program only.

They all watch too much MSNBC... they get ideas.

Specter Phoenix
Member #1,425
July 2001
avatar

No, I only have srand(time(NULL)); at that start of main. So I just need to do the iSecret = rand() % ... after it is destroyed or goes off screen? Never used it outside of guess my number programs so wasn't sure how to use it for continuous random numbers.

Arthur Kalliokoski
Second in Command
February 2005
avatar

how to make iSecret continuously generate random numbers so the ship redraws itself on different parts of the screen.

You want the ship to appear in different positions (except smooth transitions due to velocity) how often?

They all watch too much MSNBC... they get ideas.

Specter Phoenix
Member #1,425
July 2001
avatar

One of the things I'm still working out. It is kind of a trial and error type thing. I'm not even sure how many ships I will have appearing on screen and still have to decide if I want to modify the code more to space out the 'entry/launch' time or just leave it to randomly set the velocity and leave it at that. I'm leaning towards the latter as this is due by midnight tomorrow for Moosader's Villain and One button competition.

Arthur Kalliokoski
Second in Command
February 2005
avatar

I just need to do the iSecret = rand() % ... after it is destroyed or goes off screen?

You'd use it when creating a new ship (whether that happens because another one was destroyed, or because it's part of arriving reinforcements or whatever). Then you'd modify its location once per frame with a velocity that might have been initialized with a rand for x and a rand for y. You'd need to modify the velocities to make it change course, naturally.

They all watch too much MSNBC... they get ideas.

Gabriel Campos
Member #12,034
June 2010
avatar

Can u post a little more code?

Specter Phoenix
Member #1,425
July 2001
avatar

Yeah, the competition is pretty much over and I never got it done, so I'm not worried about it now. I got it semi working to like it and feel I accomplished what I set out to do (minus finishing the game). Forgive some of the ugly code, I started trying different ideas without much thought to see what it would do to the game (which is why there are tons of rand calls, was trying to see what effects it would have..some worked like I planned and others not so much).

game.h

#SelectExpand
1#ifndef GAME_H 2#define GAME_H 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_image.h> 6#include <allegro5/allegro_font.h> 7#include <allegro5/allegro_ttf.h> 8#include <allegro5/allegro_primitives.h> 9 10struct GAME 11{ 12 ALLEGRO_DISPLAY *display; 13 ALLEGRO_EVENT_QUEUE *event_queue; 14 ALLEGRO_TIMER *timer; 15 // ALLEGRO_BITMAP *icon; 16 ALLEGRO_FONT *font; 17}; 18 19#endif

init.h

#ifndef INIT_H
#define INIT_H

#include "game.h"

void init(GAME *game);

#endif

init.cpp

#SelectExpand
1#include "init.h" 2#include <fstream> 3 4const int SCREEN_W = 640; 5const int SCREEN_H = 480; 6const float FPS = 60; 7 8void init(GAME *game) 9{ 10 // log file 11 std::ofstream myLog; 12 13 myLog.open("data/err.log"); 14 15 if(!al_init()) 16 { 17 myLog << "Allegro failed to initialize...\n"; 18 } 19 20 if(!al_init_primitives_addon()) 21 { 22 myLog << "Failed to initialize primitive addon...\n"; 23 } 24 25 al_init_font_addon(); 26 al_init_ttf_addon(); 27 28 if(!al_install_keyboard()) 29 { 30 myLog << "Failed to install keyboard...\n"; 31 } 32 33 if(!al_install_mouse()) 34 { 35 myLog << "Failed to install mouse...\n"; 36 } 37 38 game->timer = al_create_timer(1.0 / FPS); 39 if(!game->timer) 40 { 41 myLog << "Failed to create timer...\n"; 42 } 43 44 if(!al_init_image_addon()) 45 { 46 myLog << "Failed to initialize image addon...\n"; 47 } 48 49 game->display = al_create_display(SCREEN_W, SCREEN_H); 50 if(!game->display) 51 { 52 myLog << "Failed to create display...\n"; 53 } 54 55 game->font = al_load_ttf_font("data/DejaVuSans.ttf", 30, 0); 56 if(!game->font) 57 { 58 myLog << "Failed to load font...\n"; 59 } 60 61 game->event_queue = al_create_event_queue(); 62 if(!game->event_queue) 63 { 64 myLog << "Failed to create event queue...\n"; 65 } 66 67 myLog.close(); 68 69}

sprite.h

#SelectExpand
1#ifndef SPRITE_H 2#define SPRITE_H 3 4#include <vector> 5#include <string> 6#include <iostream> 7#include <allegro5/allegro.h> 8#include <allegro5/allegro_image.h> 9#include <allegro5/allegro_font.h> 10#include <allegro5/allegro_ttf.h> 11#include <allegro5/allegro_primitives.h> 12 13class SPRITE 14{ 15 float x, y, w, h, xVel, yVel; 16 int frames; 17 ALLEGRO_BITMAP *sprite; 18 std::vector<ALLEGRO_BITMAP*> anim; 19 public: 20 int loadSpriteSheets(std::string filename); 21 void setCoord(float sX, float sY); 22 void setData(float sW, float sH, float sXVel, float sYVel, int frameCount); 23 void draw(); 24 void randDraw(int num); 25 void animate(int ticks, int speed); 26 void movement(); 27 float getX(); 28 float getY(); 29 float getW(); 30 float getH(); 31}; 32 33bool Collision(SPRITE A, SPRITE B); 34 35#endif

sprite.cpp

#SelectExpand
1#include "sprite.h" 2 3int SPRITE::loadSpriteSheets(std::string filename) 4{ 5 sprite = al_load_bitmap(filename.c_str()); 6 if(!sprite) 7 { 8 std::cout << "Spritesheet failed to load file: " << filename << "\n"; 9 return -1; 10 } 11 return 0; 12} 13 14void SPRITE::setCoord(float sX, float sY) 15{ 16 x = sX; 17 y = sY; 18} 19 20void SPRITE::setData(float sW, float sH, float sXVel, float sYVel, int frameCount) 21{ 22 w = sW; 23 h = sH; 24 xVel = sXVel; 25 yVel = sYVel; 26 frames = frameCount; 27} 28void SPRITE::draw() 29{ 30 al_draw_bitmap(sprite, x, y, 0); 31} 32 33void SPRITE::randDraw(int num) 34{ 35 int tileOffset = 0; 36 for(int i = 0; i < frames; i++) 37 { 38 anim.push_back(al_create_sub_bitmap(sprite, tileOffset, 0, w, h)); 39 tileOffset = tileOffset + w; 40 } 41 al_draw_bitmap(anim[num], x, y, 0); 42} 43 44void SPRITE::animate(int ticks, int speed) 45{ 46 int tileOffset = 0; 47 for(int i = 0; i < frames; i++) 48 { 49 anim.push_back(al_create_sub_bitmap(sprite, tileOffset, 0, w, h)); 50 tileOffset = tileOffset + w; 51 } 52 al_draw_bitmap(anim[ticks/ speed % frames], x, y, 0); 53} 54 55void SPRITE::movement() 56{ 57 y += yVel; 58} 59 60float SPRITE::getX(){return x;} 61float SPRITE::getY(){return y;} 62float SPRITE::getW(){return w;} 63float SPRITE::getH(){return h;} 64 65bool Collision(SPRITE A, SPRITE B) 66{ 67 // find the sides of rect 68 int leftA, leftB; 69 int rightA, rightB; 70 int topA, topB; 71 int bottomA, bottomB; 72 73 // calculate the sides of rect a 74 leftA = A.getX(); 75 rightA = A.getX() + A.getW(); 76 topA = A.getY(); 77 bottomA = A.getY() + A.getH(); 78 79 // calculate the sides of rect b 80 leftB = B.getX(); 81 rightB = B.getX() + B.getW(); 82 topB = B.getY(); 83 bottomB = B.getY() + B.getH(); 84 85 // if any of the sides from a are outside of b 86 if(bottomA <= topB){ return false; } 87 if(topA >= bottomB){ return false; } 88 if(rightA <= leftB){ return false; } 89 if(leftA >= rightB){ return false; } 90 91 // if none of the sides from a are outside b 92 return true; 93}

main.cpp

#SelectExpand
1#include "init.h" 2#include "sprite.h" 3#include <fstream> 4#include <cstdio> 5#include <cstdlib> 6#include <ctime> 7 8const int SCREEN_H = 480; 9const int SCREEN_W = 640; 10//#define SCREEN_WIDTH 640 11//#define SCREEN_HEIGHT 480 12//#define BLOCKSIZE 32 13// 20 * 32 = 640 14// 15 * 32 = 480 15// 2d array int [row][col] 16 17enum MYKEYS{ KEY_SPACE, KEY_F1 }; 18bool key[2] = { false, false }; 19 20int main() 21{ 22 /* initialize random seed: */ 23 srand(time(NULL)); 24 25 int iSecret = rand() % 608 + 16; 26 int sprite = rand() % 5; 27 int randYVel = rand() % 6 + 1; 28 29 int ticks = 0; 30 int score = 0; 31 32 GAME game; 33 init(&game); 34 35 SPRITE playerShip; 36 SPRITE splashScreen; 37 SPRITE help; 38 SPRITE info; 39 SPRITE aiShip; 40 SPRITE explosion; 41 42 splashScreen.loadSpriteSheets("data/splash.png"); 43 splashScreen.setCoord(0, 0); 44 splashScreen.setData(640, 480, 0, 0, 0); 45 46 help.loadSpriteSheets("data/help.png"); 47 help.setCoord(0, 0); 48 help.setData(640, 480, 0, 0, 0); 49 50 info.loadSpriteSheets("data/dirSheet.png"); 51 info.setCoord(512, 448); 52 info.setData(160, 32, 0, 0, 2); 53 54 playerShip.loadSpriteSheets("data/player.png"); 55 playerShip.setData(32, 32, 4, 4, 0); 56 57 58 explosion.loadSpriteSheets("data/explSheet.png"); 59 explosion.setData(32, 32, 0, 0, 3); 60 61 aiShip.loadSpriteSheets("data/shipSheet.png"); 62 aiShip.setCoord(iSecret, -20); 63 aiShip.setData(32, 32, 0, randYVel, 4); 64 65 66 67 bool redraw = true; 68 bool doexit = false; 69 70 al_set_window_title(game.display,"Global Destruction"); 71 al_set_window_position(game.display, 20, 20); 72 73 al_register_event_source(game.event_queue, al_get_display_event_source(game.display)); 74 al_register_event_source(game.event_queue, al_get_timer_event_source(game.timer)); 75 al_register_event_source(game.event_queue, al_get_keyboard_event_source()); 76 al_register_event_source(game.event_queue, al_get_mouse_event_source()); 77 78 al_clear_to_color(al_map_rgb(0, 0, 0)); 79 al_flip_display(); 80 al_start_timer(game.timer); 81 82 while (!doexit) 83 { 84 ALLEGRO_EVENT ev; 85 al_wait_for_event(game.event_queue, &ev); 86 87 if(ev.type == ALLEGRO_EVENT_TIMER) 88 { 89 ticks++; 90 sprite = rand() % 5; 91 aiShip.movement(); 92 93 94 95 96 if(Collision(playerShip, aiShip)) 97 { 98 explosion.setCoord(aiShip.getX(), aiShip.getY()); 99 explosion.animate(ticks, 10); 100 aiShip.setData(32, 32, 0, (rand() % 6 + 1), 4); 101 aiShip.setCoord((rand() % 608 + 16), -20); 102 sprite; 103 104 al_flip_display(); 105 } 106 107 if(aiShip.getY() > SCREEN_H) 108 { 109 aiShip.setData(32, 32, 0, (rand() % 6 + 1), 4); 110 aiShip.setCoord((rand() % 608 + 16), -20); 111 sprite; 112 al_flip_display(); 113 } 114 115 redraw = true; 116 } 117 else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 118 { 119 break; 120 } 121 else if(ev.type == ALLEGRO_EVENT_MOUSE_AXES || 122 ev.type == ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY) 123 { 124 playerShip.setCoord(ev.mouse.x, ev.mouse.y); 125 } 126 else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) 127 { 128 break; 129 } 130 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) 131 { 132 switch(ev.keyboard.keycode) 133 { 134 case ALLEGRO_KEY_SPACE: 135 key[KEY_SPACE] = true; 136 break; 137 case ALLEGRO_KEY_F1: 138 key[KEY_F1] = true; 139 break; 140 } 141 } 142 else if(ev.type == ALLEGRO_EVENT_KEY_UP) 143 { 144 switch(ev.keyboard.keycode) 145 { 146 case ALLEGRO_KEY_SPACE: 147 key[KEY_SPACE] = false; 148 break; 149 case ALLEGRO_KEY_F1: 150 key[KEY_F1] = false; 151 break; 152 case ALLEGRO_KEY_ESCAPE: 153 doexit = true; 154 break; 155 } 156 } 157 158 if(redraw && al_is_event_queue_empty(game.event_queue)) 159 { 160 161 redraw = false; 162 al_clear_to_color(al_map_rgb(0, 0, 0)); 163 164 playerShip.draw(); 165 aiShip.randDraw(sprite); 166 167 al_flip_display(); 168 } 169 } 170 171 al_clear_to_color(al_map_rgb(0, 0, 0)); 172 al_flip_display(); 173 al_destroy_display(game.display); 174 175 return 0; 176}

Go to: