2D: SpriteCollision on layers not possible?

Advanced game related topics
Marksman
New User
New User
Posts: 4
Joined: Mon Feb 13, 2006 3:53 pm

2D: SpriteCollision on layers not possible?

Post by Marksman »

Hi,

why does this function returns true if i shot with the mouse
on the top left corner of the blue building? It shouldn't, because the
part of the (red) enemy is behind the building, not visible and
so should not be hitable.

Code: Select all

If SpritePixelCollision(#Sprite_Mouse,MouseX(),MouseY(),#Sprite_Enemy,x,y) And MouseButton(1)
Image
MadMax
Enthusiast
Enthusiast
Posts: 237
Joined: Mon Oct 06, 2003 11:56 am

Post by MadMax »

Quite simple realy, PB checks if the sprites would collide if they were where you say, it doesn't check the screen. This is not a bad thing, as it is quite useful in many games. Of course in your case you'll need a different aproach. Don't realy know what you want to do, but I suggest checking if it's behind something before you check for collision.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Before calling the collision, clip the enemy sprite's right/bottom by the building's sprite's X/Y. Then run the collision test, then "unclip" the enemy sprite :)
Marksman
New User
New User
Posts: 4
Joined: Mon Feb 13, 2006 3:53 pm

Post by Marksman »

Okay, but what about a complex set of some trees and 20 enemies flying around?
MadMax
Enthusiast
Enthusiast
Posts: 237
Joined: Mon Oct 06, 2003 11:56 am

Post by MadMax »

Well, let's say you have a whole lot of blue rectangles and another of lot of yellow ones that can hide behind the blue ones.

The way I would go about it:
I would check collision with the blue rectangles.
a) If no collision then check collision with the yellow rectangles
b) If collision with blue DON'T check yellow

Hope this helps.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

In this case you need to add one test before accepting collision. Each object on the screen must have a number of attributes, such as x, y, #sprite and a number of others. In your program, one of these others will be "layer". So to test collision you would do: If SpritePixelCollision(...) And Object1()\Layer = Object2()\Layer <success>.
BERESHEIT
Marksman
New User
New User
Posts: 4
Joined: Mon Feb 13, 2006 3:53 pm

Post by Marksman »

The actual Structure is this:

Code: Select all

Structure Enemy

  x.l
  y.l
  speed.l
  direction.l
  layer.l

EndStructure

NewList Enemy.Enemy()
And the CollisionCheck this:

Code: Select all

If SpritePixelCollision(#Sprite_Mouse,MouseX(),MouseY(),#Sprite_Enemy,Enemy()\x,Enemy()\y) And MouseButton(1)
What value should "layer" have? 1 if in back and 2 if in front of the building?

And how must i exactly do the check?

Why does this not work (but looks logically?):

Code: Select all

If
SpritePixelCollision(#Sprite_Mouse,MouseX(),MouseY(),#Sprite_Enemy,Enemy()\x,Enemy()\y)
And
SpritePixelCollision(#Sprite_Mouse,MouseX(),MouseY(),#Sprite_Building,MouseX(),MouseY())=0
And MouseButton(1)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I'd have to see more code to say why exactly it doesn't work, but if you are shooting a projectile, and the projectile is coming from the foreground of what we're considering to be a 3d-like view, then this seems logical:

Code: Select all

Repeat
  Display sprites for objects on layer 2
  Display sprites for objects on layer 1
  Display sprites for objects on layer 0
  Collisioncheck projectile vs all objects on layer 0
  if none
    Collisioncheck projectile vs all objects on layer 1
    if none
      Collisioncheck projectile vs all objects on layer 2
    endif
  endif
until <something>
That's just some quick pseudocode, but if you implement that logic, if your projectile hits the top left corner of the building, that's the collision you'll catch, not the object behind it. (Assuming object behind has layer=2, building has layer=1)
BERESHEIT
Marksman
New User
New User
Posts: 4
Joined: Mon Feb 13, 2006 3:53 pm

Post by Marksman »

This one should just check Enemies behind the buildings:

Code: Select all

Repeat

     ExamineKeyboard():ExamineMouse():ClearScreen(0,0,0)
   
     Gosub MakeEnemies
     Gosub CheckEnemies ; if they are out of screen
     Gosub MoveEnemies

     DisplayTransparentSprite(#Sprite_Building,400,300)
     DisplayTransparentSprite(#Sprite_Mouse,MouseX(),MouseY())

     Gosub CheckCollision

     FlipBuffers()

Until KeyboardReleased(#PB_Key_Escape)




CheckCollision:

If MouseButton(1)

If SpritePixelCollision(#Sprite_Mouse,MouseX(),MouseY(),#Sprite_Building,MouseX(),MouseY())=0 ; if not shot on building

ForEach Aliens()

     If SpritePixelCollision(#Sprite_Mouse,MouseX(),MouseY(),#Sprite_Enemy,Enemy()\x,Enenmy()\y)
     DeleteElement(Enemy())
     EndIf

Next

EndIf

EndIf

Return
[/size]
Post Reply