Jump to content

  • Log In with Google      Sign In   
  • Create Account

SDL - 2D Collision/Random Coordinates bug


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
8 replies to this topic

#1 selve   Members   -  Reputation: 145

Like
0Likes
Like

Posted 03 November 2012 - 06:14 AM

Hi guys. Recently I started learning SDL. I wrote something like "Pickin' sticks". The only thing that's not working is I think the collision or maybe random coordinates of food. It is like this - I launch the game, pick some food (moving by arrows) and it's counting by int foodamount (you can see on the screen). Sometimes it works - I get +1 to foodamount and there's a single sound crunch. However sometimes when I try to pick it up, the sound of crunch is repeating and repeating, food appears in the same place on the floor, the foodamount counter rises from 5 to 300. I don't know how to fix this. I would be really grateful if you can help me. Screens are under the code. Here's the code (the code fuction didn't work for me on the forum):

#include "SDL/SDL.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"
#include "SDL/SDL_image.h"
#include <windows.h>
#include <stdbool.h>
#define randx rand()*100%1175
#define randy rand()*100%585
SDL_Surface * background;
SDL_Surface * player;
SDL_Surface * screen;
//ITEMS
SDL_Surface * hamburger;
SDL_Surface * banana;
SDL_Surface * fries;
SDL_Surface * donut;
SDL_Surface * cake;
SDL_Surface * item;
//ITEMS
SDL_Surface * koniec;
SDL_Event event;
SDL_Rect playerlocation;
//ITEMS LOCATIONS
SDL_Rect hamburgerlocation;
SDL_Rect bananalocation;
SDL_Rect frieslocation;
SDL_Rect donutlocation;
SDL_Rect cakelocation;
SDL_Rect itemlocation;
//ITEMS LOCATIONS
int fullscreen = 0;
int randomfood;
int foodamount;
void putfood()
{
srand( time( NULL ) );
int itemx,itemy;
itemx = randx;
itemy = randy;
randomfood = (rand()%(5+1)) + 1;
if(randomfood == 1)
{
hamburgerlocation.x = itemx;
hamburgerlocation.y = itemy;
hamburgerlocation.w = 40;
hamburgerlocation.h = 40;
item = hamburger;
itemlocation = hamburgerlocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 2)
{
bananalocation.x = itemx;
bananalocation.y = itemy;
bananalocation.w = 40;
bananalocation.h = 40;
item = banana;
itemlocation = bananalocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 3)
{
frieslocation.x = itemx;
frieslocation.y = itemy;
frieslocation.w = 40;
frieslocation.h = 40;
item = fries;
itemlocation = frieslocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 4)
{
donutlocation.x = itemx;
donutlocation.y = itemy;
donutlocation.w = 40;
donutlocation.h = 40;
item = donut;
itemlocation = donutlocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 5)
{
cakelocation.x = itemx;
cakelocation.y = itemy;
cakelocation.w = 40;
cakelocation.h = 40;
item = cake;
itemlocation = cakelocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
}
int collision(SDL_Rect* rect1,SDL_Rect* rect2)
{
if(rect1->y >= rect2->y + rect2->h)
return 0;
if(rect1->x >= rect2->x + rect2->w)
return 0;
if(rect1->y + rect1->h <= rect2->y)
return 0;
if(rect1->x + rect1->w <= rect2->x)
return 0;
return 1;
}
bool checkCollision(SDL_Rect *player, SDL_Rect *obj)
{
if(player->x < obj->x + obj->w && player->x + player->w > obj->x && player->y < obj->y + obj->h && player->y + player->h > obj->y)
{
return true;
}
else
{
return false;
}
}
int main(int argc, char * args[])
{
bool jump = false;
Mix_OpenAudio(22050,MIX_DEFAULT_FORMAT,2,4096);
Mix_Chunk *eat = Mix_LoadWAV("sound/eat.wav");
Mix_Chunk *intro = Mix_LoadWAV("sound/layout.wav");
Mix_Chunk *step = Mix_LoadWAV("sound/step.wav");
Mix_VolumeChunk(intro, 64);
Mix_VolumeChunk(step, 10);
Mix_VolumeChunk(eat, 70);
Mix_PlayChannel(-1, intro, 0);
int x,y;
int exit = 0;
SDL_Init(SDL_INIT_EVERYTHING);
background = IMG_Load("images/grass.jpg");
player = IMG_Load("images/player.png");
screen = SDL_SetVideoMode(1280,720,32,SDL_DOUBLEBUF|SDL_SWSURFACE);
//items
hamburger = IMG_Load("images/food.png");
banana = IMG_Load("images/banana.png");
fries = IMG_Load("images/fries.png");
donut = IMG_Load("images/donut.png");
cake = IMG_Load("images/cake.png");
//items
koniec = SDL_LoadBMP("images/koniec.bmp");
SDL_WM_SetCaption("Program testowy SDL v2 (by Selve)", NULL);
Uint8 * keystate = SDL_GetKeyState( NULL );
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_Flip(screen);
x = 500;
y = 250;
playerlocation.w = 40;
playerlocation.h = 40;
playerlocation.x = x;
playerlocation.y = y;
TTF_Init();
TTF_Font * font = TTF_OpenFont("font/font.ttf", 45);
SDL_Surface * text;
SDL_Color text_color = {255, 255, 255};
char buf[50];
sprintf(buf, "Food amount: %d", foodamount);
SDL_Surface * textSurface = TTF_RenderText_Solid(font, buf, text_color);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
SDL_Flip(screen);
putfood();
while (exit == 0)
{
char buf[50];
sprintf(buf, "Food amount: %d", foodamount);
SDL_Surface * textSurface = TTF_RenderText_Solid(font, buf, text_color);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
SDL_Quit();
return 0;
}
if(event.type == SDL_KEYDOWN)
{
if(event.key.keysym.sym == SDLK_q)
{
SDL_FreeSurface(background);
SDL_Flip( screen );
Mix_CloseAudio();
SDL_BlitSurface( koniec, NULL, screen, NULL );
SDL_Flip( screen );
SDL_Delay(2500);
SDL_Quit();
return 0;
}
if(event.key.keysym.sym == SDLK_RETURN && fullscreen == 0)
{
SDL_SetVideoMode( 1280, 720, 32, SDL_DOUBLEBUF|SDL_SWSURFACE|SDL_FULLSCREEN);
fullscreen = 1;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(player, NULL, screen, &playerlocation);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_Flip( screen );
break;
}
if(event.key.keysym.sym == SDLK_RETURN && fullscreen == 1)
{
SDL_SetVideoMode( 1280, 720, 32, SDL_DOUBLEBUF|SDL_SWSURFACE );
fullscreen = 0;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(player, NULL, screen, &playerlocation);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_Flip( screen );
break;
}
}
}
if(keystate[SDLK_RIGHT])
{
if(playerlocation.x < 1175)
{
playerlocation.x = playerlocation.x + 4;
Mix_PlayChannel(-1, step, 0);
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
if(keystate[SDLK_LEFT])
{
if(playerlocation.x > 10)
{
Mix_PlayChannel(-1, step, 0);
playerlocation.x = playerlocation.x - 4;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
if(keystate[SDLK_UP])
{
if(playerlocation.y > 10)
{
Mix_PlayChannel(-1, step, 0);
playerlocation.y = playerlocation.y - 4;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
if(keystate[SDLK_DOWN])
{
if(playerlocation.y < 585)
{
Mix_PlayChannel(-1, step, 0);
playerlocation.y = playerlocation.y + 4;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
SDL_BlitSurface(player, NULL, screen, &playerlocation);
SDL_Flip(screen);
if(checkCollision(&playerlocation, &itemlocation))
{
putfood();
Mix_PlayChannel(1, eat, 0);
foodamount++;
}
}
}

Here's the photos:
Posted Image
And next:
Posted Image

Edited by selve, 03 November 2012 - 06:28 AM.


Sponsor:

#2 RulerOfNothing   Members   -  Reputation: 1164

Like
1Likes
Like

Posted 03 November 2012 - 04:40 PM

You only need to call srand(time(NULL)) once, not every time you want to generate random numbers.

#3 selve   Members   -  Reputation: 145

Like
0Likes
Like

Posted 03 November 2012 - 06:32 PM

Great, thanks man. But the problem still appears. Instead of adding +300 to int foodamount, it sometimes adds +2 or +3 to that. What's the problem now?
Edit. Or maybe random coordinates causes food to appear in 3 similar places.

Edited by selve, 03 November 2012 - 06:52 PM.


#4 BeerNutts   Crossbones+   -  Reputation: 3000

Like
1Likes
Like

Posted 03 November 2012 - 06:49 PM

Please use the code tags.
#include "SDL/SDL.h"
#include "SDL/SDL_ttf.h"
#include "SDL/SDL_mixer.h"
#include "SDL/SDL_image.h"
#include <windows.h>
#include <stdbool.h>
#define randx rand()*100%1175
#define randy rand()*100%585
SDL_Surface * background;
SDL_Surface * player;
SDL_Surface * screen;
//ITEMS
SDL_Surface * hamburger;
SDL_Surface * banana;
SDL_Surface * fries;
SDL_Surface * donut;
SDL_Surface * cake;
SDL_Surface * item;
//ITEMS
SDL_Surface * koniec;
SDL_Event event;
SDL_Rect playerlocation;
//ITEMS LOCATIONS
SDL_Rect hamburgerlocation;
SDL_Rect bananalocation;
SDL_Rect frieslocation;
SDL_Rect donutlocation;
SDL_Rect cakelocation;
SDL_Rect itemlocation;
//ITEMS LOCATIONS
int fullscreen = 0;
int randomfood;
int foodamount;
void putfood()
{
srand( time( NULL ) );
int itemx,itemy;
itemx = randx;
itemy = randy;
randomfood = (rand()%(5+1)) + 1;
if(randomfood == 1)
{
hamburgerlocation.x = itemx;
hamburgerlocation.y = itemy;
hamburgerlocation.w = 40;
hamburgerlocation.h = 40;
item = hamburger;
itemlocation = hamburgerlocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 2)
{
bananalocation.x = itemx;
bananalocation.y = itemy;
bananalocation.w = 40;
bananalocation.h = 40;
item = banana;
itemlocation = bananalocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 3)
{
frieslocation.x = itemx;
frieslocation.y = itemy;
frieslocation.w = 40;
frieslocation.h = 40;
item = fries;
itemlocation = frieslocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 4)
{
donutlocation.x = itemx;
donutlocation.y = itemy;
donutlocation.w = 40;
donutlocation.h = 40;
item = donut;
itemlocation = donutlocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
if(randomfood == 5)
{
cakelocation.x = itemx;
cakelocation.y = itemy;
cakelocation.w = 40;
cakelocation.h = 40;
item = cake;
itemlocation = cakelocation;
SDL_BlitSurface(item, NULL, screen, &itemlocation);
//SDL_Flip(screen);
}
}
int collision(SDL_Rect* rect1,SDL_Rect* rect2)
{
if(rect1->y >= rect2->y + rect2->h)
return 0;
if(rect1->x >= rect2->x + rect2->w)
return 0;
if(rect1->y + rect1->h <= rect2->y)
return 0;
if(rect1->x + rect1->w <= rect2->x)
return 0;
return 1;
}
bool checkCollision(SDL_Rect *player, SDL_Rect *obj)
{
if(player->x < obj->x + obj->w && player->x + player->w > obj->x && player->y < obj->y + obj->h && player->y + player->h > obj->y)
{
return true;
}
else
{
return false;
}
}
int main(int argc, char * args[])
{
bool jump = false;
Mix_OpenAudio(22050,MIX_DEFAULT_FORMAT,2,4096);
Mix_Chunk *eat = Mix_LoadWAV("sound/eat.wav");
Mix_Chunk *intro = Mix_LoadWAV("sound/layout.wav");
Mix_Chunk *step = Mix_LoadWAV("sound/step.wav");
Mix_VolumeChunk(intro, 64);
Mix_VolumeChunk(step, 10);
Mix_VolumeChunk(eat, 70);
Mix_PlayChannel(-1, intro, 0);
int x,y;
int exit = 0;
SDL_Init(SDL_INIT_EVERYTHING);
background = IMG_Load("images/grass.jpg");
player = IMG_Load("images/player.png");
screen = SDL_SetVideoMode(1280,720,32,SDL_DOUBLEBUF|SDL_SWSURFACE);
//items
hamburger = IMG_Load("images/food.png");
banana = IMG_Load("images/banana.png");
fries = IMG_Load("images/fries.png");
donut = IMG_Load("images/donut.png");
cake = IMG_Load("images/cake.png");
//items
koniec = SDL_LoadBMP("images/koniec.bmp");
SDL_WM_SetCaption("Program testowy SDL v2 (by Selve)", NULL);
Uint8 * keystate = SDL_GetKeyState( NULL );
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_Flip(screen);
x = 500;
y = 250;
playerlocation.w = 40;
playerlocation.h = 40;
playerlocation.x = x;
playerlocation.y = y;
TTF_Init();
TTF_Font * font = TTF_OpenFont("font/font.ttf", 45);
SDL_Surface * text;
SDL_Color text_color = {255, 255, 255};
char buf[50];
sprintf(buf, "Food amount: %d", foodamount);
SDL_Surface * textSurface = TTF_RenderText_Solid(font, buf, text_color);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
SDL_Flip(screen);
putfood();
while (exit == 0)
{
char buf[50];
sprintf(buf, "Food amount: %d", foodamount);
SDL_Surface * textSurface = TTF_RenderText_Solid(font, buf, text_color);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
SDL_Quit();
return 0;
}
if(event.type == SDL_KEYDOWN)
{
if(event.key.keysym.sym == SDLK_q)
{
SDL_FreeSurface(background);
SDL_Flip( screen );
Mix_CloseAudio();
SDL_BlitSurface( koniec, NULL, screen, NULL );
SDL_Flip( screen );
SDL_Delay(2500);
SDL_Quit();
return 0;
}
if(event.key.keysym.sym == SDLK_RETURN && fullscreen == 0)
{
SDL_SetVideoMode( 1280, 720, 32, SDL_DOUBLEBUF|SDL_SWSURFACE|SDL_FULLSCREEN);
fullscreen = 1;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(player, NULL, screen, &playerlocation);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_Flip( screen );
break;
}
if(event.key.keysym.sym == SDLK_RETURN && fullscreen == 1)
{
SDL_SetVideoMode( 1280, 720, 32, SDL_DOUBLEBUF|SDL_SWSURFACE );
fullscreen = 0;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(player, NULL, screen, &playerlocation);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_Flip( screen );
break;
}
}
}
if(keystate[SDLK_RIGHT])
{
if(playerlocation.x < 1175)
{
playerlocation.x = playerlocation.x + 4;
Mix_PlayChannel(-1, step, 0);
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
if(keystate[SDLK_LEFT])
{
if(playerlocation.x > 10)
{
Mix_PlayChannel(-1, step, 0);
playerlocation.x = playerlocation.x - 4;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
if(keystate[SDLK_UP])
{
if(playerlocation.y > 10)
{
Mix_PlayChannel(-1, step, 0);
playerlocation.y = playerlocation.y - 4;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
if(keystate[SDLK_DOWN])
{
if(playerlocation.y < 585)
{
Mix_PlayChannel(-1, step, 0);
playerlocation.y = playerlocation.y + 4;
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_BlitSurface(item, NULL, screen, &itemlocation);
SDL_BlitSurface(textSurface, NULL, screen, NULL);
}
}
SDL_BlitSurface(player, NULL, screen, &playerlocation);
SDL_Flip(screen);
if(checkCollision(&playerlocation, &itemlocation))
{
putfood();
Mix_PlayChannel(1, eat, 0);
foodamount++;
}
}
}

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

#5 BeerNutts   Crossbones+   -  Reputation: 3000

Like
1Likes
Like

Posted 03 November 2012 - 06:55 PM

WHat happens when you run over food, and you "randomly" select the same food again? What if it randomly keeps picking the same food that you've collided with?

That's what is happening, specifically because u srand() in putfood (it should only be done at the start of the program), but , even so, there's a chance it will select the same food you've just collided with (which would cause you to continue to collide with it).

I would suggest making sure you don't choose the same food that was just being shown. Just add a check if randfood is the last randfood, just add 1 to new randfood.
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

#6 selve   Members   -  Reputation: 145

Like
0Likes
Like

Posted 03 November 2012 - 07:28 PM

The whole map is 1280x720, so adding 1 to it will I think don't work. I just want that if the food spawns, and after I picked it up, it is checking, if the difference between new x, old x, new y, old y is more than for example 100. If not, take another random. Is that possible?

#7 RulerOfNothing   Members   -  Reputation: 1164

Like
1Likes
Like

Posted 03 November 2012 - 07:49 PM

That is possible:
do
{
itemx=randx;
itemy=randy;
}
while(abs(oldx-itemx)<100||abs(oldy-itemy)<100)
oldx=itemx;
oldy=itemy;
when you want to generate a new location (abs is a function that returns the absolute value of its parameter). You will need to make oldx and oldy either global variables or static variables so that they retain their values between calls to putfood.

#8 BeerNutts   Crossbones+   -  Reputation: 3000

Like
1Likes
Like

Posted 03 November 2012 - 07:56 PM

The whole map is 1280x720, so adding 1 to it will I think don't work. I just want that if the food spawns, and after I picked it up, it is checking, if the difference between new x, old x, new y, old y is more than for example 100. If not, take another random. Is that possible?


I meant add one to the random food index, not the coordinate. It's not the best solution, as you can do what RulerOfNothing suggested. Regardless, you get the point.
My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

#9 selve   Members   -  Reputation: 145

Like
0Likes
Like

Posted 03 November 2012 - 08:06 PM

Ok, thank you both guys ;)




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS