Growbook, Cannabis, Notizbuch, Growbuch, Pflanzenzucht, Samenbank, Seedbank, Software, Stammbaum, Kreuzen, züchten,growen,anbauen,News,GIB,Lux,Omega,Mars, Dünger,BioBizz,Hesi,Athena,
die Software für deinen Anbau
1

Willkommen

Max2D Kollision Teil 1

Max2D Kollision Teil 1
(c) Assari 2006
Ins Deutsche übersetzt von simi


Ein Spiel, bei dem nichts passiert wenn zwei Objekte sich einfach übereinander bewegen, macht keinen Spass. Auch ein simples Spiel wie zum Beispiel Pong braucht Kollision.

Kollision ist nicht anderes als dass sich zwei Objekte überlappen. Lass uns einen Blick auf die einfachste Kollision werfen, wenn zwei Rechtecke sich überschneiden.

Die einfachste Form der Kollisionerkennung ist das Überschneiden von Rechtecken.

Lass uns dies an einem Beispiel anschauen:

    Graphics 640,480
While Not KeyHit(key_escape) Or AppTerminate()
  Cls
  SetColor 0,255,0
  DrawRect 150,200,100,100
  SetColor 0,0,255
  DrawRect MouseX(),MouseY(),100,100
  Flip
Wend
End


Max1 1


Wenn du das Programm ausführst, wirst du bemerken dass keine Kollision erkannt wird. Es passiert nichts, wenn sich die beiden Rechtecke gegenseitig überlappen.

Lass uns jetzt eine Kollisionsfunktion, RectsOverlap, hinzufügen und die Farbe des beweglichen Rechtecks ändern, wenn eine Überschneidung stattfindet.

    Graphics 640,480
While Not KeyHit(key_escape) Or AppTerminate()
  Cls
  SetColor 0,255,0
  DrawRect 150,200,100,100

  If RectsOverlap(150,200,100,100,MouseX(),MouseY(),100,100)
      SetColor 255,0,0
  Else
      SetColor 0,0,255
  EndIf
  DrawRect MouseX(),MouseY(),100,100
  Flip 
Wend
End

Function RectsOverlap:Int(x0, y0, w0, h0, x2, y2, w2, h2)
    If x0 > (x2 + w2) Or (x0 + w0) < x2 Then Return False
    If y0 > (y2 + h2) Or (y0 + h0) < y2 Then Return False
    Return True
End Function

 

Max1 2 3

Jetzt können wir sehen, dass das Rechteck rot wird, wenn eine Kollision vorkommt. Jetzt haben wir unsere erste funktionierende Kollisionsfunktion smile

Jetzt verändern wir unser Programm so, dass wir einen beweglichen Kreis anstatt eines Rechteckes haben:

    Graphics 640,480
While Not KeyHit(key_escape) Or AppTerminate()
  Cls
  SetColor 0,255,0
  DrawRect 150,200,100,100

  If RectsOverlap(150,200,100,100,MouseX(),MouseY(),100,100)
      SetColor 255,0,0
  Else
      SetColor 0,0,255
  EndIf
  DrawOval MouseX()-50,MouseY()-50,100,100
  Flip 
Wend
End

Function RectsOverlap:Int(x0, y0, w0, h0, x2, y2, w2, h2)
    If x0 > (x2 + w2) Or (x0 + w0) < x2 Then Return False
    If y0 > (y2 + h2) Or (y0 + h0) < y2 Then Return False
    Return True
End Function


Unsere Kollisionsüberprüfen funktioniert nicht mehr so ganz richtig. Wir brauchen jetzt eine andere Funktion, die speziell für das Überprüfen der Kollision zwischen Kreisen (oder Ellipsen!) und Rechtecken geeignet ist.

    Graphics 640,480
While Not KeyHit(key_escape) Or AppTerminate()
  Cls
  SetColor 0,255,0
  DrawRect 150,200,100,100

  If CircRectsOverlap(150,200,100,100,MouseX(),MouseY(),50)
      SetColor 255,0,0
  Else
      SetColor 0,0,255
  EndIf
  DrawOval MouseX()-50,MouseY()-50,100,100
  Flip 
Wend
End

Function CircRectsOverlap(x0, y0, w0, h0, cx, cy, r)
    testX=cX
    testY=cY
    If TestX < x0 Then TestX=x0
    If TestX > (x0+w0) Then TestX=(x0+w0)
    If TestY < y0 Then Testy=y0
    If TestY > (y0+h0) Then Testy=(y0+h0)

    Return ((cX-TestX)*(cX-TestX)+(cY-TestY)*(cY-TestY))<r*r
End Function



Max1 4 5

BlitzMax

Wenn wir für jedes verschiedene Paar von Kollisionsobjekten einen andere Funktion bräuchten, gerieten wir in ernste Schwierigkeiten. Du kannst auch sehen, dass wenn wir das simple Rechtecküberlappen verlassen haben, die dahinter steckende Mathematik immer schwieriger wird.

Zum Glück unterstützt BlitzMax (oder genauer gesagt Max2D) mehrere Kollisionsfunktionen um uns das Leben leichter zu machen. Lass uns anschauen, wie wir mit den Max2D-Kollisionsfunktionen die obige Kollision gelöst hätten.

ImagesCollide

Die simpelste Kollisionsfunktion, die von BlitzMax unterstüzt wird, ist ImagesCollide. Sie hat die folgende Syntax

Function ImagesCollide(image1:TImage,x1,y1,frame1,image2:TImage,x2,y2,frame2)


Die Funktion braucht die beiden Bilder, die wir auf Kollision überprüfen wollen, und deren Koordinaten auf dem Bildschirm. Wir können den Frame-Parameter im Moment ignorieren, indem wir ihn auf 0 setzten.

      ImagesCollide(Alien,150,200,0,Player,MouseX(),MouseY(),0)


In der obigen Codezeile befindet sich das Alien auf der Position 150,200 und der Player an der aktuellen Mausposition.

Führe das untenstehende Programm aus und schau dir die Kollision in Aktion an.

Hinweis: Alle in dieser Tutorialserie verwendeten Bilder findest du im Verzeichnis "media"!

    Graphics 640,480
Local URL:String="http::www.hanfgebiet.de/"
Local Player:TImage=LoadImage(LoadBank(URL+"blobship_1-1.png"))
Local Alien:TImage=LoadImage(LoadBank(URL+"cartoonufo_1-1.png"))

While Not KeyHit(key_escape) Or AppTerminate()
  Cls
  DrawImage Alien,150,200
  DrawImage Player,MouseX(),MouseY()
  If ImagesCollide(Alien,150,200,0,Player,MouseX(),MouseY(),0)
      SetClsColor 255,0,0
  Else
      SetClsColor 0,0,0
  EndIf
  Flip
Wend
End

 

Max1 7 6


Wie du sehen kannst, erspart das benutzen dieser Funktion sehr viel Zeit.

ImagesCollide mit Animation

Lass uns nun eine Blick auf den Frame-Parameter werfen, den wir vorhin übersprungen haben. Wenn du das Programm ausführst, wirst du eine Explosionsanimation sehen, die mit unserem Raumschiff kollidiert.

    Graphics 640,480
Local URL:String="http::www.hanfgebiet.de/"
Local Player:TImage=LoadImage(LoadBank(URL+"blobship_1-1.png"))
Local Alien:TImage
=LoadAnimImage(LoadBank(URL+"exp1.png"),64,64,0,16)
Local Frame:Int=0
Local AnimDelay:int=10

While Not KeyHit(key_escape) Or AppTerminate()
  Cls
  DrawImage Alien,150,200, Frame
  DrawImage Player,MouseX(),MouseY()
  If ImagesCollide(Alien,150,200,Frame,Player,MouseX(),MouseY(),0)
      SetClsColor 255,0,0
  Else
      SetClsColor 0,0,0
  EndIf
  Flip
  If AnimDelay<0 Then
     Frame :+ 1
     If Frame>15 Then Frame=0

     AnimDelay=10
  EndIf
  AnimDelay :- 1


Wend
End


Um ImagesCollide für animierte Funktionen zu benutzen, brauchen wir nur die Bilder mit dem aktuellen Frame zu zeichnen und dann das gleiche Frame für den ImagesCollide-Parameter zu benutzen. AnimDelay und Frame werden für die Animation benutzt.

08 09


ImagesCollide mit Skalierung

BlitzMax erlaubt es Bilder mit SetScale in Echtzeit zu skalieren. SetScale hat folgende Syntax:

Function SetScale( scale_x#,scale_y# )


Leider funktioniert die ImagesCollide-Funktion nicht mehr richtig, wenn Skalierung involviert ist. Probier den folgende Code aus und beobachte wie die Kollision nicht mehr richtig funktioniert.

    Graphics 640,480
Local URL:String="http::www.hanfgebiet,de/"
Local Player:TImage=LoadImage(LoadBank(URL+"blobship_1-1.png"))
Local Alien:TImage=
LoadAnimImage(LoadBank(URL+"exp1.png"),64,64,0,16)
Local Frame:Int=0
Local AnimDelay:int=10
Local PlayerSize:Int=1
Local AlienSize:Int=2

While Not KeyHit(key_escape) Or AppTerminate()
  Cls
  SetScale AlienSize,AlienSize
  DrawImage Alien,150,100,Frame
  SetScale PlayerSize,PlayerSize
  DrawImage Player,MouseX(),MouseY()
  If ImagesCollide(Alien,150,200,Frame,Player,MouseX(),MouseY(),0)
      SetClsColor 255,0,0
  Else
      SetClsColor 0,0,0
  EndIf
  Flip
  If AnimDelay<0 Then
     Frame :+ 1
     If Frame>15 Then Frame=0

     AnimDelay=10
  EndIf
  AnimDelay :- 1

Wend
End

 

10

Zum Glück hat BlitzMax eine Variante von ImagesCollide die ImagesCollide2 genannt wird. ImagesCollide2 hat folgende Syntax:

Function ImagesCollide2(image1:TImage,x1,y1,frame1,rot1#,scalex1#,scaley1#,image2:TImage,x2,y2,frame2,rot2#,scalex2#,scaley2#)


Beachte dass die Rotation und Skalierung des Bildes mit den Parametern angegeben werden kann. Alles was wir machen müssen ist, die folgende Funktion wie folgt zu benützen:

      If ImagesCollide2(Alien,150,200,Frame,0,AlienSize,AlienSize,Player,MouseX(),MouseY(),0,0,PlayerSize,PlayerSize)


Ersetze ImagesCollide im obigen Beispiel durch ImagesCollide2 und sie zu, wie die Kollision nun richtig funktioniert.

ImagesCollide mit Drehung

Ich lasse es also eine Übung für dich, herauszufinden, wie die Rotationsangabe benutzt werden sollte smile

In diesem Tutorial sahen wir zwei einfache (aber schnelle) Wege auf Kollision zu überprüfen, indem wird die Rechteck- und die Kreis-Rechteck-Funktionen benutzen. Aber die Funktionen gehen nur für Rechtecke und Kreise.

Weil unsere Spiele meistens Bilder verwenden, benötigen wir höher entwickelte Funktionen. Glücklicherweise unterstützt BlitzMax die beiden pixelgenauen Funktionen ImagesCollide und ImagesCollide2.

Im nächsten Tutorial, werden wir sehen, wie wir ein von BlitzMax unterstütztes, hoch entwickeltes Kollisionssystem anwenden können.