Scrollen mit View(s)
Übersicht BlitzBasic FAQ und Tutorials
Soul ReaverBetreff: Scrollen mit View(s) |
Mo, Feb 16, 2009 0:09 Antworten mit Zitat |
|
---|---|---|
Hi,
da ihr mir so schön bei meinen BB-Problemchen helft, hab ich entschlossen ein Tutorial zu schreiben. Es geht um die Verwendung von Views und dem sog. Scrolling. Oft kommt es vor, dass die Welt in seinem Spiel größer sein soll als die Bildschirmauflösung. Doch wie soll man das machen? Views sind die Antwort. Zuerst sollte man festlegen wie groß der View und der Raum werden soll: Code: [AUSKLAPPEN] Graphics 800,600 SetBuffer BackBuffer() AppTitle "Views" fpstimer=CreateTimer(60) Global roomwidth=1000 Global roomheight=1000 ;Raumgröße Global viewwidth=800 Global viewheight=600 ;Viewgröße Global viewx=0 Global viewy=0 ;Viewposition ;Main Loop While Not KeyHit(1) WaitTimer fpstimer Cls Flip 0 Wend End Man sollte immer die Viewgröße der Graphics-einstellung anpassen! So jetzt sollten wir natürlich ein paar Objekte erstellen und eine Funktion zum Bewegen des Views einbauen. Code: [AUSKLAPPEN] Graphics 800,600 SetBuffer BackBuffer() AppTitle "Views" SeedRnd MilliSecs() fpstimer=CreateTimer(60) Global roomwidth=1000 Global roomheight=1000 ;Raumgröße Global viewwidth=800 Global viewheight=600 ;Viewgröße Global viewx=0 Global viewy=0 ;Viewposition Type obj Field x,y End Type ;Zufällig ein paar Objekte erstellen... Da fällt mir auf, dass ich SeedRnd vergessen hab ;D For i=0 To 19 o.obj=New obj o\x=Rnd(roomwidth) o\y=Rnd(roomheight) Next ;Main Loop While Not KeyHit(1) WaitTimer fpstimer Cls Move() ;Funktion zum Bewegen des Views Draw() ;Funktion zum Zeichnen der Objekte Flip 0 Wend End ;Funktionen Function Move() If KeyDown(200) viewy=Max(0,viewy-3) If KeyDown(205) viewx=Min(roomwidth-viewwidth,viewx+3) If KeyDown(208) viewy=Min(roomheight-viewheight,viewy+3) If KeyDown(203) viewx=Max(0,viewx-3) ;Min() und Max() verwende ich dass der View nicht Gebiete außerhalb des Raumes zeigen kann... Ist aber nicht nötig End Function Function Draw() For o.obj=Each obj Rect o\x-viewx,o\y-viewy,10,10 ; Eigentlich sollte man Abfragen ob das Objekt im view ist!!! Next End Function Function Min(x,y) ;Gibt die kleinere Zahl zurück If x>y Return y Else Return x EndIf End Function Function Max(x,y) ;Gibt die größer Zahl zurück If x>y Return x Else Return y EndIf End Function Das ganze sollte jetzt so aussehen. Ich hoffe ich konnte einigen Anfängern helfen. |
||
hecticSieger des IS Talentwettbewerb 2006 |
Mo, Feb 16, 2009 2:40 Antworten mit Zitat |
|
---|---|---|
Eine Tilemap sollte man in den wenigsten Fällen über Types erstellen. Das Problem ist einfach, dass bei großen Maps zuviel gezeichnet bzw. bei einer Überprüfung jedes mögliche Tile jedes Frame überprüft werden muß. Bei einem 2D-Array dagegen, kann man den sichtbaren Bereich einfach über eine doppelte Schleife eingrenzen. Das auslesen der Map geschieht also direkt was sehr recourcenschonend ist.
Damit besser sichtbar ist, wie ein sichtbarer Bereich eingegrenz wird, habe ich die Schleifen jeweils ab 1 und nicht bis zum Bildschirmrand laufen lassen. Hier mal ein Beispiel: Code: [AUSKLAPPEN] Graphics 600,600,0,2
SetBuffer BackBuffer() Const TILESIZE=40 Local Timer=CreateTimer(60) Local X,Y,Block Local MapXPos Local MapYPos Dim Map(63,63) ;EINE ZUFALLS-MAP ERSTELLEN For Y=0 To 63 For X=0 To 63 Map(X,Y)=Rand(9) Next Next While Not KeyDown(1) MapXPos=MouseX() MapYPos=MouseY() ;DIE SICHTBARE MAP EINGRENZEN For Y=1 To 10 For X=1 To 10 ;DIE TILE-ID (HIER FARBE) ZWISCHENSPEICHERN Block=Map(X+(MapXPos/TILESIZE),Y+MapYPos/TILESIZE) ;WENN DIE TILE-ID GÜLTIG IST (ALSO VORHANDEN) If Block>0 Then ;IN DIESEM FALL (WEIL KEIN BILD GELADEN) DIE FARBE ANPASSEN Color Block*20,0,0 ;IN DIESEM FALL (WEIL KEIN BILD GELADEN) EIN RECT EINZEICHNEN Rect (Int(MapXPos/TILESIZE)*TILESIZE)-MapXPos+X*TILESIZE,(Int(MapYPos/TILESIZE)*TILESIZE)-MapYPos+Y*TILESIZE,TILESIZE,TILESIZE,1 End If Next Next WaitTimer Timer Flip 0 Cls Wend End Ich will allerdings dein Code auch nicht schlecht machen. Eine auf Types basierende Tilemap hat gewiss in seltenen Fällen ihre Vorteile. Man sollte allerdings diese Vorteile kennen und auch speziel darauf eingehen. Das Array-Beispiel dagegen kann nahezu beliebig groß und vor allem dicht besiedelt sein, es wird nicht langsamer, als nur mehr Speicher für die Map drauf geht. Der Speichergebrauch ist bei einem Type aber auch nicht viel weniger. Grundsätzlich würde ich auch jeden Schritt genau erklären. Ein so fertiger Code hätte sonst auch genauso gut ins Codearchiv kopiert werden können. Sachen wie ''Eigentlich sollte man Abfragen ob das Objekt im view ist!!!'' machen es nicht gerade besser. Dieses ist ein wichtiger Schritt und sollte auf jeden Fall drauf eingegangen werden. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
Soul Reaver |
Mo, Feb 16, 2009 11:58 Antworten mit Zitat |
|
---|---|---|
EDIT: Quote entfernt. MfG BladeRunner
Ich muss gestehen, dass ich es in der Engine, an der ich gerade arbeite, mit Arrays regle, aber ich habe hier Types verwendet, da es so meiner Meinung einfacher geht und das Tutorial für Anfänger ist. Ich werde das Tutorial noch verbessern, wenn ich Zeit habe. Danke für deine Antwort |
||
Sliver |
Mo, Feb 16, 2009 14:08 Antworten mit Zitat |
|
---|---|---|
Types und Anfänger... ist ne böse Kombination!
Wenn man anfängt, sollte man lieber erstmal mit Arrays experimentieren, bevor man mit Types jongliert. Edit: hectic's Code ist um Welten besser! |
||
- Zuletzt bearbeitet von Sliver am Mo, Feb 16, 2009 14:09, insgesamt einmal bearbeitet
BladeRunnerModerator |
Mo, Feb 16, 2009 14:08 Antworten mit Zitat |
|
---|---|---|
Bitte zitiert doch nicht immer ganze Beiträge die direkt über eurer Antwort stehen. Das ist einfach nur störend. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
Firstdeathmaker |
Mo, Feb 16, 2009 16:59 Antworten mit Zitat |
|
---|---|---|
Hmm, ich würde mal sagen beides sind spezielle Lösungen zu speziellen Problemen. Was ist z.B. wenn man ein Space-Game mit sehr großen Ausmaßen hat (mapsize=100.000 x 100.000 px)? Und sich die Raumschiffe und Objekte nicht auf Tiles bewegen? Dann wäre vllt. das erste besser. Allerdings fällt dann wieder die langwierige Prüfung auf Sichtbarkeit auf. Die Lösung: Kombiniert doch einfach die Tilemap mit der andern Methode (wird für massenhafte Kollision sowieso nötig):
Eine sehr großtilige Map (tiles von vllt. 200x200 pixel) in denen jeweils eine liste existiert in welche sich objekte, die sich dort befinden, reinhängen. Bei einzeichnen der Cam (=View) muss man nicht mehr alle Objekte überprüfen, sondern zeichnet einfach alle ein, die sich auf den gerade für die Kamera sichtbaren tiles befinden. Man muss allerdings beim einzeichnen darauf achten, nicht einfach hintereinander alle listen einzuzeichnen, sondern die Listen zusammen zu legen und zu sortieren. Ebenso kann man dann auch die Kollisionsprüfung nur über Objekte laufen lassen, welche sich im eigenen Tile befinden. |
||
www.illusion-games.de
Space War 3 | Space Race | Galaxy on Fire | Razoon Gewinner des BCC #57 User posted image |
Übersicht BlitzBasic FAQ und Tutorials
Powered by phpBB © 2001 - 2006, phpBB Group