Kollision / Sprites
Übersicht

TomATBetreff: Kollision / Sprites |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hallo zusammen!
Ich bin neu ![]() Ich versuche mich etwas in der Programmiersprache BlitzPlus. Leider komme ich nicht weiter ![]() 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 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! |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() ![]() 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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
TomAT |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 Ich sehe mich erst mal nach einem Tutorial zum Thema "dim" und "Type" um... Vielen Dank ! |
||
![]() |
Spark Fountain |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() 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 ![]() Also, ich versuche mal deine Baustellen zu umschreiben: ![]() BlitzBasic: [AUSKLAPPEN] ;Nicht: 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. ![]() ![]() BlitzBasic: [AUSKLAPPEN] rakete_bild1 = LoadImage("Grafik\Rakete_oben1klein.png") In deinem Fall musst du das Raketenbild also viermal an den unterschiedlichen Positionen einzeichnen. ![]() ![]() 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 ![]() ![]() BlitzBasic: [AUSKLAPPEN] Repeat 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 ![]() ![]() 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" ![]() |
||
Gewinner der MiniBCC's #11, #13 und #28 |
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 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 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 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 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 ![]() |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
![]() |
Spark Fountain |
![]() Antworten mit Zitat ![]() |
---|---|---|
@DAK: Eine sehr gute Erklärung zum Thema For-Schleifen, viel besser als meine ![]() 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 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 ![]() |
||
Gewinner der MiniBCC's #11, #13 und #28 |
![]() |
DAK |
![]() Antworten mit Zitat ![]() |
---|---|---|
@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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
So, ich habe es nun überarbeitet ![]() 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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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ü" Alles klar soweit? |
||
Gewinner der 6. und der 68. BlitzCodeCompo |
TomAT |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Zitat: Alles klar soweit?
Wenn ich ehrlich sein darf, dann nicht. Punkt 1 und Punkt 2: BB-Box: BlitzBasic: [AUSKLAPPEN] ;Rakete V1.02 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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
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 ![]() Gibt es vielleicht eine einfachere Art? Nun, hier erst mal der Code: BlitzBasic: [AUSKLAPPEN] ;Rakete V1.02 Danke für Antworten ! Tom! |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Tennisball |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
@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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() |
||
--- |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group