Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Azasel

unregistriert

1

02.11.2016, 18:58

Ich benötige Hilfe bei einem prozenduralen ASCII Snake Clone

Wie der Titel schon sagt, benötige ich Hilfe bei einem Snake Clon.
Das ganze möchte ich halt mit Turbo Pascal umsetzen.

Was ich bisher habe ist ein Schlangenkopf (Char '0') den ich in der Konsolenumgebung in alle 4 Richtungen bewegen kann, aber sobald es darum geht, dem Schlangenkopf mehr Segmente hinzuzufügen komme ich nicht mehr mit.

Sagen wir mal, die Schlange befindet sich in Position x=1, y=1 und die sammelt jetzt einen Apfel auf in Position x=2, y=1,
dann kann ich mit einer Schleife ein weiteres Segment hinzufügen.
Dieses neue Segment braucht 2 (z.B. Integer)Werte für die Position, aber mit einem Array kann man soweit ich weiss nur ein Wert mitgeben. Des weiteren weiss ich auch nicht, wie ich es hinbekommen soll, das die Segmente deren Positionen richtig ändern, also das Segment 2 auf die Position soll in der der Schlangenkopf war.

Ich habe mir schon viel Quellcode von anderen Sprachen wie Pascal,Python und Java angesehen, aber da blicke ich nicht mehr durch weil da sehr viele Funktionen dabei sind(z.B. Geschwindigkeit,Optionen), auf die ich erstmal nicht näher eingehen möchte.

Kann mir jemand, z.B. mit Pseudocode vormachen, wie ich das ganz einfach machen kann.
Aber dann bitte ohne Grafiken und ohne OOP.

Vielen Dank :)

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

02.11.2016, 19:05

Dein Problem mit den Positionen kannst du mit einer Klasse lösen. Schreib dir einfach eine Klasse für einen Vektor welcher dann deine X und Y Koordinate speichert. Statt einem Array würde ich mit einer Liste arbeiten. Laut Google gibt es bei FreePascal zum Beispiel den Typ TList. Für deine Schlange gibt es verschiedene Ansätze. Du könntet bei jeder Bewegung ein neues Stück Schlange erzeugen und vorne vor die vorhandene Schlange setzen. Gleichzeitig löschst du das letzte Stück deiner aktuellen Schlange. Bewegt sich deine Schlange auf ein Feld mit einem Apfel (oder was auch immer die Schlange bei dir sammelt) so wird das letzte Stück der Schlange eben nicht gelöscht. Eine andere Möglichkeit ist die Schlangenstücke von hinten nach vorne zu durchlaufen und jedem Stück die Position des Vordermanns zu geben. Soll sich die Schlange verlängern kannst du vorher ein Stück hinten anhängen bevor du die Schlange nach vorne bewegst.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Azasel

unregistriert

3

02.11.2016, 19:35

Ich dachte ich hätte mich deutlich ausgedrückt :D
Stichworte: Prozedural, keine Objekte, Turbo Pascal(nicht FreePascal)

So wie ich verstanden habe ist TList eine Klasse/Objekt -> http://www.freepascal.org/docs-html/rtl/classes/tlist.html

Gibt es noch einen einfacheren Weg das zu realisieren?

4

02.11.2016, 19:53

Er hat sich doch klar ausgedrueckt: Die einfachere Methode ist es, das letzte Stueck zu loeschen und vorne dranzusetzen. Wenn die Schlange laenger werden soll durch Apfel-essen, loeschst Du einfach das letzte Stueck in diesem Update-Schritt nicht.

Azasel

unregistriert

5

02.11.2016, 20:12

Er hat sich doch klar ausgedrueckt: Die einfachere Methode ist es, das letzte Stueck zu loeschen und vorne dranzusetzen. Wenn die Schlange laenger werden soll durch Apfel-essen, loeschst Du einfach das letzte Stueck in diesem Update-Schritt nicht.


Ja ist mir schon klar :D

Von der Logik her habe ich schon eine Vermutung, wie ich das hinbekommen kann, aber ich frage jetzt mal anders, damit es verständlich wird, wie bringe ich die Koordinaten(x,y) mehrerer Segmente in ein Array unter oder auf welche Alternative kann ich zurückgreifen?

Ich kann ja nicht einfach...

Quellcode

1
2
3
4
SnakeSegment[1].x = SnakeSegment[0].x
SnakeSegment[1].y = SnakeSegment[0].y
SnakeSegment[0].x = SnakeSegment[0].x + richtungX
SnakeSegment[0].y = SnakeSegment[0].y + richtungY

...machen

Meint ihr ich bin noch nicht bereit für so ein Spiel wie Snake?
Weil ich jetzt schon den dritten Tag daran hänge :pinch:

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

02.11.2016, 20:26

Na dann nimm halt die geraden Indizes für X und die ungeraden für Y Koordinaten.

btw: Turbo Pascal ist eine IDE und FreePascal ein Compiler. TurboPascal versteht auch Object Pascal womit dann nach meinem Verständnis Klassen möglich sind. Musst du natürlich nicht benutzen. Mal kurz Google gecheckt und in Pascal scheint es Record zu geben. Auf den ersten Blick sieht das ein wenig aus wie eine Klasse oder ein Struct.

Meint ihr ich bin noch nicht bereit für so ein Spiel wie Snake?

Na anscheinend fehlen dir noch Basics der Sprache selbst. Von daher vermutlich eher nein ;)

Weil ich jetzt schon den dritten Tag daran hänge

Du lernst seit 3 Tagen Pascal oder versuchst dich seit 3 Tagen an dem Spiel? Falls ersteres, das ist wirklich nicht viel Zeit und da solltest du viel viel geduldiger werden. Falls letzteres, auch das ist nicht viel Zeit. Selbst kleine Spiele wie Snake sind normalerweise nicht innerhalb von einem Tag entwickelt.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

7

02.11.2016, 20:32

Ich habe TurboPascal noch nicht verwendet, allerdings sieht mir die Übersicht an Typen sehr danach aus, als wäre es keine besonders tolle Sprache. Stattdessen könntest du genauso mit C++, C#, Java, JavaScript, Python oder einer beliebigen anderen Sprache anfangen.

Was du in deinem Array oder deiner Liste speichern willst, ist irgendein Konstrukt, das 2 voneinander unabhängig Werte speichern kann. Häufig werden dafür Vektoren (2 oder 3 dimensional) verwendet, komplexe Zahlen wären aber auch eine Möglichkeit, wenn diese bereits von der Sprache unterstützt werden. Sollte nichts derartiges vorhanden sein oder solltest du nichts derartiges implementieren können, müsstest du nach anderen Möglichkeiten schauen. Eine wäre es, eine Matrix statt eines Arrays zu verwenden, wobei die Größe immer nx2 ist. Du kannst dann zwar nicht per array[i].x auf die Werte zugreifen, aber zumindest mittels array[i, 0].
In der Typübersicht habe ich auch den Typen RECORD gesehen. Du könntest schauen, ob sich dieser für deine Zwecke verwenden lässt, also ob du damit einen eigenen Typen definieren kannst, den du in einem Array verwenden kannst.

Ich kenne mich nicht mit TurboPascal aus, entsprechend könnte es natürlich bessere Wege geben.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Sacaldur« (02.11.2016, 22:59)


Thandor

Frischling

Beiträge: 84

Wohnort: Berlin

Beruf: Softwareentwickler

  • Private Nachricht senden

8

02.11.2016, 21:43

Also das Record ist genau das, was du brauchst.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Type Schlangensegment = Record
  x, y : Integer;
end;

...

var Schlange : Array[0..SCHLANGE_MAX_LENGTH] of Schlangensegment;

...

for i:=SCHLANGE_MAX_LENGTH downto 1 begin
  Schlange[i].x := Schlange[i+1].x;
  Schlange[i].y := Schlange[i+1].y;
end;

// Schlangenkopf anhand der aktuellen Richtung verschieben
...
Ich mag pewn.de.

9

02.11.2016, 22:47

Sonst halt einfach zwei Arrays, einer für die X und einer für die Y-Koordinate.

Mein erstes Spiel war tatsächlich ein Snake in Turbo Pascal, allerdings mit diesem coolen Grafikmodus. Damit das ganze zackig lief habe ich immer nur vorne einen grünen Kreis gemalt und hinten einen weißen Kreis. Damals hab ich das glaube ich so gehandhabt, dass ich rollierend durch die Koordinatenarrays gegangen bin. Ich habe immer die älteste Position überschrieben und dann einen grünen Kreis bei diesen Koordinaten gemalt und dann den Eintrag eins höher davon weiß gemalt. Ich weiß immer noch nicht wie ich da damals drauf gekommen bin. Im Nachhinein betrachtet ein ziemlich effizientes Vorgehen...

Also ungefähr jeden Schritt so:

indexPosNeu:=(indexPosNeu+1) mod laenge;
indexPosEnde:=(indexPosNeu+1) mod laenge;
posXKopf:=posXKopf+dirX;
posYKopf:=posYKopf+dirY;
posX[indexPosNeu]:=posXKopf;
posY[indexPosNeu]:=posYKopf;

MaleGruenenKreis(posXKopf,posYKopf);
MaleWeissenKreis(posX[indexPosEnde],posY[indexPosEnde]);

Vielleicht hilft es Dir ja. Ich weiß nicht mehr genau, was ich gemacht hab, wenn die Schlange länger wurde. Aber das kriegst Du bestimmt hin!

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Chromanoid« (02.11.2016, 22:59)


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

02.11.2016, 23:35

Ich weiß nicht mehr genau, was ich gemacht hab, wenn die Schlange länger wurde. Aber das kriegst Du bestimmt hin!

Einfach nicht löschen indem du weiß übermalst?
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige