Problem mit Trefferabfrage!

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Shinkiro1

ehemals "Espada"

Betreff: Problem mit Trefferabfrage!

BeitragMi, Jul 23, 2008 18:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Community,

Leider muss mein 1 Beitrag gleich ein Hilfethema sein, aber ich sitzte an diesem Problem nun schon einige Tage, also wollte ich euch fragen.

Also, ich mach gerade meine ersten Gehversuche mit B+ und versuche eine Art Spaceshooter zu programmieren. Alles klappt recht gut, bis auf die Kollisionsabfrage.
Da ich Types benutze und diese aber in Funktionen initialisiere sind sie ja lokal(oder?), also an die Funktion gebunden. Wenn ich nun in einer anderen Funktion die Koordinaten in einer For Next Loop abfragen will
und im Spiel der Schuss mit dem Gegner überlappt kommt die Fehlermeldung "Object does not exist".
Hier mal der Code:
Code: [AUSKLAPPEN]

;============================================================>
;===================|*****ProjectName*****|==================>
;============================================================>





;------------------------------------------------------------->
;:::::::::::::::: Init >> Setup Program :::::::::::::::::::::|
;------------------------------------------------------------->

AppTitle "Aerials"
Graphics 800,600,32,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()
AutoMidHandle True



Const DOWNKEY = 208,UPKEY = 200
Const LEFTKEY = 203,RIGHTKEY = 205
Const SPACEKEY = 57
Const X1BORDER = 30,X2BORDER = 670
Const Y1BORDER = 50,Y2BORDER = 490
Const PLAYERSPEED = 6
Const SHOTSPEED = 10
Const ENEMYSPEED = 3
Const FPS = 60



Global bgPic = LoadImage("pic\bg.png")
Global playerPic = LoadImage("pic\player.png")
Global lebenPic = LoadAnimImage("pic\leben.png",54,16,0,3)
Global shotPic = LoadImage("pic\shot.png")
Global enemyPic = LoadImage("pic\enemy1.png")
Global shotSnd = LoadSound("sound\shot.wav")
Global music = PlayMusic("sound\bgmusic.mid")
Global font = LoadFont("Comic Sans MS",24)
Global frames = CreateTimer(FPS)
Global score = 0
Global continues = 3
Global enemyCreator = 0
Global enemyFrCount = 0
Global enemyFrame = 0
Global framespeed = 0


SoundVolume shotSnd,0.8
ChannelVolume music,0.3
MaskImage enemyPic,0,0,0
MaskImage playerPic,255,255,255
MaskImage shotPic,255,255,255

;------------------------------------------------------------->  Types


Type player
   Field x,y
   Field leben
   Field waffe$
End Type

Type enemy
   Field x,y
   Field tot
   Field image
   Field frame
End Type

Type shot
   Field x,y
   Field hit
   Field image
End Type


Global player.player = New player
player\x = 50
player\y = 200
player\leben = 3
player\waffe = "Normal"

;-------------------------------------------------------------> Type Ende



;------------------------------------------------------------->
;\\\\\\\\\\\\\\\\\\\\\\  Main Loop  \\\\\\\\\\\\\\\\\\\\\\\\\|
;------------------------------------------------------------->

While Not KeyHit(1)
   
   Cls
   MovePlayer()
   ShotPlayer()
   CreateEnemy()
   DrawStuff()
   WaitTimer(frames)
   Flip
   
Wend

;------------------------------------------------------------->
;**********************  Functions  *************************|
;------------------------------------------------------------->

;------------------------------------------------------------->
Function MovePlayer()
   
   If  Not player\y <= Y1BORDER Or player\y >= Y2BORDER ; wenn er nicht über den oberen oder unteren Rand hinausgeht
      If KeyDown(UPKEY)
         player\y = player\y - PLAYERSPEED
      ElseIf KeyDown(DOWNKEY)
         player\y = player\y + PLAYERSPEED
      EndIf
   ElseIf player\y <= Y1BORDER         ; wenn doch setzte ihn um 3 zurück
      player\y  = Y1BORDER + 1
   ElseIf player\y >= Y2BORDER
      player\y = Y2BORDER - 1
   EndIf
   
   If  Not player\x <= X1BORDER Or player\x >= X2BORDER ; wenn er nicht über den oberen oder unteren Rand hinausgeht
      If KeyDown(LEFTKEY)
         player\x = player\x - PLAYERSPEED
      ElseIf KeyDown(RIGHTKEY)
         player\x = player\x + PLAYERSPEED
      EndIf
   ElseIf player\x <= X1BORDER         ; wenn doch setzte ihn um 3 zurück
      player\x  = X1BORDER + 1
   ElseIf player\x >= X2BORDER
      player\x = X2BORDER - 1
   EndIf
   

End Function
;------------------------------------------------------------->
Function ShotPlayer()
   
   If KeyHit(SPACEKEY)
      shot.shot = New shot
      shot\x = player\x + 28
      shot\y = player\y
      shot\hit = 0
      shot\image = shotPic
      PlaySound shotSnd
   EndIf
   
End Function
;------------------------------------------------------------->
Function CreateEnemy()
   
   enemyCreator = enemyCreator+1
   If enemyCreator >= 120 ; kreire jeden 120 Durchlauf einen Gegner
      Local wert = Rand(10000,32000) Mod 450   ; auf einer zufälligen Position
      If wert <= Y1BORDER
         wert = Y1BORDER + 3
      ElseIf wert >= Y2BORDER
         wert = Y2BORDER - 3
      EndIf
      
      Local enemy.enemy = New enemy
      enemy\x = 800
      enemy\y = wert
      enemy\tot = 0
      enemy\image = enemyPic
      enemy\frame = 0
      enemyCreator = 0
   EndIf
   
   
End Function
;------------------------------------------------------------->
Function DrawStuff()
   
   DrawImage bgPic,0,0          ; draw BG
   DrawImage playerPic,player\x,player\y   ; draw Player
   
   SetFont font
   Color 232,158,45  ;setze Farbe auf orange
   Text 720,20,score   ;draw Score
   DrawImage lebenPic,92,14,player\leben - 1 ;weil der Frame bei 0 zu zählen beginnt
   
   For shot.shot = Each shot        ;draw Shot
      shot\x = shot\x + SHOTSPEED
      DrawImage shot\image,shot\x,shot\y
      If shot\x >= 800 Then Delete shot.shot
   Next
   
   For enemy.enemy = Each enemy
      enemy\x = enemy\x - ENEMYSPEED
      DrawImage enemy\image,enemy\x,enemy\y
      If enemy\x <= -10 Then Delete enemy.enemy
      
      If ImagesOverlap(enemy\image,enemy\x,enemy\y,shot\image,shot\x,shot\y)   ; <--------- Hier die Problemsteller
         Delete enemy.enemy            
      EndIf
   Next
   
End Function


Achja, ich will die Types nicht in Main initialisieren, es wird ja irgendeine andere Möglichkeit geben.
Vielleicht ist es auch ein anderer Fehler, aber ich komm nicht drauf.

Grüße ~ Espada

ToeB

BeitragMi, Jul 23, 2008 18:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Also erstmal Hallo und wilkommen im Forum ^^ !

Guck dir am besten die Befhle zu diesem Thema an :


Sollte erstmal reichen... Für einfache Kollision solltest du villeicht mit IF-Abfragen machen...


mfg ToeB
[/code]
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

Shinkiro1

ehemals "Espada"

BeitragMi, Jul 23, 2008 19:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Also erstmal Hallo und wilkommen im Forum ^^ !

Danke ^^

Das Problem ist, dass ich das mit einem dieser Befehle(ImagesOverlap, eine der letzten Zeilen im Code) mache und dann eine Fehlermeldung bekomme(Object does not exist).

Also das der Type nicht existiert weiß ich ja aber welche Möglichkeiten gäbe es noch eine Kollisionsabfrage zu realisieren(mit meinem Code).

Danke trotzdem für die Antwort.

Silver_Knee

BeitragMi, Jul 23, 2008 19:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]
      If enemy\x <= -10 Then Delete enemy.enemy
     
      If ImagesOverlap(enemy\image,enemy\x,enemy\y,shot\image,shot\x,shot\y)   ; <--------- Hier die Problemsteller
         Delete enemy.enemy           
      EndIf



Wenn enemy\x<=-10 ist, dann löschst du den enemy. Leider vesuchst du eine zeile später wieder auf ihn zuzugreifen....

Code: [AUSKLAPPEN]
      If enemy\x <= -10
         Delete enemy.enemy
      else
        If ImagesOverlap(enemy\image,enemy\x,enemy\y,shot\image,shot\x,shot\y)   ; <--------- Hier die Problemsteller
           Delete enemy.enemy           
        EndIf
      EndIf


So nun wird nur eine Kollision abgefragt wenn enemy\x noch nicht <= -10 ist. Dann exestiert auch das Objekt.

Shinkiro1

ehemals "Espada"

BeitragMi, Jul 23, 2008 19:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm, leider gibt der Debugger immer noch die Stelle als Fehler an die ich oben markiert habe(if imagesoverlap(...))
Wenn ich im Debugger nachsehe hat der Type "shot.shot" immer den Wert Null wenn die Fehlermeldung ausgespuckt wird.

Achja, sind Types eigentlich immer global?

Xeres

Moderator

BeitragMi, Jul 23, 2008 19:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Da ich Types benutze und diese aber in Funktionen initialisiere sind sie ja lokal(oder?), also an die Funktion gebunden.
Ich glaube, die meisten Missverständnisse im Umgang von Types gibt es, weil Zugriffsvariablen und Typeliste durcheinandergebracht werden...
Beispiel an deinem Code:
Code: [AUSKLAPPEN]
Type player
   Field x,y
   Field leben
   Field waffe$
End Type

Global player.player = New player
player\x = 50
player\y = 200
player\leben = 3
player\waffe = "Normal"

Damit besitzt du 1. eine Type-liste "player" mit einem Eintrag (der mit new erzeugt wurde) und 2. Eine zugriffsvariable "player" mit der du überall auf den Eintrag in der Liste zurückgreifen kannst. Weniger verwirrend wäre es, den Type als solchen kenntlich zu machen, nicht unüblich z.B. ein T voran zu stellen:
Code: [AUSKLAPPEN]
Type Tplayer
   Field x,y
   Field leben
   Field waffe$
End Type

Global player.Tplayer = New Tplayer
player\x = 50
player\y = 200
player\leben = 3
player\waffe = "Normal"

Okay, besser lesbar und hier kommt nun die Erklärung wie Types und Funktionen zusammenpassen: Der Type Tplayer ist immer global! D.h. du kannst in Funktionen alle Einträge mit For...Each durchgehen, neue Einträge erstellen usw.
Wenn du die Zugriffvariable player Global erstellst und nur einen Eintrag in Tplayer hast, wirst du diesen Eintrag über player auch ansprechen können.
Nun die Stelle mit dem Problem:
Code: [AUSKLAPPEN]
For shot.shot = Each shot        ;draw Shot
   [...]
Next

For enemy.enemy = Each enemy
   [...]
   If ImagesOverlap(enemy\image,enemy\x,enemy\y,shot\image,shot\x,shot\y)
Next

In der ersten Schleife aktuallisierst du die Tshot-Einträge, aber greifst dann in der enemy-Schleife auf den Eintrag nach dem letzten zu - der existiert natürlich nicht. Du musst die Schleifen verschachteln um jeden Eintrag eines Types gegen den anderen zu prüfen.
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)

Shinkiro1

ehemals "Espada"

BeitragMi, Jul 23, 2008 20:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit dem verschachteln der if Abfragen war eine sehr gute Idee.
Außerdem habe ich noch eine Bedingung eingebaut, dass das Object sicher nicht 0 ist(da es doch noch Fehler gab) aber so läuft es problemlos.

Code: [AUSKLAPPEN]

Function DetectCollision()
   
   For enemy.enemy = Each enemy
      If enemy\x <= -10
         Delete enemy.enemy
      Else
         For shot.shot = Each shot
            If Not enemy.enemy = Null
            If ImagesOverlap(enemy\image,enemy\x,enemy\y,shot\image,shot\x,shot\y)
               Delete enemy.enemy
               Delete shot.shot
            EndIf
         EndIf
         Next
      EndIf
   Next
   
End Function


@Xeres
Danke für die ausdrückliche Erklärung, wirklich nett Smile

Auch den anderen ein Danke

Grüße ~ Espada

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group