Type-Problem

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Dicker Hobbit

Betreff: Type-Problem

BeitragMi, Aug 15, 2012 17:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Blitzer,

Ich bin für meinen Beitrag zum BCC auf ein Problem gestoßen. (Wenn ihr mir nicht helfen wollt um den Wettbewerb zu gewinnen, kann ich das sehr gut nachvollziehen Very Happy )

Und zwar folgende Problematik:
Ich möchte eine Kollision prüfen, die aber nur geprüft wird wenn ein Schuss abgefeuert wurde (klingt eigentlich einfach -.- )

Hier mein Code (der nicht funktioniert):
BlitzBasic: [AUSKLAPPEN]

If Not(First schuss=Null)
If ImagesCollide(g\image, g\x, g\y, 0, e\image, e\x, e\y, 0) Then
e\leben=e\leben-g\schaden
Delete g.schuss
;Wenn die Leben 0 sind, dann sterben und Geld an Spieler geben
If e\leben<=0 Then s\geld=s\geld+e\Wert:Delete e.enemy
EndIf
EndIf


Danke schon mal im Vorraus!

Lg Dicker Hobbit

Lobby

BeitragMi, Aug 15, 2012 17:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Zuersteinmal denke ich, dass Probleme generell unabhängig von Wettbewerben gelöst werden können (solange es nicht darum geht, die eigentliche Aufgabenstellung von anderen lösen zu lassen).

Nun zu deinem Code, es handelt sich um einen kleinen Schnippsel, zu dem du nicht mehr zu sagen hast, als "funktioniert nicht"? Du solltest inzwischen wissen, dass Probleme wenn möglich immer etwas genauer zu beschreiben sind. Und in diesem Fall hättest du selbstständig einige Tests durchführen können, um in Erfahrung zu bringen, wo genau es denn hakt (siehe z.B. DebugLog). Falls du dadurch den Fehler noch immer nicht finden solltest, hättest du hier immer noch die Gelegenheit nach Rat zu fragen.

Dinge, die du ausprobieren solltest:
Wird die Bedindung Not(First schuss=Null) überhaupt ausgelöst (wenn ja, warum listest du diese If-Abfrage dann überhaupt noch in deinem Code hier auf, wenn du doch offenbar deinen Auszug möglichst kurz halten willst)?
Lasse dir die Werte g\x,g\y,e\x und e\y ausgeben, um zu sehen, ob diese Werte korrekt sind/eine Kollision zulassen.

Eine für mich wichtige Frage wäre, warum du nur ein Geschoss auf Kollision überprüfst. Zudem zeigt dein Code nicht, wie du auf das Geschoss g kommst (vl. solltest du deine Variablen auch etwas ausführlicher Benennen, das erleichtert die Verständlichkeit ungemein).
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

Dicker Hobbit

BeitragMi, Aug 15, 2012 17:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Lobby,

Ich habe schon einiges ausprobiert und irgendwie verpeilt das hier mit hin zu schreiben (Sorry)
Also: Wenn ich mein Programm starte kommt eine Fehlermeldung (Object does not exist).

Die Bedingung Not(First schuss=Null) ist komischerweise immer erfüllt obwohl ich das Geschoss erst per Mausklick später erstelle.
Die Variablen g\x,g\y,e\x und e\y auszugeben würde meiner Meinung nach nichts bringen, weil sofort die Fehlermeldung kommt.

Ich prüfe mein Geschoss auf eine Kollision mit einem Gegner, was meinesachtens nicht so abwegig ist, oder?
Ich weiß nicht ganz was du gegen meine Variablenbezeichnung hast?
Was ist an Leben, Schuss, Geld etc. nicht aussagekräftig?
Wenn du e, g , s meinst , dass steht für enemy, Geschoss und Spieler.
Ok das Denglisch ist vllt. nicht die beste Variante, aber trotzdem kann man den Sinn erkennen

Lg Dicker Hobbit

Lobby

BeitragMi, Aug 15, 2012 18:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, ich meine Variablen wie e,g,s usw. Mag sein, dass für dich, der du ja gerade viel mit diesem Code zu tun hast, deren Bedeutung sofort erkennst, aber für Außenstehende sind solche Variablennamen eben doch sehr anstrengend (zumindest für wichtigere Variablen, und darum handelt es sich bei den oben genannten ja, solltest du auf einen auch für andere aussagekräftigen Namen nicht verzichten, das hilft dir zudem auch, den Code noch in 10 Jahren zu verstehen). Es bietet sich übrigens auch an, die Namen der Types stets mit einem T oder einer anderen Kennzeichnung anfangen zu lassen, damit man später leichter zwischen Variablen und Types unterscheiden kann.

Die Fehlermeldung "Object does not exist!" sagt doch quasi schon alles, nicht? Der Debug-Mode sollte dir zudem anzeigen, in welcher Zeile das Objekt nicht existiert, auf das du aber zuzugreifen versuchst (in BlitzBasic sind alle Types Objekte). Ich vermute (mehr kann ich ohne mehr Code nicht tun, das sollte nachvollziehbar sein), dass du g nichts zugewiesen hast, sodass g\image bei der Kollisionsprüfung zur Fehlermeldung führt (du kannst im Debugmode dir auch die Werte aller Variablen zum Zeitpunkt des Fehlers ansehen, was du offenbar nicht wusstest).
Deine Bedingung, ob ein Schuss vorhanden ist oder nicht, sieht für mich korrekt aus. Wenn sie also dennoch schon bevor ein Schuss erstellt wurde wahr ist, sollte man versuchen herauszufinden, warum.

Ganz nebenbei, "es funktioniert nicht" lässt nun wirklich nicht auf eine Fehlermeldung schließen (schon gar nicht auf eine derart spezifische, die des Rätsels Lösung bereithält), also merke dir bitte, dass dein Gegenüber hier nicht mehr wissen kann, als das, was du ihm preisgibst.
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux

Dicker Hobbit

BeitragMi, Aug 15, 2012 18:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Meiner Meinung nach liegt der Fehler darin, dass ich g.schuss in einer anderen Funktion erstellt habe und somit nicht in anderen Funktionen existiert.
Die Kollision wird in der "Gegnerzeichnen"- Funktion geprüft, um die Kollision für jeden Gegner zu prüfen.
Wenn ich die Schusskollision weglasse wird der Schuss nämlich gezeichnet (also existiert g\image)
Wie kann ich den Type also "Global" setzen ?

Das mit der Variablenbezeichnung nehm ich mir vor besser zu machen. Wink

Xeres

Moderator

BeitragMi, Aug 15, 2012 19:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Wie kann ich den Type also "Global" setzen ?
Wenn du First benutzt, schaut BB in der Globalen Liste des Types - das wird's also nur dann sein, wenn du das Objekt in einer Lokalen Variablen hast, und versuchst in einer Funktion darauf zu zu greifen.
Ohne weiteren Code schwer zu sagen.
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)

Dicker Hobbit

BeitragMi, Aug 15, 2012 19:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Also in der ersten Funktion wird der Schuss erstellt und im zweiten Teil möchte ich dann darauf zugreifen und da bekomm ich dann meine Fehlermeldung.

BlitzBasic: [AUSKLAPPEN]
Function schuss()
If Magazin=-1 Then Magazin=Waffenmagazin
If nachladen=True
Text 2, 440, "Reload"
If reloadtimer<MilliSecs()
Magazin=Waffenmagazin
nachladen=False
EndIf
EndIf
; wenn Taste gedrückt ... Patrone erstellen
If MouseDown(1) Then



If schusstimer<MilliSecs() And Magazin>0 Then
schusstimer=MilliSecs()+(600/Waffenrate)
g.schuss=New schuss
g\sx=s\x+30
g\sy=s\y+10
g\image=schussimage
g\schaden=Waffenschaden
g\schusswinkel=ATan2(mx-(s\x+16), my-(s\y+16))-90
g\speed=20

Magazin=Magazin-1
EndIf



EndIf

;Magazin nach laden

If KeyHit(19) Then
nachladen=True
reloadtimer=MilliSecs()+3000
EndIf

;Schussbewegung
For g.schuss=Each schuss
;Berechnung der Schussposition
g\x=(Cos(g\schusswinkel)*g\entfernung)+g\sx
g\y=-(Sin(g\schusswinkel)*g\entfernung)+g\sy
g\entfernung=g\entfernung+g\speed
;Kugeln malen
DrawImage g\image, g\x, g\y

If g\x>640 Or g\x<32 Or g\y>480 Or g\y<32 Then Delete g.schuss

Next

End Function


Function drawenemy()

For e.enemy=Each enemy

If MilliSecs()>e\animtimer Then
e\animtimer=MilliSecs()+200
e\frame=e\frame+1
If e\frame<0 Then e\frame=1
If e\frame>1 Then e\frame=0
EndIf


;Bewegung der Gegner
Select e\image
Case tankimage
If e\reach<e\entfernung Then
e\x=e\x+e\speed
e\reach=e\reach+e\speed
ElseIf e\reach=>e\entfernung And e\reach<2*e\entfernung
e\x=e\x-e\speed
e\reach=e\reach+e\speed
ElseIf e\reach=>2*e\entfernung
e\reach=0
EndIf
Case soldatimage
If e\reach<e\entfernung Then
e\y=e\y+e\speed
e\reach=e\reach+e\speed
ElseIf e\reach=>e\entfernung And e\reach<2*e\entfernung
e\y=e\y-e\speed
e\reach=e\reach+e\speed
ElseIf e\reach=>2*e\entfernung
e\reach=0
EndIf

End Select


; Schusskollision

If Not(First schuss=Null)

If ImagesCollide(g\image, g\x, g\y, 0, e\image, e\x, e\y, 0) Then
e\leben=e\leben-g\schaden
Delete g.schuss
;Wenn die Leben 0 sind, dann sterben und Geld an Spieler geben
If e\leben<=0 Then s\geld=s\geld+e\Wert:Delete e.enemy

EndIf
EndIf

DrawImage e\image, e\x, e\y, e\frame


Next

End Function

Xeres

Moderator

BeitragMi, Aug 15, 2012 19:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Klar, wenn du die Variable g nie zuweist... immer schön deklarieren, sonst gibt's nur Probleme!
Und nicht die gleichen Bezeichner für Verschiedene Sachen benutzen. Function schuss() und g.schuss=New schuss fragt ja schier nach Ärger.
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)

count-doku

BeitragMi, Aug 15, 2012 19:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Jop g müsste deklariert werden.

Die einfachste Möglichkeit wäre jetzt:
BlitzBasic: [AUSKLAPPEN]
;	Schusskollision

If Not(First schuss=Null)
g.schuss=First schuss
If ImagesCollide(g\image, g\x, g\y, 0, e\image, e\x, e\y, 0) Then
e\leben=e\leben-g\schaden
Delete g.schuss
;Wenn die Leben 0 sind, dann sterben und Geld an Spieler geben
If e\leben<=0 Then s\geld=s\geld+e\Wert:Delete e.enemy

EndIf
EndIf

Damit würde aber immer nur der jeweils 1.Schuss in der Type list abgefragt, da du ja (wahrscheinlich) für jeden Gegner alle Schüsse probieren willst, wäre das besser:
BlitzBasic: [AUSKLAPPEN]
;	Schusskollision

If Not(First schuss=Null)
For g.schuss=Each schuss
If ImagesCollide(g\image, g\x, g\y, 0, e\image, e\x, e\y, 0) Then
e\leben=e\leben-g\schaden
Delete g.schuss
;Wenn die Leben 0 sind, dann sterben und Geld an Spieler geben
If e\leben<=0 Then s\geld=s\geld+e\Wert:Delete e.enemy:Exit ; Damit der gegner nicht nochmal geprüft wird

EndIf
Next
EndIf

So gehst du bei jedem Gegner alle Schüsse durch und prüfst auf colli.
Sollte ein Schuss den Gegner treffen und ihn töten, kann der Gegner natürlich nicht nochmal abgefragt werden, deswegen das Exit

Habe die Codes jetzt nicht getestet müsste aber so laufen...

Hoffe es hilft,
Count-Doku

Dicker Hobbit

BeitragMi, Aug 15, 2012 20:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Hilfe!

Funktioniert jetzt. Very Happy

Lg Dicker Hobbit

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group