Seite 1 von 4

Primitive Zielverfolgung

Verfasst: 15.03.2008 15:54
von obar
Hallo zusammen,

Ich hab mal ne kleine PacMan demo geschrieben und bin nun auf das Problem der Gegner gestossen. Ich krieg die Zielverfolgung einfach nicht hin. Ich poste
hier mal den Code und wäre froh, wenn ein paar von euch Profis, mir unter die Arme greifen könnten.

Ich Entschuldige mich jetzt schon für das nicht Kommentieren des Codes.

Ich habe nur einen Vermerk eingefügt wo die Zielverfolgung anfängt.
Komisch ist, dass wenn ich zum Gegner hinlaufe(durch ihn durch) verfolgt er mich. Aber nur dort oben in der Ecke.
Wenn man den Kollisionsteil aus der Zielverfolgung rausnimmt verfolgt mich der Gegner, aber dieser läuft natürlich durch alles durch.

Fragen:

- Wie kann man die Zielverfolgung lösen?
- Wie würdet ihr einzelne Bereiche bei Pacman lösen?
- Mapaufbau
- Kollision
- Punkte Aufbauen/Darstellen/Verschwinden lassen
- Zielverfolgung

Danke für die Antworten

Code: Alles auswählen

InitSprite()
InitKeyboard()
OpenScreen(1024,768,32,"")
UsePNGImageDecoder()

Global mapHeight.l  = 29
Global mapWidth.l   = 35
Global MapX.l       = 24 
Global MapY.l       = 24 
Global posX.l       = 60
Global posY.l       = 60
Global gposX.l      =800
Global gposY.l      = 60
Global i
Global k
Global gi
Global gk
Global speed        =  2
Global points       = -5

#TileSize     = 24
#playerWidth  = 24
#playerHeight = 24

CreateSprite(0,24,24)
StartDrawing(SpriteOutput(0))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,24,24,RGB(0,0,0))
StopDrawing()

CreateSprite(1,24,24)
StartDrawing(SpriteOutput(1))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,24,24,RGB(255,255,255))
StopDrawing()

CreateSprite(2,24,24)
StartDrawing(SpriteOutput(2))
DrawingMode(#PB_2DDrawing_Default)
Circle(12,12,12,RGB(255,100,255))
StopDrawing()

CreateSprite(3,24,24)
StartDrawing(SpriteOutput(3))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,24,24,RGB(0, 0, 0))
Circle(12,12,3,RGB(254, 255, 61))
StopDrawing()

CreateSprite(4,24,24)
StartDrawing(SpriteOutput(4))
DrawingMode(#PB_2DDrawing_Default)
Box(0,0,24,24,RGB(255,0,255))
Circle(12,12,12,RGB(0,0,255))
StopDrawing()

Structure _object
    TileID.l
EndStructure

Global Dim map._object(mapWidth, mapHeight)

Restore map
For t = 0 To mapHeight
      For n = 0 To mapWidth 
        Read map(n,t)\TileID
      Next 
Next 

Procedure isAcc(x.l, y.l) 
  Shared map()
  i = ((posx-mapX+x)/#TileSize)
  k = ((posy-mapY+y)/#TileSize)
    
  If map(i, k)\TileID  < 1 Or map(i, k)\TileID  > 2
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0 
EndProcedure

Procedure gisAcc(x.l, y.l) 
  Shared map()
  gi = ((gposx-mapX+x)/#TileSize)
  gk = ((gposy-mapY+y)/#TileSize) 
  
  If map(gi, gk)\TileID  < 1
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0 
EndProcedure

Repeat
    ClearScreen(0)
    ExamineKeyboard()
    
    For t = 0 To mapHeight 
        For n = 0 To mapWidth
            If init = 0
                If map(n, t)\TileID = 0
                   punkte + 1 
                   map(n, t)\TileID = 3
                EndIf
            EndIf    
            DisplayTransparentSprite(map(n, t)\TileID, (mapX + #TileSize*n),(mapY + #TileSize*t) ) 
        Next 
    Next     
   
    init = 1
        
    If KeyboardPushed(#PB_Key_Right)  
        If isAcc( speed-12,-12) And isAcc( speed+11,-12) And isAcc(speed -12,11) And isAcc(speed+ 11,11)
            right = 1:left = 0:up = 0:down = 0
        EndIf
    EndIf
    If KeyboardPushed(#PB_Key_Left)
        If isAcc(-speed-12,-12) And isAcc(-speed+11,-12) And isAcc(-speed-12,11) And isAcc(-speed+11,11)  
            right = 0:left = 1:up = 0:down = 0
        EndIf 
    EndIf
    If KeyboardPushed(#PB_Key_Up)
        If isAcc(-12,-speed-12) And isAcc(11,-speed-12) And isAcc(-12,-speed+11) And isAcc(11,-speed+11)     
            right = 0:left = 0:up = 1:down = 0
        EndIf
    EndIf
    If KeyboardPushed(#PB_Key_Down)
        If isAcc(-12, speed-12) And isAcc(11, speed-12) And isAcc(-12, speed+11) And isAcc(11, speed+11)     
            right = 0:left = 0:up = 0:down = 1
        EndIf
    EndIf
      
    If right = 1 And isAcc( speed-12,-12) And isAcc( speed+11,-12) And isAcc(speed -12,11) And isAcc(speed+ 11,11)
        posx + speed
    EndIf
    If left = 1 And isAcc(-speed-12,-12) And isAcc(-speed+11,-12) And isAcc(-speed-12,11) And isAcc(-speed+11,11)
        posx - speed
    EndIf
    If up = 1 And isAcc(-12,-speed-12) And isAcc(11,-speed-12) And isAcc(-12,-speed+11) And isAcc(11,-speed+11)
        posy - speed
    EndIf
    If down = 1 And isAcc(-12, speed-12) And isAcc(11, speed-12) And isAcc(-12, speed+11) And isAcc(11, speed+11)
        posy + speed
    EndIf
    
    ;
    ; Primitive Zielverfolgung  ( Flucht noch nicht eingefügt)
    ; 
    If posx>gposx And gisAcc( speed-12,-12) And gisAcc(speed+ 11,-12) And gisAcc(speed -12,11) And gisAcc(speed+ 11,11) 
            gposx + speed 
    EndIf
    
    If posx<gposx And gisAcc(-speed -12,-12) And gisAcc(-speed+11,-12) And gisAcc(-speed -12,11) And gisAcc( -speed+11,11) 
            gposx - speed
    EndIf    
               
    If posy>gposy And gisAcc( -12,-speed-12) And gisAcc( 11,-speed-12) And gisAcc(-12,-speed+11) And gisAcc(11,-speed+11)  
            gposy + speed  
    EndIf
    
    If posy<gposy And gisAcc( -12,speed-12) And gisAcc( 11,speed-12) And gisAcc( -12,speed+11) And gisAcc(11,speed+11) 
            gposy - speed 
    EndIf
    ;    
    ;
    ;
    If isAcc(0,0) And isAcc(0,0) And isAcc(0,0) And isAcc(0,0)
        If map(i, k)\TileID = 3
            map(i, k)\TileID = 0
            punkte - 1
            points + 5
        EndIf
    EndIf   
    
    DisplayTransparentSprite(2,posX-#playerWidth/2,posY-#playerHeight/2)
    
    DisplaySprite(4,gposX-#playerWidth/2,gposY-#playerHeight/2)

    StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(925,50,"PUNKTE",RGB(255,255,255))
    DrawText(930, 80, RSet(Str(points), 6, "0"),RGB(255,255,255))
    StopDrawing()
    
    Delay(1)
    FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

End

DataSection
    map:
    Data.l 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
    Data.l 1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1
    Data.l 1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1
    Data.l 1,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,1
    Data.l 1,0,1,1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1,0,1
    Data.l 1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,1,1,0,0,0,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1
    Data.l 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
    Data.l 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
EndDataSection

Gruss obar

Verfasst: 16.03.2008 13:56
von obar
:( Kann mir keiner Helfen??

Verfasst: 16.03.2008 14:06
von STARGÅTE
dein Bot läuft nicht, weil er ja keine Freiheit hat, weil für ihn gelbe Punkte auch Wände sind

du musst beim BOT auch die Punkte "frei" machen:

Code: Alles auswählen

  If map(gi, gk)\TileID  < 1  Or map(gi, gk)\TileID  > 2
    ProcedureReturn 1 
  EndIf 
außerdem hattest du unten was vertauscht, hier die verbesserung:

Code: Alles auswählen

    ; 
    ; Primitive Zielverfolgung  ( Flucht noch nicht eingefügt) 
    ; 
    If posx>gposx And gisAcc( speed-12,-12) And gisAcc(speed+ 11,-12) And gisAcc(speed -12,11) And gisAcc(speed+ 11,11) 
            gposx + speed 
    EndIf 
    
    If posx<gposx And gisAcc(-speed -12,-12) And gisAcc(-speed+11,-12) And gisAcc(-speed -12,11) And gisAcc( -speed+11,11) 
            gposx - speed 
    EndIf    
                
    If posy>gposy And gisAcc( -12,speed-12) And gisAcc( 11,speed-12) And gisAcc(-12,speed+11) And gisAcc(11,speed+11)  
            gposy + speed  
    EndIf 
    
    If posy<gposy And gisAcc( -12,-speed-12) And gisAcc( 11,-speed-12) And gisAcc( -12,-speed+11) And gisAcc(11,-speed+11) 
            gposy - speed 
    EndIf 

Verfasst: 16.03.2008 14:51
von obar
Super. Danke vielmal.
Jetzt muss ich noch eine Lösung finden dass der Gegner nicht hängt. Mal schauen, vielleicht krieg ich dass ja hin.

Verfasst: 16.03.2008 15:03
von STARGÅTE
naja wenn du es "ganz einfach" machen willst, sag dem Gegner doch einfach:

Primärziel : Er soll in Richtung des Spielers gehen (also das, was du jetzt schon hast).
Falls er dann auf eine Wand stößt, tritt sein Sekundärziel ein.
Sekundärziel : Er versucht in Bewegung zu bleiben, wenn er also nicht zum Spieler kommt, dann geht er halt (von ihm aus gesehen) nach links oder rechts oder auch zurück.

Wenn du es besser machen willst, kannst du auch n keine Wegsuche schreiben, sodass der Gegner immer mal wieder den Kürzesten Weg zum Spieler versucht zu finden. Infos für Wegsuche einfach mal in der Suche eingeben.

Verfasst: 16.03.2008 18:17
von obar
Kann mir noch jemand sagen, welches Prinzip der Wegsuche beim original PacMan verwendet wird?

Verfasst: 17.03.2008 02:47
von Kaeru Gaman
jup.
der gegner geht an jeder ecke mit ca. 60%iger wahrscheinlichkeit in richtung pacman.
kann sein, dass es damals ein ungefähr so lief:

Code: Alles auswählen

If Random(2) 
  ; Geh richtung player
Else
  ; geh woanders hin
denk dran: genauso wie der pacman können auch die gegner nur an den ecke die richtung ändern.

ps:
btw, wegsuche kann man das nicht nennen, das ist einfach ein <> der koordinaten.

Verfasst: 17.03.2008 08:19
von obar
Danke für die Antworten. :D

Verfasst: 19.03.2008 18:23
von obar
Ich wäre froh, wenn mir einer weiterhelfen könnte dieses Problem(für mich) zu lösen. Muss nicht Code sein.
Es wäre schon schön, wenn ich Hinweise bekäme, wie ich Vorgehen muss um diese Verfolgung zu erstellen.
:(
Die Verfolgung sollte so Aussehen wie von @Kaeru Gaman es beschrieben hat.

Verfasst: 19.03.2008 19:19
von Kaeru Gaman
wenn geist an ecke ->
wenn richtungswechsel nötig (geht nich gradeaus) -> richtungswechsel ja
nicht nötig -> zufall 2 -> ergebnis 1 (also 50%) -> richtungswechsel ja
sonst
geist geht gradaus weiter.

richtungswechsel ja ->
zufall 2 -> ergebnis 1 (also 50%) -> pacman folgen
sonst
irgendein richtungswechsel.

pacman folgen
pac über mir und weg frei -> wechsel hoch
pac unter mir und weg frei -> wechsel runter
pac links von mir und weg frei -> wechsel links
pac rechts von mir und weg frei -> wechsel rechts

so ungefähr halt... ;)