Seite 1 von 2

SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 13:44
von funkheld
Hallo, guten Tag.
Die Spritecolli ist grottenschlecht, oder mach ich einen Fehler ?
Ich habe ein Sprite 64x64(Raupenfahrzeig) und ein Sprite 500x500(Grundfläche mit Umrandung).
Bei beiden ist die Farbe 255,0,255 durchsichtig.

4-5 Pixel vor der Collision wird schon eine Colli angezeigt.
Wenn ich mit dem Fahrzeugkörper ausserhalb der Berührung bin und dann drehe und der Kettenantrieb kommt in die Berührungsfläche , wird erst nach 5-6 Punkten in der Fläche eine Colli angezeigt.

Was ist da falsch ?
Vielleicht kann ich einem Mal die Sprite schicken zum Testen?

Gruss

Code: Alles auswählen

Global x1.f,y1.f,dx.f,dy.f,winkel.f, r.l,delta.l,colli.l
 
 Enumeration
   #Window_0
   #sprite_0
   #sprite_1
 EndEnumeration

InitSprite()

OpenWindow(#Window_0, 0, 0, 800, 700, "Screen", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window_0), 150, 10, 600,600, 0, 0, 0)

LoadSprite(#sprite_0, "raupe.bmp", #PB_Sprite_PixelCollision)
LoadSprite(#sprite_1, "grundspr.bmp", #PB_Sprite_PixelCollision)
TransparentSpriteColor(#sprite_0, RGB(255,0,255))
TransparentSpriteColor(#sprite_1, RGB(255,0,255))

dx=100
dy=100
delta=2

Repeat
  Event = WaitWindowEvent(1)
  
  Select Event
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
    
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        CloseWindow(#Window_0)
        Break
      EndIf
  EndSelect

  If GetAsyncKeyState_(#VK_RIGHT)
    winkel=winkel+2
  ElseIf GetAsyncKeyState_(#VK_LEFT)
    winkel=winkel-2
  EndIf
 
  If GetAsyncKeyState_(#VK_UP)
    y1=Sin(winkel/180*#PI)*delta
    x1=Cos(winkel/180*#PI)*delta
    dx+x1
    dy+y1   
  ElseIf GetAsyncKeyState_(#VK_DOWN)
    y1=Sin(winkel/180*#PI)*delta
    x1=Cos(winkel/180*#PI)*delta
    dx-x1
    dy-y1
  EndIf
  
  ClearScreen(RGB(255,255,0))
  DisplayTransparentSprite(#sprite_1,10,10)
  DisplayTransparentSprite(#sprite_0,dx,dy)
  RotateSprite(#sprite_0,winkel+90,#PB_Absolute)
  colli = SpritePixelCollision(#Sprite_0, dx,dy, #Sprite_1,10,10)
  
  FlipBuffers()
  Debug colli
   
ForEver

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 15:13
von STARGÅTE
Also zuerst mal, SpritePixelCollision() funktioniert nicht mit rotierten Sprites, denn davon steht auch nix in der Hilfe, da steht nur gezoomt.

Ansonsten kann ich keine Abweichung feststellen:

Code: Alles auswählen

InitSprite()


Enumeration
	#Window
EndEnumeration

OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

TransparentSpriteColor(#PB_Default, $000000)
CreateSprite(1, 256, 256, #PB_Sprite_PixelCollision)
CreateSprite(2, 64, 64, #PB_Sprite_PixelCollision)

If StartDrawing(SpriteOutput(1))
	Box(0, 0, 16, 256, $FFFFFF)
	Box(0, 0, 256, 16, $FFFFFF)
	StopDrawing()
EndIf

If StartDrawing(SpriteOutput(2))
	Box(24, 0, 16, 64, $FFFFFF)
	StopDrawing()
EndIf

Define X, Y

Repeat
	
	Repeat
		
		Select WindowEvent()
			Case #PB_Event_CloseWindow
				End
			Case #Null
				Break
		EndSelect
		
	ForEver
	
	ClearScreen(0)
	
	DisplayTransparentSprite(1, 100, 100)
	DisplayTransparentSprite(2, WindowMouseX(#Window)-32, WindowMouseY(#Window)-32)
	
	SetWindowTitle(#Window, Str(SpritePixelCollision(1, 100, 100, 2, WindowMouseX(#Window)-32, WindowMouseY(#Window)-32)))
	
	FlipBuffers()
	
ForEver

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 17:10
von funkheld
Jup, danke.
Da ist ja öde....

Wie kann man das realisieren ?
Evtl mit Catchsprite das gedrehte Sprite irgendwie wieder in das Originalsprite setzen, aber wie ?

Gruss

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 19:11
von STARGÅTE
funkheld hat geschrieben:Evtl mit Catchsprite das gedrehte Sprite irgendwie wieder in das Originalsprite setzen, aber wie ?
Nene, viel zu langsam, um es in Echtzeit auszuführen.

Je nach Form des Objekts würde ich dann lieber n Kollisionsabfrage zwischen: Kugel/Box/Dreieck/Polygon und der Wand machen.

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 20:30
von KeyKon
Ich hab das mal vor Ewigkeiten recht einfach gemacht, indem ich zu jedem Sprite (das waren in meinem Fall wohlgemerkt nur einige wenige) einfach 180 Rotations-Stufen generiert habe (beim Laden).
Dadurch konnte ich immer mit dem entsprechenden Sprites die Kollision so genau wie es für mich nötig war nachprüfen (wenn mans genauer will muss man halt mehr Rotations-Stufen anlegen^^).
Ich denke in zweiten von Rechnern mit 4GB+ RAM kann man sich sowas leisten^^

Wenn möglich ist natürlich STARGATEs Methode vorzuziehen!

LG KeyKon

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 22:44
von funkheld
Jup, danke.
Wollte ich auch erst machen.

Jetzt habe ich eine Lösung mit "Grabsprite" und "Copysprite" gefunden.
Das Sprite habe ich ausserhalb des sichtbaren Bereichs gelegt mit Displaysprite und habe es dann da auch mit Grabsprite abgeholt.

--------------------------
OpenWindow(#Window_0, 0, 0, 900, 650, "Screen", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window_0), 120, 10, 1000,600, 0, 0, 0)
---------------------------
OpenWindowedScreen geht nach rechts raus und ist grösser in der Breite als das Openwindow und da ausserhalb sehe ich das Sprite nicht auf meinem Spielwindow. Die Geschwindigkeit wird durch diese 3 Spritegeschichten hintereinander nicht wesentlich beeinflusst, weil die Kopiergeschichten echt superschnell sind.

Code: Alles auswählen

DisplaySprite(#sprite_auto_load,910,10)
GrabSprite(#sprite_grab,900,0,84,84,#PB_Sprite_PixelCollision) 
CopySprite(#Sprite_grab, #Sprite_auto,#PB_Sprite_PixelCollision) 
Gruss

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 22:53
von NicTheQuick
Interessante Idee. Denk dran, dass ein gedrehtes Sprite später insgesamt breiter und höher ist als zuvor, wenn du es wieder komplett grabben willst.

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 22:59
von funkheld
Die Grundfläche ist grösser als das Spielsprite damit beim drehen die Ecken mit berücksicht werden.

Gruss

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 23:14
von funkheld
So jetzt habe ich das Roboterauto fertig mit 2 Tastern vorn , die eine Kollision aufnehmen.
Habe als Grundkörper ein Sprite und die 2 Tasten vorn sind auch je ein Sprite. Alle 3 Sprite haben die gleiche Grundgrösse damit beim Drehen keine Verschiebungen zu sehen sind. Das Auto dreht sich um einpaar Grad , je nachdem welcher Taster eine Kollision hat.
Es funktioniert einwandfrei. Das Auto weicht allen Hindernissen aus.

Gruss

Code: Alles auswählen

 Global x1.f,y1.f,dx.f,dy.f,winkel.f, r.l,delta.l,collir.l,collil.l,neuspr.l,sprite_hgrund.l
 
 Enumeration
   #Window_0
   #sprite_auto_load
   #sprite_auto_loadr
   #sprite_auto_loadl
   #sprite_zaun
   #sprite_grab
   #sprite_auto
   #sprite_autor
   #sprite_autol
   #button_0
   #button_1
   #button_2
 EndEnumeration

InitSprite()

OpenWindow(#Window_0, 0, 0, 900, 650, "Screen", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window_0), 120, 10, 1000,600, 0, 0, 0)

ButtonGadget(#button_0, 10,10, 80, 25, "")
ButtonGadget(#button_1, 10,35, 80, 25, "")
ButtonGadget(#button_2, 10,60, 80, 25, "")

LoadSprite(#sprite_auto_load, "d:/data/auto.bmp", #PB_Sprite_PixelCollision)
LoadSprite(#sprite_auto_loadr, "d:/data/autor.bmp", #PB_Sprite_PixelCollision)
LoadSprite(#sprite_auto_loadl, "d:/data/autol.bmp", #PB_Sprite_PixelCollision)

LoadSprite(#sprite_zaun, "d:/data/grundsprs5.bmp", #PB_Sprite_PixelCollision)
sprite_hgrund=CreateSprite(#PB_Any,90,90,#PB_Sprite_PixelCollision)

StartDrawing(SpriteOutput(sprite_hgrund))
  Box(0,0,90,90,RGB(0,0,0))
StopDrawing()

dx=220
dy=100
delta=1

Repeat
  Event = WaitWindowEvent(1)
  
  Select Event
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      
      If EventGadget = #Button_0
             
      EndIf
      If EventGadget = #Button_1
             
      EndIf
      If EventGadget = #Button_2
             
      EndIf
    
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        CloseWindow(#Window_0)
        Break
      EndIf
  EndSelect

  If GetAsyncKeyState_(#VK_RIGHT)
    winkel=winkel+2
  ElseIf GetAsyncKeyState_(#VK_LEFT)
    winkel=winkel-2
  EndIf
 
  
    y1=Sin(winkel/180*#PI)*delta
    x1=Cos(winkel/180*#PI)*delta
    dx+x1
    dy+y1   
  
  
  ClearScreen(RGB(255,255,0))
  DisplayTransparentSprite(#sprite_zaun,150,10)
  
  DisplaySprite(sprite_hgrund,900,0) 
  DisplaySprite(#sprite_auto_load,910,10)
  GrabSprite(#sprite_grab,900,0,84,84,#PB_Sprite_PixelCollision) 
  CopySprite(#Sprite_grab, #Sprite_auto,#PB_Sprite_PixelCollision) 
  
  DisplaySprite(#sprite_auto_loadr,910,10)
  GrabSprite(#sprite_grab,900,0,84,84,#PB_Sprite_PixelCollision) 
  CopySprite(#Sprite_grab, #Sprite_autor,#PB_Sprite_PixelCollision) 
  
  DisplaySprite(#sprite_auto_loadl,910,10)
  GrabSprite(#sprite_grab,900,0,84,84,#PB_Sprite_PixelCollision) 
  CopySprite(#Sprite_grab, #Sprite_autol,#PB_Sprite_PixelCollision) 
  
  
  RotateSprite(#sprite_auto_load,winkel+90,#PB_Absolute)
  RotateSprite(#sprite_auto_loadr,winkel+90,#PB_Absolute)
  RotateSprite(#sprite_auto_loadl,winkel+90,#PB_Absolute)
  

  DisplayTransparentSprite(#sprite_auto,dx,dy)
  DisplayTransparentSprite(#sprite_autor,dx,dy)
  DisplayTransparentSprite(#sprite_autol,dx,dy)
  colli = SpritePixelCollision(#Sprite_auto, dx,dy, #Sprite_zaun,150,10)
  collir = SpritePixelCollision(#Sprite_autor, dx,dy, #Sprite_zaun,150,10)
  collil = SpritePixelCollision(#Sprite_autol, dx,dy, #Sprite_zaun,150,10)
  
  FlipBuffers()
  If collil
    winkel=winkel+3
  ElseIf collir
    winkel=winkel-3
  EndIf  
   
ForEver

Hier ein Bild:
Bild

Re: SpritePixelCollision bei 5.2 so schlecht !

Verfasst: 01.10.2013 23:31
von STARGÅTE
Warum machst du denn noch ein CopySprite() ?
Du kannst doch gleich GrabSprite(#Sprite_autol) und GrabSprite(#Sprite_autor) machen.
funkheld hat geschrieben:Die Geschwindigkeit wird durch diese 3 Spritegeschichten hintereinander nicht wesentlich beeinflusst, weil die Kopiergeschichten echt superschnell sind.
Wenn du meinst ...
bei diesem Code habe ich ohne GrabSprite() 9500 FPS
mit einem GrabSprite() habe ich nur noch 300 FPS !! Also 32 mal langsammer.
Klar sind 300 FPS immer noch genug, aber wenn du mehr solche Sachen einbaust ...

Code: Alles auswählen

InitSprite()


Enumeration
   #Window
EndEnumeration

OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0, #PB_Screen_NoSynchronization)

TransparentSpriteColor(#PB_Default, $000000)
CreateSprite(1, 256, 256, #PB_Sprite_PixelCollision)
CreateSprite(2, 64, 64, #PB_Sprite_PixelCollision)

If StartDrawing(SpriteOutput(1))
   Box(0, 0, 16, 256, $FFFFFF)
   Box(0, 0, 256, 16, $FFFFFF)
   StopDrawing()
EndIf

If StartDrawing(SpriteOutput(2))
   Box(24, 0, 16, 64, $FFFFFF)
   StopDrawing()
EndIf

Define X, Y, Time.i, Count.i

Repeat
   
   Repeat
      
      Select WindowEvent()
         Case #PB_Event_CloseWindow
            End
         Case #Null
            Break
      EndSelect
      
   ForEver
   
   ClearScreen(0)
   
   DisplayTransparentSprite(1, 100, 100)
   DisplayTransparentSprite(2, WindowMouseX(#Window)-32, WindowMouseY(#Window)-32)
   
   GrabSprite(3,0,0,100,100,#PB_Sprite_PixelCollision) 
   
   If ElapsedMilliseconds()-Time > 1000
     SetWindowTitle(#Window, Str(Count))
     Time = ElapsedMilliseconds()
     Count = 0
   EndIf
   
   FlipBuffers()
   Count + 1
   
ForEver