Seite 1 von 3

Tutorial zu arrays

Verfasst: 06.07.2006 14:53
von Ghost
HI

Ich will demnächst mit mein nächsten Projeckt beginnen (ein Strategiel)
hab aber leider keine Ahnung wie man arrays erstellt, Sprites darauf Platziert,bewegt, collisonsabfragen kann, ... und wollte mal fragen ob jemand dazu ein tutorial kennt

Verfasst: 06.07.2006 14:59
von Kaeru Gaman
mir ist kein Tile-Engine&Co-Tutorial für PB bekannt, es gibt allerdings zig threads hier im board und in der lounge, die sich mit diesem thema beschäftigen.

Verfasst: 06.07.2006 19:53
von Alves
Musste vll mal auf www.robsite.de nach PB Tutorialen für Sprites gucklen, damit hab ich auch angefangen :allright:

Verfasst: 07.07.2006 14:13
von Ghost
gute ideen danke :wink: ich werde mich mal ein wenig dazu durchlesen

ähm hab aber mal noch eine Frage zu der tile-engine .
dient sie nur der Bequemlichkeit oder kann ich die sprites auch manuell im Code Platzieren (also mit DisplayTransparentSprite(...).
oder hatt das etwas mit dem verbrauch von Arbeitsspeicher zu tun?

Verfasst: 07.07.2006 15:10
von #NULL
programme dienen immer (nur) der bequemlichkeit. man könnte auch für ein ganzes spiel "einfach" die farbe jedes screen-pixels, in jeder situation des spiels festlegen. aber dann wirste blöd. programmierung besteht ja gerade darin, sachverhalte zu verallgemeinern, und wiederkehrende aufgaben nur einmal zu beschreiben.

Verfasst: 07.07.2006 15:24
von DarkDragon

Code: Alles auswählen

; Sprite- und Keyboardfunktionen voreinstellen
If InitSprite() = 0 : MessageRequester("Error", "Can't init. screens and sprites") : End : EndIf
If InitKeyboard() = 0 : MessageRequester("Error", "Can't init. keyboard") : End : EndIf

; Geschwindigkeitskonstante
#SPEED = 2

; Diese Funktion prüft ob eine Kollision vorliegt
Procedure Collision(x.f, y.f)
  Result = 0
;   Gehe alle Tiles durch
  Restore Map
 
  For my=0 To 17
    For mx=0 To 24
     
      a.b
      Read a
;       Wenn der Tile-Typ 1(Mauer) ist, so prüfe auf eine Kollision mit diesem Tile...
      If a = 1
;         ... mit den entsprechenden Tile-koordinaten(IndexX*TileBreite, IndexY*TileBreite)...
;         ... und den entsprechenden Spieler-koordinaten(SpielerX, SpielerY)...
;         ... so, wie man es Zeichnen würde.
        If SpriteCollision(0, Int(x), Int(y), 1, mx*32, my*32)
;           Wenn ja: gib 1(True) zurück
          Result = 1
;           und springe aus beiden Schleifen(Anzahl: 2) raus
          Break 2
        EndIf
      EndIf
     
    Next
  Next
 
  ProcedureReturn Result
EndProcedure

; Öffne einen Screen
If OpenScreen(800, 600, 32, "Test") = 0 : MessageRequester("Error", "Can't open a screen") : End : EndIf

; Erstelle 2 Sprites
; Rotes viereck = Mauer
CreateSprite(0, 32, 32)
StartDrawing(SpriteOutput(0))
Box(0, 0, 32, 32, RGB(255, 0, 0))
StopDrawing()

; Blaues viereck = Spieler
CreateSprite(1, 32, 32)
StartDrawing(SpriteOutput(1))
Box(0, 0, 32, 32, RGB(0, 0, 255))
StopDrawing()

; Spielerposition genau in der Mitte des Bildschirms
X.f = 800/2
Y.f = 600/2

; Framerate auf 30 setzen(reich völlig)
SetFrameRate(30)

;- Hauptschleife
Repeat
;  Keyboardstatus erneuern und abfragen
  ExamineKeyboard()
 
  If KeyboardPushed(#PB_Key_Up)     ; laufe hoch
    If Collision(X, Y-#SPEED) = 0
      Y - #SPEED
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Down)   ; laufe runter
    If Collision(X, Y+#SPEED) = 0
      Y + #SPEED
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Left)   ; laufe links
    If Collision(X-#SPEED, Y) = 0
      X - #SPEED
    EndIf
  EndIf
  If KeyboardPushed(#PB_Key_Right)  ; laufe rechts
    If Collision(X+#SPEED, Y) = 0
      X + #SPEED
    EndIf
  EndIf
 
;   Beenden?
  If KeyboardPushed(#PB_Key_Escape)
    Quit = 1
  EndIf
 
;  Screeninhalt löschen und mit Schwarz überdecken
  ClearScreen(0, 0, 0)
;  Spieler anzeigen
  DisplaySprite(1, X, Y)
 
;  Mapdaten durchgehen
  Restore Map
  For my=0 To 17
    For mx=0 To 24
     
      a.b
      Read a
      If a = 1
;        Mauer = 1, also anzeigen
        DisplaySprite(0, mx*32, my*32)
      EndIf
     
    Next
  Next
;  Gefüllten Backbuffer zum Frontbuffer bringen
  FlipBuffers()
 
;  Eine kleine Verzögerung um den Prozessor nicht vollständig auszulasten
  Delay(5)
Until Quit = 1
End

; Mapdaten
DataSection
  Map:
  Data.b 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.b 1, 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.b 1, 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.b 1, 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.b 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1
  Data.b 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
  Data.b 1, 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.b 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1
  Data.b 1, 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.b 1, 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.b 1, 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.b 1, 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.b 1, 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.b 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
  Data.b 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1
  Data.b 1, 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.b 1, 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.b 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
Vielleicht ändert dir das jemand ab zu Arrays, dann hättest du schonmal ein kleines, handliches und auskommentiertes Beispiel.

Verfasst: 07.07.2006 17:04
von Zaphod
Hauptsächlich benutzt man Tile Engines wegen des Speicherverbrauches.

Stell dir mal folgendes vor:

Du Willst ein RPG schreiben. Die Welt deines RPGs soll mindestens 100*100 Bildschirme groß sein. Als Bildschirmauflösung hast du 800*600 Pixel gewählt. Ohne Tilemapping hast du nicht viele Möglichkeiten deine Welt fest zu legen. Du könntest zum Beispiel eine große Bitmap als Welt erstellen. Dann ist deine Welt also (800*100)*(600*100) = 4 800 000 000 Pixel groß.

Deine Welt brauch also ohne gegenstände oder irgendwas außer dem Hintergrund Bild 4 800 000 000 Byte (wenn du dich auf 256 Farben beschränkst) das entspricht 4 687 500 kb oder rund 4577,64 Megabyte... prost Mahlzeit, das wird ein schöner Download. Rechner die genug Ram haben gibt es bestimmt auch in ein paar Jahren.

Oder du machst das Ganze als Tile Engine.
Als Tilegröße wählst du zb 100*100 Pixel, dann brauch deine Welt

((800*100)/100)*(600*100)/100= 800*600 = 480 000 Elemente
Da du am besten mit einem Long Array arbeitest ist das 480 000 * 4 (denn ein long besteht aus 4 Bytes) = 1 920 000 Bytes. Das entspricht 1875 Kb oder rund 1,84 Mb + dem Speicherbedarf deiner Tiles. Sagen wir du benutzt 500 Tiles (und das ist schon eine sehr hochgegriffene zahl) dann kommen dazu noch 100*100*500*4 (4, weil wir uns ja nicht auf 256 Farben beschränken wollen) = rund 20 Mb dazu.

Weniger als 22 Megabyte sind doch schon viel besser als 4 1/2 Gigabyte oder? ;)

Verfasst: 08.07.2006 09:56
von Ghost
danke für den Beispielcode.
@ Zaphod :o stimmt da is schon ein kleiner Unterschied
Danke jedenfals

Verfasst: 08.07.2006 12:44
von Konne
Auserdewm viel Flexiebler und schneller usw mal ganz davon abgesehen das PB grose Bilder gar nicht verarbeiten kann.

Verfasst: 08.07.2006 19:21
von Kaeru Gaman
Konne hat geschrieben:Auserdewm viel Flexiebler und schneller usw mal ganz davon abgesehen das PB grose Bilder gar nicht verarbeiten kann.
nuja, ein bild von 4GB kann kein 32bit-system verwalten...