Complex Procedure Parameters and SpritePixelCollision Issues

Linux specific forum
The_Pharao
User
User
Posts: 57
Joined: Sun Jan 04, 2004 2:11 pm

Complex Procedure Parameters and SpritePixelCollision Issues

Post 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?
MadMax
Enthusiast
Enthusiast
Posts: 237
Joined: Mon Oct 06, 2003 11:56 am

Post 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
The_Pharao
User
User
Posts: 57
Joined: Sun Jan 04, 2004 2:11 pm

Post by The_Pharao »

Until 3.92 is released i offer you this piece of code. i was bored today :wink:

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 :)
lodger
User
User
Posts: 13
Joined: Mon May 28, 2007 6:08 pm
Location: Germany

Surprise, surprise!!

Post 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.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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.
oh... and have a nice day.
Post Reply