VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
Go Back  Xtreme Visual Basic Talk > > > VB2008 - Space Invader Collision Detection


Reply
 
Thread Tools Display Modes
  #1  
Old 12-28-2010, 04:53 PM
uniquex217 uniquex217 is offline
Newcomer
 
Join Date: Dec 2010
Posts: 9
Question VB2008 - Space Invader Collision Detection


Okay, i've looked up several tutorials on what i should do to create a collision detection, but im not too positive on how to function my ideas and convert them to code.
Basically, i'm creating a space invaders like-game that is 2D Mario-themed (sprites used).
I am using a panel for my enemies and Mario is being controlled by the movement of arrow keys and space button shoots.
The problem is I can not make my bullets collide with the enemies to make them disappear.

This piece of code is what i've got so far with the collision detection :
Code:
    '*******************************************************************************************************************************************************
    '   Collision occurs whenever the pctShoot(podoboo) hits any of the enemy
    '   When blnTrue, both pctShoot and the enemy disappear
    '*******************************************************************************************************************************************************

    Private Sub tmrCollisionDetect_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrCollisionDetect.Tick
        '****************************************************************************************
        'Current method using; no collision occurs
        'not positive on what ctlEnemy is suppose to be (a single picturebox or the panel (?))
        'purpose of the tags are like "health" when they reach to zero, enemy disappears
        '   ->purpose of this function is to help the timing issue 
        'time interval set to 1
        '***************************************************************************************

        Dim rect As New Rectangle
        Dim intScore As Integer
        Dim ctlEnemy As Control = pctKoopa1


        For Each c As Control In pnlEnemies.Controls 'all picture boxes in the panel are controlled  

            If TypeOf c Is PictureBox Then  'and "c" is a picture box in the panel

                If pnlEnemies.Visible = True AndAlso pctBullet.Visible = True AndAlso rect.IntersectsWith(pctBullet.Bounds) Then
                    pnlEnemies.Tag = CType(pnlEnemies.Tag, Integer) - 1 'converts the tag to integer to claim an enemies "health"
                    blnCollison = True 'collision happens
                    pctBullet.Visible = False 'bullet disappears

                    If CInt(pnlEnemies.Tag) <= 0 Then 'when enemies health reaches 0 or lower
                        blnCollison = True 'collision activated
                        c.Visible = False 'enemy disappears
                        intScore = intScore + 100 'score accumulated by 100
                    End If
                End If
            End If

        Next
        Me.lblScore.Text = intScore 'score becomes updated


        '*****************************************************************************************
        'Last method used, it works but when playing, the bullet doesn't hit exactly on the enemy
        '   -> bullet hits enemy from one side, the collision occurs on the opposite side
        '   ->said to be due to a timing issue
        '*****************************************************************************************

        'For Each c As Control In pnlEnemies.Controls 'all picture boxes in the panel are controlled

        '    If TypeOf c Is PictureBox Then
        '        If pctBullet.Visible And c.Visible Then
        '            If c.Bounds.IntersectsWith(pctBullet.Bounds) Then
        '                blnCollison = True 'Collsion is true
        '                c.Visible = False
        '            Else
        '                blnCollison = False
        '                c.Visible = True
        '            End If
        '        End If
        '    End If
        'Next
    End Sub
While I'm at it, i have another question in concern; but this is not really related to collision but:
How do you make an object move down automatically using a timer but make it appear randomly??
Like any space invader game, the enemies are shooting back at the hero to make it appear more challenging right?

Any help is appreciative! Please and THANK YOUS IN ADVANCE!
(using Visual Basic 2008)

EDIT: If you want me to post my full code, i can save it as a Notepad (or post here), to understand how im creating this game overall. Im a real newbie in Visual Basic. Who knows, maybe the problem to my collision is due to somewhere else in my code :/

Last edited by uniquex217; 12-28-2010 at 05:27 PM.
Reply With Quote
  #2  
Old 12-29-2010, 02:32 AM
ZaCkOX's Avatar
ZaCkOX ZaCkOX is offline
Contributor
 
Join Date: May 2006
Location: CA
Posts: 645
Default

Ya I think you have several problems (1 might be collision). I made some code for simple collision for a moving object: Problem is I only write with VB 6, but looking at this code can help you out.

Code:
Option Explicit 'Declare Speed Private sngObjectSpeed As Single Private Sub Form_Load() 'Announce Speed sngObjectSpeed = 300 End Sub Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) 'Check For Movement Select Case KeyCode Case 37 'Left Arrow If CollisionLeft = False Then shpObject.Left = shpObject.Left - sngObjectSpeed End If Case 38 'Up Arrow If CollisionUp = False Then shpObject.Top = shpObject.Top - sngObjectSpeed End If Case 39 'Right Arrow If CollisionRight = False Then shpObject.Left = shpObject.Left + sngObjectSpeed End If Case 40 'Down Arrow If CollisionDown = False Then shpObject.Top = shpObject.Top + sngObjectSpeed End If End Select 'Update Position In Label lblPosition.Caption = shpObject.Left & ", " & shpObject.Top End Sub Private Function CollisionLeft() As Boolean 'Declare Dim intNextNumber As Integer 'Check For Collision To The Left Of Object For intNextNumber = shpWall.LBound To shpWall.UBound If shpObject.Left - sngObjectSpeed < shpWall(intNextNumber).Left + shpWall(intNextNumber).Width _ And shpObject.Left + shpObject.Width > shpWall(intNextNumber).Left _ And shpObject.Top + shpObject.Height > shpWall(intNextNumber).Top _ And shpObject.Top < shpWall(intNextNumber).Top + shpWall(intNextNumber).Height Then If shpObject.Left <> shpWall(intNextNumber).Left + shpWall(intNextNumber).Width Then shpObject.Left = shpWall(intNextNumber).Left + shpWall(intNextNumber).Width End If CollisionLeft = True Exit Function End If Next 'Return Function CollisionLeft = False End Function Private Function CollisionRight() As Boolean 'Declare Dim intNextNumber As Integer 'Check For Collision To The Right Of Object For intNextNumber = shpWall.LBound To shpWall.UBound If shpObject.Left + shpObject.Width + sngObjectSpeed > shpWall(intNextNumber).Left _ And shpObject.Left < shpWall(intNextNumber).Left + shpWall(intNextNumber).Width _ And shpObject.Top + shpObject.Height > shpWall(intNextNumber).Top _ And shpObject.Top < shpWall(intNextNumber).Top + shpWall(intNextNumber).Height Then If shpObject.Left <> shpWall(intNextNumber).Left - shpObject.Width Then shpObject.Left = shpWall(intNextNumber).Left - shpObject.Width End If CollisionRight = True Exit Function End If Next 'Return Function CollisionRight = False End Function Private Function CollisionUp() As Boolean 'Declare Dim intNextNumber As Integer 'Check For Collision To The Upside Of Object For intNextNumber = shpWall.LBound To shpWall.UBound If shpObject.Top - sngObjectSpeed < shpWall(intNextNumber).Top + shpWall(intNextNumber).Height _ And shpObject.Top + shpObject.Height > shpWall(intNextNumber).Top _ And shpObject.Left + shpObject.Width > shpWall(intNextNumber).Left _ And shpObject.Left < shpWall(intNextNumber).Left + shpWall(intNextNumber).Width Then If shpObject.Top <> shpWall(intNextNumber).Top + shpWall(intNextNumber).Height Then shpObject.Top = shpWall(intNextNumber).Top + shpWall(intNextNumber).Height End If CollisionUp = True Exit Function End If Next 'Return Function CollisionUp = False End Function Private Function CollisionDown() As Boolean 'Declare Dim intNextNumber As Integer 'Check For Collision To The Downside Of Object For intNextNumber = shpWall.LBound To shpWall.UBound If shpObject.Top + shpObject.Height + sngObjectSpeed > shpWall(intNextNumber).Top _ And shpObject.Top < shpWall(intNextNumber).Top + shpWall(intNextNumber).Height _ And shpObject.Left + shpObject.Width > shpWall(intNextNumber).Left _ And shpObject.Left < shpWall(intNextNumber).Left + shpWall(intNextNumber).Width Then If shpObject.Top <> shpWall(intNextNumber).Top - shpObject.Height Then shpObject.Top = shpWall(intNextNumber).Top - shpObject.Height End If CollisionDown = True Exit Function End If Next 'Return Function CollisionDown = False End Function

4 functions for detecting collision with walls (rectangle or square like objects). If there is a collision the object will move up against the wall and can't move after that. You could alter that, instead have the bullet and object disappear at that point. But basically the same concept will apply. You will need 4 statements with AND because you need to check all 4 sides of a square in this type of collision. If you read the statements closely, you will notice it makes an area of a rectangular or square, this is the space an object cannot move into.

Also I sent an email with my channel, I have some videos for doing random numbers. Here is BillSoo's link to Random Numbers:

Random Numbers

Although this is VB 6 again, I believe this will still work for generating your random number.

I tried to make the collision as simple to understand as possible so I included a picture of an object moving left. Follow the numbers to these statements:

1. shpObject.Left - sngObjectSpeed < shpWall(intNextNumber).Left + shpWall(intNextNumber).Width

2. shpObject.Left + shpObject.Width > shpWall(intNextNumber).Left

3. shpObject.Top + shpObject.Height > shpWall(intNextNumber).Top

4. shpObject.Top < shpWall(intNextNumber).Top + shpWall(intNextNumber).Height

You'll notice this is the CollisionLeft Function:

Code:
Private Function CollisionLeft() As Boolean 'Declare Dim intNextNumber As Integer 'Check For Collision To The Left Of Object For intNextNumber = shpWall.LBound To shpWall.UBound If shpObject.Left - sngObjectSpeed < shpWall(intNextNumber).Left + shpWall(intNextNumber).Width _ And shpObject.Left + shpObject.Width > shpWall(intNextNumber).Left _ And shpObject.Top + shpObject.Height > shpWall(intNextNumber).Top _ And shpObject.Top < shpWall(intNextNumber).Top + shpWall(intNextNumber).Height Then If shpObject.Left <> shpWall(intNextNumber).Left + shpWall(intNextNumber).Width Then shpObject.Left = shpWall(intNextNumber).Left + shpWall(intNextNumber).Width End If CollisionLeft = True Exit Function End If Next 'Return Function CollisionLeft = False End Function
Attached Images
File Type: jpg CollisionLeft.JPG (6.5 KB, 7 views)
__________________
ZaCkO ... Who is your attitude?
Reply With Quote
  #3  
Old 12-30-2010, 12:28 AM
uniquex217 uniquex217 is offline
Newcomer
 
Join Date: Dec 2010
Posts: 9
Default

thanks for replying again
okay, a couple of things are on my mind :/
when i post your entire code into VB08 it looked like it is going to work but there are some things i dont understand about your code.
-what is Option Explicit
-What is shpObject and shpWall ?? (is it like a picturebox or a variable??)
-
Code:
 'Update Position In Label
        lblPosition.Caption = shpObject.Left & ", " & shpObject.Top
... what does this mean, am i suppose to like put a blank label in my game or something?

Now when you say like leftside, upside, etc.. does that mean the object will collide with the wall from the side of the boundary?? umm...
like in my game..

the bullets that mario shoots moves in an upward direction and the enemies are moving left to right as moving down okay.. so say its the "collision to the downside of the object", that means the bullet will collide with the downside boundary of the picturebox enemy right?
(i made a picture myself to try to explain myself, hope it makes sense -_-, this is based from my understanding of your drawing somewhat, even though i am using my characters (collision_problem.gif))

-------------
now another thing im confused about is about the random number thing.. i know how to do them myself since i've done exercises about them @school but how does that help my problem with the enemies shooting back at mario?? all i want to know is how to make my "enemies bullet" come down automatically using a timer and then change it to a new position after it goes off screen ..
(made another picture to explain what i want to do (enemy_shoot.gif))

Hope it makes sense
Attached Images
File Type: gif collision_problem.gif (6.8 KB, 6 views)
File Type: gif enemy_shoot.gif (6.8 KB, 9 views)
Reply With Quote
  #4  
Old 12-30-2010, 01:46 AM
ZaCkOX's Avatar
ZaCkOX ZaCkOX is offline
Contributor
 
Join Date: May 2006
Location: CA
Posts: 645
Default

Ok, I'll answer first questions.

Option Explicit is used for declaring outside variables. You should be able to declare an outside variable (being not used in procedures, but in the form).

shpObject and shpWall are shapes. The prefix "shp" is what I use for Shape. But this can work with anything that has a left, top, height and width property.

Code:
'Update Position In Label lblPosition.Caption = shpObject.Left & ", " & shpObject.Top

This is a label displaying the position of the shape object. It is updated everytime the object moves.

Now to the random number, you use random only if you want something to move or show up randomly. Obivously you don't need this, unless you want to randomly spawn enemies in different places. But for moving a bullet, all you need is where it is located, and add or subtract speed to move to a new location. So for example:

Bullet Moving Upward, create a timer with an interval of 100, Put this code in the timer procedure.
Code:
'Sub Procedure shpBullet.Top = shpBullet.Top - 50 'End Sub

For going down you would use "+", why is this? Because the top neutral position is 0 (Imagine a grid, starting at 0,0). To move downward you must add and to move up you must subtract.

Now for collision. Your just confusing yourself. You need a push in the right direction. So here I'll try:

Pause your game for a second. Then unpause... what happens? Each object moves individually. However you create the code for which objects move first. So basically, you need to check collision for each object. If an object must move left, you need to check for collision to it's left.

My function CollisionLeft does just that. It checks for collision to the left of the object. So if mario moves left, use the CollisionLeft to make sure he doesn't run into a border (wall edge).

After he moves, move a bullet, or the whole set of space ships. But you need an order in which what moves first. Overall the collision should apply to all objects moving but seperately.

I would start with one timer, and just have speeds for the objects that move. Don't forget, if a bullet can only move up or down, you won't need collision for it's left and right sides. The collision for detecting that should be the other objects that do move left or right.
__________________
ZaCkO ... Who is your attitude?
Reply With Quote
  #5  
Old 01-02-2011, 06:05 AM
uniquex217 uniquex217 is offline
Newcomer
 
Join Date: Dec 2010
Posts: 9
Default

im sorry >< but no matter what i do, i just can't get it! And without this ONE collision, i can't accomplish anything else cause they all relate to eachother if you know what i mean D: i wish i was using VB6 instead of VB8 cause there are a lot of tutorials based on that. I wish someone just gives me a code that i can copy willingly without worring about logical errors cause im basically not understanding anything! im a visual learner not a logical learner D:
----------- sorry for my rant, i just had to let it all out -sigh-
==============================

Anyways, what is .LBound and .UBound??

Quote:
Don't forget, if a bullet can only move up or down, you won't need collision for it's left and right sides. The collision for detecting that should be the other objects that do move left or right.
When you say this, does this mean do not use CollisionLeft procedure?
Okay im totally lost in all this collision detection thing, too many concepts!! I'm not even sure what to ask even though my mind if filled with questions that just dont want to come out!

Let me try again, i'll try to put it as an algorithm

- A timer is used for detecting collision
- What i want my collision to do is the following:
  • To make a picturebox (size: 14x16, name: pctMarioBullet) that is moving upward (when user pressed the space button) until it hits another picturebox (size: 40x40 name: pctGoomba[#] ) which is grouped and aligned with a bunch of the same pictureboxes in a panel (10 columns, 3 rows)
  • When the collision pctMarioBullet hits that ONE picturebox (enemy), both pictureboxes disappear. Simple as that [when it comes to visual terms] right?
Major problem that i need when making the code part is:
How do you get that ONE picturebox to disappear when the collision occurs without affecting the pictureboxes in the panel.
I tried adding a control in the code but im not sure what to control? Every picturebox in the panel or that single picturebox as an indiviual . Im not sure how my fellow classmates accomplish this.. Its soo hard to explain!

Cause you know in my code in the first post that has comment code saying "Last Method Used" , it would collide but it will just take out the whole column on the other side even when the bullet is nowhere near the enemies. My teacher said it was due to a timing issue and she suggested that i should include tags in all of my enemies, and then convert the tags to integer, and when that tag reaches 0, it will disappear (like an enemy's health) But when i tried this out, that doesn't really help my collision detection either! I'll send an attachment of my teacher's previous student work that she sent me as an example of all what i mentioned above if you are confused. Not sure if it will help though -sigh-IM DESPERATE!!


========================================
im sorry im slow, everything is too overwhelming for me that i try to ignore this project, but time is ticking!! also i am really bad at asking questions GRR! Yes, you may say that I am being too hard on myself, but that's who I am and cant change a fact about that! But sorry for ranting complete nonsense on you, which you may have no idea what to respond back. But Im really desperate, i'd do [almost] anything to obtain that ONE piece of code!
Oh btw, Happy New Year
Reply With Quote
  #6  
Old 01-02-2011, 10:20 AM
AtmaWeapon's Avatar
AtmaWeaponVB2008 - Space Invader Collision Detection AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Quote:
I wish someone just gives me a code that i can copy willingly without worring about logical errors cause im basically not understanding anything!
Quote:
im a visual learner not a logical learner
It may be true, but I don't think this is the right approach to learning to program. When I was starting out, I too looked for full applications because I figured if I saw how the experts did things it'd rub off on me. This isn't how it works. Programming is the art of describing the steps in a process that solves a particular problem. There are an infinite number of problems, and there are always multiple solutions to a given problem. If you memorize "how to do collision detection in Space Invaders" but don't understand how it works, then when you want to solve collision detection for Breakout or Berserk you'll want us to post the modifications to copy/paste. If, on the other hand, you understand the basics of 2D collision detection in general, you're 5-10 minutes of thought away from writing collision detection code for every game ever. At this forum, we prefer to teach the general solution and let you reason out the specific.

Metaphor time! I had a rough time in Physics III. In my previous Physics classes, the teachers were quite soft and many exam questions were very much like our practice problems. If I memorized the steps to solve each practice problem, I was guaranteed a B on the exam. The Physics III teacher was much better: he wrote his exam questions to be different from our practice problems, and often his problems required some clever insight to solve. The early physics classes let me use the "visual learner" approach, but it was a ruse. I wasn't learning anything about physics, I was memorizing how to solve particular problems. The final physics class required me to learn the fundamental theories and apply them in novel ways. I was completely unprepared for this and it hurt worse since I hadn't gained good fundamental knowledge in the earlier physics classes. This is how I feel you should approach programming: understanding the general theory behind a subject is far superior to knowing the solution to a single problem.

I'd like to provide an explanation to complement ZOX's work using VB .NET to help reduce the amount of mental olympics related to understanding the code, but I have an appointment approaching and I'll have to try that later today. For now, I'll try to respond to your questions:
Quote:
Anyways, what is .LBound and .UBound??
They stand for "lower bound" and "upper bound". Upper bound is easy: it's the largest number that can be used to index a data structure (usually an array.) If your array has 10 elements, the valid range of indices are 0 through 9, so UBound() would return 9. In VB .NET, UBound() is available but it's more idiomatic to use .Length - 1 for reasons that LBound() make clear. You've probably guessed that LBound() is "lower bound". In VB6, you can change the starting index of an array from 0 to any arbitrary number. This also affects the upper bound. In .NET, you can't change the lower bound of an array. So in .NET, LBound() will always return 0. Because of this, .Length - 1 replaces UBound(). (There's nothing wrong with using the methods instead of the length property, but most .NET programmers prefer using length.)

Quote:
How do you get that ONE picturebox to disappear when the collision occurs without affecting the pictureboxes in the panel.
I'm unclear on why this is a problem. Your collision detection code needs to know which picture box it's working with to determine if the picture collides with anything. If you know which picture box is colliding, make that one disappear by setting the Visible property to False.

It's possible you've explained why my view of the scenario doesn't fit your code and I haven't read that part of the thread; I've only casually followed so far since someone else was answering (game code is not my favorite stuff to answer because setting up the scenario is always complicated.)

The next paragraph kind of sheds some light; I could see how an entire column could disappear at once if the code is written a certain way. I've got some ideas for a solution and you'll see me in here again. I've got an idea for a demo that's stripped-down enough you'll still have some work on your hands to make it functional. It'll be much later in the day though; I've got some errands to run and I've procrastinated paying the bills for *almost* too long (I hate it! It's tedious.)

ZaCkOX, feel free to keep answering; I think you're doing a good job and I'm going to be a bit slow because I pay too much attention to detail. It's possible you'll make things click before I finish.

*edit*
This note is here to remind myself you're using VS 2008 and I should use that instead of VS 2010 for the solution. If I don't type it out I'll forget.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #7  
Old 01-02-2011, 05:29 PM
AtmaWeapon's Avatar
AtmaWeaponVB2008 - Space Invader Collision Detection AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

I spent most of the day generalizing a different approach to collision detection; I put it on my blog because I felt the inline images make it easier to follow along. Have a look at my Simple Collision Detection article and the example solution attached. It ought to give you a good idea of how to do collision detection in general. If you're still in the dark, it will take me much less time to whip up the original example I had envisioned now that I've satisfied my urge to write about it in general.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #8  
Old 01-03-2011, 03:06 AM
ZaCkOX's Avatar
ZaCkOX ZaCkOX is offline
Contributor
 
Join Date: May 2006
Location: CA
Posts: 645
Default My Simplest Form

Rules To Know:
The very Top of a form position is 0.
The very Left of a form position is 0.

Set:
Form To Pixels Scale

Position Of a PictureBox Example:
pic.Top = -1
pic.Left = -1

This position is the top left position, should be outside of view unless the picture is bigger than 1 by 1 pixel.

Now let's move this picture box downward on the form.
pic.Top = pic.Top + 1

Now the picture's position should be Left = -1, Top = 0

So what did we learn so far?
To go down we must add, same as going right
To go up we must subtract, same as going left

So where is this picture box?
pic.Top = 100
pic.Left = 100

Bottom Right!

Now let's form a wall. We will start with a shape. Call it shpWall.

Let's find it's dimensions:
shpWall.Height
shpWall.Width

Ok what about it's sides? Problem here, we can't get all the properties for this. So we must use some geometry to figure out all sides.
shpWall.Left
shpWall.Top

We need Right and Bottom... Then here is what we do:
shpWall.Left + shpWall.Width = Right side
shpWall.Top + shpWall.Height = Bottom side

Now very simple collision prevention would be this:
Object 1 = Wall
Object 2 = Ship
Object 1's Right side can touch Object 2's Left Side. This would be side to side. So what does this look like?

If shpWall.Left + shpWall.Width = shpShip.Left Then
'Objects are touching side to side
End If

Pretty simple so far... Ok so let's expand on this.

Let's imagine the ship moving. Therefore when we write, we should now start with the ship. Let's imagine, the wall on the left, and the ship on the right.

As the ship moves closer to the wall, it is moving left. If it's left ever falls into the wall's right then we have collision.

If shpShip.Left < shpWall.Left + shpWall.Width Then
'Ship is inside the wall, from moving left.
End if

But if we want to prevent the ship from EVER moving into the wall we must do:

If shpShip.Left - ShipSpeed < shpWall.Left + shpWall.Width Then
'Don't Move
Else
'Move
End If

Now that is one side of the wall. We cannot forget there is 4 sides to the shape of a square or rectangle. Therefore, we must have 4 statements! Otherwise, let's stick with the above statement... you'll notice you can never move the ship left even if it is above the wall or below it... even if the ship is on the left and the wall is on the right, the ship cannot move left. So we need these other 3 statements.

These statements are:

shpShip.Left + shpShip.Width > shpWall.Left (ship on left, wall on right)
shpShip.Top + shpShip.Height > shpWall.Top (ship on top, wall on bottom)
shpShip.Top < shpWall.Top + shpWall.Height (ship on Bottom, wall on top)

You'll notice these can touch, side to side, top to bottom. Imagine them in your head. If you don't understand this concept yet, study until you do.

Now 1 important note you'll notice... I don't have speed above. Why not? If the ship is moving left, it can move with it's speed left. But if the ship cannot get into the wall without speed then we don't need speed. Good way to imagine this is:

Ship on the left, Wall on the right. Ship keeps moving left... it will never touch the wall. Therefore speed doesn't need to be checked. Same as if the ship is below the wall or above it... speed doesn't matter. So we don't need this value unless the ship is moving towards the wall.

So we created our first collision for moving left...

If shpShip.Left - ShipSpeed < shpWall.Left + shpWall.Width _
And shpShip.Left + shpShip.Width > shpWall.Left _
And shpShip.Top + shpShip.Height > shpWall.Top _
And shpShip.Top < shpWall.Top + shpWall.Height Then
'Don't Move Left
Else
'Move Left
End If

Ok, but what if we want to close the gap, let's say have our ship slam right up next to the wall, because the ship could have any speed right?

shpShip.Left = shpWall.Left + shpWall.Width (Side to side) Ship on right, wall on left.

Now if we must collide, we want the ship to slam into the wall instead.

If shpShip.Left - ShipSpeed < shpWall.Left + shpWall.Width _
And shpShip.Left + shpShip.Width > shpWall.Left _
And shpShip.Top + shpShip.Height > shpWall.Top _
And shpShip.Top < shpWall.Top + shpWall.Height Then
shpShip.Left = shpWall.Left + shpWall.Width 'Against the wall
Else
'Move Left
End If

Now if you understand this, you can make one for moving up. Then right, and finally down. Only check statements for wherever the object is moving. If the object is moving left then only check collision left.

Or you could just use my statements since I created them and yours would be the same LOL Regardless if you write it backwards it's still the same.

I hope this helps, took me some time to write it.
__________________
ZaCkO ... Who is your attitude?
Reply With Quote
  #9  
Old 01-03-2011, 04:05 AM
uniquex217 uniquex217 is offline
Newcomer
 
Join Date: Dec 2010
Posts: 9
Default

ahh i feel thankful (and very grateful) that both of you are willing to take your precious time to explain things to me even though i feel completely overwhelmed about programming.

Quote:
If you know which picture box is colliding, make that one disappear by setting the Visible property to False.
hmm.. the thing is i dont know ): because the user who is playing the game will like shoot randomly as the enemies move.
Here is an example of a basic space invaders game that i am trying to accomplish, but a little simpler (since im just a beginner)
http://www.goriya.com/flash/invaders/invaders.shtml

To be honest, your blog sort of refreshed me.. i started to understand collision better than i did before.. I experimented a little -- well based from your code examples -- [sorry] and it worked. I was completely shocked! but when i fiddled around with the code more, i discovered some issues that this may not work out at all. One of them was when i moved my hero character far away from the enemy, which was just a stationary picturebox, and then shoot; it also disappeared. There was no direct contact at all and yet the collision function became true.

-------
And about your little metaphor; i understand that you should know the basics or the general concept first before you can advance on the subject; but.. it's just difficult for me to remember even the most basic things; and act like i know it even though i have no idea until they advance and then all of a sudden the subject will make sense to me.. its complicated i know. my brain doesnt like to function the way an average brain does -sadly-

Thank you again!

Edit: uhh sorry; most of this is meant for AtmaWeapon, but when i just posted; i realize ZaCkOX posted before.. So is off to read ZaCkOX posts next ^^;;

Last edited by uniquex217; 01-03-2011 at 04:11 AM.
Reply With Quote
  #10  
Old 01-03-2011, 07:10 AM
AtmaWeapon's Avatar
AtmaWeaponVB2008 - Space Invader Collision Detection AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Quote:
One of them was when i moved my hero character far away from the enemy, which was just a stationary picturebox, and then shoot; it also disappeared. There was no direct contact at all and yet the collision function became true.
That's very concerning. I think you need to post your code so we can figure out what's going on there.

In the meantime, here's some comments on what I think is wrong with your original code.

I think the "new" code starts to go sour here (snipped the unimportant parts out):
Code:
If ... AndAlso rect.IntersectsWith(pctBullet.Bounds) Then
You never set rect to anything, so it's a rectangle at (0, 0) with a width and height of 0. It'll never collide with anything.

There's also a problem in this part:
Code:
pnlEnemies.Tag = CType(pnlEnemies.Tag, Integer) - 1 

...

If CInt(pnlEnemies.Tag) <= 0 Then 'when enemies health reaches 0 or lower
	blnCollison = True 'collision activated
	c.Visible = False 'enemy disappears
The problem is you're checking the Tag property of the entire panel; odds are you wanted to check the tag of the enemy that you're looking at, c.Tag. This is probably why more than one enemy disappears; if you don't have Option Strict on an automatic conversion from whatever is in Tag will happen, and it's likely it contains Nothing which will convert to 0. Even if that's not the case, there's not a decent way to make the panel represent the health of the enemies. It's the wrong thing to do, and since health is 0 after one bullet hits every enemy past the enemy hit will disappear. That's not what you want, but it's what you told the computer to do.

The section of code that's been commented out looks correct; I'm not sure why you believe there'd be a timing issue. Unless your code is multithreaded (you won't do this accidentally) there's only one thread in the application so there's no way for the bullet to move while you're doing collision detection.

There's one possibility I just thought of: how large is the bullet picture box? It should be as close as possible to the size of the bullet. The problem with this kind of collision detection is if there are "dead" areas of the image (like transparent pixels) they will collide since they are part of the rectangle. If the bullet picture box is large enough, there's a possibility it touches more than one invader at the same time. This would cause multiple collisions. If you're not sure, here's an easy way to test: give the picture box a border using the BorderStyle property and change your timer interval to something you can witness like 2 seconds. Then, fire off some shots and watch the bullet slowly head towards the invaders. When it hits, how many invaders is it touching? In addition, you might want to think about using the debugger or some message boxes to indicate when the program thinks the bullet hit an invader; this way you can see if it's hitting multiples. If you're using the debugger, you can poke around and find out why.

Oh, and a side note:
Quote:
hmm.. the thing is i dont know ): because the user who is playing the game will like shoot randomly as the enemies move.
You *do* know. When you do your collision detection, you visit each enemy picturebox. For that instant, c represents an enemy. If the bullet touches that enemy, you can make that enemy invisible. You've done this in *both* of your code samples. If you don't understand your own code, you won't be able to fix it.

I'd like to see your newer code before moving on to an example; that'd help me figure out if there's something specific that needs explaining.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #11  
Old 01-03-2011, 12:58 PM
ZaCkOX's Avatar
ZaCkOX ZaCkOX is offline
Contributor
 
Join Date: May 2006
Location: CA
Posts: 645
Default Where I last left off...

If shpShip.Left - ShipSpeed < shpWall.Left + shpWall.Width _
And shpShip.Left + shpShip.Width > shpWall.Left _
And shpShip.Top + shpShip.Height > shpWall.Top _
And shpShip.Top < shpWall.Top + shpWall.Height Then
shpShip.Left = shpWall.Left + shpWall.Width 'Against the wall
Else
'Move Left
End If

That does one wall while the object moves left, it checks for collision to that wall. So what if you want all walls? Well where it says shpWall you need to loop for each wall. I only know how to do this with VB 6. I would use a variable loop integer counter.

Code:
'Declare Dim i as Integer 'Loop Through All Walls For i = shpWall.LBound To shpWall.UBound If shpShip.Left - ShipSpeed < shpWall(i).Left + shpWall(i).Width _ And shpShip.Left + shpShip.Width > shpWall(i).Left _ And shpShip.Top + shpShip.Height > shpWall(i).Top _ And shpShip.Top < shpWall(i).Top + shpWall(i).Height Then shpShip.Left = shpWall(i).Left + shpWall(i).Width 'Against the wall collided! Else 'Move Left End If Next

Just like AtmaWeapon is saying, if you loop through all your objects, you will know which object is collided. Look above

shpShip.Left = shpWall(i).Left + shpWall(i).Width

At that point in time, i = the Index of the Wall Collided. Also note if we already collided we don't need to check all other walls left. So we would exit the loop at this point.

Code:
Exit For 'Or Exit Function if we created a function

Now if you want to add some animation for colliding against a wall, like when a character rams into a wall, you do it at the same line above. But you only need to show the animation once. This is why I do this:

Code:
If shpShip.Left <> shpWall(i).Left + shpWall(i).Width Then 'Animation And Then Move It shpShip.Left = shpWall(i).Left + shpWall(i).Width Exit For End If

You could even check speed or distance to make the ramming happen at certain times, but we start to go further down the road, what content are we creating for the game? Not all games have content like this anyway... is it worth it, so forth. Don't we want enemies instead? Yea maybe, so we might leave this part out.

If you understand everything I discussed then you should be able to convert this code. I would start simple and just make wall collision. Then you can re-write the same code for checking all enemy ships. And then when you get more advanced you'll notice you can tie everything together and make the code much simpler by looping through all objects. I'm not sure if you'll need collections for that though?

Ah I better not leave this out. So if the ship can move left what is the code?

Code:
shpShip.Left = shpShip.Left - ShipSpeed

You would use that when it can move freely. But you should of been able to figure that out without me spoiling it.

So I might as well spoil all the code added together:

Code:
'Declare Dim i as Integer 'Loop Through All Walls For i = shpWall.LBound To shpWall.UBound If shpShip.Left - ShipSpeed < shpWall(i).Left + shpWall(i).Width _ And shpShip.Left + shpShip.Width > shpWall(i).Left _ And shpShip.Top + shpShip.Height > shpWall(i).Top _ And shpShip.Top < shpWall(i).Top + shpWall(i).Height Then If shpShip.Left <> shpWall(i).Left + shpWall(i).Width Then shpShip.Left = shpWall(i).Left + shpWall(i).Width 'Against the wall collided! Exit For End If Else 'Move Left shpShip.Left = shpShip.Left - ShipSpeed End If Next

And If you wanted it to be a function so you can check before moving the ship:

Code:
Private Function CollisionLeft() As Boolean 'Declare Dim intNextNumber As Integer 'Check For Collision To The Left Of Object For intNextNumber = shpWall.LBound To shpWall.UBound If shpObject.Left - sngObjectSpeed < shpWall(intNextNumber).Left + shpWall(intNextNumber).Width _ And shpObject.Left + shpObject.Width > shpWall(intNextNumber).Left _ And shpObject.Top + shpObject.Height > shpWall(intNextNumber).Top _ And shpObject.Top < shpWall(intNextNumber).Top + shpWall(intNextNumber).Height Then If shpObject.Left <> shpWall(intNextNumber).Left + shpWall(intNextNumber).Width Then shpObject.Left = shpWall(intNextNumber).Left + shpWall(intNextNumber).Width End If CollisionLeft = True Exit Function End If Next 'Return Function CollisionLeft = False End Function

Back to the CollisionLeft function I created from the beginning
So if we want to run this collision we check for the key movement:

Code:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) 'Check For Movement Select Case KeyCode Case 37 'Left Arrow If CollisionLeft = False Then shpObject.Left = shpObject.Left - sngObjectSpeed End If End Select End Sub

And we're done with my lesson for a space ship moving left against all objects. Repeat same for up, down, right, or just refer to the code earlier posted and try to write your own from beginning. I know it's hard, but if you practice you will get it in your head. Took me some time as well to understand.
__________________
ZaCkO ... Who is your attitude?
Reply With Quote
Reply

Tags
aardvarks, collision, detection, invaders, space, vague tags, visual basic 2008


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
 
VB2008 - Space Invader Collision Detection
VB2008 - Space Invader Collision Detection
 
-->