Problem mit Steuerung bei Jump'n'Run[solved]

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

 

Mauli93

Betreff: Problem mit Steuerung bei Jump'n'Run[solved]

BeitragMo, März 14, 2011 1:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Guten Abend,

ich hatte mir heute Nachmittag vorgenommen eine gute Steuerung für ein mögliches Jump'n'Run Projekt zu entwickeln, doch allerdings bin ich jetzt auf einen Fehler gestoßen, der mich nun seit einigen Stunden aufhält. Inzwischen ist mir schwindlig und ich hab Kopfschmerzen.
Möglicherweise ist der Fehler kein grober und vielleicht hab ich auch zu früh aufgegeben allerdings kann ich jetzt nicht ins Bett gehen ohne irgendwas für die Lösung noch getan zu haben.

Erstmal der Quelltext:

Code: [AUSKLAPPEN]
Graphics 1024,768,32,2
SetBuffer BackBuffer()

Global x#=400,y#=300,absx#,absy#,scrollx#,scrolly#,ground#=768,speedx#,speedy#,maxspeed#=8
Global reibung#=1,key_pressed%,scroll%,gravity#=0.2

Global set=False

timer = CreateTimer(60)

Type area
   Field x,y,lenght,height
End Type

a.area = New area
a\x=0
a\y=700
a\lenght=1000
a\height=50

a.area = New area
a\x = 700
a\y = 600
a\lenght=300
a\height=50

a.area = New area
a\x=1000
a\y=400
a\lenght=300
a\height=50

a.area = New area
a\x=700
a\y=200
a\lenght=300
a\height=50

a.area = New area
a\x = 1300
a\y=200
a\lenght=300
a\height=50

Repeat
   Cls
   
   ;Rect 0-scrollx,700-scrolly,1000,50
   Color 0,255,0
   Rect x#,y#,50,50
   Color 255,255,255
   
   
   ground = 718 ;zurücksetzen
   ground_beta=718
   
   For a.area = Each area
      Rect a\x-scrollx,a\y-scrolly,a\lenght,a\height
      
      If absx+50 >= a\x And absx <= a\x+a\lenght Then
         ground_beta = a\y
         If ground_beta < absy+50 Then
            ground_beta = 718
         EndIf
      EndIf
      
      If ground_beta < ground Then ground = ground_beta
   Next
   
   scroll = False
   scroll2 = False
   
   If x# <= 200 And speedx#<0 Then
      scrollx#=scrollx#+speedx#
      absx#=x#+scrollx#
      scroll=True
   ElseIf x# >= 824 And speedx#>0 Then
      scrollx#=scrollx#+speedx#
      absx#=x#+scrollx#
      scroll=True
   EndIf
   
   If scroll = False
      x# = x# + speedx#
      absx#=x#+scrollx#
   EndIf

   If y# <= 100 And speedy#<0 Then
      scrolly#=scrolly#+speedy#
      absy# = y#+scrolly#
      scroll2=True
   ElseIf y# >= 668 And speedy#>0 Then
      If absy#+50+speedy# < ground Then
         scrolly#=scrolly#+speedy#
         absy#=y#+scrolly#
         scroll2=True
      Else
         y=ground-50-scrolly
         absy#=y#+scrolly#
         speedy=0
      EndIf
   EndIf
   
   If scroll2 = False Then ;abfrage ob schon gescrollt wurde
      If absy#+50+speedy# < ground Then
         y#=y#+speedy#
         absy#=y#+scrolly#
      Else
         y#=ground-50-scrolly#
         absy#=y#+scrolly#
         speedy=0
      EndIf
   EndIf
   
   key_pressed%=False ;zurücksetzen
   
   ;links rechts
   If KeyDown(203) Then
      If speedx > -maxspeed Then
         If speedx > 0 Then
            If reibung <= speedx Then ;mit beachtung der reibung
               speedx = speedx - 0.15 - reibung
               absx#=x#+scrollx#
            Else
               speedx = 0
            EndIf
         Else
            speedx = speedx - 0.15
         EndIf
      EndIf
      key_pressed%=True
   ElseIf KeyDown(205) Then ;pfeil nach rechts
      If speedx# < maxspeed Then ;abfrage der höchstgeschwindigkeit
         If speedx# < 0 Then ;abfrage der aktuellen bewegungsrichtung
            If reibung# <= speedx*(-1) Then ;abfrage ob reibung niedrig genug ist um sie realistisch zu nutzen
               speedx# = speedx# + 0.15 + reibung ;für die rechnung der richtungsänderung
            Else
               speedx# = 0 ;falls nicht(zu hohe reibung) wird die bewegungsgeschwindigkeit auf 0 gesetzt
            EndIf
         Else
            speedx# = speedx# + 0.15 ;falls richtungsänderung unnötig
         EndIf
      EndIf
      key_pressed%=True
   EndIf
   
   test1#=absy+50
   test2#=ground
   If KeyDown(200) Then
      If absy#+50=ground Then
         speedy# = -10
      EndIf
   EndIf
   
   If absy#+50 = ground And key_pressed = False Then ;reibung
      If speedx# > 0 Then
         If speedx#-reibung# >= 0 Then
            speedx# = speedx# - reibung#
         Else
            speedx#=0
         EndIf
      ElseIf speedx# < 0 Then
         If speedx#+reibung# <= 0 Then
            speedx# = speedx# + reibung#
         Else
            speedx#=0
         EndIf
      EndIf
   EndIf
   
   ;schwerkraft
   If absy#+50 < ground Then
      speedy#=speedy#+gravity
   EndIf
   
   Text 10,30,test1
   Text 10,50,test2
   Text 10,70,scrolly
   If absy+50 = ground Then Oval 10,10,10,10
   
   WaitTimer timer
   Flip
Until KeyDown(1)
End


Noch kurze Erklärungen zu den Variablen:

ground: aktuelle Höhe auf der man beim Fallen zum Stillstand kommt

absx und absy: die absoluten Koordinaten (x+scrollx/y+scrolly) (Verwendet wird eine Steuerung bei die Kamera sich erst bewegt, wenn man richtung Rand kommt.)

scrollx und scrolly: Der Wert um wie viel der Bildschirm bewegt wurde.

ich denke der Rest ist selbsterklärend

dann noch ein Bild, das die Problematik verdeutlichen soll:
http://img848.imageshack.us/i/probleml.png/

Wie hoffentlich zu erkennen ist sieht man einen Screenshot des ausgeführten Programms und links oben ein paar Codeschnipsel.
Zunächst die Ausgabe der Variablen und darunter die Bedeutung dieser.

Es werden also test1 und test2 ausgegeben, welche beide den Wert 200.0 haben. Man sieht auch, dass falls diese beiden Werte gleich sein sollten, eigentlich ein Kreis im linken oberen Eck zu sehen sollte.
Was ich nicht verstehe ist, wieso mir mein Programm sagt, dass die beiden Werte nicht gleich sind. >_>

Darunter noch der Ausschnitt aus dem Programm, das die Sprung"methode" darstellt, nur um zu erklären wozu ich das brauch.

Das Interessante ist, dass das nur bei dem Wert 204.8 für scrolly auftritt der genau beim 3. senkrechten Sprung nach oben auf dieser Plattform erreicht ist. Ich konnte das noch nicht deuten.
Außerdem passiert es, dass das grüne Quadrat manchmal den weißen Balken tunnelt nach einem Sprung.(auch nur in der Höhe)
Ich habe schon selber verschiedene Theorien was der Grund sein könnte, trotzdem komm ich nicht weiter.

So mein Hirn ist Matsch, ich hoffe mir kann jemand helfen.

Lg an euch alle (:
Mauli
  • Zuletzt bearbeitet von Mauli93 am Mi, März 16, 2011 16:29, insgesamt einmal bearbeitet

ToeB

BeitragMo, März 14, 2011 1:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Komisch, bei mir wird der Punkt angezeigt (immer wenn ich auf einem Block lande).

mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!
 

Mauli93

BeitragMo, März 14, 2011 1:22
Antworten mit Zitat
Benutzer-Profile anzeigen
ToeB hat Folgendes geschrieben:
Komisch, bei mir wird der Punkt angezeigt (immer wenn ich auf einem Block lande).

mfg ToeB


Du musst tatsächlich genau drei mal springen, auf einem der oberen beiden Blöcke, ansonsten funktioniert bei mir auch alles, aber das nervt mich einfach total Evil or Very Mad
Also bis -204.8 erreicht ist für scrolly (3. Zeile links oben)

Lg Mauli

Midimaster

BeitragMo, März 14, 2011 9:27
Antworten mit Zitat
Benutzer-Profile anzeigen
also ich kann keine Fehler feststellen. Die beiden Werte sind immer gleich, egal wie oft und wohin ich springe. Auch die Figur fällt nie durch die Ebenen.

Ich könnte mir aber vorstellen, warum es auf manchen Computern zu seltsamen Phaenomenen kommt: sobald Du mit Fließkommazahlen arbeitest, sind If-Zeilen, die auf Gleichheit testen sehr kritisch:


BlitzBasic: [AUSKLAPPEN]
If absy#+50=ground Then

...

If absy#+50 = ground And key_pressed = False Then ;reibung

...

;schwerkraft
If absy#+50 < ground Then

....

If absy+50 = ground Then Oval 10,10,10,10



Das sind auch ziemlich genau die Stellen, die Du in deinem Code bemängelst. Versuche das Gleichheitzeichen durch ein "ungefähr gleich" zu ersetzen:


BlitzBasic: [AUSKLAPPEN]
If Abs(absy#+50-ground)<0.1 Then
 

Mauli93

Betreff: Vielen Dank

BeitragMo, März 14, 2011 14:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay danke, daran hatte ich auch schon gedacht.

Also vielen Dank euch beiden Wink

mal sehen ob ich jetzt weiter komm

Edit:

So hab jetzt noch folgende Sicherheitsabfrage eingebaut:

Code: [AUSKLAPPEN]
   ;schwerkraft
   If absy#+50 < ground Then
      If Abs(absy#+50-ground) > 1 Then
         speedy#=speedy#+gravity
      EndIf
   EndIf


Jetzt sollte das Tunneln auch nicht mehr auftreten, nochmals danke an Midimaster Wink


Edit2:
Ok er tunnelt tatsächlich immer noch bei allen x.003 Werten für scrolly, auch wenn das sehr selten der Fall ist.
 

Mauli93

BeitragDi, März 15, 2011 22:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Hat niemand ne Idee, woran das Tunneln liegen könnte?
Ich dachte ja eigentlich, dass es irgendwie am Gravitationscode liegt, aber bemerkenswerterweise landet er ohne Problem auf der Plattform, stoppt dann für einen winzigen Augenblick und fängt dann erst an durchzufallen.

Hab jetzt schmalere Plattformen noch eingebaut, habe das Gefühl, dass es dort häufiger passiert.
Nochmal der Code:
Code: [AUSKLAPPEN]
Graphics 1024,768,32,2
SetBuffer BackBuffer()

Global x#=400,y#=300,absx#,absy#,scrollx#,scrolly#,ground#=768,speedx#,speedy#,maxspeed#=8
Global reibung#=1,key_pressed%,scroll%,gravity#=0.4,bottom_ground

Global set=False

timer = CreateTimer(60)

Type area
   Field x,y,lenght,height
End Type

a.area = New area
a\x=0
a\y=700
a\lenght=1000
a\height=20

a.area = New area
a\x = 700
a\y = 600
a\lenght=300
a\height=20

a.area = New area
a\x = 1000
a\y=480
a\lenght=300
a\height=20

a.area = New area
a\x = 1200
a\y=360
a\lenght=50
a\height=10

a.area = New area
a\x = 1100
a\y = 240
a\lenght=50
a\height=10

a.area = New area
a\x=700
a\y=200
a\lenght=300
a\height=20

a.area = New area
a\x = 1300
a\y=200
a\lenght=300
a\height=20

Repeat
   Cls
   
   ;Rect 0-scrollx,700-scrolly,1000,50
   Color 0,255,0
   Rect x#,y#,50,50
   Color 255,255,255
   
   
   ground = 718 ;zurücksetzen
   ground_beta=718
   
   For a.area = Each area
      Rect a\x-scrollx,a\y-scrolly,a\lenght,a\height
      
      If absx+50 >= a\x And absx <= a\x+a\lenght Then
         ground_beta = a\y
         If ground_beta < absy+50 Then
            ground_beta = 718
         EndIf
      EndIf
      
      If ground_beta < ground Then ground = ground_beta
   Next
   
   scroll = False
   scroll2 = False
   
   If x# <= 200 And speedx#<0 Then
      scrollx#=scrollx#+speedx#
      absx#=x#+scrollx#
      scroll=True
   ElseIf x# >= 824 And speedx#>0 Then
      scrollx#=scrollx#+speedx#
      absx#=x#+scrollx#
      scroll=True
   EndIf
   
   If scroll = False
      x# = x# + speedx#
      absx#=x#+scrollx#
   EndIf

   If y# <= 100 And speedy#<0 Then
      scrolly#=scrolly#+speedy#
      absy# = y#+scrolly#
      scroll2=True
   ElseIf y# >= 668 And speedy#>0 Then
      If absy#+50+speedy# < ground Then
         scrolly#=scrolly#+speedy#
         absy#=y#+scrolly#
         scroll2=True
      Else
         y#=ground-50-scrolly#
         absy#=y#+scrolly#
         speedy#=0
      EndIf
   EndIf
   
   If scroll2 = False Then ;abfrage ob schon gescrollt wurde
      If absy#+50+speedy# < ground Then
         y#=y#+speedy#
         absy#=y#+scrolly#
      Else
         y#=ground-50-scrolly#
         absy#=y#+scrolly#
         speedy=0
      EndIf
   EndIf
   
   key_pressed%=False ;zurücksetzen
   
   ;links rechts
   If KeyDown(203) Then
      If speedx > -maxspeed Then
         If speedx > 0 Then
            If reibung <= speedx Then ;mit beachtung der reibung
               speedx = speedx - 0.15 - reibung
               absx#=x#+scrollx#
            Else
               speedx = 0
            EndIf
         Else
            speedx = speedx - 0.15
         EndIf
      EndIf
      key_pressed%=True
   ElseIf KeyDown(205) Then ;pfeil nach rechts
      If speedx# < maxspeed Then ;abfrage der höchstgeschwindigkeit
         If speedx# < 0 Then ;abfrage der aktuellen bewegungsrichtung
            If reibung# <= speedx*(-1) Then ;abfrage ob reibung niedrig genug ist um sie realistisch zu nutzen
               speedx# = speedx# + 0.15 + reibung ;für die rechnung der richtungsänderung
            Else
               speedx# = 0 ;falls nicht(zu hohe reibung) wird die bewegungsgeschwindigkeit auf 0 gesetzt
            EndIf
         Else
            speedx# = speedx# + 0.15 ;falls richtungsänderung unnötig
         EndIf
      EndIf
      key_pressed%=True
   EndIf
   
   
   If KeyDown(200) Then
      If Abs(absy#+50-ground) < 0.1 Then
         speedy# = -10
      EndIf
   EndIf
   
   If Abs(absy#+50-ground) < 0.1 And key_pressed = False Then ;reibung
      If speedx# > 0 Then
         If speedx#-reibung# >= 0 Then
            speedx# = speedx# - reibung#
         Else
            speedx#=0
         EndIf
      ElseIf speedx# < 0 Then
         If speedx#+reibung# <= 0 Then
            speedx# = speedx# + reibung#
         Else
            speedx#=0
         EndIf
      EndIf
   EndIf
   
   Text 10,10,scrolly
   Text 10,30,absy
   
   ;schwerkraft
   If absy#+50 < ground Then
      If Abs(absy#+50-ground) > 1 Then
         speedy#=speedy#+gravity
      EndIf
   EndIf
   
   WaitTimer timer
   Flip
Until KeyDown(1)
End


lg Mauli (:

Midimaster

BeitragMi, März 16, 2011 9:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich kann es bei mir leider nicht beobachten. Aber durchfallen kann er ja wohl nur, wenn sein Y# irgendwie vergrößert wird, oder? und das kann ja wohl nur an SpeedY# oder ScrollY# oder Reibung# liegen.

Teste doch mal welchen Wert Y#, Speedy# und Scrolly# in einem solchen Moment hat. Und dann finde heraus, warum SpeedY# oder ScrollY# oder Reibung# nicht wie erwartet exakt null sind.
 

Mauli93

BeitragMi, März 16, 2011 15:48
Antworten mit Zitat
Benutzer-Profile anzeigen
So, danke nochmal für den Denkanstoß, hab jetzt wieder neue Motivation bekommen und gleich einen verdächtigen Programmteil gefunden, Nachdem ich eine Sicherheitsabfrage zu Beginn des Programms eingebaut habe.
Abs(absy#+50-ground) < 0.1 Then speedy=0
Daraufhin hatte sich nichts geändert was mich also dazu geführt hat, dass das Problem in der Ermittlung des Bodens liegt:

Code: [AUSKLAPPEN]
   For a.area = Each area
      Rect a\x-scrollx,a\y-scrolly,a\lenght,a\height
      
      If absx+50 >= a\x Then
         If absx <= a\x+a\lenght Then
            ground_beta = a\y
            If ground_beta < absy+50 Then
               ground_beta = 718
            EndIf
         EndIf
      EndIf
      
      If ground_beta < ground Then
         ground = ground_beta
      EndIf
   Next


Werde das jetzt nochmal schön überarbeiten. Smile


Edit1: 5 Minuten später...

Code: [AUSKLAPPEN]
   For a.area = Each area
      Rect a\x-scrollx,a\y-scrolly,a\lenght,a\height
      
      If absx+50 >= a\x Then
         If absx <= a\x+a\lenght Then
            If (a\y-absy#-49) >= 0 Then
               ground_beta = a\y
            EndIf
         EndIf
      EndIf
      
      If ground_beta < ground Then ground = ground_beta
   Next


Es konnte kein Tunneln mehr festgestellt werden. Jetzt braucht es noch ein paar Optimierungen.
Danke für alle Antworten!

lg Mauli

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group