Page 1 of 1
Complex Procedure Parameters and SpritePixelCollision Issues
Posted: Tue Dec 14, 2004 7:02 pm
by The_Pharao
today i had time to crunch through my game code. the code compiles and runs fine with the windows purebasic.
though i got an memory access error when i tried to compile the app with linux purebasic.
i was able to nail down the error in an endless comment/uncomment orgy.
i used this command:
Code: Select all
DisplayTransparentSprite(Anim(Player(nPlr)\CurrentAnim)\FramePic[Anim(Player(nPlr)\CurrentAnim)\CurFrame], Anim(Player(nPlr)\CurrentAnim)\Pos\x, Anim(Player(nPlr)\CurrentAnim)\Pos\y)
this code above caused the compiler to spit out an error message (without line number though...).
i fixed the problem by breaking down the whole line into two statements:
Code: Select all
;create dummy variable
dummy=Anim(Player(nPlr)\CurrentAnim)\FramePic[Anim(Player(nPlr)\CurrentAnim)\CurFrame]
;pass dummy variable to procedure
DisplayTransparentSprite(dummy, Anim(Player(nPlr)\CurrentAnim)\Pos\x, Anim(Player(nPlr)\CurrentAnim)\Pos\y)
remember: the first version works fine under windows! this seems to be a bug in the linux compiler.
the second thing is that SpritePixelCollision does not seem to work under linux. the sprites collide just like in SpriteCollision, without caring about the transparency of the sprites (which is displayed correct). can anybody confirm this?
Posted: Tue Dec 14, 2004 8:58 pm
by MadMax
the second thing is that SpritePixelCollision does not seem to work under linux. the sprites collide just like in SpriteCollision, without caring about the transparency of the sprites (which is displayed correct). can anybody confirm this?
Yes, I'm hoping this will be corrected in 3.92
Posted: Fri Dec 17, 2004 7:31 pm
by The_Pharao
Until 3.92 is released i offer you this piece of code. i was bored today
Code: Select all
;Declare Stuff for Cross-Platform Pixel Perfect Collision
Declare SpritePixelCollision2(SprOne.l, SprOneX.l, SprOneY.l, SprTwo.l, SprTwoX.l, SprTwoY.l) ;Cross-Platform SpritePixelCollision Procedure for Win and Linux
Global SpritePixelCollision2Color.l
SpritePixelCollision2Color = RGB(255,0,255) ;set default transparent color to Magenta
and here is the procedure:
Code: Select all
;SpritePixelCollision2
;used like SpritePixelCollision(#Sprite1, x1, y1, #Sprite2, x2, y2)
;makes SpritePixelCollision available for Linux games, too.
;created 17-December-2004 by Benedikt Engelhard (fleecer99@yahoo.de)
Procedure.l SpritePixelCollision2(SprOne.l, SprOneX.l, SprOneY.l, SprTwo.l, SprTwoX.l, SprTwoY.l)
;
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_AmigaOS
;no support for amiga platform
CompilerCase #PB_OS_Linux
; hand-written pixel perfect collision detection for linux,
; using only PureBasic commands
ColX.l = 0
ColY.l = 0
ColH.l = 0
ColW.l = 0
If SprOneX = SprTwoX
ColX = SprOneX
if SpriteWidth(SprOne) = SpriteWidth(SprTwo)
ColW = SpriteWidth(SprOne)
else
if SpriteWidth(SprOne) > SpriteWidth(SprTwo)
ColW = SpriteWidth(SprTwo)
else
ColW = SpriteWidth(SprOne)
endif
endif
Else
if SprOneX < SprTwoX
ColW = (SprOneX + SpriteWidth(SprOne)) - SprTwoX
ColX = SprTwoX
else
ColW = (SprTwoX + SpriteWidth(SprTwo)) - SprOneX
ColX = SprOneX
endif
EndIf
if ColW > SpriteWidth(SprTwo)
ColW = SpriteWidth(SprTwo)
endif
if ColW > SpriteWidth(SprOne)
ColW = SpriteWidth(SprOne)
endif
If SprOneY = SprTwoY
ColY = SprOneY
if SpriteHeight(SprOne) = SpriteHeight(SprTwo)
ColH = SpriteHeight(SprOne)
else
if SpriteHeight(SprOne) > SpriteHeight(SprTwo)
ColH = SpriteHeight(SprTwo)
else
ColH = SpriteHeight(SprOne)
endif
endif
Else
if SprOneY < SprTwoY
ColH = (SprOneY + SpriteHeight(SprOne)) - SprTwoY
ColY = SprTwoY
else
ColH = (SprTwoY + SpriteHeight(SprTwo)) - SprOneY
ColY = SprOneY
endif
EndIf
if ColH > SpriteHeight(SprTwo)
ColH = SpriteHeight(SprTwo)
endif
if ColH > SpriteHeight(SprOne)
ColH = SpriteHeight(SprOne)
endif
Dim SprOnePixels.b(ColW-1,ColH-1)
Dim SprTwoPixels.b(ColW-1,ColH-1)
g.l=0
h.l=0
StartDrawing(SpriteOutput(SprOne))
nx.l=0
ny.l=0
if ColX > SprOneX
nx = ColX - SprOneX
endif
if ColY > SprOneY
ny = ColY - SprOneY
endif
for g = 0 to ColW-1
for h = 0 to ColH-1
if Point(nx+g, ny+h) = SpritePixelCollision2Color
SprOnePixels(g, h)=0
else
SprOnePixels(g, h)=1
endif
next h
next g
StopDrawing()
StartDrawing(SpriteOutput(SprTwo))
nx.l=0
ny.l=0
if ColX > SprTwoX
nx = ColX - SprTwoX
endif
if ColY > SprTwoY
ny = ColY - SprTwoY
endif
for g = 0 to ColW-1
for h = 0 to ColH-1
if Point(nx+g, ny+h) = SpritePixelCollision2Color
SprTwoPixels(g, h)=0
else
SprTwoPixels(g, h)=1
endif
next h
next g
StopDrawing()
;Uncomment the following lines to see the collision rectangle:
;If StartDrawing(ScreenOutput())
;Box(ColX, ColY, ColW, ColH ,RGB(255,0,0))
for g=0 to ColW-1
for h = 0 to ColH-1
if SprOnePixels(g,h)=1 And SprTwoPixels(g,h)=1
ProcedureReturn 1 ;say yes - there is a pixel collision
endif
next h
next g
; StopDrawing()
;EndIf
ProcedureReturn 0 ;no, no pixel collision
CompilerCase #PB_OS_Windows
; in Windows, we use Fred's built-in routine:
ProcedureReturn SpritePixelCollision(SprOne, SprOneX, SprOneY, SprTwo, SprTwoX, SprTwoY)
CompilerEndSelect
EndProcedure
use it like the normal SpritePixelCollision command!
if anyone wants to contribute, please feel free to optimize this procedure

Surprise, surprise!!
Posted: Thu Jul 26, 2007 5:53 pm
by lodger
Well, glad to find this thread as the SpritePixelCollision issue still isn't fixed in version 4.01 (Linux). Surprise, surprise!!
Hopefully someone in the development team will also recognize that problem and properly fix it for version 4.10. Thanks for your code snippet, that'll help me out in the meantime.
Posted: Thu Jul 26, 2007 6:34 pm
by Kaeru Gaman
sorry to hear that, but do you really need SpritePixelCollision?
I normally don't even use SpriteCollision, but only coordinate-checks,
also with bounding circle or such.
SpritePixelCollision is a Function supported by the graphical subsystem.
it is slow enough, re-writing it in ASM would be even slower,
using Draw like in the above example must be amazingly slow.
I'm sure you could check für a dozen covering little circles and still be faster.