Kollision / Sprites

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

TomAT

Betreff: Kollision / Sprites

BeitragMi, Aug 14, 2013 20:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen!

Ich bin neu Very Happy

Ich versuche mich etwas in der Programmiersprache BlitzPlus.

Leider komme ich nicht weiter Sad

Folgendes:

Ich versuche 4 Raketen von Rechts nach Links fliegen zu lassen.
Der Spieler muss diesen ausweichen.
Falls er es nicht schafft, dann game over!

Aber wie mache ich das ???

Folgendes habe ich mir überlegt:

BlitzBasic: [AUSKLAPPEN]
Graphics 1024,768,0,2
SetBuffer BackBuffer()

variable = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein.png")
variable2 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")
variable3 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")
variable4 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")
variable5 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")

y = 50
x = 1000

a = 50
b = 500

c = 1000
d = 100

e = 1000
f = 200

g = 1000
h = 500


Repeat
Cls

DrawImage variable, a, b
DrawImage variable2, x, y
DrawImage variable3, c, d
DrawImage variable4, e, f
DrawImage variable5, g, h


For x=x-1 To 0
For c=c-1 To 0
For e=e-1 To 0
For g=g-1 To 0



If KeyDown(208) Then b=b+2
If KeyDown(200) Then b=b-2


If ImagesCollide(variable, a, b, 0, variable2, x, y, 0) Then Print "Kolli"


Next
Next
Next
Next

Flip

Until KeyHit(1)

End


Leider startet eine Rakete nach der Anderen und ich kann meinen Spieler nicht bewegen.
Ich weiß, dass etwas mit FOR/NEXT nicht stimmt, aber wie bekomme ich es hin, dass alles Gleichzeitig passiert ?

Tom!

Xeres

Moderator

BeitragMi, Aug 14, 2013 20:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Willkommen.
Was mir Spontan auffällt:
- Benenne deine Variablen eindeutig. variable sagt rein gar nichts aus. Rakete_bild wäre besser.
- Du benutzt zum laden einen absoluten Pfad - das wird auf anderen Rechnern nicht mehr funktionieren. Besser ist, Ressourcen relativ, d.h. ausgehend vom Quellcode zu laden.
- Du Lädst das gleiche Bild ein paar mal - das verbraucht Speicher und ist nur dann nötig, wenn du die Bilder einzeln verändern wolltest. Das Bild kannst du beliebig oft zeichnen.
Insgesamt also:
BlitzBasic: [AUSKLAPPEN]
Rakete_bild = LoadImage("Grafik\Rakete_oben1klein.png")


Wenn du jetzt mehrere Objekte verwalten willst, könntest du mit dim ein Array definieren oder besser gleich einen Type benutzen.

Erst mal solltest du ein Grundlagen Tutorial machen, vielleicht wird dir dann schon klarer, wie du das anpacken solltest.
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)
 

TomAT

BeitragMi, Aug 14, 2013 20:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke an Xeres !

Das mit den Variablen, das gleiche Bild ein paar mal und dem Pfad hat mich sowieso gestört.

Abgesehen davon habe ich etwas an meinem Quellcode verändert.
Nun kann ich meine Rakete bewegen und es kommt zu einer Antwort sobald ich mit der ersten Kollidiert bin, aber die anderen scheinen immer doppelt so schnell zu fliegen wie die vorher.

BlitzBasic: [AUSKLAPPEN]
Graphics 1024,768,0,2
SetBuffer BackBuffer()

variable = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein.png")
variable2 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")
variable3 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")
variable4 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")
variable5 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png")

y = 50
x = 1000

a = 50
b = 500

c = 1000
d = 100

e = 1000
f = 200

g = 1000
h = 500


Repeat
Cls

DrawImage variable, a, b
DrawImage variable2, x, y
DrawImage variable3, c, d
DrawImage variable4, e, f
DrawImage variable5, g, h


If KeyDown(208) Then b=b+5
If KeyDown(200) Then b=b-5
If ImagesCollide(variable, a, b, 0, variable2, x, y, 0) Then Print "Kolli"




For x=x-2 To 0
For c=c-2 To 0
For e=e-2 To 0
For g=g-2 To 0









Next
Next
Next
Next

Flip

Until KeyHit(1)

End



Ich sehe mich erst mal nach einem Tutorial zum Thema "dim" und "Type" um...

Vielen Dank !

Spark Fountain

BeitragMi, Aug 14, 2013 23:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo TomAT,

leider hast du ja in deiner neuen Version gar keine der Änderungen vorgenommen, die Xeres vorgeschlagen hatte. Falls du es noch nicht verstanden hast, ist das kein Problem, dafür ist das Beginner-Forum ja da Wink. Aber wenn du schreibst,
Zitat:
Das mit den Variablen, das gleiche Bild ein paar mal und dem Pfad hat mich sowieso gestört.

aber in deinem neuen Quellcode noch immer fast das gleiche steht, hast du wohl noch Schwierigkeiten damit. Dann frag lieber nochmal nach. Das soll übrigens, wenn überhaupt, nur konstruktive Kritik sein Very Happy.

Also, ich versuche mal deine Baustellen zu umschreiben:

Arrow Ein absoluter Pfad beginnt mit einem Laufwerksbuchstaben, meistens C, in deinem Fall ist es E. Dahinter kommt dann der gesamte Pfad, wo deine Ressource (=dein Bild / Sound / was auch immer) liegt. Ein relativer Pfad bezieht sich hingegen auf das Verzeichnis, in dem du deine BlitzBasic-Datei abgespeichert hast. Das ist in deinem Falle wahrscheinlich E:\BlitzData. Der Unterordner Grafik enthält deine Bilddateien, und ist immer dem aktuellen Verzeichnis untergeordnet, in welchem deine BlitzBasic-Datei liegt. Es reicht also, wenn du deine Bilder mit der Angabe des relativen Pfades lädst:

BlitzBasic: [AUSKLAPPEN]
;Nicht:
rakete_bild1 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein.png") ;FALSCH!
rakete_bild2 = LoadImage("E:\BlitzData\Grafik\Rakete_oben1klein1.png") ;FALSCH!

;Sondern:
rakete_bild1 = LoadImage("Grafik\Rakete_oben1klein.png") ;RICHTIG!
rakete_bild2 = LoadImage("Grafik\Rakete_oben1klein1.png") ;RICHTIG!

Jetzt kannst du dein Hauptverzeichnis auch beliebig umbenennen oder verschieben, die Grafiken werden trotzdem immer richtig geladen, solange du den Ordner Grafik liegen lässt, wo er ist. Wichtig ist der relative Pfad vor allem, wenn du dein Spiel später hochladen willst und andere Benutzer es irgendwo auf ihrer Festplatte entpacken. Dann funktionieren die absoluten Pfade nicht mehr, wie Xeres schon sagte.

Arrow Wenn du ein Bild mehrmals anzeigen willst, brauchst du es nur einmal zu laden und dann mehrmals zu zeichnen. Du legst also eine Variable an und lädst dein Bild dort rein, und dann rufst du DrawImage so oft auf, wie dein Bild gezeichnet werden soll:

BlitzBasic: [AUSKLAPPEN]
rakete_bild1 = LoadImage("Grafik\Rakete_oben1klein.png")

;zeichnet die Rakete das erste mal, ganz links oben
DrawImage rakete_bild1,0,0
;zeichnet die gleiche Rakete nochmal, etwas weiter unten
DrawImage rakete_bild1,0,50
;zeichnet sie ein drittes mal, etwas weiter rechts
DrawImage rakete_bild1,50,0
;usw...


In deinem Fall musst du das Raketenbild also viermal an den unterschiedlichen Positionen einzeichnen.

Arrow Der Grund, warum sich die Raketen von oben nach unten immer doppelt so schnell wie zuvor bewegen, liegt an den verschachtelten For-Schleifen. Das Prinzip ist Folgendes: Wenn du zwei (oder mehr) Schleifen ineinander verschachtelst, dann arbeitet die äußere "langsamer" als die innere, weil alle Werte für die innere Schleife zuerst abgearbeitet werden, und dann die der äußeren. Außerdem wird die innere Schleife bei jedem Aufruf der Äußeren wieder komplett abgearbeitet. In deinem Fall ergeben sich sogar negative Werte für a, c, e und g, aber das zu erklären führt etwas zu weit.
Das Problem ist, dass eine For-Schleife gar nicht das ist, was du brauchst (geschweige denn vier Stück). Du hast in deinem Programm eine Hauptschleife, das ist der ganze Teil zwischen Repeat und Until. Dieser Code wird in jedem Durchlauf neu aufgerufen. - Und damit hast du schon deine Schleife! Es reicht also, wenn du einfach irgendwo in der Hauptschleife schreibst, dass a, c, e und g um zwei verringert werden sollen:

BlitzBasic: [AUSKLAPPEN]
Repeat
;...
x=x-2
c=c-2
e=e-2
g=g-2
;...
Until KeyHit(1)

Denn diese Hauptschleife wird immer wieder aufgerufen und damit verringern sich die entsprechenden Werte auch kontinuierlich. Du müsstest dann nur eine "Bremse" einbauen, damit die Raketen nicht weiter fliegen, sobald sie ganz links angekommen sind. Das geht z.B. mit

BlitzBasic: [AUSKLAPPEN]
If x>0 Then x=x-2
;usw...


Arrow Außerdem lege ich dir nahe, dich mit dem Thema CPU-Auslastung zu beschäftigen. Denn im Moment verheizt dein Spiel unnötig viele CPU-Ressourcen. Außerdem läuft es je nach Leistung des Rechners mal schneller, mal langsamer. Lies dir den Artikel ruhig mal durch, es lohnt sich Wink. Eventuell musst du hinterher die Geschwindigkeit etwas anpassen, mit der deine Raketen über den Bildschirm fliegen.


Viele Grüße,
Spark Fountain


PS: Die ausführlichen Codehilfen habe ich nur gegeben, weil du noch Anfänger bist. Später gibt's nur noch Tipps in "menschlicher Sprache" Smile.
Gewinner der MiniBCC's #11, #13 und #28

DAK

BeitragDo, Aug 15, 2013 8:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Spark hat eigentlich eh den Großteil sehr gut beschrieben, wollte nur noch mal dazu schreiben, was eine For-Schleife wirklich tut:

BlitzBasic: [AUSKLAPPEN]
For i=1 To 5 Step 2
Print("i:"+i)
Next


Gibt folgendes aus:
Code: [AUSKLAPPEN]
i:1
i:3
i:5


Das heißt, am Ende des Schleifendurchlaufes wird zu deiner Zählvariablen (hier i) die Zahl nach dem Step (hier 2) hinzugezählt und wieder zum For gesprungen. Das passiert, bis einmal vor dem Hinzuzählen die Zählvariable größer oder gleich der Zahl nach dem to (hier 5 ist). Step kann man auch weglassen, dann wird standardmäßig 1 genommen.

Mit verschachtelten Fors schaut es dann so aus:
BlitzBasic: [AUSKLAPPEN]
For i=1 To 5 Step 2
For j=1 To 3
Print("i:"+i+" j:"+j)
Next
Next


Die Ausgabe dazu:
Code: [AUSKLAPPEN]

i:1 j:1
i:1 j:2
i:1 j:3
i:3 j:1
i:3 j:2
i:3 j:3
i:5 j:1
i:5 j:2
i:5 j:3


For-Schleifen sind nicht dazu da, Variablen herunterzuzählen, sondern um Code, der sich innerhalb der Schleife befindet, eine bestimmte Anzahl oft auszuführen (wird besonders in Verbindung mit Arrays wichtig).

Noch zwei Sachen, die man beachten sollte:
BlitzBasic: [AUSKLAPPEN]
For i=5 To 0 Step 1
Next

Diese Schleife hört nie auf. Er wartet, dass i 0 erreicht, aber statt herunter zu zählen, zählt er immer rauf. Da die Zahl nach dem To kleiner ist als der Startwert wird hier als Default-Wert, wenn man Step weglässt, -1 für Step genommen.

BlitzBasic: [AUSKLAPPEN]
For i=5 To 0 Step -1
i = i+1
Next

Auch diese Schleife endet nicht. Der Header der For-Schleife passt zwar (es wird in die richtige Richtung gezählt), aber i wird in der Schleife immer wieder erhöht.

Hoffe, das hilft ein wenig mit den For-Schleifen.

Wie Spark gesagt hat: Sonderbehandlung für Anfänger, weil du nett fragst Wink
Gewinner der 6. und der 68. BlitzCodeCompo

Spark Fountain

BeitragDo, Aug 15, 2013 11:35
Antworten mit Zitat
Benutzer-Profile anzeigen
@DAK: Eine sehr gute Erklärung zum Thema For-Schleifen, viel besser als meine Smile. Allerdings stimmt eine Kleinigkeit nicht ganz, und zwar bei den runterzählenden Schleifen:
DAK hat Folgendes geschrieben:
Da die Zahl nach dem To kleiner ist als der Startwert wird hier als Default-Wert, wenn man Step weglässt, -1 für Step genommen.


Ich habs mit BlitzPlus und Blitz3D ausprobiert, und da liefert folgender Code
BlitzBasic: [AUSKLAPPEN]
For i=5 To 1
Print i
Next
Print "Schleife beendet"
WaitKey

dieses Resultat:
Zitat:
Schleife beendet


Das heißt, der Default-Wert für den Step wird nicht automatisch auf -1 gesetzt, sondern die ganze Schleife wird einfach übersprungen. Das passiert übrigens auch, wenn man einen expliziten Step angibt, der positiv ist (1, 2 oder was auch immer). Lediglich bei Step 0 produziert er eine Endlosschleife, logischerweise Wink.
Gewinner der MiniBCC's #11, #13 und #28

DAK

BeitragDo, Aug 15, 2013 14:12
Antworten mit Zitat
Benutzer-Profile anzeigen
@Spark: Danke für die Ergänzungen, war mir nicht bewusst, dass Blitz das so macht. Ich hätte erwartet, dass es For-Schleifen so handhabt, wie die meisten anderen Sprachen auch. Danke fürs ausbessern!
Gewinner der 6. und der 68. BlitzCodeCompo
 

TomAT

BeitragFr, Aug 16, 2013 15:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen und Danke für die Hilfe!

@Spark Fountain

Leider war ich noch nicht soweit, denn Tipp von Xeres umsetzen zu können.
Ich werde mich, dank deiner und eure Hilfe weiter mit dem Quellcode beschäftigen und hoffe,
dass ich bald etwas präsentieren kann.

Nochmals vielen Dank für die rasche und guter Erklärung !

Tom !
 

TomAT

BeitragFr, Aug 16, 2013 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
So, ich habe es nun überarbeitet Smile

Die Gegner fliegen also von rechts nach links.
Der Spieler kann sich nach oben und unten bewegen.
Eine Grenze für den Spieler eingerichtet.
Sobald die Gegner durch sind, werden sie neu gezeichnet. Kollisionsabfrage führt momentan nur zur Darstellung eines Bildes.

Dazu gleich eine Frage:

Wie kann ich nach einer Kollision zum ende das Programms springen, ohne auf GOTO zurückzukommen ???


Aber ganz WICHTIG :
VIELEN DANK FÜR DIE HILFE !!!

Damit kann ich nun das Programm weiter ausbauen. Neue Gegner, das Schießen, neue Bewegungen für Gegner usw...

Bedeutet also: Ich melde mich bald wieder!

Hier nun mein Quellcode, über Kritik würde ich mich freuen :

Code: [AUSKLAPPEN]
Graphics 1024,768,0,2
SetBuffer BackBuffer()

Spieler = LoadImage("Grafik\Rakete.png")
Gegner = LoadImage("Grafik\Gegner.png")
Ende = LoadImage("Grafik\Ende.png")

; Spieler

a=50
b=350

; Gegner

c=1000
d=100
e=1000
f=600
g=1000
h=350

Repeat
 Cls   

; Zeichnet Spieler und Gegner
 DrawImage Spieler, a, b
 DrawImage Gegner, c, d
 DrawImage Gegner, e, f
 DrawImage Gegner, g, h



; Steuerung Spieler

If KeyDown(208) Then b=b+5
 If KeyDown(200) Then b=b-5

; Abfrage der Kollision
If ImagesCollide(Spieler,a,b, 0, Gegner,c,d, 0) Then DrawImage Ende, 0, 0
If ImagesCollide(Spieler,a,b, 0, Gegner,e,f, 0) Then DrawImage Ende, 0, 0
If ImagesCollide(Spieler,a,b, 0, Gegner,g,h, 0) Then DrawImage Ende, 0, 0


; Gegner
c=c-2
e=e-2
g=g-2


If c=0 Then c= 1000
If e=0 Then e= 1000
If g=0 Then g= 1000

; Spieler

If b=5 Then b=b+5
If b=730 Then b=b-5


 Flip

Until KeyHit(1)



End

DAK

BeitragFr, Aug 16, 2013 17:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Zuerst zwei generelle Sachen:
Wenn du BlitzBasic-Code postest, dann verwende statt der Code-Box doch die BB-Box. Da wird der Code gleich passend gehighlightet und es ist einfach schöner.

Das zweite: bitte rücke den Code richtig ein. Dazu wird immer der Bereich zwischen Anfang und Ende eines Blocks mittels Tabulator (Die vierte Taste von unten ganz links auf der Tastatur, die mit den beiden Pfeilen) um eine Stufe ein. Dadurch wird der Code viel schöner lesbar. Wenn du das mit Tab statt mit der Leertaste machst, dann übernimmt die IDE die Einrückung immer von der letzten Zeile und so musst du die nicht ständig nachsetzen.

Jetzt zu deinem eigentlichen Problem: Dafür gibt es mehrere Ansätze, die alle gehen. Einer ist zum Beispiel, dass du eine Variable running oder so machst, die vor der Hauptschleife auf True gesetzt wird. In der Hauptschleife (bei dem Until) überprüfst du nicht auf den KeyHit(1), sondern auf running=False. Wenn du die Schleife verlassen willst, musst du nur die Variable running auf False setzen. Willst du die Funktionalität mit dem Escape behalten, musst du das natürlich dann extra in die Schleife einbauen.

Ein anderer Ansatz ist, für jeden Zustand, den dein Programm haben kann, eine Funktion machen. Diese Funktionen haben dann selbst keine Hauptschleife, sondern sind nur der Inhalt der jeweiligen Hauptschleife. Solche Zustände sind zum Beispiel "Hauptmenü", "Spiel", "Game Over-Bildschirm".
Dann hast du noch eine Variable, in der der momentane Zustand steht und machst noch eine Hauptschleife nach diesem Schema:

BlitzBasic: [AUSKLAPPEN]
Local zustand$="Hauptmenü"
While zustand$<>"Beendet"
If (zustand$="Hauptmenü") Then
hauptmenue()
ElseIf (zustand$="Spiel") Then
spiel()
ElseIf (zustand$="GameOver") Then
gameOver()
EndIf
Wend
End



Alles klar soweit?
Gewinner der 6. und der 68. BlitzCodeCompo
 

TomAT

BeitragFr, Aug 16, 2013 18:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Alles klar soweit?


Wenn ich ehrlich sein darf, dann nicht.
Punkt 1 und Punkt 2:

BB-Box:
BlitzBasic: [AUSKLAPPEN]
;Rakete V1.02

Graphics 1024,768,0,2
SetBuffer BackBuffer()

Spieler = LoadImage("Grafik\Rakete.png")
Gegner = LoadImage("Grafik\Gegner.png")
Gegner1 = LoadImage("Grafik\Gegner1.png")
Gegner2 = LoadImage("Grafik\Gegner2.png")
Ende = LoadImage("Grafik\Ende.png")
Explosion = LoadImage("Grafik\Explosion.png")


; Spieler

a=50
b=350

; Gegner

c=1000
d=100
e=1000
f=600
g=1000
h=350

; Gegner1

i=1000
j=200
k=1000
l=450
m=1000
n=680
o=1000
p=560
q=1000
r=720
s=1000
t=250

; Zustand für Game Over

x=0
y=100


Repeat
Cls

; Zeichnet Spieler und Gegner

DrawImage Spieler, a, b

DrawImage Gegner, c, d
DrawImage Gegner, e, f
DrawImage Gegner, g, h

DrawImage Gegner1, i, j
DrawImage Gegner1, k, l
DrawImage Gegner1, m, n

DrawImage Gegner2, o, p
DrawImage Gegner2, q, r
DrawImage Gegner2, s, t



; Steuerung Spieler

If KeyDown(208) Then b=b+5
If KeyDown(200) Then b=b-5

; Abfrage der Kollision

If ImagesCollide(Spieler,a,b, 0, Gegner,c,d, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner,e,f, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner,g,h, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner1,i,j, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner1,k,l, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner1,m,n, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner2,o,p, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner2,q,r, 0) Then x=x+10
If ImagesCollide(Spieler,a,b, 0, Gegner2,s,t, 0) Then x=x+10




; Gegner
c=c-4
e=e-3
g=g-5

; Gegner 1

i=i-7
k=k-6
m=m-8

; Gegner 3

o=o-9
q=q-1
s=s-2

;Start Gegner NEU

If c<0 Then c= 1000
If e<0 Then e= 1000
If g<0 Then g= 1000
If i<0 Then i= 1000
If k<0 Then k= 1000
If m<0 Then m= 1000
If o<0 Then o= 1000
If q<0 Then q= 1000
If s<0 Then s= 1000



; Spieler

If b=5 Then b=b+5
If b=730 Then b=b-5


Flip

If x=y Then DrawImage Ende, 100, 100


Until KeyHit(1)



End


Punkt 3:

Eigentlich dachte ich, dass ich bei jeder Kollision einen Wert X + 10 setze.
Am Ende prüfe ich immer wieder, ob X = einen Wert von Y hat.

Damit wollte ich dem Spieler y= 100 % geben und bei jeder Kollision 10 % abziehen.
Wenn x=y dann Game Over.

Leider habe ich nun ein Problem mit der Kollision an sich.

Es scheint so, als würde sie Pixel genau passieren.
D.h.: Auch bei "nur" einer Kollision erreiche ich die 100 %

Nun gut, ich denke, dass ich für heute genug gelernt habe.
Und genug zum nach denken...

Vielen Dank für die Hilfe.
Echt nett von Euch !

Tom.

DAK

BeitragFr, Aug 16, 2013 20:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Zum ersten: schaut besser aus, nur noch nicht ganz, mit dem Einrücken. Prinzipiell schaut das so aus, dass alles was einen zugehörigen Block hat, eingerückt wird, also alles, was einen Blockbeginn und ein Blockende hat. Das sind im Grunde folgende Befehle:

Code: [AUSKLAPPEN]
If [...] Then bis EndIf (nicht, wenn du kein EndIf verwendest, sondern nur einzeilige Ifs)
While [...] bis Wend
Repeat bis Until [...]
Select [...] bis Endselect
For [...] bis Next


Also nur Befehle, die den Kontrollfluss beeinflussen. Befehle wie SetBuffer(BackBuffer()) gehören da nicht dazu.

Kommentare rückt man üblicherweise gleich ein, wie Befehle.

Als nächstes ändere bitte deine Variablennamen auf was sinnvolles. Du kannst diese Namen (fast) komplett frei wählen. Jetzt hast du schon (zumindest) 22 Variablen, deren Namen nur die Buchstaben des Alphabets sind. Das sind genügend Variablen, dass ich nicht mehr durch deinen Code blicke. Mach noch eine Handvoll mehr, und du kommst selber nicht mehr mit. Statt z.B. die Gegnerkoordinaten c und d zu nennen, nenne sie lieber gegner1x und gegner1y oder so. Das ist wirklich wichtig.

Zu deinem anderen Problem: Wie gesagt: vor deine Hauptschleife schreib irgendwo hin "Local running = True" ändere dein "Until KeyHit(1)" auf "Until running = False", und in die Hauptschleife kommt ein "If x=y Then running=false". Dazu vielleicht auch noch in die Hauptschleife "If KeyHit(1) Then End".
Gewinner der 6. und der 68. BlitzCodeCompo
 

TomAT

BeitragMo, Aug 26, 2013 16:24
Antworten mit Zitat
Benutzer-Profile anzeigen
So,

ich habe eure Tipps befolgt und habe einiges geändert.

Neu ist nun, dass jede Kollision etwas vom Schild des Spielers abzieht.
Die Variablennamen und die Hauptschleife wurden nun überarbeitet.

Meine Ziele für die Zukunft:

1. Spieler muss schießen können
2. Beim Treffer muss Gegner verschwinden
3. Beim Treffer erhält der Spieler Punkte
4. Gegner treffen nun Zufällig in der x Variabel auf, nach dem sie das Bild verlassen haben.

Ich habe einiges probiert, um Punkt 1 zu realisieren. Leider ohne Erfolg.
Nun habe ich gelesen, dass es am besten mit Type zu realisieren wäre.
Leider komme ich damit überhaupt nicht weiter Rolling Eyes

Gibt es vielleicht eine einfachere Art?

Nun, hier erst mal der Code:

BlitzBasic: [AUSKLAPPEN]
;Rakete V1.02

Graphics 1024,768,0,2
SetBuffer BackBuffer()

Spieler = LoadImage("Grafik\Rakete.png")
Gegner = LoadImage("Grafik\Gegner.png")
Gegner1 = LoadImage("Grafik\Gegner1.png")
Gegner2 = LoadImage("Grafik\Gegner2.png")
Ende1 = LoadImage("Grafik\Ende.png")
Explosion = LoadImage("Grafik\Explosion.png")
Schuss = LoadImage("Grafik\schuss.png")

; Starpositionen

; Spieler

SpielerX=50
SpielerY=350

; Gegner

GegnerRotX=1000
GegnerRotY=100

GegnerRot2X=1000
GegnerRot2Y=600

GegnerRot3X=1000
GegnerRot3Y=350

; Gegner1

GegnerGrünX=1000
GegnerGrünY=200

GegnerGrün2X=1000
GegnerGrün2Y=450

GegnerGrün3X=1000
GegnerGrün3Y=680

; Gegner 2
GegnerGelbX=1000
GegnerGelbY=560
GegnerGelb2X=1000
GegnerGelb2Y=720
GegnerGelb3X=1000
GegnerGelb3Y=250

; Zustand für Game Over

x=1000
y=0


Local running = True

Repeat
Cls

; Zeichnet Spieler und Gegner

Text 50,30,"SCHILD:"
Text 50,50,x





DrawImage Spieler, SpielerX, SpielerY

DrawImage Gegner, GegnerRotX, GegnerRotY
DrawImage Gegner, GegnerRot2X, GegnerRot2Y
DrawImage Gegner, GegnerRot3X, GegnerRot3Y

DrawImage Gegner1, GegnerGrünX, GegnerGrünY
DrawImage Gegner1, GegnerGrün2X, GegnerGrün2Y
DrawImage Gegner1, GegnerGrün3X, GegnerGrün3Y

DrawImage Gegner2, GegnerGelbX, GegnerGelbY
DrawImage Gegner2, GegnerGelb2X, GegnerGelb2Y
DrawImage Gegner2, GegnerGelb2X, GegnerGelb3Y



; Steuerung Spieler

If KeyDown(208) Then SpielerY=SpielerY+5
If KeyDown(200) Then SpielerY=SpielerY-5

;If KeyDown(32) Then DrawImage Schuss, a, b


; Abfrage der Kollision

If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner,GegnerRotX,GegnerRotY, 0) Then x=x-10
If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner,GegnerRot2X,GegnerRot2Y, 0) Then x=x-10
If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner,GegnerRot3X,GegnerRot3Y, 0) Then x=x-10

If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner1,GegnerGrünX,GegnerGrünY, 0) Then x=x-10
If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner1,GegnerGrün2X,GegnerGrün2Y, 0) Then x=x-10
If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner1,GegnerGrün3X,GegnerGrün3Y, 0) Then x=x-10

If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner2,GegnerGelbX,GegnerGelbY, 0) Then x=x-10
If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner2,GegnerGelb2X,GegnerGelb2Y, 0) Then x=x-10
If ImagesCollide(Spieler,SpielerX,SpielerY, 0, Gegner2,GegnerGelb3X,GegnerGelb3Y, 0) Then x=x-10




; Gegner
GegnerRotX=GegnerRotX-3
GegnerRot2X=GegnerRot2X-12
GegnerRot3X=GegnerRot3X-5

; Gegner 1

GegnerGrünX=GegnerGrünX-4
GegnerGrün2X=GegnerGrün2X-6
GegnerGrün3X=GegnerGrün3X-8

; Gegner 2

GegnerGelbX=GegnerGelbX-9
GegnerGelb2X=GegnerGelb2X-12
GegnerGelb3X=GegnerGelb3X-7

;Start Gegner NEU

If GegnerRotX<0 Then GegnerRotX= 1000
If GegnerRot2X<0 Then GegnerRot2X= 1000
If GegnerRot3X<0 Then GegnerRot3X= 1000
If GegnerGrünX<0 Then GegnerGrünX= 1000
If GegnerGrün2X<0 Then GegnerGrün2X= 1000
If GegnerGrün3X<0 Then GegnerGrün3X= 1000
If GegnerGelbX<0 Then GegnerGelbX= 1000
If GegnerGelb2X<0 Then GegnerGelb2X= 1000
If GegnerGelb3X<0 Then GegnerGelb3X= 1000



; Spieler

If SpielerY=5 Then SpielerY=SpielerY+5
If SpielerY=730 Then SpielerY=SpielerY-5


Flip

If x=y Then running=False

Until running = False

; Until KeyHit(1)

Cls



DrawImage Ende1,100,100

WaitKey()



End


Danke für Antworten !

Tom!

Xeres

Moderator

BeitragMo, Aug 26, 2013 16:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, Types sind anfangs nicht ganz einfach zu verstehen. Dafür gibt es aber im Tutorial Subforum eine Reihe von Beiträgen.

Was du noch tun solltest, ist einen Timer und Flip(0) zu benutzen um die CPU nicht aus zu lasten.
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)

Tennisball

BeitragMo, Aug 26, 2013 16:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein, Types sind die beste Lösung und du solltest dich unbedingt damit beschäftigen. Schwer zu verstehen sind die auch nicht wirklich.
Das hier habe ich damals zum Lernen gelesen: http://de.wikibooks.org/wiki/B...agen#Types

Midimaster

BeitragMo, Aug 26, 2013 16:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Hast schon mal die ersten 3 Kapitel aus meinem Typ-Tutorial versucht?

https://www.blitzforum.de/foru...hp?t=33551
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

TomAT

BeitragMo, Aug 26, 2013 16:58
Antworten mit Zitat
Benutzer-Profile anzeigen
@Xeres

Das mit dem Timer und Flip(0) ist mir noch nicht ganz klar.
Aber mit der CPU hast Recht. Die geht echt in die Höhe.
Ich suche mal etwas im Netz und versuche es zu ändern.

@Tennisball

Danke für den LINK! Lese mich etwas tiefer ein....

@Midimaster

Auch dir vielen Dank. Habe dein Tutorial mal "schnell" durchgelesen und die Idee bekommen, ob ich nicht die Gegner auch Type realisieren sollte. Das würde mir einiges ersparen .... Zumindest denke ich im Moment so.

Gut, ich habe einiges zu lesen....
Vielen Dank ! Ich melde mich wieder.


Noch etwas:
Programmieren war immer so ein Thema...
Ein Thema, dass man können möchte.
Ein Thema wo man schnell aufgibt.

Dank euch bin ich immer wieder motiviert weiter zu machen.
Wenn es so weiter geht, dann habe ich mein "Retro" Game programmiert !

VIELEN DANK AN EUCH UND DIE LEUTE, DIE DIESES FORUM BETREIBEN!

Tom...

DAK

BeitragMo, Aug 26, 2013 20:17
Antworten mit Zitat
Benutzer-Profile anzeigen
@Timer und Flip(0)
Die Idee dahinter ist, dass du einen Framelimiter brauchst, also eine Beschränkung, wie oft die Sekunde alles neugezeichnet werden soll. Das ist deswegen notwendig, weil sonst selbst eine leere While-Schleife sich einfach alles an Leistung nimmt, die sie bekommen kann, und somit den Prozessor auf Volllast ausfährt.
Ein normaler LCD-Bildschirm zeigt üblicherweise nicht mehr als 60 Bilder die Sekunde an, also ist alles, was man das Spiel darüber hinaus laufen lässt, absolut nutzlose Rechenkraftverschwendung.
Flip(0) ist die nicht-ausbremsende Variante des Flip (bremst also nicht von sich selbst aus)
WaitTimer kann verwendet werden, um die Frameanzahl ganz genau und schön zu bremsen.

@Gegner als Type:
Ist wahrscheinlich keine schlechte Idee. In BlitzBasic hast du ja hauptsächlich 3 Datenstrukturen:
-) Normale Variablen. Die eignen sich nur gut, wenn du von einer Objektart immer nur eines hast (z.B. Spieler)
-) Arrays. Die sind gut, wenn du von einer Sache eine dauerhaft fix bleibende, von Anfang an bekannte Anzahl hast (z.B. Inventarslots)
-) Types. Die sind immer dann zu verwenden, wenn du von etwas eine undefinierte, schwankende Anzahl hast (z.B. Schüsse, Gegner)
Gewinner der 6. und der 68. BlitzCodeCompo

Lakorta

BeitragMo, Aug 26, 2013 21:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier (Link) gibt's 'nen schönen Beispielcode für einen 2D-Spaceshooter von Firstdeathmaker. Der ist zwar lange nicht perfekt (siehe WaitTimer und Flip(0)), aber da kannst du dir immerhin mal angucken, wie Types benutzt werden können. Wichtig ist, dass du diesen Code verstehst und höchstens als Inspiration benutzt, nicht 1 zu 1 kopierst, denn davon lernst du nichts Wink
---

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group