Pacman & Undurchgehbare Wände

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Keine64MB

Betreff: Pacman & Undurchgehbare Wände

BeitragSo, Jun 26, 2011 18:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo! Mein Kumpel und ich programmieren gerade an einem Pacman Klon rum.
Und da stellt sich folgendes Problem: in der Demoversion von BB funktioniert folgender Code, der in der Hauptschleife aufgerufen wird, nicht Code: [AUSKLAPPEN]
Function kollidieren()
  For i = 0 To 31
    For j = 0 To 31
      If ImagesCollide(wall , j*25, i*25 , 0, pacman, posx, posy, 0) Then
        If KeyDown(200)
          xspeed = 4
          yspeed = 0
        EndIf
        If KeyDown(208) Then
          xspeed = 0
          yspeed = 4
        EndIf
        If KeyDown(205) Then
          xspeed = 4
          yspeed = 0
        EndIf
        If KeyDown(203) Then
          xspeed = 4
          yspeed = 0
        EndIf
      ElseIf ImagesCollide(wall , j*25, i*25 , 0, pacman, posx, posy, 0)Then
        If KeyDown(208)
          xspeed = 4
          yspeed = 0
        ElseIf KeyDown(200) Then
          xspeed = 0
          yspeed = 4
        ElseIf KeyDown(205) Then
          xspeed = 4
          yspeed = 0
        ElseIf KeyDown(203) Then
          xspeed = 4
          yspeed = 0
        EndIf
      ElseIf ImagesCollide(wall , j*25, i*25 , 0, pacman, posx, posy, 0) Then
        If KeyDown(205)
          xspeed = 0
          yspeed = 4
        ElseIf KeyDown(203) Then
          xspeed = 0
          yspeed = 4
        ElseIf KeyDown(200) Then
          xspeed = 0
          yspeed = 4
        ElseIf KeyDown(208)
          xspeed = 0
          yspeed = 4
        EndIf
      ElseIf ImagesCollide(wall , j*25, i*25 , 0, pacman, posx, posy, 0) Then
        If KeyDown(203)
          xspeed = 0
          yspeed = 4
        ElseIf KeyDown(205) Then
          xspeed = 4
          yspeed = 0
        ElseIf KeyDown(200) Then
          xspeed = 0
          yspeed = 4
        ElseIf KeyDown(208)
          xspeed = 0
          yspeed = 4
        EndIf
      Else
        xspeed = 4
        yspeed = 4
      EndIf
    Next
  Next
End Function

Pacman "durchgeht" einfach die Wände , wobei wir ihn nicht als Geist eingebaut haben.
Kann mir hier jemand helfen Question
(k)eine Signatur

Johannes´

BeitragSo, Jun 26, 2011 19:00
Antworten mit Zitat
Benutzer-Profile anzeigen
In Pacman bewegt sich der Spieler doch immer von Feld zu Feld, er bleibt nicht zwischen zwei Feldern stehen. Insofern reicht es ja, einfach zu prüfen, ob das angesteuerte Feld begehbar ist oder nicht.
Wo habt ihr eigentlich eure Karte gespeichert? Sinnvoll wäre hier sicherlich ein Dim Feld. Dabei schaut ihr, welche Testen gedrückt werden und prüft dann, welches Feld angesteuert wird (die Spielerposition +- der Richtung durch Tasten). Ist dieses Feld begehbar, bewegt sich der Spieler dahin, ansosten kann die Aktion nicht durchgeführt werden.

Zu eurem Code:
- Wieso immer die gleiche Kollisionabfrage trotz dem Gebrauch von Elseif?
- Es wird immer das gleiche Bild auf allen möglichen Positionen geprüft, wieso das?
- Ihr solltet erst prüfen, ob eine Bewegung wegen möglicher Hindernisse in einer Richtung überhaupt möglich ist, dann erst sollte die Bewegung erfolgen.
- Wenn eine Kollision stattfindet, soll sich der Spieler bewegen?
- Wenn garkeine Kollision stattfindet, soll xspeed und yspeed gleich 4 gesetzt werden, wieso?

ToeB

BeitragSo, Jun 26, 2011 19:08
Antworten mit Zitat
Benutzer-Profile anzeigen
1. Benutzt auf gar keinen Fall ImagesCollide. Der Befehl mag zwar recht Einfach zu gebrauchen sein, führt aber oft zu Fehlern und ist seeehr langsam. Benutz RectsOverlap wenn schon.

2. Wie Johannes´ schon sagte, ihr braucht nur das Feld, wo der Pacman als nächstes hingehen möchte, zu prüfen, ob er überhaupt dort hingehen KANN. Dazu Legt ihr einfach mit Dim ein 2D-Array an, in das ihr speichert, wo ein begehbares Feld ist und wo nicht.

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!

Keine64MB

BeitragSo, Jun 26, 2011 19:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Wir haben auch die Karte in ein Dim Feld gespeichert. Ich hab nur vergessen dies auch zu sagen, was etwas störend wirkt. Allerdings wollten wir keinen 100% Klon machen, weswegen wir es auch möglich machen wollen schräg zu gehen und das feld in der Bedeutung etwas zu dämpfen.
Arrow es möglich zu machen, zwischen 2 Feldern zu stehen
Arrow Plätze und Flächen im Labyrinth
und so fort...
Darüber hinaus ändern wir beim Drücken einer der Pfeiltasten das Bild, was gerade für Verwirrung sorgte.
Und wir haben versucht bei einer Kollision die Geschwindigkeit der Figur auf 0 zu setzen, um ein Stopp zu bewirken.
Das wars vorerst.
(k)eine Signatur

Hubsi

BeitragSo, Jun 26, 2011 20:05
Antworten mit Zitat
Benutzer-Profile anzeigen
https://www.blitzforum.de/foru...hp?t=37310

Ich denke das sollte Euch erstmal weiterhelfen grundsätzlich schonmal in die richtige Richtung zu werkeln Very Happy
Den ganzen Doag im Bett umanandflagga und iaz daherkema und meine Hendl`n fressn...

Keine64MB

BeitragMi, Jun 29, 2011 19:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Nun hia bin i wida!!!
I fass mi kurz: Pacman is widerspenstig und geht immer noch durch Wände:Code: [AUSKLAPPEN]
Graphics 800, 825, 16, 2
SetBuffer BackBuffer()
AppTitle "Pacman"
file = ReadFile("Karte.txt")
Global wall = LoadImage("wall.bmp")
Global muenze = LoadImage("muenze.bmp")
Global pointbig = LoadImage("pointbig.bmp")
Global pointsmall = LoadImage("pointsmall.bmp")
Global pacman = LoadImage("Pacman_right.bmp")
Global posx = 100
Global posy = 100
Global pacposx = 100
Global pacposy = 100
Global punkte = 0
Global gold = 0
Global xspeed = 4
Global yspeed = 4
Global leben = 3
Global collide = False
Global Intro_music = LoadSound("Pacman_Introduction_Music.wav")
Global menuimage = LoadImage("menu.bmp")
font = LoadFont("Arial",15,1)
SetFont font
Dim karte$(31, 31)
For i = 1 To 32
  x$ = ReadLine(file)
  For j = 1 To 32
    karte(i-1, j-1) = Mid(x$, j, 1)
  Next
Next


Dim kartebegehbar(31, 31)
For i = 0 To 31
  For j = 0 To 31
    If karte(i, j) = "a"
      kartebegehbar(i, j) = False
    Else
      kartebegehbar(i, j) = True
    EndIf
  Next
Next

Function menu()
  timer = CreateTimer(45)
  Repeat
    DrawImage menuimage, 0, 0
    WaitTimer timer
    Flip
  Until MouseHit(1) Or KeyHit(28) Or KeyHit(57)
End Function
menu()
PlaySound(Intro_music)

Function drawmap()
  For i = 0 To 31
    For j = 0 To 31
      If karte(i, j) = "a" Then DrawImage wall, j*25, i*25
      If karte(i, j) = "b" Then DrawImage pointsmall, j*25, i*25
      If karte(i, j) = "c" Then DrawImage pointbig, j*25, i*25
      If karte(i, j) = "d" Then DrawImage muenze, j*25, i*25
    Next
  Next
End Function


Function kollidieren()
  For j = 0 To 31
    For i = 0 To 31
      If RectsOverlap(j*25, i*25 , 25, 25, posx, posy, 25, 25)
        If kartebegehbar(i, j) = True
          If karte(i, j) = "b" Then
            karte(i, j) = "z"
            punkte = punkte + 1
          ElseIf karte(i, j) = "c" Then
            karte(i, j) = "z"
            punkte = punkte+ 2
          ElseIf karte(i, j) = "d" Then
            karte(i, j) = "z"
            gold = gold+1
          EndIf
          yspeed = 4
          xspeed = 4
        ElseIf kartebegehbar(i, j) = False
          collide = True
        EndIf
      EndIf
    Next
  Next
End Function


Function animieren()
  If KeyDown(203) Then
    posx = posx - xspeed
    pacman = LoadImage( "Pacman_left.bmp" )
    kollidieren()
    If colllide  = True
      pacposx = posx+xspeed
    Else
      pacposx = posx
    EndIf
  EndIf
  If KeyDown(205) Then
    posx = posx + xspeed
    pacman = LoadImage( "Pacman_right.bmp" )
    kollidieren() 
    If colllide  = True
      pacposx = posx-xspeed
    Else
      pacposx = posx
    EndIf
  EndIf
  If KeyDown(200) Then
    posy = posy - yspeed
    pacman = LoadImage( "Pacman_up.bmp" )
    kollidieren()
    If colllide  = True
      pacposy = posy+yspeed
    Else
      pacposy = posy
    EndIf
  EndIf
  If KeyDown(208) Then
    posy = posy + yspeed
    pacman = LoadImage( "Pacman_down.bmp" )
    kollidieren()
    If colllide  = True
      pacposy = posy-yspeed
    Else
      pacposy = posy
    EndIf
  ;collide = False
  EndIf   
  DrawImage pacman , pacposx, pacposy
End Function
Repeat
Cls
  Text 100, 800, "Punkte: "+punkte
  Text 200, 800, "Gold: "+gold
  Text 300, 800, "Leben: "+leben
  drawmap()
  animieren()
Flip
Until KeyHit(1)
End

Leider funktioniert der Code trotz Hilfe von Johannes' und Toe B ( Vielen dank, mein Pentium IV nerft net mehr so) nicht ganz ,wie vorhergesehen.
Bye, hoffe auf Hilfe von netten "Blitzern"
(k)eine Signatur

ZEVS

Betreff: Allgemeinposten

BeitragMi, Jun 29, 2011 20:17
Antworten mit Zitat
Benutzer-Profile anzeigen
auch wenn ich nicht grade einen direkten Fehler finden kann, so fällt mir doch einiges auf:
1. Die Bilder von pacman in allen Drehungen werden immer wieder geladen (Performance lässt grüßen), was ausgesprochen sinnfrei ist. Man sollte sie einmal laden und dann in Variablen speichern.
2. Die Kollision kann vergleicht pacman mit jedem Feld auf der ganzen Karte (es grüßt wieder die Performance). Durch posx/25.0 bwz posy/25.0 erhält man näherungsweisen den gewünschten Index.
Mit Ceil und Floor kann man damit alle Indizes ermitteln und braucht keine 32² = 1024edit: nicht 961 Schleifendurchläufe.
BlitzBasic: [AUSKLAPPEN]

Function kollidieren()
Local iX# = posx/25.0
Local iY# = posy/25.0
checkCollision Floor(iX), Floor(iY)
checkCollision Ceil(iX), Floor(iY)
checkCollision Floor(iX), Ceil(iY)
checkCollision Ceil(iX), Ceil(iY)
End Function
Function checkCollision(x, y)
If RectsOverlap(x*25, y*25 , 25, 25, posx, posy, 25, 25)
If kartebegehbar(i, j) = True
If karte(i, j) = "b" Then
karte(i, j) = "z"
punkte = punkte + 1
ElseIf karte(i, j) = "c" Then
karte(i, j) = "z"
punkte = punkte+ 2
ElseIf karte(i, j) = "d" Then
karte(i, j) = "z"
gold = gold+1
EndIf
yspeed = 4
xspeed = 4
ElseIf kartebegehbar(i, j) = False
collide = True
EndIf
EndIf
End Function


edit: es muss 25.0 heißen
  • Zuletzt bearbeitet von ZEVS am Fr, Jul 01, 2011 18:51, insgesamt 2-mal bearbeitet

hazumu-kun

BeitragDo, Jun 30, 2011 1:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein Tipp für dich, Keine64MB:
Denk bei jedem etwas komplexerem Stück Code hinterher nochmal nach: "Ist das sinnvoll wie ich das gelößt habe? Geht das einfacher?"

Mein Vorposter hat durch diese Einstellung schon 2 massive Performancekiller gefunden.
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

ZEVS

Betreff: Verbesserung

BeitragFr, Jul 01, 2011 19:02
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich muss leider feststellen, dass meine sog. Verbesserung eher eine Verschlimmerung ist.
Ich probiere es daher nochmal:
BlitzBasic: [AUSKLAPPEN]
Function kollidieren()
Local iX# = posx/25.0
Local iY# = posy/25.0
checkCollision Floor(iX), Floor(iY)
checkCollision Ceil(iX), Floor(iY)
checkCollision Floor(iX), Ceil(iY)
checkCollision Ceil(iX), Ceil(iY)
End Function
Function checkCollision(x, y)
Select karte(y, x);besser als 4xIf
Case "a"
collide = True
Case "b"
karte(y, x) = "z"
punkte = punkte + 1
Case "c"
karte(y, x) = "z"
punkte = punkte + 2
Case "d"
karte(y, x) = "z"
gold = gold+1
End Select
If karte(y, x) <> "a" Then
yspeed = 4
xspeed = 4
EndIf
End Function

Xeres

Moderator

BeitragFr, Jul 01, 2011 19:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Strings sind im Vergleich zu Zahlen wesentlich langsamer! Benutzte Konstanten wenn du lesbaren und schnellen Code haben willst:
BlitzBasic: [AUSKLAPPEN]
Const Karte_Wand=1, Karte_Weg=2, Karte_Punkte=2

Select karte(y, x)
Case Karte_Wand
collide = True
Case Karte_Punkte
karte(y, x) = Karte_Weg
punkte = punkte + 1
;[...]
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Midimaster

BeitragSa, Jul 02, 2011 7:58
Antworten mit Zitat
Benutzer-Profile anzeigen
liegt das Problem mit dem "durch die Wände gehen" vielleicht daran, dass du in der Funktion Kollidieren die Variable Collide auf TRUE setzt, wenn das Feld nicht begehbar ist?

Später fragt ihr dann genau diesen Zustand ab und wenn Collide TRUE ist, zieht die Figur weiter...

Ein weiteres Problem liegt daran, dass eure Spielfigur mit dem RECTOVERLAP natürlich meist 4 Felder gleichzeitig berührt. Sie kann ja "zwischen" den Feldern stehen. Und das Ergebnis Collide zeigt Euch immer den Zustand des letzten gefundenen RECTOVERLAP Feldes (meist rechts unten vom Spieler)

Wenn die Figur nach links oben läuft, wird zwar für die ersten gefundenen Felder Collide TRUE, aber das letzte Feld links unten setzt Collide wieder auf FALSE.

Eine Lösung wäre die Collide-Werte zu addieren:

BlitzBasic: [AUSKLAPPEN]
Function kollidieren()
Collide=0
For j = 0 To 31
For i = 0 To 31
If RectsOverlap(j*25, i*25 , 25, 25, posx, posy, 25, 25)
If ...
.....
ElseIf kartebegehbar(i, j) = False
collide = Collide+1
EndIf
EndIf
Next
Next
End Function


Ist das Ergebnis dann >0 steht irgendwas im Weg

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group