GPWiki.org
GPWiki.org
It is currently Wed Jun 19, 2013 5:55 am

All times are UTC




Post new topic Reply to topic  [ 19 posts ] 
Author Message
PostPosted: Wed May 23, 2012 3:17 pm 
Hi!

I'm new to this forum and need help for my breakout (destroy all bricks) game. the problem i'm having is that it wont update all the time, a video i made to show how it works:
http://www.youtube.com/watch?v=lKRAMHeY ... ature=plcp
here is my collision code:
Code:
        public void colballblockdown() {
            for (int n = 0; n < 40; n++)
            {
                if (ballpos.X >= blockpos[n].X - balltex.Width &&
                    ballpos.X <= blockpos[n].X + blocktex[n].Width &&
                    ballpos.Y == blockpos[n].Y + blocktex[n].Height)
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    up = false;
                }
                if (ballpos.Y >= blockpos[n].Y + balltex.Height &&
                    ballpos.Y <= blockpos[n].Y + blocktex[n].Height &&
                    ballpos.X == blockpos[n].X + blocktex[n].Width
                    )
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    left = false;
                }
                if (ballpos.X >= blockpos[n].X - balltex.Width &&
                    ballpos.X <= blockpos[n].X + blocktex[n].Width &&
                    ballpos.Y == blockpos[n].Y - balltex.Height)
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    up = true;
                }
                if (ballpos.Y >= blockpos[n].Y + balltex.Height &&
                    ballpos.Y <= blockpos[n].Y + blocktex[n].Height &&
                    ballpos.X == blockpos[n].X - balltex.Width)
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    left = true;
                }
            }

blockpos/blocktex are arrays so i think i need to make a for-loop or foreach-loop to check all the values.
ballpos/balltex
IsVisible is a boolean, if it's false it wont draw the image on the screen.
left and up is the direction as a boolean.

the method is called inside the update method. ( colballblockdown(); )


Top
  
 
PostPosted: Wed May 23, 2012 8:57 pm 
Grand Optimizer
User avatar

Joined: Mon Jan 17, 2005 6:01 pm
Posts: 353
Location: Canada
i had a look at the video..

so the ball is destroying the blocks sometimes but not other times?

I noticed that in your collision code, your checking whether or not the ball's X is greater than the block's X and smaller than the blocks (X + width).. thats all well and good, but you've got another condition in there ("ballpos.Y == blockpos[n].Y + blocktex[n].Height) stipulating that in order to satisfy the IF statement, the ball's Y value must EXACTLY match the block's Y value (+ the height).. that won't happen very often, because unless your ball position updates are literally +1, +1, +1, you're going to skip over that exact point almost all of the time. You might be better off specifying the full range in the 2nd axis to determine proper collision.

Maybe when im not as tired later il look it over again in more detail, but for now it just looks like you need more robust collision detection logic.
Hope this helps..

_________________
"None are more hopelessly enslaved than those who falsely believe they are free."
"It is no measure of health to be well adjusted to a profoundly sick society."
"Hope is the first step on the road to dissapointment." -Jonah Orion
http://tankzgame.blogspot.com


Top
 Profile  
 
PostPosted: Thu May 24, 2012 5:10 am 
So i changed the code a little bit and it look like this right now:
Code:
public void colballblockdown() {
            for (int n = 0; n < 40; n++)
            {
                if (ballpos.X >= blockpos[n].X - balltex.Width &&
                    ballpos.X <= blockpos[n].X + blocktex[n].Width &&
                    ballpos.Y <= blockpos[n].Y + blocktex[n].Height&&
                    ballpos.Y >= blockpos[n].Y + blocktex[n].Height-4)
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    up = false;
                }
                if (ballpos.Y >= blockpos[n].Y + balltex.Height &&
                    ballpos.Y <= blockpos[n].Y + blocktex[n].Height &&
                    ballpos.X <= blockpos[n].X + blocktex[n].Width&&
                    ballpos.X >= blockpos[n].X + blocktex[n].Width-4)
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    left = false;
                }
                if (ballpos.X >= blockpos[n].X - balltex.Width &&
                    ballpos.X <= blockpos[n].X + blocktex[n].Width &&
                    ballpos.Y >= blockpos[n].Y - balltex.Height&&
                    ballpos.Y <= blockpos[n].Y -balltex.Height+4)
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    up = true;
                }
                if (ballpos.Y >= blockpos[n].Y + balltex.Height &&
                    ballpos.Y <= blockpos[n].Y + blocktex[n].Height &&
                    ballpos.X >= blockpos[n].X - balltex.Width &&
                    ballpos.X <= blockpos[n].X - balltex.Width +4)
                {
                    IsVisible[n] = false;
                    blockpos[n].Y = -100;
                    blockpos[n].X = -100;
                    left = true;
                }
            }
        }


it still doesn't work like i want, the ball go through the block sometime and sometime it works great, but it works better. I've also tried other values that i add (now im using 4, ive tried 5,6,7 but nothing works, the ball speed is 4)tell me if you want the whole code or a video of it to see how it works.

I forgot to say that I'm coding in Xna.


Top
  
 
PostPosted: Thu May 24, 2012 12:10 pm 
Im at work atm, so i cant look too deep, but i think I see another problem.

XNA works like this:

X axis: Left = 0, right = high.
Y axis: Top = 0, bottom = high.

the X,Y coord of an object in XNA is the TOP LEFT corner.

if (ballpos.X >= blockpos[n].X - balltex.Width &&
ballpos.X <= blockpos[n].X + blocktex[n].Width &&
ballpos.Y <= blockpos[n].Y + blocktex[n].Height&&
ballpos.Y >= blockpos[n].Y + blocktex[n].Height-4)

If you look closely at your code, you're checking if the ball's X is larger than the blocks position(Minus the width!)!
You're checking for collision on a block that isn't there, and applying it to the current block.

Try something like

if ballpos.X >= blockpos[n].X && ballpos.X <= (blockpos[n].X + blocktex[n].Width)

you shouln't need to check with minuses until your checking the Y axis.. something like:
if (ballpos.X >= blockpos[n].X - balltex.Width &&
ballpos.X <= blockpos[n].X + blocktex[n].Width &&
ballpos.Y <= blockpos[n].Y + blocktex[n].Height&&
ballpos.Y >= blockpos[n].Y + blocktex[n].Height-4)
is ballpos.Y greater than blockpos.Y AND is ballpos.Y smaller than (blockpos.Y + blocktex.width)

hope this helps


Top
  
 
PostPosted: Thu May 24, 2012 12:13 pm 
arg. stupid firefox. disregard THIS chunk near the bottom of my last post:
if (ballpos.X >= blockpos[n].X - balltex.Width &&
ballpos.X <= blockpos[n].X + blocktex[n].Width &&
ballpos.Y <= blockpos[n].Y + blocktex[n].Height&&
ballpos.Y >= blockpos[n].Y + blocktex[n].Height-4)


Top
  
 
PostPosted: Thu May 24, 2012 12:21 pm 
Oh yeah, one other thing. What you've got going on there is point vs rectangle collision.. what you want is actually rect vs rect, but il dive deeper in to that later.


Top
  
 
PostPosted: Thu May 24, 2012 1:11 pm 
not being logged in sucks, cant edit posts.
disregard the thing about point vs rect.


Top
  
 
PostPosted: Thu May 24, 2012 2:47 pm 
NotLoggedInATM wrote:
Im at work atm, so i cant look too deep, but i think I see another problem.

XNA works like this:

X axis: Left = 0, right = high.
Y axis: Top = 0, bottom = high.

the X,Y coord of an object in XNA is the TOP LEFT corner.

if (ballpos.X >= blockpos[n].X - balltex.Width &&
ballpos.X <= blockpos[n].X + blocktex[n].Width &&
ballpos.Y <= blockpos[n].Y + blocktex[n].Height&&
ballpos.Y >= blockpos[n].Y + blocktex[n].Height-4)

If you look closely at your code, you're checking if the ball's X is larger than the blocks position(Minus the width!)!
You're checking for collision on a block that isn't there, and applying it to the current block.

Try something like

if ballpos.X >= blockpos[n].X && ballpos.X <= (blockpos[n].X + blocktex[n].Width)

you shouln't need to check with minuses until your checking the Y axis.. something like:
if (ballpos.X >= blockpos[n].X - balltex.Width &&
ballpos.X <= blockpos[n].X + blocktex[n].Width &&
ballpos.Y <= blockpos[n].Y + blocktex[n].Height&&
ballpos.Y >= blockpos[n].Y + blocktex[n].Height-4)
is ballpos.Y greater than blockpos.Y AND is ballpos.Y smaller than (blockpos.Y + blocktex.width)

hope this helps


but if i don't use the balltex.Width/balltex.Height the ball wont collide at some points
picture:
Image
just pretend that the ball is just going horizontal, then the ball wont hit the block in this case if you code like you posted.


Top
  
 
PostPosted: Thu May 24, 2012 4:42 pm 
Which is why you need to make sure your comparing the ball's rect to the block's rect. If all you're comparing is the ball's X,Y, youl run into the problem you just illustrated.

Ok I had it right in the first place, lol. You're apparently doing point vs rect. you need rect vs rect. (basic "Rectangular Collision")

Theres lots of tutorials out there for basic rectangular collision.. but if memory serves, it goes something like this:

Are they overlapping horizontally?
are they overlapping vertically?

if the ball's left side(x) is larger than the block's left(x) AND smaller than the blocks right (x.width) OORRRRR if the right side (ball.x +ballwidth) is doing the same, you're overlapping horizontally

if the balls top(y) is larger than the blocks top(y) AND smaller than the blocks bottom (y.height), OOORRRRR if the ball's bottom is doing the same, you're overlapping vertically

if you're overlapping on both axes, you have a collision

this is just off the top of my head, i can dig out the proper logic when i get home.


Top
  
 
PostPosted: Fri May 25, 2012 4:48 am 
Level 1 Cleric

Joined: Thu May 24, 2012 2:33 pm
Posts: 13
Do I need the change my position variable to Rectangle then? I'm using Vector2 to position the blocks,ball and player right now.


Top
 Profile  
 
PostPosted: Fri May 25, 2012 11:59 am 
You can use RECTs if you want, they're handy and elegant. But the way you have it setup will still work, it's just that you're considering all four corners of your blocks but only one corner of your ball.

The same way you have "block.x + width, block.Y + height" and all that, set the same thing up for your ball.

So again, if one of the ball's sides is between the blocks left and right, there's horizontal collision.
If the ball's top or bottom is between the block's top or bottom, there's vertical collision.
If you have collisions on both axes, you have an actual collision.


Top
  
 
PostPosted: Fri May 25, 2012 4:58 pm 
Level 1 Cleric

Joined: Thu May 24, 2012 2:33 pm
Posts: 13
I still can't make it work I've tried some other things but it doesn't work. it seems to always work when the bottom of the block collides with the top of the ball but not always on the sides (it collides sometimes on the sides) . So i have no idea how i can make this work I think i followed your tips right but it wouldn't work for me...
also do you have a tutorial to make collisions with arrays, that is simple to follow?


Top
 Profile  
 
PostPosted: Fri May 25, 2012 5:24 pm 
The top of the ball collisio wil work because the X,Y co-ord of the ball is the top left. You essentially need to check all four corners of your ball, not just the top left(x,y)


Top
  
 
PostPosted: Fri May 25, 2012 6:37 pm 
Bibliotherapist
User avatar

Joined: Wed Nov 03, 2004 1:28 pm
Posts: 6751
Location: Oxford, Englandshire
Haven't done this for a while, but my rect collision code was something along the lines of:

Code:
if (Ball.top > Brick.bottom) // If this is false, you can pretty much skip the rest of the bricks in this row. The ball isn't as high as this row.
{
   if (Ball.bottom < Brick.top) // Again, if this is false, the ball has gone beyond this row. No point checking anything else at the same level.
   {
      if (Ball.left < Brick.right && Ball.right > Brick.left)
      {
         CollideFunc();  // We've hit!
      }
   }
}


If I've remembered that right, CollideFunc() should be called when ever there's an overlap between the Ball and Brick rects.

For an array of bricks, just index through Brick rects checking each one against the Ball rect.

You can save a bunch of checks if you test for the vertical collision first and ignore the rest of the row if the ball isn't overlapping the Brick.top/Brick.bottom range of the first brick in the row.

Hope that's clear enough.

_________________
10 PRINT "Bad Monkey ";
20 GOTO 10


Top
 Profile  
 
PostPosted: Fri May 25, 2012 10:05 pm 
Level 1 Cleric

Joined: Thu May 24, 2012 2:33 pm
Posts: 13
I actually made new variables to declare the ball width position and the same with the player and blocks and now its working like i want. i probably messed something up before. Bibliotherapist actually inspired me to do it when you/he/she wrote ball.top, block.bottom etc, i just thought I could make a variable that hold the width, height position instead of blockpos.X + blocktex.Width all the time. Thanks everyone that helped me with this.


Top
 Profile  
 
PostPosted: Sat May 26, 2012 12:01 am 
Grand Optimizer
User avatar

Joined: Mon Jan 17, 2005 6:01 pm
Posts: 353
Location: Canada
Did you end up getting it working the way you wanted?

Codehead worded it very well in his solution, he said it more elegantly than I did. You can do it with RECTs, or with straight X,Ys. The key is to make sure your comparing all four sides to all four sides of the other object, not just point-to-rect.

_________________
"None are more hopelessly enslaved than those who falsely believe they are free."
"It is no measure of health to be well adjusted to a profoundly sick society."
"Hope is the first step on the road to dissapointment." -Jonah Orion
http://tankzgame.blogspot.com


Top
 Profile  
 
PostPosted: Sat May 26, 2012 8:30 am 
Level 1 Cleric

Joined: Thu May 24, 2012 2:33 pm
Posts: 13
yes it works like i wanted right now. but thanks for trying to help me :D


Top
 Profile  
 
PostPosted: Wed Oct 10, 2012 3:54 am 
Rookie

Joined: Wed Oct 10, 2012 2:40 am
Posts: 3
What you want is in fact correct and right, but Kim Jong-depth later.

_________________
My doctor gave me six months to live, but when I couldn't pay the bill, he gave me six months more.


Top
 Profile  
 
PostPosted: Wed Jun 05, 2013 4:08 pm 
Rookie

Joined: Wed Jun 05, 2013 1:57 pm
Posts: 1
If you are using XNA, and you have the ball's collision rectangle stored as an XNA Rectangle struct (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.rectangle(v=xnagamestudio.35).aspx), and likewise the brick, you can just use Rectangle.Intersects, like so:

Code:
if (Brick.Intersects(Ball)) //Do something


Assuming Brick is the brick's rectangle, and Ball is the ball's rectangle.

Sure, there are ways to make it more efficient, but for Breakout, you simply do not need that efficiency. A game-programmer operating solo has to optimize not only for speed of execution and memory consumed, but also time he spends coding.


Last edited by IGTHORN on Sat Jun 15, 2013 9:54 pm, edited 1 time in total.
fixed url


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group