Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Feld zu klein

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
luemmel



Anmeldungsdatum: 20.11.2010
Beiträge: 2

BeitragVerfasst am: 21.11.2010, 00:19    Titel: Feld zu klein Antworten mit Zitat

Hi. vorweg: ich bin absoluter anfänger in qbasic.
zum problem:
ich möchte so etwas wie snake, aber erstmal sehr vereinfacht, in qbasic programmieren.
die schlange (reihe von pixeln) lässt sich bisher mit wasd steuern und das ganze lässt sich mit m abbrechen. das problem ist nun, dass ich alle koordinaten (x,y), die die schlange durchlaufen hat, in 2 feldern ( x(I),y(I) )
"abspeichere" um diese in einem definierten abstand (I - Länge) wieder löschen zu können.I läuft dabei die ganze zeit mit. die felder können jedoch, wie wahrscheinlich bekannt lachen ,nur etwas mehr als 16000 variablen erfassen. das bedeutet, dass nach 16000 gezeichneten pixeln eine fehlermeldung kommt und das spiel abbricht. ein abspeichern der koordinaten in einer datei verlangsamt das programm zu sehr und ließ sich letztlich auch nicht von mir realisieren, da aus einer datei hätte gelesen werden müssen in die gleichzeitig geschrieben wird.
ich habe dazu 2 ideen, die ich bisher aber auch noch nicht geschafft habe zu realisieren.
1. wenn man bei I>5000 ist braucht man die alten werte von x(I) und y(I) ja nicht mehr, das heißt man könnte das feld erneut von vorn belegen.
2. man lässt bevor man I wieder auf eine niedrigere zahl setzt die letzten werte von x und y durch 2 andere felder "mitprotokollieren", aus denen dann die werte zum löschen vom ende der schlange entnommen werden.

hier noch der code:
Code:

SCREEN 12
'Steuerung mit wasd, Abbruch mit m
delay = 30    'schnelligkeit der schlange
l = 450        'l„nge der schlange
x = 0
y = 0          'start der schlange
farbe = 10           'farbe der schlange
DIM x(16000)
DIM y(16000)
I = 0
rechts:
DO
  a$ = INKEY$
  x(I) = x
  y(I) = y
  I = I + 1
  b = 0
  x = x + 1
    DO
      b = b + 1
    LOOP UNTIL b = delay
   PSET (x, y), farbe
   IF I > l THEN
     PSET (x(I - l), y(I - l)), 0
   END IF
IF a$ = "s" THEN
    GOTO runter
  ELSEIF a$ = "w" THEN
    GOTO hoch
  ELSEIF a$ = "m" THEN
    GOTO ende
END IF
LOOP
runter:
DO
  a$ = INKEY$
  x(I) = x
  y(I) = y
  I = I + 1
  b = 0
  y = y + 1
    DO
      b = b + 1
    LOOP UNTIL b = delay
   PSET (x, y), farbe
   IF I > l THEN
     PSET (x(I - l), y(I - l)), 0
   END IF
IF a$ = "d" THEN
    GOTO rechts
  ELSEIF a$ = "a" THEN
    GOTO links
  ELSEIF a$ = "m" THEN
    GOTO ende
END IF
LOOP
links:
DO
  a$ = INKEY$
  x(I) = x
  y(I) = y
  I = I + 1
  b = 0
  x = x - 1
    DO
      b = b + 1
    LOOP UNTIL b = delay
   PSET (x, y), farbe
   IF I > l THEN
     PSET (x(I - l), y(I - l)), 0
   END IF
IF a$ = "w" THEN
    GOTO hoch
  ELSEIF a$ = "s" THEN
    GOTO runter
  ELSEIF a$ = "m" THEN
    GOTO ende
END IF
LOOP
hoch:
DO
  a$ = INKEY$
  x(I) = x
  y(I) = y
  I = I + 1
  b = 0
  y = y - 1
    DO
      b = b + 1
    LOOP UNTIL b = delay
   PSET (x, y), farbe
   IF I > l THEN
     PSET (x(I - l), y(I - l)), 0
   END IF
IF a$ = "a" THEN
    GOTO links
  ELSEIF a$ = "d" THEN
    GOTO rechts
  ELSEIF a$ = "m" THEN
    GOTO ende
END IF
LOOP
ende:
END



MfG
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
dreael
Administrator


Anmeldungsdatum: 10.09.2004
Beiträge: 2529
Wohnort: Hofen SH (Schweiz)

BeitragVerfasst am: 21.11.2010, 12:02    Titel: Antworten mit Zitat

Ähnliches Projekt von mir früher:

http://www.dreael.ch/Deutsch/Download/Wurmi.html

Ansonsten zu Deinem Fall: Nutze die Tatsache, dass Deine Spielfigur nur immer eine begrenzte Länge besitzt und somit alte X-Y-Tupel nach dem Pixel wegräumen nicht mehr benötigt werden. Somit brauchst Du also nur ein Array in der Grösse der maximalen Schlangenlänge.

Dieses Array musst Du nun als sog. FIFO (First In - First Out)-Speicher benutzen, wofür es zwei Integer braucht, z.B. kopfIndex% und schwanzIndex%. Handhabung sieht in etwa wie folgt aus:

Code:
' Beginn
DIM x%(99), y%(99)
kopfIndex% = 0
schwanzIndex% = 0

' Kopf bewegen (=Schlange wird 1 Glied länger)
PSET (x%, y%)
x%(kopfIndex%) = x%
y%(kopfIndex%) = y%
kopfIndex% = (kopfIndex% + 1) MOD 100

' Schwanz bewegen (=Schlange wird 1 Glied kürzer)
PRESET (x%(schwanzIndex%), y%(schwanzIndex%))
schwanzIndex% = (schwanzIndex% + 1)MOD 100

=> somit wird nur noch ein sehr kleines Array benötigt.

Ansonsten noch weitere Optimierungsmöglichkeit im Sinne von

http://www.dreael.ch/Deutsch/BASIC-Knowhow-Ecke/Anfaengerfehler.html

Stichwort Code-Wiederholung: Damit Du nicht für jede Bewegungsrichtung den ganzen Codeteil wiederholen musst, bietet es sich an, mit Richtungsvariablen zu arbeiten:
Code:
' Startrichtung nach rechts
rx% = 1
ry% = 0
verz! = TIMER

drinBleib% = -1   ' -1 = TRUE; diese Variable müsste
' eigentlich vom Typ BOOLEAN sein, aber QB kennt dies nicht
WHILE drinBleib%
  t$ = INKEY$
  SELECT CASE t$
  CASE "w, CHR$(0) + "H
    ' oben
    rx% = 0
    ry% = -1
  CASE "a", CHR$(0) + "K"
    ' links
    rx% = -1
    ry% = 0
  CASE "d", CHR$(0) + "M"
    ' rechts
    rx% = 1
    ry% = 0
  CASE "s", CHR$(0) + "P"
    ' unten
    rx% = 0
    ry% = 1
  CASE "m", CHR$(27)
    drinBleib% = 0  ' entspricht FALSE
  END SELECT

  ' Kopf bewegen (=Schlange wird 1 Glied länger)
  x% = x% + rx%
  y% = y% + ry%
  ' Kollisionsabfrage
  IF POINT(x%, y%) <> 0 THEN
    ' Auswertung Crash / Zusammenstoss
    drinBleib% = 0
  END IF
  PSET (x%, y%)
  x%(kopfIndex%) = x%
  y%(kopfIndex%) = y%
  kopfIndex% = (kopfIndex% + 1) MOD 100

  ' Schwanz bewegen (=Schlange wird 1 Glied kürzer)
  PRESET (x%(schwanzIndex%), y%(schwanzIndex%))
  schwanzIndex% = (schwanzIndex% + 1)MOD 100

  ' Verzögerung: z.B. alle 0.1 Sek. 1 Pixel bewegen
  verz! = verz! + 0.1
  WHILE TIMER < verz!
    ' Nur Compiler: Hier ein CALL INTERRUPT auf 2Fh, AX=1680h machen
    ' damit CPU-Last nicht bei 100% oben bleibt
    ' Siehe http://www.ctyme.com/intr/rb-4530.htm
  WEND
WEND

Nebenbei noch die Geschwindigkeit verbessert, damit das Spiel unabhängig von der CPU immer gleichschnell läuft.
_________________
Teste die PC-Sicherheit mit www.sec-check.net
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
luemmel



Anmeldungsdatum: 20.11.2010
Beiträge: 2

BeitragVerfasst am: 22.11.2010, 20:21    Titel: Antworten mit Zitat

jo dankeschön
habs mit den 2 Indizes jetzt soweit hinbekommen, dass die schlange potentiell unendlich lange läuft.
probier es gerade mit einer einzigen DO..LOOP schleife ohne die sprungmarken, aber irgendwie hängts noch. er zeichnet 1 pixel und geht dann raus. vielleicht seh ich auch gerade den wald vor lauter bäumen nicht Kopf schütteln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu QBasic. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz