Page 1 of 1
2D: SpriteCollision on layers not possible?
Posted: Wed Mar 01, 2006 11:02 pm
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)

Posted: Thu Mar 02, 2006 12:38 am
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.
Posted: Thu Mar 02, 2006 12:58 am
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

Posted: Thu Mar 02, 2006 1:07 am
by Marksman
Okay, but what about a complex set of some trees and 20 enemies flying around?
Posted: Thu Mar 02, 2006 1:48 am
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.
Posted: Thu Mar 02, 2006 10:45 am
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>.
Posted: Thu Mar 02, 2006 4:29 pm
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)
Posted: Thu Mar 02, 2006 4:48 pm
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)
Posted: Thu Mar 02, 2006 5:18 pm
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]