 |
CodeDread.com
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: 2005-03-02 4:10 pm Post subject: Questions on my design |
|
|
Hi,
I've been working on this battlegrid design. Basiclly its a bitmap of a math grid change a bit to look like a battleship grid by me. I have decided that its going to be a Jezzball clone. Currently grid has its own surface along with the player and the ball. The player starts out at a certain position along with the ball. Jeff has kindly gave me a lecture on how I should do velocity and flip it for it to bounce around on the grid. It works . What I need to do now is make it so if you press spacebar you place a brick down and the ball (if it comes into the brick's path bounce the other way (making the brick seem solid). I had done some tests but I dont feel up to explaining them here as I wont explain it well at all.
If it helps here is the full code:
| Code: |
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <SDL_video.h>
SDL_Surface *grid;
SDL_Surface *image,*enemy;
SDL_Surface *screen;
SDL_Surface *takespace;
SDL_Surface *wall;
int xpos=29,ypos=26;
int wallx,wally;
int ex=29,ey=51;
int svx=6,svy=11;//enemy's velocity
int wallgrid[26][23];
int InitImages()
{
//takespace = SDL_LoadBMP("takespace.bmp");
grid = SDL_LoadBMP("data/pics/battlegrid.bmp");
image = SDL_LoadBMP("data/pics/player.bmp");
enemy = SDL_LoadBMP("data/pics/enemy.bmp");
wall = SDL_LoadBMP("data/pics/wall.bmp");
if(!image ||!grid ||!enemy ||!wall)
{
fprintf(stderr,"error loading bitmaps\n");
//exit(1);
}
return 0;
}
void DrawIMG(SDL_Surface *img, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
}
void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_Rect dest2;
dest2.x = x2;
dest2.y = y2;
dest2.w = w;
dest2.h = h;
SDL_BlitSurface(img, &dest2, screen, &dest);
}
void DrawIMG(SDL_Surface *img, int x, int y,SDL_Surface *img2)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, img2, &dest);
}
void DrawBG()
{
DrawIMG(grid, 0, 0);
}
void DrawScene(int x, int y, SDL_Surface *scrn)
{
DrawIMG(grid, x-30, y-30, 90, 90, x-30, y-30);
DrawIMG(scrn, x, y);
SDL_Flip(screen);
}
int main(int argc, char *argv[])
{
Uint8 *keys;
if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
{
printf("Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
screen=SDL_SetVideoMode(800,600,32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE|SDL_ANYFORMAT);
if ( screen == NULL )
{
fprintf(stderr,"Unable to set 800x600 video: %s\n", SDL_GetError());
exit(1);
}
SDL_ShowCursor(0);//cursor is annoying
InitImages();//call up function InitImages from the global space which loads the images.
DrawBG();//draw the background
int done=0;
while(done == 0)
{
SDL_Event event;
while ( SDL_PollEvent(&event) )
{
switch(event.type)
{
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN://|| forward == LOCAL_KEY_ESCAPE
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
break;
}
}//end while loop
//I would use a case here but switch complains that Uints arent integers and it doesnt work even with the conversion specifier.
keys = SDL_GetKeyState(NULL);
ex += svx;
ey += svy;
if(wallgrid[ex][ey]==2)
{
svx = -(svx);
svy = -(svy);
}
if(ex < 29)
{
svx = -(svx);
}
if(ex > 770)
{
svx = -(svx);
}
if(ey < 26)
{
svy = -(svy);
}
if(ey > 575)
{
svy = -(svy);
}
if (keys[SDLK_UP] && ypos >30)
{
ypos -= 25;
}
if (keys[SDLK_DOWN] && ypos <575)
{
ypos += 25;
}
if (keys[SDLK_LEFT] && xpos >30)
{
xpos -= 30;
}
if (keys[SDLK_RIGHT] && xpos <770)
{
xpos += 30;
}
if( keys[SDLK_SPACE] )
{
wallgrid[ex][ey]=2;
DrawIMG(wall,xpos,ypos,grid);
}
DrawScene(ex,ey,enemy);
DrawScene(xpos,ypos,image);
SDL_Delay(100);
}//end the main while
return 0;
}
|
Thanks in advance,
George |
|
| Back to top |
|
 |
Mr.Ampersand() Frequent Poster
Joined: 17 May 2004 Posts: 75 Location: United States
|
Posted: 2005-03-02 4:11 pm Post subject: |
|
|
argh...
I logged in and it didnt take affect _________________ Never stop learning |
|
| Back to top |
|
 |
Jeff Site Admin
Joined: 26 Apr 2004 Posts: 356
|
Posted: 2005-03-02 4:56 pm Post subject: Re: Questions on my design |
|
|
HI George,
I don't have a lot of time right now so I'll just say a couple things.
| Code: |
while(done == 0)
{
SDL_Event event;
while ( SDL_PollEvent(&event) )
{
switch(event.type)
{
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN://|| forward == LOCAL_KEY_ESCAPE
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
break;
}
}//end while loop
//I would use a case here but switch complains that Uints arent integers and it doesnt work even with the conversion specifier.
keys = SDL_GetKeyState(NULL);
...
if (keys[SDLK_UP] && ypos >30)
{
ypos -= 25;
}
if (keys[SDLK_DOWN] && ypos <575)
{
ypos += 25;
}
|
You seem to be mixing a couple ways of getting the keyboard input. You check for ESC during the SDL_PollEvents loop and then later you check each individual key (Up, Down, etc).
Why not modify your code like this:
| Code: |
while(done == 0)
{
SDL_Event event;
while ( SDL_PollEvent(&event) )
{
switch(event.type)
{
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN://|| forward == LOCAL_KEY_ESCAPE
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
else if( event.key.keysym.sym == SDLK_UP ) { do up stuff }
else if( event.key.keysym.sym == SDLK_DOWN ) { do down stuff }
else if( event.key.keysym.sym == SDLK_SPACE) { fart a brick }
// etc...
break;
}
}//end while loop
|
I assume this code is what you added to make the ball bounce off a wall:
| Quote: |
if(wallgrid[ex][ey]==2)
{
svx = -(svx);
svy = -(svy);
}
|
It seems the problem with this is that it only reverses the direction of the ball, it doesn't bounce it. If the ball connects with a wall, you should flip the velocity component that makes sense. For this you'll need to determine which SIDE of the wall/brick was struck. If it struck a horizontal wall, you would flip the vertical component of the velocity. If it struck a vertical wall, you would flip the horizontal component of the velocity.
This is where collision detection becomes trickier. Does your ball occupy a full square? |
|
| Back to top |
|
 |
Mr.Ampersand() Frequent Poster
Joined: 17 May 2004 Posts: 75 Location: United States
|
Posted: 2005-03-02 7:45 pm Post subject: |
|
|
Wrong. This is what was used to switch velocities to make ball bounce off wall.
| Code: |
if(ex < 29)
{
svx = -(svx);
}
if(ex > 770)
{
svx = -(svx);
}
if(ey < 26)
{
svy = -(svy);
}
if(ey > 575)
{
svy = -(svy);
}
|
What you saw before was a test for spacebar.
For the modification you said would be better it wouldnt be for me. I want it so if you hold down the keys you keep going in that direction. With that modification you cant and you can only move in one direction. The timeslice's are different as you put it.
I have the ball to be a circle smaller than the square. I have a square I could use for experemting. But would ultimatly like to use the ball. I never did this so bear with me.
thanks
--George _________________ Never stop learning |
|
| Back to top |
|
 |
Mr.Ampersand() Frequent Poster
Joined: 17 May 2004 Posts: 75 Location: United States
|
Posted: 2005-03-03 7:55 am Post subject: |
|
|
Hi,
I was thinking of just noting this out:
| Code: |
while ( SDL_PollEvent(&event) )
{
switch(event.type)
{
case SDL_QUIT:
done = 1;
break;
case SDL_KEYDOWN://|| forward == LOCAL_KEY_ESCAPE
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
break;
}
}//end while loop
|
and do this instead:
| Code: |
if (keys[SDLK_ESCAPE] )
{
done = 1;
SDL_Quit();
}
|
Is that such a bad idea? I was thinking of putting the quitting into one switch statement. Would that increase performance in the code? I know we had this discussion before about cononcial switch/case's. The reason I dont have just if's for the movements is because if I do the if/else if's it wont work properly.
Now for this Jezzball clone i'm trying to attempt I've been thinking of how to do this. I understand that I have to worry about the sides of the square/ball... If the bouncing square hits the "farted wall" it would need to be negated like the code for the ball. I just need to figure out how to negate it from one side of the square. I'm kind of confused on how to do this. Now this isnt going to be like jezzball where if you make the wall it goes all the way across untill it hits both walls it'll just make one square when spacebar invoked. and each square would be a wall. _________________ Never stop learning |
|
| Back to top |
|
 |
Jeff Site Admin
Joined: 26 Apr 2004 Posts: 356
|
Posted: 2005-03-03 8:37 am Post subject: |
|
|
George, no I don't think that's a bad idea to move the ESCAPE handler to the rest of your keyboard handling. You're right that if you want a key to be held down that you'll need to do what you're doing now.
As for "Jezzball" I don't really know what that is, sorry, but I think I get the idea of what you're trying to do anyway.
If your ball is going to be smaller than the walls then your coordinate system will need to be changed. That is, if your walls are on integer boundaries and you want your ball to be smaller than this and move on any angle, you will need for its velocity and position to be floating point.
Your ball will also have to have a "radius" value that specifies how large your ball is. This willl help you in figuring out your collision detection.
Unfortunately good collision detection is tough mathematically. The simple case of the walls that surround your grid is different than a brick/wall object in the center of the grid because in that case the ball could bounce off either a horizontal side, a vertical side or the corner (while at the edges it can only ever bounce off one side). Each time you are about to advance the ball along its velocity vector, you need to determine if any area between the old position and new position will intersect with any wall.
If you make the ball smaller than a brick, it will help you somewhat because you won't have to search through every wall, just the walls that might be in the locations where the ball is. For instance, if the center of your ball is at (8.9,5.8) and the ball radius is 0.3, then the ball overlaps with grid locations (8,5), (8,6), (9,5), (9,6) so you only need to check those locations for any bricks/walls..
Sorry I can't help you more, I'm thinking there might be tutorials out there that could help you with it. Another possibility is using a library that does collision detection for you. Rob wrote a blog entry about one recently, though it might be overkill for what you want. |
|
| Back to top |
|
 |
Mr.Ampersand() Frequent Poster
Joined: 17 May 2004 Posts: 75 Location: United States
|
Posted: 2005-03-09 5:42 pm Post subject: |
|
|
Hi,
I finally decided to make the changes to the code...
First off I got rid of the event polling out of the code then recompiled and ran. After I ran I noticed that the ball still bounced off edges however when I attempted to move it didnt respond. I then put this back:
| Code: |
SDL_Event event;
while ( SDL_PollEvent(&event) )
{
}
|
I put it back just like that without anything in it and it was polling once again. However I added the quit testing and escape testing to my main keyboard movements.
I've been putting some thought of how i'm going to make this Jezzball clone after reading some of my AI programming book. I feel as if i'm having lots of things thrown at me and i'm getting confused. My friend says he knows his solution will work. I forgot what he said exactly to post it here. If I tried to explain it it wouldnt come out right.
So, according to what you said I made my xpos,ypos,ex,ey all into floats. I had to use the conversion from float to int in some places. I couldnt change the DrawIMG int's to floats since it complained about a short int being converted from a float or something. You could scroll up to see the DrawIMG function.
I looked at that blog link. I dont think that'll help me to much. I feel as if thats giving me more info than I really need. I dont think there is a real simple solution to this or is there... I was thinking to myself... how would I set the balls radius? I was also searching gamedev's articles. I found some things but they dont seem like the "holy grail" or what I need exactly. I might just have to look at other source code or maybe check out that blog some more.
Sorry if i'm being a pain. I know you have work to do. You dont have to respond to this quickly. I just thought i'd keep the forums active somewhat. Maybe someone might find our discussions helpful.
aaah.... George=Confused
--George _________________ Never stop learning |
|
| Back to top |
|
 |
Rob Frequent Poster
Joined: 27 Apr 2004 Posts: 234
|
Posted: 2005-03-14 12:06 pm Post subject: |
|
|
Hi George,
It can get overwhelming - projects like that can easily go from a simple demo to a laundry list of impossible tasks. Cut back to what you said in the first place. Pick the one feature you're trying to make work and evaluate the app against that. If it's anything to do with physics (collision detection, gravity, etc) write it out on paper. Draw out all the important facts and work through the math. Having sketches of all the important details gives you something to reference when you're writing code and also tells you how to know it's really working. The best results I've gotten on projects like that always start on paper.
Good luck _________________ Late Night PC |
|
| Back to top |
|
 |
Jeff Site Admin
Joined: 26 Apr 2004 Posts: 356
|
Posted: 2005-03-14 9:29 pm Post subject: |
|
|
Hi George,
Sorry, I was out of town for a few days and I just saw this thread (actually on another forum that you posted on too when checking my server logs).
Even simple collision detection with pure horizontal/vertical walls can be quite challenging mathematically. The reason Rob and I aren't giving you the answer is because we don't really know it and trying to work it out would be time-consuming (but that's what programming games is all about).
Rob's suggestion is a good one though, draw it out on paper. Use geometry that you're learning in school to help you.
Here's some notes that might help you:
- the ball has position x,y and radius r
- each "tick" of the game clock (i.e. "dt") the ball is moving along the velocity vector (vx, vy). So every tick, x = x + vx, etc.
- what you want to know is between Time T and Time T+dt if the ball would have collided with any walls. What this means is do any of the following points land inside a square with a wall: (x-r,y-r), (x-r,y+r), (x+r,y-r), (x+r,y+r)
If your game "tick" is small enough, this might work just as is, but if your ball can travel at different speeds (and might go across more than 1 square a "tick") then you will have to do something fancier.
Anyway, see if you can get the above working first. That is, any time a ball would have collided with a wall pause the game until you press a key (or do something that proves it works). This allows you to prove that you've got the collision detection part working correctly.
Next, you would move on to the collision response part (that would be where you change the ball's direction and adjust its position where it should have bounced, etc).
Regards,
Jeff |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|