Tile Engine: GameBoy Verhalten

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Tile Engine: GameBoy Verhalten

Beitrag von Vermilion »

Jeder von euch kennt doch die GameBoy Spiele, wie z.B. Pokemon Rote Edition. :mrgreen: So'ne Steuerung will ich haben...
So, ich habe in letzter Zeit mit einer Tile Engine experimentiert, jedoch bin ich nun an einem Punkt, an dem ich nicht weiter komme.

Das 1. was zu ändern wäre, ist, dass, wenn man eine Bewegungstaste drückt, sich die Spielfigut flüssig von einem Tile zum andern bewegt und dabei natürlich immer auf der Mitte des Tiles stehen bleibt. So wie beim Schach ungefähr...(Damit das nicht schon wieder so affig rast, muss man da wahrscheinlich auch wieder Zeitanhängige Steuerung benutzen -.-° ).

Derzeit habe ich die Bewegungen so gelöst, dass man sich durch KeyboardReleased() ein Feld je nach Richtung bewegt, weil mit KeyboardPushed() ist man locker innerhalb 2 Sekunden am anderen Ende der Map. Das wäre das 2. was ich ändern will, dass man eine Bewegungstaste gedrückt lassen kann und sich die Figur genauso bewegt.

Jetzt die Frage: Wie kriege ich das hin?

Ich habe die Angelegenheit mit den zugänglichen Sprites etc. durch ein 2. Array gelöst, anstatt einen 2. Layer in ein Array einzubauen.

Link für das komplette Paket hier, Code der Engine unten (Auch im Archiv enthalten):
http://www.thenameless.de/Software/gbtile.rar

Code: Alles auswählen

#ScreenWidth  = 800
#ScreenHeight = 600
#TileSize     = 32
#NumberOfDifferentTiles = 8 ; (Immer 1 weniger als wirklich ist)

Global PlayerX
Global PlayerY

InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(#ScreenWidth, #ScreenHeight, 32, "OE_FH-mod")

LoadSprite(0, "player.bmp")

PlayerSprite = 0

For n = 0 To #NumberOfDifferentTiles
  LoadSprite( 100+n, Right("00"+Str(n),3)+".bmp")
Next

If ReadFile(0, "Layer0.lyr")
  Global MapWidth  = ReadLong(0)
  Global MapHeight = ReadLong(0)
  Dim Map_0(MapWidth-1, MapHeight-1)
  For t = 0 To MapHeight-1
    For n = 0 To MapWidth-1
      Map_0(n, t) = ReadLong(0)
    Next
  Next
  CloseFile(0)
EndIf

If ReadFile(0, "Layer1.lyr")
  Global MapWidth  = ReadLong(0)
  Global MapHeight = ReadLong(0)
  Dim Map_1(MapWidth-1, MapHeight-1)
  For t = 0 To MapHeight-1
    For n = 0 To MapWidth-1
      Map_1(n, t) = ReadLong(0)
    Next
  Next
  CloseFile(0)
EndIf

MouseLocate(400, 300)

Repeat
  ExamineKeyboard()
  ExamineMouse()
  MouseX = MouseX() : MouseY = MouseY()
  ClearScreen(0)
  
If KeyboardReleased(#PB_Key_Left) And Map_0(PlayerX-1, PlayerY) <> 0
      MapX-1
      If MapX < 0
        MapX = 0
      EndIf
  ElseIf KeyboardReleased(#PB_Key_Right) And Map_0(PlayerX+1, PlayerY) <> 0
      MapX+1
      If MapX > MapWidth-26
        MapX = MapWidth-26
      EndIf
  ElseIf KeyboardReleased(#PB_Key_Up) And Map_0(PlayerX, PlayerY-1) <> 0
      MapY-1
      If MapY < 0
        MapY = 0
      EndIf
  ElseIf KeyboardReleased(#PB_Key_Down) And Map_0(PlayerX, PlayerY+1) <> 0
      MapY+1
      If MapY > MapHeight-20
        MapY = MapHeight-20
      EndIf
  EndIf

PlayerX  = 400 / #TileSize + MapX
PlayerY  = 300 / #TileSize + MapY
ActTileX = MouseX / #TileSize + MapX
ActTileY = MouseY / #TileSize + MapY

; Tile Engine __________________________________________________________________________________________________________________
  
  For SY = 0 To 19
    For SX = 0 To 25
      DisplaySprite(100+Map_1(MapX+SX, MapY+SY), #TileSize*SX-FineX, #TileSize*SY-FineY)
    Next
  Next
    
;_______________________________________________________________________________________________________________________________

  DisplayTransparentSprite(PlayerSprite, 384, 256)
  
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(ActTileX*#TileSize-MapX*#TileSize, ActTileY*#TileSize-MapY*#TileSize, #TileSize, #TileSize, RGB(0, 127, 255))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText( 8,  8, "X: "+Right("000"+Str(ActTileX), 4))
    DrawText( 8, 24, "Y: "+Right("000"+Str(ActTileY), 4))
    Line(MouseX, MouseY, 0, #TileSize, RGB(0, 127, 255))
    Line(MouseX, MouseY, (#TileSize/4)*3, #TileSize-(#TileSize/2), RGB(0, 127, 255))
  StopDrawing()

  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
End
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ich kenne die engines vom gameboy nicht.

a) flüssige bewegung bis zur mitte des nächsten tiles
b) KeyboardReleased

nimm auf keinen fall KeyboardReleased.
das gibt immer absolutes anti-game-feeling.
nur bei speziellen fällen kann man sowas anwenden.

du wirst mehrere frames brauchen, damit die spielfigur ins nächste tile gelaufen ist.

also checkst du wenn sie in der mitte des jetzigen tiles steht,
wie die tasten aussehen (keyboardpushed), und initiierst demendsprechend
eine fortdauernde bewegung.
die bewegung läuft dann weiter ab, bis die figur in der mitte des nächsten tiles angekommen ist,
erst dann wird erneut abgefragt, welche tasten gedrückt sind.

nachfragen? bitte.

code gibts nich, is feiertag
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
inti
Beiträge: 90
Registriert: 01.02.2006 17:25

Re: Tile Engine: GameBoy Verhalten

Beitrag von inti »

'hoffe du hast verständnis wenn ich mich jetzt nicht durch deinen code durcharbeite aber die lösung ist ganz einfach - habe es dir schnell mal aus dem gedächtniss "quick'n'dirty" zusammengebaut (wehe es lacht jemand), ist PB4.0X... nicht die figur/sprite direkt bewegen sondern sie nach einem punkt bewegen der sich im tile raster bewegt.

Code: Alles auswählen

; spritecoordinaten
Global SpriteX = 0
Global SpriteY = 0

; "ziel"punkt an den sich das sprite bewegen soll
Global SpriteY32 = 0
Global SpriteX32 = 0

InitSprite()
InitKeyboard()

OpenWindow(1, #PB_Ignore, #PB_Ignore , 320, 240, "test", #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(1), 0, 0, 320, 240, 1, 0, 0)

CreateSprite(0, 32, 32)

Repeat
  ClearScreen(RGB(255,255,255))
  
  StartDrawing(ScreenOutput())
    For x = 0 To 9
      For y = 0 To 7
        Box(x*32, y*32, 32, 32, RGB(255,0,0))
        Box(x*32+1, y*32+1, 30, 30, RGB(255,255,255))
      Next
    Next
  StopDrawing()

  ExamineKeyboard()

  If SpriteX = SpriteX32 And SpriteY = SpriteY32
    If KeyboardPushed(#PB_Key_Down) : SpriteY32 + 32 : EndIf
    If KeyboardPushed(#PB_Key_Up) : SpriteY32 - 32 : EndIf
    If KeyboardPushed(#PB_Key_Left) : SpriteX32 - 32 : EndIf
    If KeyboardPushed(#PB_Key_Right) : SpriteX32 + 32 : EndIf
  EndIf
 
  If SpriteX > SpriteX32 : SpriteX - 1 : EndIf
  If SpriteX < SpriteX32 : SpriteX + 1 : EndIf
  If SpriteY > SpriteY32 : SpriteY - 1 : EndIf
  If SpriteY < SpriteY32 : SpriteY + 1 : EndIf

  DisplaySprite(0, SpriteX, SpriteY)
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
End
'hoffe das hilft dir etwas weiter.
mir SpriteX32/SpriteY32 kannst du auch das array für die eigenschaften der tiles gleich mit überprüfen.
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

Dank an euch, ich werde mir das nochmal reinziehen, kann des im Moment nicht durchchecken... Falls noch was unklar wäre, werde ich nochmal posten... :)
code gibts nich, is feiertag
:mrgreen:
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
wasser
Beiträge: 125
Registriert: 27.11.2006 21:16

Beitrag von wasser »

code gibts nich, is feiertag......

fauler Sack!
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

hast du da vielleicht nen smily vergessen?
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Beitrag von DarkSoul »

hab das so gemacht (kompletter code!)

Code: Alles auswählen

;musste den code ein wenig anpassen, daher must du ihn unter umständen zurück-anpassen!
#ScreenWidth  = 800 
#ScreenHeight = 600 
#TileSize     = 32 
#NumberOfDifferentTiles = 8 ; (Immer 1 weniger als wirklich ist) 

Global PlayerX 
Global PlayerY 

InitSprite() 
InitKeyboard() 
InitMouse() 
OpenScreen(#ScreenWidth, #ScreenHeight, 32, "OE_FH-mod") 

LoadSprite(0, "player.bmp") 

PlayerSprite = 0 

For n = 0 To #NumberOfDifferentTiles 
  LoadSprite( 100+n, Right("00"+Str(n),3)+".bmp")   ;PS: Das hier funktioniert nur bis zum 10 sprite :-)
Next 

If ReadFile(0, "Layer0.lyr") 
  Global MapWidth  = ReadLong(0) 
  Global MapHeight = ReadLong(0) 
  Dim Map_0(MapWidth-1, MapHeight-1) 
  For t = 0 To MapHeight-1 
    For n = 0 To MapWidth-1 
      Map_0(n, t) = ReadLong(0) 
    Next 
  Next 
  CloseFile(0) 
EndIf 
; 
 If ReadFile(0, "Layer1.lyr") 
   Global MapWidth  = ReadLong(0) 
   Global MapHeight = ReadLong(0) 
   Dim Map_1(MapWidth-1, MapHeight-1) 
   For t = 0 To MapHeight-1 
     For n = 0 To MapWidth-1 
       Map_1(n, t) = ReadLong(0) 
     Next 
   Next 
   CloseFile(0) 
 EndIf 

MouseLocate(400, 300) 

Repeat 
  ExamineKeyboard() 
  ExamineMouse() 
  MouseX = MouseX() : MouseY = MouseY() 
  ClearScreen(0) 
  If DirectionY
    ;dummy, schaltet die tastenabfrage ab!
  ElseIf KeyboardPushed(#PB_Key_Up) And Map_0(PlayerX, PlayerY-1)  
    DirectionY=1
    DirCountY=#TileSize
  ElseIf KeyboardPushed(#PB_Key_Down) And Map_0(PlayerX, PlayerY+1) 
    DirectionY=3
    DirCountY=#TileSize
  EndIf    
  If DirectionX
    ;dummy, schaltet die tastenabfrage ab!
  ElseIf KeyboardPushed(#PB_Key_Left) And Map_0(PlayerX-1, PlayerY)  
    DirectionX=4
    DirCountx=#TileSize
  ElseIf KeyboardPushed(#PB_Key_Right) And Map_0(PlayerX+1, PlayerY)
    DirectionX=2
    DirCountx=#TileSize
  EndIf
  Select DirectionY
    Case 1
      FineY-2
      DirCountY - 2
      If DirCountY=0:FineY=0:MapY-1:DirectionY=0:EndIf
    Case 3
      FineY+2
      DirCountY - 2
      If DirCountY=0:FineY=0:MapY+1:DirectionY=0:EndIf
  EndSelect
  Select DirectionX
    Case 2
      FineX+2
      DirCountx - 2
      If DirCountx=0:FineX=0:MapX+1:DirectionX=0:EndIf
    Case 4
      FineX-2
      DirCountx - 2
      If DirCountx=0:FineX=0:MapX-1:DirectionX=0:EndIf
      
      
  EndSelect
    
  PlayerX  = 400 / #TileSize + MapX 
  PlayerY  = 300 / #TileSize + MapY 
  ActTileX = MouseX / #TileSize + MapX 
  ActTileY = MouseY / #TileSize + MapY 
  
  ; Tile Engine __________________________________________________________________________________________________________________ 
  
  For SY = -1 To 19         ;geändert!
    For SX = -1 To 25 
      If MapX+SX > 0 And MapY+SY > 0  And MapX+SX < MapWidth And MapY+SY < MapHeight
        DisplaySprite(100+Map_1(MapX+SX, MapY+SY), #TileSize*SX-FineX, #TileSize*SY-FineY) 
      EndIf
    Next 
  Next 
  
  ;_______________________________________________________________________________________________________________________________ 
  
  DisplayTransparentSprite(PlayerSprite, 384, 256) 
  
  StartDrawing(ScreenOutput()) 
  DrawingMode(4) 
  Box(ActTileX*#TileSize-MapX*#TileSize, ActTileY*#TileSize-MapY*#TileSize, #TileSize, #TileSize, RGB(0, 127, 255)) 
  DrawingMode(1) 
  DrawText(8,8, "X: "+Right("000"+Str(ActTileX), 4)) 
  DrawText(8,24  "Y: "+Right("000"+Str(ActTileY), 4)) 
  Line(MouseX, MouseY, 0, #TileSize, RGB(0, 127, 255)) 
  Line(MouseX, MouseY, (#TileSize/4)*3, #TileSize-(#TileSize/2), RGB(0, 127, 255)) 
  StopDrawing() 
  
  FlipBuffers() 
Until KeyboardPushed(#PB_Key_Escape) 
CloseScreen() 
End
[/code]
Bild
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

:mrgreen: Danke für den Code.. nur leider habe ich es nun auch schon selber hingekriegt <) . Allerdings so, dass sich die Map bewegt, und nicht der Spieler (so hatte ich das auch vor). Das war eine Arbeit, stundenlang heute Vormittag dran rumgeschraubt... :freak:

Die Engine will ich in mein neues Projekt einbauen. Bei dem hatte ich schon circa 2000 Zeilen, das war aber auch nur das Menü und nur Teile der Alpha Stadium Engine. :roll: Den Spielcode mach ich auch neu, aus vielen verschiedenen Gründen*, dann lässt sich diese Engine auch besser einbauen.

*: Unnötige Programmzeilen/Operationen, stark in den ganzen Code verflochtener logischer Müll, usw.
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Beitrag von DarkSoul »

the Nameless hat geschrieben::mrgreen: Danke für den Code.. nur leider habe ich es nun auch schon selber hingekriegt <) . Allerdings so, dass sich die Map bewegt, und nicht der Spieler (so hatte ich das auch vor). Das war eine Arbeit, stundenlang heute Vormittag dran rumgeschraubt... :freak:

Die Engine will ich in mein neues Projekt einbauen. Bei dem hatte ich schon circa 2000 Zeilen, das war aber auch nur das Menü und nur Teile der Alpha Stadium Engine. :roll: Den Spielcode mach ich auch neu, aus vielen verschiedenen Gründen*, dann lässt sich diese Engine auch besser einbauen.

*: Unnötige Programmzeilen/Operationen, stark in den ganzen Code verflochtener logischer Müll, usw.

meine engine macht das doch... Der player
ist ein fixes sprite, wi eim orginalsource

Du musst dicgh nicht schämen und das unangenehme klein drucken! wir sind doch hier zum teil hobby-programmierer, die können sich sowat erlauben!!!.
Bild
Benutzeravatar
Vermilion
Beiträge: 1846
Registriert: 08.04.2006 16:00
Computerausstattung: Apple iMac (2010) & HP Notebook
Wohnort: Heidekreis

Beitrag von Vermilion »

meine engine macht das doch
Ups, sorry, hatte den Code nur überflogen...
Du musst dicgh nicht schämen und das unangenehme klein drucken! wir sind doch hier zum teil hobby-programmierer, die können sich sowat erlauben!!!
Naja, ok, schämen tue ich mich nun auch wieder nicht wirklich, bloß da habe ich manche Sachen eingebaut, die, wenn ich nachgedacht hätte, gar nicht reingekommen wären, weil sie totaler müll sind. :roll:
Naja, jedenfalls bin ich jetzt fast wieder auf dem Stand der Programmierung des Spiels wie vorher.. seit gestern 800 Zeilen geschrieben, hätte mehr leisten können, aber da das ja was ordentliches werden soll...
Bild

Immer die neueste PureBasic Version. Auf allem Betriebssystemen. Ich bin ein OS-Nomad!
Antworten