 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
ThommyBee
Anmeldungsdatum: 30.03.2006 Beiträge: 14
|
Verfasst am: 30.03.2006, 15:15 Titel: Anfängerfragen - Datei laden, Mausunterstützung |
|
|
Hi,
ich habe vor Jahren als Schüler mal angefangen, ein kleines RPG unter QBasic zu programmieren. Meine Kenntnisse sind gering, deshalb war es nichts Tolles, keine Grafiken oder so, nur Texteingaben etc.
Jetzt will ich nach Jahren damit fortfahren, und da QB unter XP nicht läuft, bin ich auf FreeBasic gestoßen, das ja ähnlich wie QB sein soll.
Nur leider läuft mein Programm überhaupt nicht, wenn ich es probeweise mit F5 starte.
Ich habe mir damals aus einem anderen Programm Subroutinen geklaut, die Mausunterstützung bieten und WAVs abspielen können. Selbst konnte ich so was nicht programmieren. Doch schon das verursacht Fehler. Sound will ich eh nicht mehr nutzen, aber ohne Mausunterstützung im fertigen Spiel – das ist blöd, aber machbar.
Die Message bei Teilen der Sub zur Mausabfrage ist:
Array not dimensioned, before: ’(’
PoiSeg% = VARSEG(OutregBx) 'Segment und Offset der Variable
Ich habe das erst mal alles entfernt und die Mausunterstützung rausgeworfen und durch Eingabe durch Tastatur ersetzt, um weiter zu testen.
Ich habe das Spiel damals auch in mehrere Dateien unterteilt, wenn man in ein neues Gebiet kommt, werden die Daten der Attribute, Erfahrungspunkte, Ausrüstung etc. gespeichert, die neue Datei wird geladen und ebenso die zuvor gespeicherten Daten.
Allerdings öffnet der RUN-Befehl nicht mal mehr die neue Datei – das Programm kehrt einfach zu FreeBasic zurück, ohne Fehlermeldung. Ist das vielleicht normal? Wie soll ich vorher testen, ob alles glatt läuft?
Bevor eine neue Datei geladen wird, wird gespeichert:
OPEN "dat\zwwkn.dat" FOR OUTPUT AS #1
WRITE #1, ohnwaff%, schwerter%, hiebs%, hiebst%, axt%, stab%, stwaff%, zwh%, schwimm%, klett%, kbeh%, schleich%, zechen%, reiten%, springen%, pflk%, jag%, orient%, fakenn%, tierk%, fess%, fallst%, ohnwaffat%, ohnwaffpa%, schwerterat%, schwerterpa%, hiebsat%, hiebspa%, hiebstat%, hiebstpa%, axtat%, axtpa%, stabat%, stabpa%, stwaffat%, stwaffpa%, zwhat%, zwhpa%
CLOSE #1
Und so weiter, das scheint zu klappen.
Dann soll die nächste Datei geöffnet werden:
RUN "wsmenu3.bas"
Passiert aber nicht, da beim Run-Befehl zu FB zurückgekehrt wird.
Das Spiel wird sich nicht in einer Datei unterbringen lassen, es wird zu umfangreich.
Deshalb ist mein größtes Problem, von einer Datei zur nächsten zu wechseln.
Des Weiteren hätte ich gerne Mausunterstützung.
Bitte habt Nachsehen, ich kenne mich noch kaum aus und blicke auch nicht durch.
Ich habe mal die SUBs für Maus hier reingesetzt, die ich mir einfach von einem anderen Programm abgeschaut habe, welche nun leider nicht mehr laufen. Ich verstehe die Befehle nicht, vielleicht weiß ja jemand, was ich ändern muss, oder was ich alternativ machen kann: Wer Spaß hat, kann es ja mal lesen:
DECLARE SUB INTERRUPT (Nr%, iax%, ibx%, icx%, idx%)
DECLARE SUB initinterrupt ()
DECLARE SUB mausabfrag (xm, ym)
DIM SHARED InterFeld(0 TO 34) AS INTEGER
DIM SHARED OutregBx AS INTEGER 'Datenfeld f?r Register bx nach dem Interrupt.
DIM SHARED OutregCx AS INTEGER ' " " " cx " " "
DIM SHARED OutregDx AS INTEGER ' " " " dx " " "
SUB initinterrupt
PoiSeg% = VARSEG(OutregBx) 'Segment und Offset der Variable
PoiPos% = VARPTR(OutregBx) 'OutregBx bestimmen.
bxSLow% = (PoiSeg% MOD 256) 'Segment in Highbyte und Lowbyte
bxSHigh% = INT(PoiSeg% / 256) 'umrechnen.
bxPLow% = (PoiPos% MOD 256) 'Offset in Highbyte und Lowbyte
bxPHigh% = INT(PoiPos% / 256) 'umrechnen.
PoiSeg% = VARSEG(OutregCx) 'Segment und Offset der Variable
PoiPos% = VARPTR(OutregCx) 'OutregCx bestimmen.
cxSLow% = (PoiSeg% MOD 256) 'Segment in Highbyte und Lowbyte
cxSHigh% = INT(PoiSeg% / 256) 'umrechnen.
cxPLow% = (PoiPos% MOD 256) 'Offset in Highbyte und Lowbyte
cxPHigh% = INT(PoiPos% / 256) 'umrechnen.
PoiSeg% = VARSEG(OutregDx) 'Segment und Offset der Variable
PoiPos% = VARPTR(OutregDx) 'OutregDx bestimmen.
dxSLow% = (PoiSeg% MOD 256) 'Segment in Highbyte und Lowbyte
dxSHigh% = INT(PoiSeg% / 256) 'umrechnen.
dxPLow% = (PoiPos% MOD 256) 'Offset in Highbyte und Lowbyte
dxPHigh% = INT(PoiPos% / 256) 'umrechnen.
DEF SEG = VARSEG(InterFeld(0)) 'In die Variable InterFeld wird der
Poi% = VARPTR(InterFeld(0)) 'Maschinencode direkt eingetragen.
REM *** Maschinencode ****** entsprechender Assemblercode ***
POKE Poi%, &HB8 'mov ax, dummy (Inhalt von ax wird
POKE Poi% + 1, &H0 ' sp„ter mittels Poke
POKE Poi% + 2, &H0 ' eingef?gt.)
POKE Poi% + 3, &HBB 'mov bx, dummy
POKE Poi% + 4, &H0
POKE Poi% + 5, &H0
POKE Poi% + 6, &HB9 'mov cx, dummy
POKE Poi% + 7, &H0
POKE Poi% + 8, &H0
POKE Poi% + 9, &HBA 'mov dx, dummy
POKE Poi% + 10, &H0
POKE Poi% + 11, &H0
POKE Poi% + 12, &HCD 'int dummy (Interruptnummer mit Poke
POKE Poi% + 13, &H0 ' einf?gen.)
POKE Poi% + 14, &H6 'push es
POKE Poi% + 15, &H56 'push si
POKE Poi% + 16, &HB8 'mov ax, Segment von OutregCx
POKE Poi% + 17, cxSLow%
POKE Poi% + 18, cxSHigh%
POKE Poi% + 19, &H8E 'mov es, ax
POKE Poi% + 20, &HC0
POKE Poi% + 21, &HB8 'mov ax, Pointer auf OutregCx
POKE Poi% + 22, cxPLow%
POKE Poi% + 23, cxPHigh%
POKE Poi% + 24, &H8B 'mov si, ax
POKE Poi% + 25, &HF0
POKE Poi% + 26, &H26 'mov es:[si], cl
POKE Poi% + 27, &H88
POKE Poi% + 28, &HC
POKE Poi% + 29, &H26 'mov es:[si+1], ch
POKE Poi% + 30, &H88
POKE Poi% + 31, &H6C
POKE Poi% + 32, &H1
POKE Poi% + 33, &HB8 'mov ax, Segment von OutregDx
POKE Poi% + 34, dxSLow%
POKE Poi% + 35, dxSHigh%
POKE Poi% + 36, &H8E 'mov es, ax
POKE Poi% + 37, &HC0
POKE Poi% + 38, &HB8 'mov ax, Pointer auf OutregDx
POKE Poi% + 39, dxPLow%
POKE Poi% + 40, dxPHigh%
POKE Poi% + 41, &H8B 'mov si, ax
POKE Poi% + 42, &HF0
POKE Poi% + 43, &H26 'mov es:[si], dl
POKE Poi% + 44, &H88
POKE Poi% + 45, &H14
POKE Poi% + 46, &H26 'mov es:[si+1], dh
POKE Poi% + 47, &H88
POKE Poi% + 48, &H74
POKE Poi% + 49, &H1
POKE Poi% + 50, &HB8 'mov ax, Segment von OutregBx
POKE Poi% + 51, bxSLow%
POKE Poi% + 52, bxSHigh%
POKE Poi% + 53, &H8E 'mov es, ax
POKE Poi% + 54, &HC0
POKE Poi% + 55, &HB8 'mov ax, Pointer auf OutregBx
POKE Poi% + 56, bxPLow%
POKE Poi% + 57, bxPHigh%
POKE Poi% + 58, &H8B 'mov si, ax
POKE Poi% + 59, &HF0
POKE Poi% + 60, &H26 'mov es:[si], bl
POKE Poi% + 61, &H88
POKE Poi% + 62, &H1C
POKE Poi% + 63, &H26 'mov es:[si+1], bh
POKE Poi% + 64, &H88
POKE Poi% + 65, &H7C
POKE Poi% + 66, &H1
POKE Poi% + 67, &H5E 'pop si
POKE Poi% + 68, &H7 'pop es
POKE Poi% + 69, &HCB 'ret
DEF SEG
END SUB
SUB INTERRUPT (Nr%, iax%, ibx%, icx%, idx%)
ah% = INT(iax% / 256) 'Die an INTERRUPT ?bergebenen Registerwerte werden
bh% = INT(ibx% / 256) 'in ihre Highbyte und Lowbyte aufgeteilt.
ch% = INT(icx% / 256)
dh% = INT(idx% / 256)
al% = (iax% MOD 256)
bl% = (ibx% MOD 256)
cl% = (icx% MOD 256)
dl% = (idx% MOD 256)
DEF SEG = VARSEG(InterFeld(0)) 'Segmentzeiger auf InterFeld
Poi% = VARPTR(InterFeld(0)) 'Pointer auf InterFeld
POKE Poi% + 1, al% 'Die Werte f?r die Inreg-Register
POKE Poi% + 2, ah% 'und die Interruptnummer werden in die
'Stellen der Assemblerroutine eingetragen,
POKE Poi% + 4, bl% 'die bei der Initialisierung mit Dummywerten
POKE Poi% + 5, bh% '(0) freigehalten wurden.
POKE Poi% + 7, cl%
POKE Poi% + 8, ch%
POKE Poi% + 10, dl%
POKE Poi% + 11, dh%
POKE Poi% + 13, Nr%
CALL ABSOLUTE(Poi%) 'Hier verzweigt das Programm zur Maschinen-
'routine, die jetzt mit sinnvollen Werten
'f?r die Inreg-Register und der
'Interruptnummer versehen worden ist.
DEF SEG
END SUB
SUB mausabfrag (xm, ym)
tast = 0
CALL INTERRUPT(&H33, &H7, 0, 0, 630) 'Interrupt 33hex (Mausinterrupt)
'inreg.ax = 7hex (horiz. Grenzen)
'inreg.bx = 0 (ohne Bedeutung)
'inreg.cx = 100 (linke Grenze)
'inreg.dx = 200 (rechte Grenze)
CALL INTERRUPT(&H33, &H8, 0, 0, 340) 'Interrupt 33hex (Mausinterrupt)
'inreg.ax = 8hex (vertikale Grenzen)
'inreg.bx = 0 (ohne Bedeutung)
'inreg.cx = 50 (obere Grenze)
'inreg.dx = 300 (untere Grenze)
CALL INTERRUPT(&H33, &H1, 0, 0, 0) 'Interrupt 33hex (Mausinterrupt)
'inreg.ax = 1hex (Cursor an)
'inreg.bx = 0 (ohne Bedeutung)
'inreg.cx = 0 (ohne Bedeutung)
'inreg.dx = 0 (ohne Bedeutung)
WHILE tast = 0 OR tester = 1 'Solange keine Taste gedr. wurde
CALL INTERRUPT(&H33, &H3, 0, 0, 0) 'Interrupt 33hex (Mausinterrupt)
'inreg.ax = 3hex (Position u. Tasten)
'inreg.bx = 0 (ohne Bedeutung)
'inreg.cx = 0 (ohne Bedeutung)
'inreg.dx = 0 (ohne Bedeutung)
xm = OutregCx
ym = OutregDx
tast = OutregBx
IF tast = 0 THEN tester = 0
WEND
tester = 1
CALL INTERRUPT(&H33, &H2, 0, 0, 0) 'Interrupt 33hex (Mausinterrupt)
'inreg.ax = 2hex (Cursor aus)
'inreg.bx = 0 (ohne Bedeutung)
'inreg.cx = 0 (ohne Bedeutung)
'inreg.dx = 0 (ohne Bedeutung)
END SUB |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 30.03.2006, 16:29 Titel: |
|
|
Hallo!
Mausunterstützung ist unter FB viel einfacher!
Um die Mauskoordinaten dauerhaft abzufragen genügt bereits folgender Code:
Code: |
SCREEN 18 ' kannst auch was anderes verwenden
DO
GETMOUSE(x,y,rad,buttons) ' eigentlich reicht schon allein _diese_ Zeile
LOCATE 1: PRINT x
LOCATE 2: PRINT y
LOCATE 3: PRINT rad
LOCATE 4: PRINT buttons
LOOP UNTIL INKEY$<>""
|
Es müsste ersichtlich sein, dass x die X-Position und y die Y-Position des Mauszeigers darstellt. Mit der Variable rad und dem Mausrad müsstest du ein wenig herumexperimentieren. buttons gibt schließlich die gedrückten Mausbuttons an. Das geschieht mit Hilfe von Zahlen.
Da du noch neu in FB bist würde ich dir die Seite FreeBasic.de empfehlen. Dort ist unter anderem auch die Befehlsreferenz zu finden; jeder Befehl ist dort ausführlich (meist auch an Hand eines Beispiels) und verständlich erklärt.
Speziell zum GetMouse-Befehl von FB: GetMouse-Eintrag in der Befehlsreferenz.
QBasic ist im Gegensatz zu QuickBasic und FreeBasic ein Interpreter. Die beiden Anderen sind Compiler. Soll heißen, dass ein CHAIN oder RUN nicht funktioniert (bei FB). Jedoch dürfte es kein Problem sein alles in eine Datei unter zu bekommen, da FB keine 160 KB Grenze mehr hat.
/edit: CALL INTERUPT funktioniert übrigens auch _nicht_ mehr.
Viel Spaß damit!
Grüße,
Mao _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
ThommyBee
Anmeldungsdatum: 30.03.2006 Beiträge: 14
|
Verfasst am: 30.03.2006, 16:53 Titel: |
|
|
Hey, vielen Dank!
Bei der Maus brauch ich nur die linke Maustaste, also kann ich rad und so einfach weg lassen, oder?
kann ich theoretisch so vorgehen:
screen 18
Print "willst du"
print
print " nach Süden reisen"
print " nach Norden reisen"
DO
GETMOUSE(x,y) '
LOCATE 1: PRINT x
LOCATE 2: PRINT y
LOOP UNTIL INKEY$<>""
If x > 1 and x < 160 and y > 16 and y < 25 then
goto south:
elseif......
Wenn ich alles in eine Datei bekomme, ist das schon mal gut. Aber gibt es wirklich keine Grenzen? Das Spiel ist noch nicht sehr lang, hat aber mit dem Kampfsystem und verschiedenen Orten und komplexen Formeln etc. bereits jetzt schon einen ganz schönen Umfang. Und ich weiß nicht, wie lang es werden wird, es kann ein sehr kurzes Spiel werden, aber auch ein sehr, sehr langes. |
|
Nach oben |
|
 |
ThommyBee
Anmeldungsdatum: 30.03.2006 Beiträge: 14
|
Verfasst am: 30.03.2006, 17:56 Titel: |
|
|
Hm, irgendwie stimmt mit den Koordinaten was nicht.
Wenn ich den Zeiger nach ganz oben links bewege, und dann langsam nach rechts oder nach unter fahre, werden die Koordinaten in Hunderter-Schritten gezählt. Erst wenn eine bestimme Stelle überschritten ist, wird wieder ab 0 in Einser-Schritten gezählt. Woran liegt das? Dann wäre es nicht möglich, bestimmte Aktionen bei einem Klick auf eine bestimmte Stelle auszuführen, da die Koordinaten ja doppelt existieren... |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 30.03.2006, 18:05 Titel: |
|
|
LOCATE 1: PRINT x
LOCATE 2: PRINT y
mach da mal
LOCATE 1: PRINT x;" "
LOCATE 2: PRINT y;" "
draus, dann gehts..
wenn der 100 hinschreibt und danach wieder zurückgeht bis auf 2 dann schreibt er 2 aber die beiden 00 sind noch da, das sieht also nur so aus  _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Michael Frey

Anmeldungsdatum: 18.12.2004 Beiträge: 2577 Wohnort: Schweiz
|
Verfasst am: 30.03.2006, 18:10 Titel: |
|
|
Ja, du kannst das Rad weglassen.
Dann geht der Befehl einfach so:
Code: | GETMOUSE(X,Y,,Buttons) |
|
|
Nach oben |
|
 |
ThommyBee
Anmeldungsdatum: 30.03.2006 Beiträge: 14
|
Verfasst am: 30.03.2006, 19:10 Titel: |
|
|
Danke, jetzt habe ich einen Mauszeiger und ich sehe die Koordinaten - wie aber lautet der Befehl, der es mir ermöglicht, dass bei Klicks an bestimmten Stellen bestimmte Aktionen durchgeführt werden? |
|
Nach oben |
|
 |
Michael Frey

Anmeldungsdatum: 18.12.2004 Beiträge: 2577 Wohnort: Schweiz
|
Verfasst am: 30.03.2006, 19:19 Titel: |
|
|
Du kannst mit IF prüfen, ob an einem bestimmten Ort geklickt wurde.
Code: | screen 12
cl=5
do
getmouse(x,y,,taste)
color 15
LOCATE 1
PRINT x;" "
PRINT y;" "
if x>100 and x<140 and y>100 and y<140 and taste=1 and tasteAlt=0 then
cl=not cl
end if
line(100,100)-(140,140),cl,bf
tastealt=taste
loop[quote][/quote] |
|
|
Nach oben |
|
 |
ThommyBee
Anmeldungsdatum: 30.03.2006 Beiträge: 14
|
Verfasst am: 30.03.2006, 19:48 Titel: |
|
|
Danke, werde ich bald mal ausprobieren.
So ähnlich hatte ich das auch probiert, aber da lief dann eine Endlosschleife und ich kinnte gar nichts mehr machen.
Ich habe tasteAlt=0 und cl=not cl nicht verwendet. Was bewirkt das denn? |
|
Nach oben |
|
 |
Michael Frey

Anmeldungsdatum: 18.12.2004 Beiträge: 2577 Wohnort: Schweiz
|
Verfasst am: 31.03.2006, 17:16 Titel: |
|
|
Das taste=1 and tasteAlt=0 achtet auf den Click selbst, statt auf den Zustand der Taste.
Das cl=not cl ist einfach ein Grafik Effekt.
Wenn du das Programm startest und auf das Rechteck klickst, ändert sich die Farbe.
(Das cl=not cl ist eben dieser Farbwechsel) |
|
Nach oben |
|
 |
ThommyBee
Anmeldungsdatum: 30.03.2006 Beiträge: 14
|
Verfasst am: 31.03.2006, 18:09 Titel: |
|
|
Danke, hab ich jetzt ausprobiert, und das mit der Grafik auch gemerkt.
Jetzt kann ich eigentlich loslegen.
Aber nochmal zur Größe des Programms: Gibt es keinerlei Begrenzung? Unter QBasic musste das Spiel immer in einer neuen Datei fortgesetzt werden, mit Run-Befehl.
Gibt es bei FB keine Beschränkung, oder fällt diese so hoch aus, dass ich mir keine Sorgen machen muss? |
|
Nach oben |
|
 |
Michael Frey

Anmeldungsdatum: 18.12.2004 Beiträge: 2577 Wohnort: Schweiz
|
Verfasst am: 31.03.2006, 18:27 Titel: |
|
|
Letzeres.
Die Beschränkung liegt bei 2 Giga Byte für die .Exe Datei und 2 Giga Byte für den Quellcode.
(Es gibt kein Programm, das diese 2 GB Grenze erreicht) |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 31.03.2006, 18:28 Titel: |
|
|
Es gibt wirklich _keine_ Begrenzung. (Höchstens die deines Speichers. )
Und da es RUN und CHAIN nicht mehr gibt - es passt alles in eine Datei, keine Sorge - egal wie groß es wird.  _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 31.03.2006, 21:23 Titel: |
|
|
es gibt RUN und CHAIN aber die können nur auf .exe angewand werden, nicht mehr auf .bas _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
|
|
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.
|
|