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:

Abstürzender Code
Gehe zu Seite Zurück  1, 2
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 25.11.2005, 22:54    Titel: Antworten mit Zitat

tilli hat Folgendes geschrieben:
Code:
while inkey$="": wend

groooooßer Fehler.. das gibt ne endlosschleife!
Code:
while inkey$<>"": wend

so muss sein.
_________________
"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
Benutzer-Profile anzeigen Private Nachricht senden
Eastler_dart



Anmeldungsdatum: 25.09.2005
Beiträge: 177
Wohnort: Baden-Würtemberg + Sachsen

BeitragVerfasst am: 26.11.2005, 00:38    Titel: Antworten mit Zitat

ZUM PORSCHE:
Dachte immer, ich bin der einzigste auf dieser Welt, der erst dann nen anderen (schnelleren) PC holt, wenn der bisherige wirklich zu langsam ist.
Hm. Man sollte der Werbung doch nicht zuviel Sachverständnis zutrauen.
-grins-

ZU LINUX:
hab ich mittlerweile auch getestet, auch dort ist die eins kaum auf ne Zwei zu verbiegen (SuSe-Linux 8.2 auf dem 200MMX, sowohl nur Konsole als auch in nem Konsole-Fenster unter KDE).

ZUM FEHLER:
hatte gedacht, mit dem Leeren des Tastaturpuffers mit der DO-Loop-Schleife bis Inkey$ leer ist wäre der Fehler weg?
War der Meinung, Fehler behoben, nur noch die Sorge, ob der Anwender das Prog an der Schleife zum stehen zwingen kann verwundert
Hatte doch die Zeitschleife testweise auf Tastendrücken abgeändert, dann liefs bei mir super mit Taschenrechner auf Spacetaste für Dauerfeuer (mit der Inkey$-Leerungsschleife drin). Hm.
Aber in meinem Test war nix von
WHILE Threadcontrol=1......WEND !!!
drin. Auch war es keine SUB.
Hm. Also, die TastaturSub wird solange/sooft durchlaufen, bis Threadcontrol nicht mehr 1 ist !!

zu MisterD:
Bienchen lächeln nur so wirds leer

Zu Tilli:
So wie du das aufführst, hat ich das ja auch gesehen.
Die Fragestellung war, wenn man mit MisterD's oder meiner
Tastaturleerungsroutine arbeitet, kann der Endanwender des
Programmes mittels Dauerfeuer auf ner Taste den Programm-
Ablauf anhalten, weil Inkey$ nicht leer wird.
Klar, du hast super begründet, was ich vermutet hatte,
nein, das kann der Endanwender nicht.
So eine Leerungsschleife einbauen ist ungefährlich in der Beziehung.

Zu ProggerX-Listing:
Wollte dein letztes, komplettes Listing an mein FreeBasic014
verfüttern, der findet aber die DLL nicht. weinen
Dabei wollte ich nur die Thread-Geschichte austesten.

Hab kurzerhand ein eigenes Thread-Test-Prog erstellt,
um in das Thema mal reinzuschnüffeln.

Ist eine unheimlich Zeitkritische Sache, mit Threads zu arbeiten.
Hatte eine wüste Anzeige in meinem Prog, obwohl Hauptprogramm
und parallel dazu laufender UhrAnzeigeThread sauber per
Locate die Anzeigen auf dem Monitor positionieren sollten.
Da die Beiden Programmteile gleichzeitig laufen, kommt das
Setzen des Cursors per Locate und die Anzeige selber zeitlich
so weit auseinander, das dazwischen der Thread schon seine
uhranzeige an dieser Stelle bringt.

Drum komm ich hier erst mal zu dem kurzen Schluß:
Mit Threads ne Tastaturabfrage für ein Spiel wie die Stämme
zu erstellen, scheint mir wie mit Kanonen auf Spatzen zu schießen.

Zu viel Aufwand ohne wirklichen Sinn.
Der User sitzt doch vor dem Spiel, überlegt ne Sekunde, was er
mit seinem Gold machen will und drückt dann eine Taste, je nach dem.

Warum dazu die allerletzte tausendstel Sekunde herausgekitzelt
werden soll (Thread und Multikey) ist mir schleierhaft.

DAS EIGENTLICHE PROBLEM:
wie grad beschrieben, läuft deine Tastaturabfrage als Thread.
Thread heißt (hab nachgelesen), daß deine Tastaturabfrage
gleichzeitig mit dem Hauptprogramm abläuft.

Somit könnten deine benannten Abstürze/Fehler daraus kommen,
daß der Thread grad zu dem Zeitpunkt an deinen Variablen Werte ändert,
wenn dein Hauptprogramm dies ebenfalls grad macht (wurschtel wurschtel). Schätze mal, für einen Thread muß ganz genau überlegt
werden, auf welche Variablen eine solche Schleife zugreifen darf.

Was mir weiterhin auffällt. Eigentlich sollte in der zuletzt geposteten Version die Tastaturabfrage gar nicht laufen. Sie ist eingeschlossen in den Schleifenconstrukt: WHILE threadcontrol=1 ...... WEND
Und threadcontrol wird als Byte mit Wert 0 erstellt !
Erst wenn die Hauptschleife beendet wird, wird threadcontrol auf 1 gesetzt,
sodaß die While-Bedingung erfüllt wäre und die Tastaturkontrolle arbeiten dürfte.
An der Stelle, wo threadcontrol auf 1 gesetzt wird, beginnt das Programmende. Und dazu wäre es notwendig, threadcontrol auf 0 (und nicht auf 1) zu setzen. Nur so wird der Thread auch beendet.
Meine Schlußfolgerungen daraus lauten:
1) Wenn du dein Betriebssystem frisch hochfährst und dann dein Programm startest, wird es wohl keine Tastatureingaben annehmen. (Bitte testen, ob das so ist)
2) Wenn du dein Programm beendest, wird der Tastaturthread vermutlich NICHT beendet, (da threadcontrol auf 1 steht).
3) Wenn du das Programm mehrfach beendest und wieder neu startest, ist stark zu vermuten, daß dadurch mehrere (alte und der jeweils neue) Threads im Arbeitsspeicher laufen.

Um diese (vermuteten) Fehlerquellen auszuschließen, ändere in deinem Programm bitte folgendes:
A) bei: DIM SHARED as byte threadcontrol den Anfangswert auf 1 setzen (=1)
B) beim Programmende (bisher threadcontrol=1) threadcontrol=0 eintragen
C)Windows runterfahren (um übrig gebliebene, noch laufende Threads zu töten), neu starten, Programm compilieren und testen.

Sollten immer noch Abstürze auftreten, wird es wohl an den zeitkritischen Stellen beim Variablenzugriff liegen. Weiß nicht, ob ich dir dabei wirklich helfen kann, bestimmt sind hier noch mehr schlaue Köpfe, die sich damit dann auskennen.

Halte uns mit dem Werdegang deines Programmes auf dem Laufenden. Ist wirklich interessant.

Viel Spaß noch, Eastler
_________________
Kaum macht mans richtig, schon geht's
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen Yahoo Messenger
Progger_X
Mr. Lagg


Anmeldungsdatum: 24.11.2004
Beiträge: 784
Wohnort: Leipzig

BeitragVerfasst am: 26.11.2005, 00:44    Titel: Antworten mit Zitat

Na ja, nee, der Spieler baut dann ja meinentwegen 100 krieger auf einmal, dafür muss er 100 Durchläufe die Taste gedrückt halten. Ansonsten wäre das alles recht schwer.

Ich gehe jetzt schlafen, die Fehlersuche mach ich morgen. Nur ein was fällt mir noch ein, was mich interresieren würde: wenn ich das mit Maussteuerung mache, und dann 1 rotes viereck 0,0-200,200, und wenn man dort drauf klickt, dann wird das ausgeführt, das eben für alle Befehle, würde das dann ohne größere probleme gehen?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Eastler_dart



Anmeldungsdatum: 25.09.2005
Beiträge: 177
Wohnort: Baden-Würtemberg + Sachsen

BeitragVerfasst am: 26.11.2005, 01:38    Titel: Antworten mit Zitat

klar gibt es für die Maussteuerung mögliche Lösungen.
Genauso, wie es die für die Tastatur gibt.

Schwierig wird das nur, wenn diese Abfragen wirklich als Thread laufen sollen.

Tastatur ohne Thread = viel einfacher und für deinen Zweck ausreichend.
Maus ohne Thread = sogar zusätzlich zur Tastatur möglich.
Der User kann klicken oder tippen, ganz wie er es wünscht.

Viel Spaß beim grübeln. Morgen Abend schau ich wieder rein


Euer Eastler
_________________
Kaum macht mans richtig, schon geht's
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen Yahoo Messenger
Progger_X
Mr. Lagg


Anmeldungsdatum: 24.11.2004
Beiträge: 784
Wohnort: Leipzig

BeitragVerfasst am: 26.11.2005, 16:57    Titel: Antworten mit Zitat

Hallo!

Mal alles wegeditiert, weil ich's jetzt mit Maus hab:

Code:
'$INCLUDE: "SDL/SDL_NET.bi"
DECLARE SUB Connect(socket as tcpsocket,nummer)
OPTION EXPLICIT

TYPE spielereigenschaften
    gold AS integer
    goldmiene AS integer
    krieger AS integer
    wall AS integer
    angreifen AS integer
END TYPE

DIM SHARED spieler(5) AS spielereigenschaften
 
SCREEN 18,8,3,0
COLOR 1,7
CLS
DIM sockclient AS tcpsocket
DIM SHARED nummer AS integer, gegi AS integer
Connect(sockclient,nummer)
IF nummer=1 THEN gegi=2 ELSE gegi=1
spieler(1).goldmiene=1
spieler(2).goldmiene=1
spieler(1).krieger=50
spieler(2).krieger=50
spieler(1).wall=2
spieler(2).wall=2
DIM nachricht AS string
DIM t#
t#=TIMER
DIM SHARED e AS integer
DIM SHARED dummy AS string
DIM zahler AS integer
DIM gold AS integer
DIM krieger AS integer
DIM gm AS integer
DIM angr AS integer
DIM vert AS integer
DIM wall AS integer
DIM angreifen AS integer
DIM attbild(5878 ) AS ubyte
DIM gmbild(5878 ) AS ubyte
DIM kriegerbild(5878 ) AS ubyte
DIM wallbild(5878 ) AS ubyte
BLOAD "att.bmp", VARPTR(attbild(0))
BLOAD "gm.bmp", VARPTR(gmbild(0))
BLOAD "krieger.bmp", VARPTR(kriegerbild(0))
BLOAD "wall.bmp", VARPTR(wallbild(0))
SETMOUSE (1,1,1)
DIM x AS integer, y AS integer, button AS integer

WHILE e=0
    IF TIMER-t#>1 THEN
       GOSUB senden
       t#=TIMER
    END IF
    GOSUB maus
    GOSUB bildschirm
    GOSUB tasten
    SLEEP 30
WEND


END
maus:
GETMOUSE(x,y,,button)
IF button=1 THEN
    IF y<40 AND spieler(nummer).goldmiene*spieler(nummer).goldmiene<spieler(nummer).gold THEN
       spieler(nummer).gold=spieler(nummer).gold-spieler(nummer).goldmiene*spieler(nummer).goldmiene
       spieler(nummer).goldmiene=spieler(nummer).goldmiene+1
    END IF
    IF y>40 AND y<80 AND spieler(nummer).gold>10 THEN
       spieler(nummer).gold=spieler(nummer).gold-10
       spieler(nummer).krieger=spieler(nummer).krieger+1
    END IF
    IF y>80 AND y<120 AND spieler(nummer).wall*spieler(nummer).wall<spieler(nummer).gold THEN
       spieler(nummer).gold=spieler(nummer).gold-spieler(nummer).wall*spieler(nummer).wall
       spieler(nummer).wall=spieler(nummer).wall+1
    END IF
    IF y>120 AND spieler(nummer).krieger>0 THEN
       spieler(nummer).angreifen=1
    END IF
END IF
RETURN

bildschirm:
    SCREENLOCK
    CLS
    LOCATE 12,1
    PRINT spieler(nummer).angreifen
    PRINT spieler(gegi).angreifen
    PRINT "Gold(1): "+STR$(spieler(1).gold)
    PRINT "Goldmiene(1): "+STR$(spieler(1).goldmiene)+" Kosten einer neuen Miene: "+_
    STR$(spieler(1).goldmiene*spieler(1).goldmiene)+" Gold"
    PRINT "Krieger(1): "+STR$(spieler(1).krieger)
    PRINT "Wall(1): "+STR$(spieler(1).wall)
    PRINT "Gold(2): "+STR$(spieler(2).gold)
    PRINT "Goldmiene(2): "+STR$(spieler(2).goldmiene)+_
    " Kosten einer neuen Miene: " + STR$(spieler(2).goldmiene*spieler(2).goldmiene)+" Gold"
    PRINT "Krieger(2): "+STR$(spieler(2).krieger)
    PRINT "Wall(2): "+STR$(spieler(2).wall) +_
    " Kosten eines neuen Walls: " + STR$(spieler(2).wall*spieler(2).wall)+" Gold"
    IF spieler(nummer).goldmiene*spieler(nummer).goldmiene<spieler(nummer).gold THEN
        PRINT "Goldmiene Bauen=1"
        PUT (1,1), gmbild, PSET
    END IF
    IF spieler(nummer).gold>10 THEN
        PRINT "Söldner anwerben=2"
        PUT (1,40), kriegerbild, PSET
    END IF
    IF spieler(nummer).gold>1000 THEN
        PRINT "100 Söldner anwerben=3"
    END IF
    IF spieler(nummer).wall*spieler(nummer).wall<spieler(nummer).gold THEN
        PRINT "Wall Bauen=4"
        PUT (1,80), wallbild, PSET
    END IF
    IF spieler(nummer).krieger>0 AND spieler(nummer).angreifen<>1 THEN
        PRINT "Angreifen = 5"
        PUT (1,120), attbild, PSET
    END IF
    IF spieler(nummer).angreifen=1 THEN
        PRINT "Angriff läuft...."
    END IF
    PRINT nachricht
    SCREENUNLOCK
RETURN

senden:
   nachricht=""
   zahler=0
   spieler(nummer).gold=spieler(nummer).gold+spieler(nummer).goldmiene*5
   gold=spieler(nummer).gold
   gm=spieler(nummer).goldmiene
   krieger=spieler(nummer).krieger
   wall=spieler(nummer).wall
   angreifen=spieler(nummer).angreifen
   SDLNET_TCP_SEND(sockclient, @gold,LEN(gold))
   SDLNET_TCP_SEND(sockclient, @gm,LEN(gm))
   SDLNET_TCP_SEND(sockclient, @krieger,LEN(krieger))
   SDLNET_TCP_SEND(sockclient, @wall,LEN(wall))
   SDLNET_TCP_SEND(sockclient, @angreifen,LEN(angreifen))
   SDLNET_TCP_RECV(sockclient, @gold,LEN(gold))
   SDLNET_TCP_RECV(sockclient, @gm,LEN(gm))
   SDLNET_TCP_RECV(sockclient, @krieger,LEN(krieger))
   SDLNET_TCP_RECV(sockclient, @wall,LEN(wall))
   SDLNET_TCP_RECV(sockclient, @angreifen,LEN(angreifen))
   spieler(gegi).gold=gold
   spieler(gegi).goldmiene=gm
   spieler(gegi).krieger=krieger
   spieler(gegi).wall=wall
   spieler(gegi).angreifen=angreifen
   IF spieler(gegi).angreifen<>spieler(nummer).angreifen THEN
      IF spieler(nummer).angreifen=1 THEN
         angr=nummer
         vert=gegi
      END IF
      IF spieler(gegi).angreifen=1 THEN
         angr=gegi
         vert=nummer
      END IF
      IF spieler(angr).krieger>spieler(vert).wall*spieler(vert).krieger THEN
         nachricht="Der Angreifer gewann"
         spieler(angr).gold=spieler(angr).gold+spieler(vert).gold
         spieler(vert).gold=0
         spieler(angr).krieger=spieler(angr).krieger-spieler(vert).krieger*spieler(vert).wall
         spieler(vert).krieger=0
      END IF
      IF spieler(angr).krieger<spieler(vert).wall*spieler(vert).krieger THEN
         nachricht="Der Verteidiger gewann"
         spieler(vert).krieger=CINT((spieler(vert).krieger*spieler(vert).wall-spieler(angr).krieger)/spieler(vert).wall)
         spieler(angr).krieger=0
      END IF
   END IF
   IF spieler(gegi).angreifen=1 AND spieler(nummer).angreifen=1 THEN
      nachricht="Beide griffen an, waren in der gegnerischen Stadt und plünderten sie"
      gold=spieler(gegi).gold
      spieler(gegi).gold=spieler(nummer).gold
      spieler(nummer).gold=gold
   END IF
   spieler(1).angreifen=0
   spieler(2).angreifen=0
RETURN

tasten:
   IF MULTIKEY(&h02) AND spieler(nummer).goldmiene*spieler(nummer).goldmiene<spieler(nummer).gold THEN
       spieler(nummer).gold=spieler(nummer).gold-spieler(nummer).goldmiene*spieler(nummer).goldmiene
       spieler(nummer).goldmiene=spieler(nummer).goldmiene+1
   END IF
   IF MULTIKEY(&H03) AND spieler(nummer).gold>10 THEN
       spieler(nummer).gold=spieler(nummer).gold-10
       spieler(nummer).krieger=spieler(nummer).krieger+1
   END IF
   IF MULTIKEY(&H04) AND spieler(nummer).gold>1000 THEN
       spieler(nummer).gold=spieler(nummer).gold-1000
       spieler(nummer).krieger=spieler(nummer).krieger+100
   END IF   
   IF MULTIKEY(&H05) AND spieler(nummer).wall*spieler(nummer).wall<spieler(nummer).gold THEN
       spieler(nummer).gold=spieler(nummer).gold-spieler(nummer).wall*spieler(nummer).wall
       spieler(nummer).wall=spieler(nummer).wall+1
   END IF
   IF MULTIKEY(&H06) AND spieler(nummer).krieger>0 THEN
       spieler(nummer).angreifen=1
   END IF
   IF MULTIKEY(&H01) THEN e=1
   DO
     dummy$=INKEY$
   LOOP UNTIL INKEY$=""
RETURN

SUB Connect(socket as tcpsocket,nummer)
 DIM dummy AS string
 IF SDLNet_Init() <> 0 THEN 
     PRINT "Fehler"
     SLEEP
     END
 END IF
 PRINT "1-Server"
 PRINT "2-Client"
 DO
     dummy$=INKEY$
     nummer=VAL(dummy$)
     IF dummy$=CHR$(27) THEN END
 LOOP UNTIL nummer=1 OR nummer=2
 DIM sock AS tcpsocket'Socket einstellen
 DIM sockclient AS tcpsocket
 DIM ip AS ipaddress'Variable IP vom Typ IP Addresse
 DIM zahler AS integer
 IF nummer=1 THEN 
    SDLNet_Write32( INADDR_ANY, @ip.host )
    SDLNet_Write16( 5678, @ip.port )
    sock = SDLNet_TCP_Open( @ip )'TCP Verbindung öffnen, in den Socket schreiben
    zahler=1
    PRINT "Warte auf Client..."
    WHILE sockclient = NULL
       IF INKEY$=CHR$(27) THEN END
       sockclient = SDLNet_TCP_Accept( sock )
       SLEEP 5
    WEND
 END IF
 IF nummer=2 THEN
    DIM host AS string
    INPUT "IP Addresse des Hostes: ", host$
    SDLNet_ResolveHost( @ip, host$, 5678 )
    sockclient = SDLNet_TCP_Open( @ip )
 END IF
 socket=sockclient
END SUB


Das geht ja erstmal so ganz gut...leider habe ich nur folgende Grafiken:

http://thefight.koolhost.de/Grafiken.zip

Weiß jemand, woher ich ordentliche Grafiken dafür bekomme?


Ach ja, und das Problem mit den Tasten gibt's immer noch. Hab ich mit dem Inkey weg machen was falsch gemacht?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
tilli



Anmeldungsdatum: 10.09.2005
Beiträge: 73

BeitragVerfasst am: 26.11.2005, 22:08    Titel: Antworten mit Zitat

moin,

Bezüglich:
Zitat:

Tilli:
Das soll also der Code sein, um die Tasten abzufragen, und dann soll man das in nen thread packen?

Antwort: nein! Das ist die Variante ohne Thread!

Man könnte allerdings eine Funktion draus machen, die ein Ergebnis liefert.
z.b.
Code:

function tastendruck (xy as integer) as integer

dann der Code von oben mit der Rückgabe tastendruck = true oder false (-1 oder 0)


dann kann man recht einfach abfragen nach:
Bsp: if tastendruck(h17) then ...

--- new theme:

@MrD:
tilli hat Folgendes geschrieben:
Code:
while inkey$="": wend

groooooßer Fehler.. das gibt ne endlosschleife!
Code:
while inkey$<>"": wend

so muss sein.

Antwort:
JAIN
es ergib nicht zwangläufig eine Endlosschleife,. sondern wartet aufd Tastendruck lächeln

aber in der Tat - hatte ich in der Eile der Weile verwechselt lächeln

Bezüglich : Eastler_dart
Tastatur ohne Thread = viel einfacher und für deinen Zweck ausreichend.

@Progger_X
Weiß jemand, woher ich ordentliche Grafiken dafür bekomme?


see Gimp zwinkern


CU2
Tilli
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail 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 FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite Zurück  1, 2
Seite 2 von 2

 
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