Kollisionen verursachen Performanceeinsturz
Übersicht

Turion87Betreff: Kollisionen verursachen Performanceeinsturz |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallöchen zusammen,
ich habe nach langer Zeit in vb.net und c# nun auch den Weg in die Spieleprogrammierung gefunden und mich mit einem Tutorial in die wichtigsten Befehle in Blitzmax eingearbeitet. (das war gestern) Jetzt sollte es mit Learning by Doing weitergehen. Ich möchte gerne ein Spiel gestalten, in dem es darum geht, aufgebaute Dominosteine umkippen zu lassen. Also habe ich mir mit Paint eine png "gemalt" in der eine Fallanimation enthalten ist. (test.png) dann habe ich einen Type "Stone" geschrieben und mir mit entsprechender Methode einige Steine "bauen" lassen. Durch eine Kollisionsabfrage wars dann auch möglich, die Steine fallen zu lassen. Cool ![]() Ich weiß, dass die Lösung mit 5 png's nicht die Beste ist. Vorher hatte ich es auch mit "LoadAnimImage" auf die test.png bezogen. Resultat war dasselbe ![]() Hier ist mal der Quellcode: Achso und wegen der lustigen for-Schleifen zum Erstellen der Steine bitte auch keine Kommentare ![]() Kurz was zum Code: Field Direction is dazu da, anzugeben in welche Richtung der Stein kippt. l-links r-rechts - = noch nicht gefallen x-bereitsgefallen Code: [AUSKLAPPEN] '-----------------SETUP GAME CONDITIONS-------------------- Global StoneList:TList=CreateList() Global ScreenW=1024 Global ScreenH=768 Global TDelay= 1 Global Img1:TImage=LoadImage("1.png") Global Img2:TImage=LoadImage("2.png") Global Img3:TImage=LoadImage("3.png") Global Img4:TImage=LoadImage("4.png") Global Img5:TImage=LoadImage("5.png") Graphics ScreenW,ScreenH,0 Abstand = 20 Start:TStone = New TStone.Create(Img1,20,50) Start2:TStone = New TStone.Create(Img1,20,80) Start3:TStone = New TStone.Create(Img1,20,110) Start4:TStone = New TStone.Create(Img1,20,140) Start5:TStone = New TStone.Create(Img1,20,170) Start6:TStone = New TStone.Create(Img1,20,200) Start7:TStone = New TStone.Create(Img1,20,230) Start8:TStone = New TStone.Create(Img1,20,260) Start9:TStone = New TStone.Create(Img1,20,290) Start10:TStone = New TStone.Create(Img1,20,320) Start11:TStone = New TStone.Create(Img1,20,350) Start12:TStone = New TStone.Create(Img1,20,380) For s = 2 To 10 TStone.Create(Img1,s*Abstand,50) Next For s = 2 To 20 TStone.Create(Img1,s*Abstand,80) Next For s = 2 To 30 TStone.Create(Img1,s*Abstand,110) Next For s = 2 To 40 TStone.Create(Img1,s*Abstand,140) Next For s = 2 To 50 For s2 = 1 To 10 TStone.Create(Img1,s*Abstand,140+s2*30) Next Next ' ---------------------MAIN LOOP------------------------- Repeat Cls For o:TGameObject=EachIn StoneList o.DrawSelf() o.UpdateState() Next If KeyDown(KEY_SPACE) Then Start.Direction = "r" If KeyDown(KEY_SPACE) Then Start2.Direction = "r" If KeyDown(KEY_SPACE) Then Start3.Direction = "r" If KeyDown(KEY_SPACE) Then Start4.Direction = "r" If KeyDown(KEY_SPACE) Then Start5.Direction = "r" If KeyDown(KEY_SPACE) Then Start6.Direction = "r" If KeyDown(KEY_SPACE) Then Start7.Direction = "r" If KeyDown(KEY_SPACE) Then Start8.Direction = "r" If KeyDown(KEY_SPACE) Then Start9.Direction = "r" If KeyDown(KEY_SPACE) Then Start10.Direction = "r" If KeyDown(KEY_SPACE) Then Start11.Direction = "r" If KeyDown(KEY_SPACE) Then Start12.Direction = "r" Flip Until KeyDown(KEY_ESCAPE) Or AppTerminate() End Type TStone Extends TGameObject Field DelayTime:Int = TDelay Field Direction:String = "-" Function Create:TStone(Image:TImage,xstart:Int,ystart:Int) Local Stone:TStone=New TStone CreateObject(Stone,Image,xstart,ystart) ListAddLast StoneList, Stone Return Stone End Function Method UpdateState() If KeyDown(KEY_RIGHT) X :+4 EndIf CheckCollision() DelayTime :-1 If DelayTime<=0 Then If Direction = "r" Or Direction = "l" Then If Frame < 4 Then 'Frame=-1 DrawText Frame, X+10,Y-10 DelayTime = TDelay Frame:+1 Select Frame Case 1 Image = Img2 Case 2 Image = Img3 Case 3 Image = Img4 Case 4 Image = Img5 Direction = "x" End Select Else DrawText Frame, X+10,Y-10 Direction = "x" EndIf EndIf EndIf End Method Method CheckCollision() For Local g:TStone=EachIn StoneList If g.Direction <> "x" Then If g<>Self Then If g.Direction <> "-" Then If ImagesCollide(Self.Image,X,Y,0,g.Image,g.X,g.Y,0) 'ListRemove(GameObjectList,g) Self.Direction = "r" EndIf EndIf EndIf EndIf Next ResetCollisions() End Method End Type Type TGameObject Field X:Int = 320 Field Y:Int = 420 Field Speed:Int=3 Field Image:TImage Field Frame:Int=0 Field XScale:Float=1.0 Field YScale:Float=1.0 Field Explosion:Int=0 Method DrawSelf() SetColor 255,255,255 SetScale XScale,YScale DrawImage Image,X,Y,0 End Method Method UpdateState() Abstract End Type Function CreateObject(Obj:TGameObject, Image:TImage,xstart:Int,ystart:Int,scale:Float=1.0) Obj.X=xstart Obj.Y=ystart Obj.XScale=scale Obj.YScale=Scale Obj.Image=Image If Obj.Image=Null Print "Not able to load image file. Program aborting" End EndIf End Function Hier ist auch nochmal der Code zum Download, damit ihr sehen könnt, was da nich so läuft: http://www.file-upload.net/dow...o.zip.html |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das liegt vermutlich an ImagesCollide. Pixelgenaue Kollisionsabfragen dauern. Mach erst eine schnelle Rechteck Kollision, und erst wenn die eintrifft wenn nötig etwas exakteres.
Setz' noch an den Anfang des Codes SuperStrict -> erzwingt Deklaration der Variablen, was Fehler vermeidet und verbessert etwas die Performance. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
Turion87 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Danke für die schnelle Antwort.
eine Rechteckkollision.. D.h. aus Stein 1, der nach rechts fällt nehm ich den am weitesten rechten Pixel und generiere daraus ein Rechteck und prüfe das mit den Steinen in meiner Stonelist? Wenn das Ergebnis positiv ist, dann mach ich eine Pixelgenaue Prüfung? Meinste das bringt was? Im Prinzip werden pro Reihe, in der Steine fallen - 5 Prüfungen gemacht. Frame 0 auf 1 1 auf 2 2 auf 3 3 auf 4 und 4 selbst (erst wenn die 4 geprüft wird, wird Direction auf "x" gesetzt und fällt dann nicht mehr. Mir ist grad ne Idee gekommen, dass ich die 5 Prüfungen auf eine reduzieren könnte, indem ich die Steine mit einem Tag versehe, der kennzeichnet, ob der geprüfte Stein bereits einen anderen angestoßen hat. Wenn dem so ist, dann braucht der nicht mehr geprüft werden, denn entweder ist der gerade beim Fallen (Frame 1-4) oder er liegt dann um (Frame 4) Naja werde ich wohl morgen mal testen. Kannst ja noch kurz schreiben, wie eine Rechteckprüfung/Kollision gemacht wird, wurde bestimmt schon im Forum hier behandelt. Danke schonmal ![]() |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Jedes Bild ist ein Rechteck. Wenn zwei Bilder nicht überlappen, kann es auch keine Kollision geben. Mit bekannten Positionen sowie Breite & Höhe sollte das kein Problem sein.
Wenn du von vorn herein noch Steine ausschließen kannst, ist natürlich auch gut. "Direction" würde ich noch als Integer deklarieren. Stringvergleiche dauern länger, was sich u.U. auch summieren kann - mit Konstanten hältst du den Code trotzdem lesbar. Funktionen kannst du übrigens auch in den Type Stecken; TypeName.Funktion(...) Oh, und... Code: [AUSKLAPPEN] If KeyDown(KEY_SPACE) Then
Start.Direction = "r" Start2.Direction = "r" Start3.Direction = "r" '[...] EndIf ...wäre hübscher. Mit Keyhit funktionierst deshalb nicht (in deiner Version), wie du vielleicht fest gestellt hast, da der Buffer beim ersten Keyhit gelöscht wird und bei den nachfolgenden nicht mehr True zurück gibt. Nicht vergessen im Forum zu suchen, viele Fragen werden schon mal aufgekommen sein. Ansonsten: Weitermachen & Viel Erfolg. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du könntest, bevor du auf eine Rechteckkollision prüfst, erstmal noch prüfen wie weit zwei Steine voneinander entfernt sind. Das dürfte noch ein wenig schneller sein als die Rechteckkollisionsprüfung. Dann kannst du sagen: Erst wenn zwei Steine eine Entfernung < x haben können sie überhaupt kollidieren und erst dann prüfe ich das auch.
Btw. Gehört das nicht ins Beginners? Lg, M0rgenstern |
||
Turion87 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
eigentlich ist das ja auch nur ne gaaanz simple testversion.
die eigentliche version soll dann nachher ein "raster" oder ein 2d feld im hintergrund haben, wo ich dann eine Zelle sogroß mache, wie eine png, also 32 x 32 und dann könnte ich mir das kollidieren auch sparen, weil wenn in der Zelle x ein Stein steht und in x+1 keiner, brauch ich nicht prüfen, wie morgenstern schon sagte. komm leider erst morgen zum proggen :/ |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Durch das Einfügen der Bilder in jedes neue Element des Types wird auch viel Speicher verbraten.
Es würde eigentlich genügen die 5 Bilder in ein Array zu speichern und nun nur die Elementnummer im Typ zu verwalten. Die gibt es ja eh schon als "Frame". BlitzMax: [AUSKLAPPEN] Global Images:TImage[0]=LoadImage("1.png") Dann sind es für die Grafikkarte wirklich die immer gleichen 5 Bilder und es werden nicht soviele Daten in die Karte geschaufelt. |
||
- Zuletzt bearbeitet von Midimaster am Mo, Jul 25, 2011 16:39, insgesamt 2-mal bearbeitet
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich wüsste trotzdem mal gerne, was genau du mit Zeilen wie der folgenden bezwecken willst:
BlitzMax: [AUSKLAPPEN] Start6:TStone = New TStone.Create(Img1,20,200) Es wundert mich, dass das mit dem New davor überhaupt compiliert. Das New brauchst du gar nicht, das steckt ja schon in deinem Konstruktor mit drin. Lg, M0rgenstern |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group