Seite 1 von 1

Spielfigur mit der Maus steuern

Verfasst: 02.05.2008 12:00
von Rokur
Hallo,

ich habe mir mal Gedanken gemacht wie man eine Maussteuerung wie sie z.B. in Diablo II, Legend - Hand of God und ähnlichen Spielen verwendet wird umsetzen könnte.

Ein Klick mit der linken Maustaste legt das Ziel fest, die Spielfigur bewegt sich mit einer festgelegten Geschwindigkeit direkt auf das Ziel zu. Wird die Maus mit gedrückter Taste bewegt, läuft die Spielfigur immer dem Cursor nach.

Automatisches Umlaufen von Hindernissen sowie Kollisionsabfragen fehlen zwar noch, aber als Ansatz schonmal ganz brauchbar.

roter Kreis: Spielfigur
gelbes Kreuz: Cursor
grünes Kreuz: Ziel

Verwendete PB-Version: 4.10 Windows

Code: Alles auswählen

InitSprite()
InitMouse()
InitKeyboard()

#width = 800
#height = 600

#fps = 60

frame.l = 0

speed.l = 5 ;Geschwindigkeit in Pixel

posX.l = #width / 2
posY.l = #height / 2
zielX.l = posX
zielY.l = posY
vectorX.l = 0
vectorY.l = 0
vector.f = 0
factor.f = 0

OpenWindow(0, 0, 0, #width, #height, "Maussteuerung", #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(0), 0, 0, #width, #height, #False, 0, 0)

SetFrameRate(#fps)

Repeat
  event.l = WindowEvent()
  
  ;Frame-Zähler
  frame = frame + 1
  If frame > #fps
    frame = 0
  EndIf
  
  Select event
    Case #PB_Event_CloseWindow
      End
    ;hier kommt der Rest rein
  EndSelect
  
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Escape)
    End
  EndIf
  
  ExamineMouse()
  ;linke Maustaste => neues Ziel auf Cursor-Position setzen
  If MouseButton(#PB_MouseButton_Left)
    zielX = MouseX()
    zielY = MouseY()
  EndIf
  
  If frame%2=0 ;Berechnung nicht bei jedem Frame durchführen
    Gosub SpielerBewegen
  EndIf
  
  ClearScreen(RGB(0,0,0))
  
  Gosub zeichnen
  
  FlipBuffers()
  
  Delay(1) ;CPU freigeben
ForEver

End

SpielerBewegen:
  ;Spieler nicht am Zielort => zum Zielort bewegen
  If posX <> zielX Or posY <> zielY
    ;Vektoren berechnen
    vector = Sqr(Pow(ZielX-posX,2)+Pow(ZielY-PosY,2)) ;Entfernung zum Ziel mit dem Satz des Pythagoras berechnen
    factor = speed / vector
    vectorX = (ZielX-posX)*factor
    vectorY = (ZielY-posY)*factor
    ;nahe genug am Ziel um es mit einem Schritt zu erreichen => letzten Schritt verkürzen, um nicht über das Ziel hinaus zu laufen
    If Abs(posX-zielX)<speed
      posX = ZielX
    Else
      posX = posX + vectorX
    EndIf
    If Abs(posY-ZielY)<speed
      posY = ZielY
    Else
      posY = posY + vectorY
    EndIf
  EndIf
Return

zeichnen:
  StartDrawing(ScreenOutput())
    
    ;Text
    DrawText(1,1,"Laufen: linke Maustaste, Beenden: Esc",RGB(255,255,255), RGB(0,0,0))
    
    
    ;Zielort (um zu sehen wie das Ganze hier funktioniert)
    Line(zielX-5, zielY,   10, 0,  RGB(0,255,0))
    Line(zielX,   zielY-5, 0,  10, RGB(0,255,0))
  
    ;Spieler
    Circle(posX,posY,5,RGB(255,0,0))
    
    ;Cursor (zum Schluss, damit er über allem anderen liegt und somit immer sichtbar ist)
    Line(MouseX()-5, MouseY(),   10, 0,  RGB(255,255,0))
    Line(MouseX(),   MouseY()-5, 0,  10, RGB(255,255,0))
    
  StopDrawing()
Return
Grüße
Rokur

Verfasst: 02.05.2008 12:14
von STARGÅTE
du solltest bei "freien Bewegungsrichtungen" allgemein immer mit Floats arbeiten, da sonst die bewegung sehr ruckelt.
Auch wenn die Position immer nur Pixelweise sein kann, ist es besser:
posX,posY,vectorX,vectorY auch Float zu machen, damit die bewegung als ganzes flüssig ist.

EDIT: könnte auch an deiner "verkürzung" liegen, das bei leicht geneigten Wegen der Spieler auf einfach springt.