|
asteroids game, wrap around screen edges problem |
scorpx333
Member #13,695
November 2011
|
Hi to all, i am making an asteroid clone game and i am stuck at wrap around screen edges function, without it everything is fine, when i hit the asteroid it breaks into 3 smaller asteroids, and so on. but they off screen. so in order to wrap them around the screen i had made this function in asteroid class (function is at the end of code part called AsteroidVsScreen()) 1#include "asteroid.h"
2#include <allegro5\allegro.h>
3#include <allegro5\allegro_image.h>
4#include <allegro5\allegro_font.h>
5#include <allegro5\allegro_ttf.h>
6#include <allegro5\allegro_primitives.h>
7#include <allegro5\allegro_native_dialog.h>
8#include <math.h>
9
10
11
12asteroid::asteroid()
13{
14dead = false;
15asteroidSize = 3;
16 Width=900;
17 Height=600;
18
19
20
21xspeed= rand() % 5 - 3;
22yspeed= rand() % 5 - 3;
23
24xposition = rand() % (Width - 100);
25yposition = rand() % (Height - 100);
26if (xposition > Width/2 - 200 && xposition < Width/2 + 200 && yposition > Height/2 -200 && yposition < Height + 200)
27{
28xposition = 1;
29yposition = 1;
30}
31
32Ast_angl=0;
33
34}
35
36
37
38
39asteroid::asteroid(int size, int x, int y)
40{
41asteroidSize = size;
42
43
44if (xposition > Width/2 - 200 && xposition < Width/2 + 200 && yposition > Height/2 -200 && yposition < Height + 200)
45{
46xposition = 33;
47yposition = 33;
48}
49
50dead = false;
51
52xspeed= rand() % 5 - 3;
53yspeed= rand() % 5 - 3;
54if (xspeed == 0 && yspeed == 0)
55{
56xspeed= (rand() % 8 - 5)/2;
57yspeed= (rand() % 8 - 5)/2;
58}
59xposition = x;
60yposition = y;
61
62
63Ast_angl=0;
64}
65
66
67
68void asteroid::refreshAsteroid(ALLEGRO_BITMAP *Asteroid,ALLEGRO_FONT *font24)
69{
70
71
72if (dead==true) return;
73
74
75
76Ast_angl+=0.03;
77 xposition = xposition + xspeed;
78 yposition = yposition + yspeed;
79
80 //al_draw_textf(font24, al_map_rgb(255,0,0), 200,200,0, " %i",Ast_angl);
81
82
83if (asteroidSize == 3)
84{
85 al_draw_scaled_rotated_bitmap(Asteroid,50,50,xposition,yposition,1,1,Ast_angl,0);
86 //al_draw_rectangle(xposition-25,yposition-25,xposition+25,yposition+25,al_map_rgb(255,0,0),3);
87}
88if (asteroidSize == 2)
89{
90 al_draw_scaled_rotated_bitmap(Asteroid,50,50,xposition,yposition,0.5,0.5,Ast_angl,0);
91 //al_draw_rectangle(xposition-12,yposition-12,xposition+12,yposition+12,al_map_rgb(255,0,0),3);
92}
93if (asteroidSize == 1)
94{
95 al_draw_scaled_rotated_bitmap(Asteroid,50,50,xposition,yposition,0.25,0.25,Ast_angl,0);
96 //al_draw_rectangle(xposition-6,yposition-6,xposition+6,yposition+6,al_map_rgb(255,0,0),3);
97
98}
99if (asteroidSize == 0)
100{
101dead = true;
102return;
103}
104}
105
106void asteroid::AsteroidVsScreen()// al my game problems are here!!!!!!!!!
107{
108
109 if (dead == true) return;
110
111if(xposition > Width)
112{
113xposition=0;
114}
115
116else if(xposition < 0)
117{
118xposition = Width;
119}
120
121if(yposition > Height)
122{
123yposition =0;
124}
125
126else if(yposition < 0)
127{
128yposition = Height;
129}
130
131
132
133}
134
135
136int asteroid::getAsteroidXPosition()
137{
138return xposition;
139}
140int asteroid::getAsteroidYPosition()
141{
142return yposition;
143}
144
145
146int asteroid::getAsteroidSize()
147{
148return asteroidSize;
149}
150
151
152void asteroid::setAsteroidDead()
153{
154dead = true;
155}
156
157asteroid::~asteroid()
158{
159}
and now for the part in main where i call this function 1
2list<asteroid>::iterator iter;
3list<bullet>::iterator bulliter;
4
5iter = AsteroidList.begin();
6
7while(iter != AsteroidList.end())
8{
9
10 asteroid& s = *iter;
11 //s.AsteroidVsScreen();// the problematic function (gives 0 0 )
12
13
14
15 if (s.getAsteroidSize() == 3) { TempAsteroidSize = 25; }
16 if (s.getAsteroidSize() == 2) { TempAsteroidSize = 12; }
17 if (s.getAsteroidSize() == 1) { TempAsteroidSize = 6; }
18
19
20 bulliter = BulletList.begin();
21while(bulliter != BulletList.end())
22{
23 bullet& bull = *bulliter;
24
25
26 if (bull.getBulletXPosition() > s.getAsteroidXPosition()-TempAsteroidSize &&
27 bull.getBulletXPosition() < s.getAsteroidXPosition() + TempAsteroidSize &&
28 bull.getBulletYPosition() > s.getAsteroidYPosition() -TempAsteroidSize&&
29 bull.getBulletYPosition() < s.getAsteroidYPosition() + TempAsteroidSize)
30 {
31 tempSize = s.getAsteroidSize() - 1;
32 tempx = s.getAsteroidXPosition();
33 tempy = s.getAsteroidYPosition();
34
35 s.~asteroid();
36
37
38
39 iter = AsteroidList.erase(iter);//if colision asteroid is errased
40 bulliter = BulletList.erase(bulliter);
41 collision=true;// withaut this the iter++ will make an error
42 if (tempSize > 0){
43
44AsteroidList.push_back(*new asteroid(tempSize, tempx+(n+1)*10, tempy+(n+1)*10));
45AsteroidList.push_back(*new asteroid(tempSize, tempx, tempy));
46AsteroidList.push_back(*new asteroid(tempSize, tempx-(n+1)*10, tempy-(n+1)*10));
47
48 }
49
50 }
51 else{bulliter++;}
52
53}
54if (!collision){iter++;}
55if (collision){collision=false; score+=1;} // the iter error solved
56
57}// while asteroids
then the part of the code that refreshes asteroids on the screen iter = AsteroidList.begin(); while(iter != AsteroidList.end()) { // Retrieve the asteroid that the iterator points at asteroid& s = *iter; s.refreshAsteroid(Asteroid,font24); iter ++; } Any suggestions would be great |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Your first problem is mixing drawing with logic. You should not both alter position and draw in the same function. Split your functions apart and keep any logic separate from any drawing. Ideally, your loop should look like this : while (!game.Quit()) { game.CheckInputs(); game.Update(time_passed); game.Display(); } You have input logic, update logic, and drawing all separated out. Update logic checks for collisions, and marks asteroids and bullets as dead, and updates their positions, as well as the position of the player. Drawing just draws, based on the state of the game. Input logic affects turn rate and acceleration, or angle and velocity of the player, or anything else controlled by the user. Your update function should probably look something like this (pseudocode) : 1void Game::Update(double dt) {
2
3 for each asteroid a {a.Update(dt);}
4 for each bullet b {b.Update(dt);}
5 player.Update(dt);
6
7 for each asteroid a {
8 for each bullet b {
9 if (overlaps(b.circle , a.circle)) {
10 a.destroy();// This doesn't always delete the asteroid,
11 // but takes care of creating new sub asteroids if necessary
12 b.destroy();
13 }
14 }
15 if (overlaps(player.circle , a.circle)) {
16 player.GotHit();
17 }
18 }
19
20}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
scorpx333
Member #13,695
November 2011
|
Thank you Edgar Reynaldo, but maybe you know how could i complete this game with such code structure: logic and drawing together? or this is impossible? I need only to solve the combination of: asteroids being on the screen and breaking into smaller asteroid, problem. So i'll have an alpha version of this game working |
Thomas Fjellstrom
Member #476
June 2000
|
It's not impossible, but it can make things harder. It's certainly messier. -- |
Edgar Reynaldo
Major Reynaldo
May 2007
|
scorpx333 said: Thank you Edgar Reynaldo, but maybe you know how could i complete this game with such code structure: logic and drawing together? I'll just let you know, you're doing it The Hard WayTM. If you separate everything out, it will be much easier to code. I even gave you an example of what your Update function would look like. I don't want to set a bad example by helping you do it the wrong way. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
scorpx333
Member #13,695
November 2011
|
Ok, but wait a sec, look at code again if i put line 76-78 from asteroid class function asteroid::refreshAsteroid() And I call s.refreshAsteroid(Asteroid,font24) (that makes drawing) in other loop but still it doesn't work. Or i don't understand the separation thing? |
Edgar Reynaldo
Major Reynaldo
May 2007
|
scorpx333 said:
Ok, but wait a sec, look at code again if i put line 76-78 from asteroid class function asteroid::refreshAsteroid() Yes, that would help. If you do that, you should change the name of the function to reflect that it updates the state of the asteroid, and doesn't just fix the screen position. Quote: but still it doesn't work. Be specific - what do you expect it to do, and what is happening instead? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
scorpx333
Member #13,695
November 2011
|
I expect that asteroid::refreshAsteroid() function would work normally on new created 3 asteroids after the big one is destroyed,(it works on big one) but instead 3 asteroids get the needed size, but their positions (x and y ) becomes (0,0) and they don't move, if i don't use asteroid::refreshAsteroid() part: it works, but my asteroids need to be on screen if not destructed with a bullet or ship |
Edgar Reynaldo
Major Reynaldo
May 2007
|
scorpx333 said:
if (tempSize > 0){ What is the value of n? Also, you are adding the data pointed to by a new asteroid. That means you leak the address (and memory) of the asteroid you just created. Don't use *new, just use the asteroid constructor. scorpx333 said: their positions (x and y ) becomes (0,0) and they don't move, Then you are setting their position and velocity to zero somewhere else, because the constructor takes the position values you passed to it, and their velocity shouldn't be changing either. Use your IDE's find function, and look at all the instances of the position and velocity variables, and figure out which lines are changing the values. Because AsteroidVsScreen doesn't change the velocity, and it only changes the position if they go off screen. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
scorpx333
Member #13,695
November 2011
|
the n is 0, it doesn't do anything(forgot to rewrite that). after experimenting a bit i found out that AsteroidVsScreen only adds speed 1 time to new smaller asteroids, constructor gets position but somehow AsteroidVsScreen gets that x and y isn't on screen and makes them 0 0 then adds x=0+speed and stops, but why it stops, why AsteroidVsScreen only goes for 1 time for the new asteroid. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Well, I can't guess what is wrong anymore. I need to see all of your code together if you want me to figure out what is wrong. Post a zip file of all your source code and I will take a look at it. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
scorpx333
Member #13,695
November 2011
|
Edgar Reynaldo, here is my zip file, if you could check it, that would be really helpful, and thank you for your time spent on my game problem |
scorpx333
Member #13,695
November 2011
|
sorry for that i am trying to find a way to post it, ok now it should be working, do you need full game file or this source? |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Edit your post and look in the bottom right of the screen for 'attachments for use with substandard browsers', or use Firefox or Chrome to upload your attachment. Edit I found the problem. It is in your constructor. Your default constructor sets values for Width and Height, but your Asteroid::Asteroid(int,int,int) constructor does not. This means they are probably 0, but are really uninitialized. That is why if (xposition > Width) {xposition = 0;} always sets the value to 0. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
scorpx333
Member #13,695
November 2011
|
THANK YOU EDGAR Reynaldo!!!!!!!! |
Edgar Reynaldo
Major Reynaldo
May 2007
|
To prevent this problem in the future, google for 'initialization list', and then always write one in your constructors that initializes every member variable to a set value. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|