ImagesCollide bei gleichen Types

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Lakorta

Betreff: ImagesCollide bei gleichen Types

BeitragDo, Dez 09, 2010 17:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich wollte bei meinem Programm eine Kollision unter 2 gleichen Types machen. Ich hab das jetzt schon mal so versucht:

Code: [AUSKLAPPEN]

If ImagesCollide(kugel,k\x,k\y,0,kugel,k\x,k\y,0)
         If not k\id=k\id
         End              ;Das End ist nur zum testen da
         EndIf
EndIf


Die ID hat sich bei jeden erstellen um 1 erhöht, so ungefähr:
Code: [AUSKLAPPEN]

k\id=kugel_id
kugel_id=kugel_id+1


Das funktioniert aber irgendwie nicht. Ich hoffe ihr könnt mir helfen.


ps: Schreibfehler nicht beachten, hab den Code jetzt noch mal aus dem Kopf abgeschrieben^^
---

Xeres

Moderator

BeitragDo, Dez 09, 2010 17:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei doppelt verschachtelten Types, muss die Zugriffsvarible eben anders heißen...
BlitzBasic: [AUSKLAPPEN]
Local t1.TTest, t2.TTest

For t1 = Each TTest
For t2 = Each TTest
If t1<>t2 Then

EndIf
Next
Next

IDs sind nicht nötig.
Beachte: Alle TTest objekte werden in t1/t2 abgelegt - also kann es auch passieren, dass das gleiche Objekt in beiden Variablen referenziert wird - darum die Bedingung um das aus zu schließen.
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Lakorta

BeitragDo, Dez 09, 2010 18:16
Antworten mit Zitat
Benutzer-Profile anzeigen
So ganz versteh ich das jetzt nicht. Geht das auch wenn ich mehr als 2 Kugeln habe, die miteinander Kollidieren sollen?

Schonmal danke für die Antwort Very Happy
---

Hubsi

BeitragDo, Dez 09, 2010 18:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja. Die Schleifen sind verschachtelt. Heißt es werden alle Kugeln mit der 1. Kugel getestet. Im nächsten Durchlauf werden alle Kugeln mit der 2. Kugel getestet. Im dritten Durchlauf werden alle Kugeln mit... Du verstehst? Very Happy
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...

Xeres

Moderator

BeitragDo, Dez 09, 2010 18:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Types funktionieren so:
Neue Objekte werden mit New erstellt und in die interne Type-Liste eingetragen. Die Zugriffsvariable führt nur zu dem Eintrag in der Liste.
Wenn du mit Each die Liste/Type durchiterierst, bekommst du jedes Objekt aus dem Type. Ob schon eine andere Zugriffsvariable darauf zeigt oder nicht, ob es irgendwo Local mit New erstellt wurde oder Global ist egal - jedes Objekt wird in die eine, Globale Typeliste eingetragen und verschwindet von erst dann, wenn das Objekt mit Delete gelöscht wurde.

Wenn dir damit noch nicht geholfen ist, poste was von deinem Code.
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Lakorta

BeitragDo, Dez 09, 2010 18:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine Frage hätt ich da noch. Wo genau fügt man das denn ein? Also ich hätte das jetzt beim "New" eingefügt, währe das richtig?

Code: [AUSKLAPPEN]

Function create_kugel(x,y)
k.kugel=New kugel
k\x=x
k\y=y
k\dead=0
End Function
---

Xeres

Moderator

BeitragDo, Dez 09, 2010 18:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Was willst du da einfügen/machen?
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Lakorta

BeitragDo, Dez 09, 2010 18:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Das t1.TTest, t2.TTest

Code: [AUSKLAPPEN]

Function create_kugel(x,y)
k.kugel=New kugel      ;<-- Hier statt k.kugel
k\x=x
k\y=y
k\dead=0
End Function
---

Xeres

Moderator

BeitragDo, Dez 09, 2010 18:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich sehe immer noch nicht, was du da machen willst. Die Neue Kugel auf Kollision mit den schon vorhanden prüfen?
Was möchtest du erreichen?
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Lakorta

BeitragDo, Dez 09, 2010 19:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube ich habe dich irgendwie nicht ganz verstanden. Hier ist mal mein ganzer Code. Dabei soll die Energie sich addieren und so größer werden. Dafür muss ich überprüfen ob die 1er-Energie collidiert. Wo müsste ich dann dein Codestück einfügen?

Code: [AUSKLAPPEN]

;---Grafikeinstellungen---
Graphics 800,600,16,2
SetBuffer BackBuffer()
timer=CreateTimer(60)



;---IDs---
Global energie1_id
Global energie2_id
Global energie4_id
Global energie8_id
Global energie16_id



;---Typeeinstellungen---
background=LoadImage("Images\background.png")

energie1=LoadImage("Images\energie1.png")
MidHandle energie1
MaskImage energie1,255,0,255
Type energie1
Field x#
Field y#
Field counter
Field richtung
Field id
Field dead
End Type

energie2=LoadImage("Images\energie2.png")
MidHandle energie2
MaskImage energie2,255,0,255
Type energie2
Field x#
Field y#
Field counter
Field richtung
Field id
Field dead
End Type

energie4=LoadImage("Images\energie4.png")
MidHandle energie4
MaskImage energie4,255,0,255
Type energie4
Field x#
Field y#
Field counter
Field richtung
Field id
Field dead
End Type

energie8=LoadImage("Images\energie8.png")
MidHandle energie8
MaskImage energie8,255,0,255
Type energie8
Field x#
Field y#
Field counter
Field richtung
Field id
Field dead
End Type

energie16=LoadImage("Images\energie16.png")
MidHandle energie16
MaskImage energie16,255,0,255
Type energie16
Field x#
Field y#
Field counter
Field richtung
Field id
Field dead
End Type

create_energie1(400,300)
create_energie1(400,300)
;---!---Hauptschleife---!---
While Not KeyHit(1)
TileImage background



;---Atomeinstellungen---
;Energie1
For e1.energie1=Each energie1

e1\counter=e1\counter+1
If e1\counter=50
e1\richtung=Rand(1,8)
e1\counter=0
EndIf

If e1\richtung=1 Or e1\richtung=8
e1\y=e1\y-2
EndIf

If e1\richtung=2 Or e1\richtung=7
e1\x=e1\x-2
EndIf

If e1\richtung=3 Or e1\richtung=6
e1\y=e1\y+2
EndIf

If e1\richtung=4 Or e1\richtung=5
e1\x=e1\x+2
EndIf

If e1\x<0 e1\x=0
If e1\x>800 e1\x=800
If e1\y<0 e1\y=0
If e1\y>600 e1\y=600

DrawImage energie1,e1\x,e1\y

If ImagesCollide(energie1,e1\x,e1\y,0,energie1,e1\x,e1\y,0)
If Not e1\id=e1\id
End
EndIf
EndIf

If e1\dead=1 Delete e1.energie1
Next

;Energie2
For e2.energie2=Each energie2

e2\counter=e2\counter+1
If e2\counter=50
e2\richtung=Rand(1,8)
e2\counter=0
EndIf

If e2\richtung=1 Or e2\richtung=8
e2\y=e2\y-2
EndIf

If e2\richtung=2 Or e2\richtung=7
e2\x=e2\x-2
EndIf

If e2\richtung=3 Or e2\richtung=6
e2\y=e2\y+2
EndIf

If e2\richtung=4 Or e2\richtung=5
e2\x=e2\x+2
EndIf

If e2\x<0 e2\x=0
If e2\x>800 e2\x=800
If e2\y<0 e2\y=0
If e2\y>600 e2\y=600

DrawImage energie2,e2\x,e2\y

If e2\dead=1 Delete e2.energie2
Next

;Energie4
For e4.energie4=Each energie4

e4\counter=e4\counter+1
If e4\counter=50
e4\richtung=Rand(1,8)
e4\counter=0
EndIf

If e4\richtung=1 Or e4\richtung=8
e4\y=e1\y-2
EndIf

If e4\richtung=2 Or e4\richtung=7
e4\x=e4\x-2
EndIf

If e4\richtung=3 Or e4\richtung=6
e4\y=e4\y+2
EndIf

If e4\richtung=4 Or e4\richtung=5
e4\x=e1\x+2
EndIf

If e4\x<0 e4\x=0
If e4\x>800 e4\x=800
If e4\y<0 e4\y=0
If e4\y>600 e4\y=600

DrawImage energie4,e4\x,e4\y

If e4\dead=1 Delete e4.energie4
Next

;Energie8
For e8.energie8=Each energie8

e8\counter=e8\counter+1
If e8\counter=50
e8\richtung=Rand(1,8)
e8\counter=0
EndIf

If e8\richtung=1 Or e8\richtung=8
e8\y=e8\y-2
EndIf

If e8\richtung=2 Or e8\richtung=7
e8\x=e8\x-2
EndIf

If e8\richtung=3 Or e8\richtung=6
e8\y=e8\y+2
EndIf

If e8\richtung=4 Or e8\richtung=5
e8\x=e8\x+2
EndIf

If e8\x<0 e8\x=0
If e8\x>800 e8\x=800
If e8\y<0 e8\y=0
If e8\y>600 e8\y=600

DrawImage energie8,e8\x,e8\y

If e8\dead=1 Delete e8.energie8
Next

;Energie16
For e16.energie16=Each energie16

e16\counter=e16\counter+1
If e16\counter=50
e16\richtung=Rand(1,8)
e16\counter=0
EndIf

If e16\richtung=1 Or e16\richtung=8
e16\y=e16\y-2
EndIf

If e16\richtung=2 Or e16\richtung=7
e16\x=e16\x-2
EndIf

If e16\richtung=3 Or e16\richtung=6
e16\y=e16\y+2
EndIf

If e16\richtung=4 Or e16\richtung=5
e16\x=e16\x+2
EndIf

If e16\x<0 e16\x=0
If e16\x>800 e16\x=800
If e16\y<0 e16\y=0
If e16\y>600 e16\y=600

DrawImage energie16,e16\x,e16\y

If e16\dead=1 Delete e16.energie16
Next



;---Sonstiges---
WaitTimer timer
Flip 0
Wend
End



;---!---Funktionen---!---
Function create_energie1(x,y)
e1.energie1=New energie1
e1\x=x
e1\y=y
e1\counter=0
e1\richtung=Rand(1,8)
e1\id=energie1_id
e1\dead=0
energie1_id=energie1_id+1
End Function

Function create_energie2(x,y)
e2.energie2=New energie2
e2\x=x
e2\y=y
e2\counter=0
e2\richtung=0
e2\dead=0
End Function

Function create_energie4(x,y)
e4.energie4=New energie4
e4\x=x
e4\y=y
e4\counter=0
e4\richtung=Rand(1,8)
e4\dead=0
End Function

Function create_energie8(x,y)
e8.energie8=New energie8
e8\x=x
e8\y=y
e8\counter=0
e8\richtung=Rand(1,8)
e8\dead=0
End Function

Function create_energie16(x,y)
e16.energie16=New energie16
e16\x=x
e16\y=y
e16\counter=0
e16\richtung=Rand(1,8)
e16\dead=0
End Function


Erstmal danke für die Antworten Very Happy
---

Blitzprogger

BeitragDo, Dez 09, 2010 19:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ich dich richtig verstanden habe, willst du alle Teile eines gleichen Types miteinander testen.
Falls ja:
PseudoCode: [AUSKLAPPEN]
for t.typ = each typ
   old_tx = t\x
   old_ty = t\y
   for t.typ = each typ
      if blabla (  t\x  ,  old_tx  ,  t\y  ,  old_ty  ) then
         blub
      endif
   next
next

So hat's bei mir immer funktioniert.

mfg,Blitzprogger
Mein aktuelles Projekt, Irnithal: http://www.blitzforum.de/worklogs/415/

Unfreiwilliger Gewinner des BAC# 115. Wink

Tennisball

BeitragDo, Dez 09, 2010 20:20
Antworten mit Zitat
Benutzer-Profile anzeigen
@Blitzprogger: Es funktioniert vielleicht, aber es wird doppelt geprüft etc.
Xeres hatte da schon den besseren Ansatz. Wink

@Lakorta: Xeres' Code musst du dort einfügen, wo du deine Kollision überprüfen willst. In die innere If-Abfrage in seinem Code musst du deine Kollisionsabfrage einfügen.

mfg,
Tennisball

Hubsi

BeitragDo, Dez 09, 2010 20:26
Antworten mit Zitat
Benutzer-Profile anzeigen
@Blitzprogger: Das funktioniert so nicht. Nach dem ersten Durchlauf der inneren Schleife hat t.typ den Wert Null. Heißt wenn die äußere Schleife ihren zweiten Durchlauf starten will ist der Zeiger schon jenseits von gut und böse Mr. Green
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...

Xeres

Moderator

BeitragDo, Dez 09, 2010 20:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Lakorta, du hast da Mehrfach identischen Code - man benutzt Types für die Gleichen Objekte, da ist es nicht sonderlich sinnvoll energie1,2,4,8,16 zu verwenden - nimm stattdessen ein Field für den Unterschied und schon hast du schon mal 4/5 des Codes gespart.
Statt Richtungen würde ich dir auch empfehlen, direkt Geschwindigkeitsvariablen, entweder für X,Y oder Winkel und Stärke zu verwenden.
Schön wäre auch, wenn du den Code einrücken würdest (und bei If nicht auf Then verzichtest), dann sieht man auch Zugehörigkeiten.

Dein Problem sollte sich dann etwa so lösen lassen:
BlitzBasic: [AUSKLAPPEN]
For e1.energie1=Each energie1

;[...]
DrawImage energie1,e1\x,e1\y

For e1_2.energie1=Each energie1
If e1 <> e1_2 Then
If ImagesCollide(energie1,e1\x,e1\y,0,energie1,e1_2\x,e1_2\y,0) Then
;**Reaktion
EndIf
EndIf
Next

If e1\dead=1 Delete e1.energie1
Next
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
  • Zuletzt bearbeitet von Xeres am Fr, Dez 10, 2010 18:25, insgesamt einmal bearbeitet

Lakorta

BeitragDo, Dez 09, 2010 21:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke.
Das mit dem Einrücken werde ich auch noch tun, aber zurzeit hab ich ja noch relativ wenig If-Abfragen. Und Then sollte ich auch mal wieder verwenden, da hast du recht. Aber da das ja erstmal die Grundstruktur wird, wo ich das Prinzip meines Spiels teste, brauche ich ja noch nicht so sehr auf die Äußerlichkeit zu achten, solange ich den Code noch lesen kann Wink

Auf jeden Fall danke für die Antworten und auch für die Verbesserungskritik Very Happy
---

Hubsi

BeitragFr, Dez 10, 2010 16:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Naja, Deine Meinung soweit was das einrücken und Codestil angeht Very Happy Hast Du schonmal an IDEal gedacht? Das kann sich selbst um Einrückung und anderen Kram kümmern. Früher oder früher holt Dich das sonst ein Mr. Green
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...

Lakorta

BeitragFr, Dez 10, 2010 17:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Werde ich mir mal anschauen Very Happy
---

Shinkiro1

ehemals "Espada"

BeitragFr, Dez 10, 2010 19:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Da ich auch gerade an einem Kollisionssytem arbeite, hier ein paar Tipps die Performance zu steigern.
1) Beschränke die Zahl der Objekte die gegeneinander geprüft werden
Das ist der wichtigste Punkt, zB: 200 Objekte gegen 200 = 200² = 40 000
2) Mach eine Unterscheidung deiner Objekte zwischen sich bewegenden und statischen.
Ein statisches Objekt muss nämlich gegen kein anderes Objekt geprüft werden! Somit erspart man sich, dass
statische Objekte gegen andere statische Objekte prüfen (man muss auch gegen keine sich bewegende Objekte prüfen,
weil das bewegende Objekt sowieso gegen das statische checkt).
3) Sobald ein Objekt alle anderen geprüft hat sollte es aus der Kollision vollständig ausgechlossen werden. In BlitzMax macht man das einfach mit RemoveList( objekt ). In BB könnte es mit einer eigens geschriebenen Liste gemacht werden.
Diese Methode eliminiert über die Hälfte aller Kollisionen (geht man davon aus, dass alle bewegende Objeke sind).
4) Teile den Bildschirm in Bereiche (zb:9) und ordne jedes deiner Objekte dem Bereich zu wo es sich befindet (Achtung: ein Objekt kann sich auch in mehreren Bereichen befinden). Dann gehst du wieder normal vor und überprüfst jedes Objekt gegen jedes andere.
Vergleich:
Wir haben 900 Objekte am Bildschirm die alle miteinander kollidieren können: 900² = 810 000 Checks -.-
Wir teilen den Bildschirm in 9 Bereiche => jeder Bereich hat 900/9 = 100 Objekte
Nun prüfen wir in jedem Bereich, jedes Objekt gegen jedes andere in diesem Bereich:
100² = 10 000 Checks pro Bereich, 10 000 x 9 = 90 000 Checks
Die Anzahl der Checks ist von 810 000 auf 90 000 geschrumpft.
Dieser Test ist allerdings nicht ganz wahrheitsgetreu, da ein Objekt in mehreren Bereichen sein kann.

Ich habe die Methoden 1 - 3 schon selbst angewendet, was jedes mal zu großen Performance-Sprüngen geführt hat.
Derzeit werkle ich an Punkt 4, daher kann ich hier keine Garantie abgeben, dass diese so wie in der Theorie funktioniert.

BladeRunner

Moderator

BeitragFr, Dez 10, 2010 20:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Um ein wenig zu ergänzen: wenn es Dir bei BMax um Performance geht:
a) nicht listremove() sondern linkremove - gib jedem objekt seinen link in der Liste mit auf den Weg, das erspart kiloweise Iterationen.
oder noch besser:
b) Speichere die Objekte in eine Bank oder ein Array und iteriere über kleiner werdende Slices. schneller geht es nicht.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

mpmxyz

BeitragFr, Dez 10, 2010 20:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Noch besser zum Durchiterieren:
Fummelt erst gar nicht an der Liste herum!
BlitzBasic: [AUSKLAPPEN]
Local obj1.TObj,obj2.TObj
For obj1=Each TObj
obj2=After obj1
While obj2<>Null And obj1<>Null '
'Prüfen
obj2=After obj2
Wend
Next

mfG
mpmxyz
Moin Moin!
Projekte: DBPC CodeCruncher Mandelbrot-Renderer

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group