Tetris - die Blöcke fallen nicht...

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Dice of Darkness

Betreff: Tetris - die Blöcke fallen nicht...

BeitragMi, Okt 15, 2008 19:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich hab schon alle Themen zu "Tetris" durchgesucht aber ich bin einfach nicht auf die richtige Lösung gekommen. Bzw. das was dort als "Lösungen" stand war nicht gerade hilfreich für mich...

Also folgendes: Ich bin gerade dabei ein Tetris zu programmieren. Dabei geht es erstmal nur darum, die verschiedenen Steine (also L,Z,I etc.) aus einem einzelnen Block darzustellen. Damit habe ich angefangen, bis jetzt habe ich nur den langen 4*1-Block geproggt (die anderen kommen später).
Jetzt hab ich in den anderen Themen herausgefunden, dass man das am besten mit Arrays macht (also den I-Block aus vier untereinander gepackten "Grundblöcken"). Es wird auch prima auf dem Bildschirm dargestellt, nur hab ich jetzt ein Problem: Wie schaffe ich es, dass die Steine runterfallen?

Code: [AUSKLAPPEN]
Graphics 640,480,16,0
SetBuffer BackBuffer()

frametimer = CreateTimer (45)

Global Stein = LoadImage("Stein.bmp")
Global x = 250
Global y = 0
Global Blocktime


Dim langer_stein(3,3)

Restore langer_steindata
For y = 0 To 3
   For x = 0 To 3
      Read langer_stein(x,y)
   Next
Next



.langer_steindata
Data 0,0,1,0
Data 0,0,1,0
Data 0,0,1,0
Data 0,0,1,0


;Hauptschleife
Repeat
ClsColor 0,255,0
Cls
WaitTimer(frametimer)
DrawStein()
Flip

Until KeyHit(1)

WaitKey
End


;Funktionen:

Function DrawStein()
For y = 0 To 3
   For x = 0 To 3
      If langer_stein(x,y) = 1 Then
         DrawBlock Stein,x*32,y*32
      EndIf
   Next
Next

End Function

Function Fallen(); das ist die Function mit der der I-Stein automatisch herunterfallen soll

If MilliSecs() - Blocktime >= 1000 Then
   If y < (480 - 32) Then                 ;480-32, weil das Tile 32*32 groß ist
      Blocktime = MilliSecs()
      y = y + 32 ; hier sollte THEORETISCH der Block herunterfallen, was er rein praktisch nicht tut
   EndIf
EndIf

End Function


Ich vermute mal, dass man noch eine weitere Variable braucht, damit der Stein herunterfällt?!
Mein Problem ist, dass ich die Sache mit den Labels noch nicht so wirklich verstanden habe. Für mich sieht es jetzt so aus, dass mit dem Dim irgendwas (3,3) ein Feld erstellt wird, das über 3 mal 3 Variablen verfügt, mit denen ich unter irgendwasdata den I-Stein darstellen kann. Aber wie kann ich jetzt z.B. den erstellten Stein in der Mitte des Bildschirms darstellen und nicht oben rechts? (In diesem Programm wird der Stein ja rechts oben erstellt, weil Data nur über 4 Felder verfügt => Data 0,0,1,0). Müsste man zwangsläufig ein größeres Feld definieren oder kann man den erstellten Baustein in seiner Position auch verschieben??
Und dann wäre da halt noch meine Ausgangsfrage, wie man es machen kann, dass der Stein herunterfällt...

Ich hoffe, dass meine Frage einigermaßen verständlich formuliert ist und ihr mir helfen könnt (sicher sieht man am Code, dass ich ein totaler Anfänger bin Embarassed )...

Danke im Voraus,
Dice of Darkness
Gratis Spiele, Musik, Tools

sheldon

BeitragMi, Okt 15, 2008 19:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehe ich das falsch, oder hast du vergessen den Blocktimer zu erhöhen?

ozzi789

BeitragMi, Okt 15, 2008 19:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier ein beispiel von Abrexxes

Code: [AUSKLAPPEN]
;------- Design-time definition (static)

     Const Screen_SizeX = 640
     Const Screen_SizeY = 480

     Const Key_ArrowUp    = 200  ; Rotate block right (clockwise)
     Const Key_ArrowDown  = 208  ; Move block down
     Const Key_ArrowLeft  = 203  ; Move block left
     Const Key_ArrowRight = 205  ; Move block right
     Const Key_RightCtrl  = 157  ; Drop block
     Const Key_AlphaZ     =  44  ; Rotate block left (counter clockwise)
     Const Key_AlphaX     =  45  ; Rotate block right (clockwise)
     Const Key_Escape     =   1  ; Exit

     ; Block to rotate/place

     Const Block_SizeX = 5
     Const Block_SizeY = 5
     Const Block_Count = 8

     Const Block_Current = 0
     Const Block_Rotate  = 1

     Const Dir_Left  = 1
     Const Dir_Right = 2
     Const Dir_Down  = 3

.BlockData
     Data "     "
     Data "     "
     Data "  X  "
     Data "     "
     Data "     "

     Data "     "
     Data "     "
     Data " XX  "
     Data "     "
     Data "     "

     Data "     "
     Data "     "
     Data " XXX "
     Data "     "
     Data "     "

     Data "     "
     Data "     "
     Data "  XX "
     Data "  X  "
     Data "     "

     Data "     "
     Data "     "
     Data " XXX "
     Data " X   "
     Data "     "

     Data "     "
     Data " X   "
     Data " XXX "
     Data "     "
     Data "     "

     Data "     "
     Data "     "
     Data " XXX "
     Data "  X  "
     Data "     "

     Data "     "
     Data "     "
     Data "XXXX "
     Data "     "
     Data "     "

     ; Playing field

     Const Field_SizeX = 11
     Const Field_SizeY = 20

     ; Visual sizes

     Const VisualBrick_SizeX = 12*2
     Const VisualBrick_SizeY = 10*2

     ; Time

     Const Block_MoveDelay_Default = 1000  ; Initial block auto-move delay (in millisecs)
     Const Block_MoveDelay_Factor# = 0.05  ; Generic increment/decrement game move delay factor

     Const Block_AvgBrickCount = 3  ; Average number of bricks in a block
     Const Block_CountPerLine = Field_SizeX / Block_AvgBrickCount  ; Rounded number of blocks to make a line

     Const Block_MoveDelay_IncFactor# = 1 + Block_MoveDelay_Factor  ; Multiplier for increasing delay
     Const Block_MoveDelay_DecFactor# = 1 + Block_MoveDelay_Factor / Block_CountPerLine  ; Divisor for decreasing delay

     ; Notes:
     ;  Game goes faster with each block placed. Game goes slower with each line filled.
     ;  The game speed increase for each block placed should be equal to the game speed decrease for each line filled
     ;   divided by the rounded number of bricks in each block required to make a straight line (Block_CountPerLine).

     ; Collisions

     Const Collide_None  = 0
     Const Collide_Wall  = 1
     Const Collide_Brick = 2

;------- Run-time definition (variable)

     Dim PlayField( Field_SizeX , Field_SizeY )

     Dim Block( 1 , Block_SizeX , Block_SizeY )  ; Current block and temporary space to store rotated block

     Dim BlockBank( Block_Count , Block_SizeX , Block_SizeY )  ; All unique blocks

     Global Block_PosX  ; Current block position
     Global Block_PosY

     Global Block_MoveDelay  ; Current delay of block moving down auto
     Global Block_LastMoved  ; Remember last time block moved automatically (down)

     Global Game_Score

;------- Run (init, game, exit)

     SeedRnd MilliSecs ()

     BlockBank_Load
     Game_Reset

     Graphics Screen_SizeX , Screen_SizeY
     Color 255 , 255 , 255
     ClsColor 0 , 0 , 0

     SetBuffer BackBuffer ()
     Repeat

          ;- Logic update

          If KeyHit ( Key_ArrowUp    ) Then Block_Rotate Dir_Right
          If KeyHit ( Key_ArrowDown  ) Then Block_Move Dir_Down
          If KeyHit ( Key_ArrowLeft  ) Then Block_Move Dir_Left
          If KeyHit ( Key_ArrowRight ) Then Block_Move Dir_Right
          If KeyHit ( Key_RightCtrl  ) Then Block_Drop
          If KeyHit ( Key_AlphaZ     ) Then Block_Rotate Dir_Left
          If KeyHit ( Key_AlphaX     ) Then Block_Rotate Dir_Right
          FlushKeys
          Block_AutoMove

          ;- Visual update

          ; Make (0,0) center of screen
          Origin Screen_SizeX/2 - Field_SizeX/2 * VisualBrick_SizeX , Screen_SizeY/2 - Field_SizeY/2 * VisualBrick_SizeY
          PlayField_Draw
          Block_Draw
          Origin 0 , 0
          Stats_Draw
          Flip
          Cls

     Until KeyHit ( Key_Escape )

End

;-------

     Function Game_Reset ()
          PlayField_Erase
          Block_MoveDelay = Block_MoveDelay_Default
          Block_New
          Game_Score = 0
     End Function

     Function Block_New ()
          Local Rotate_Count
          Local Repeat_Number

          Block_PosX = Field_SizeX/2 - Block_SizeX/2  ; Center horizontally
          Block_PosY = 0                              ; Top of playing field
          Block_Assign Rand ( 1 , Block_Count )
          Rotate_Count = Rand ( 0 , 3 )  ; Select random direction
          For Repeat_Number = 1 To Rotate_Count
               Block_Rotate Dir_Right
          Next
          Block_MoveDelay = Block_MoveDelay / Block_MoveDelay_DecFactor  ; Faster
          Block_LastMoved = MilliSecs ()  ; Reset auto move start time
          If Block_Collide ( Block_Current , Block_PosX , Block_PosY ) Then Game_Reset  ; Game over
     End Function

     Function Block_Assign ( BlockNumber )  ; Get unique block from blockbank and replace current block
          Local BrickX
          Local BrickY

          For BrickX = 1 To Block_SizeX
               For BrickY = 1 To Block_SizeY
                    Block( Block_Current , BrickX , BrickY ) = BlockBank ( BlockNumber , BrickX , BrickY )
               Next
          Next
     End Function

     Function Block_AutoMove ()
          If MilliSecs () >= Block_LastMoved + Block_MoveDelay
               Block_LastMoved = MilliSecs ()
               Block_Move Dir_Down
          End If
     End Function

     Function Block_Move ( Direction )
          Local Future_PosX
          Local Future_PosY

          ; Test for collision with block's future position (prevention)
          Future_PosX = Block_PosX
          Future_PosY = Block_PosY
          Select Direction
               Case Dir_Left
                    Future_PosX = Future_PosX - 1
               Case Dir_Right
                    Future_PosX = Future_PosX + 1
               Case Dir_Down
                    Future_PosY = Future_PosY + 1
                    Block_LastMoved = MilliSecs ()  ; Reset automove time
          End Select
          Select Block_Collide ( Block_Current , Future_PosX , Future_PosY )
               Case Collide_None  ; Move normally
                    Block_PosX = Future_PosX
                    Block_PosY = Future_PosY
               Case Collide_Wall  ; Can't move
               Case Collide_Brick  ; Place block
                    If Direction = Dir_Down  ; Place block only if moving down
                         Block_Integrate
                         PlayField_Check
                         Block_New
                    End If
          End Select
     End Function

     Function Block_Rotate ( Direction )
          Local BrickX
          Local BrickY

          Select Direction
               Case Dir_Left
                    ; Rotate by mixing X and Y and put into temporary space to prevent overwrite
                    For BrickX = 1 To Block_SizeX
                         For BrickY = 1 To Block_SizeY
                              Block( Block_Rotate , BrickY , BrickX ) = Block( Block_Current , Block_SizeX-BrickX+1 , BrickY )
                         Next
                    Next
               Case Dir_Right
                    ; Rotate by mixing X and Y and put into temporary space to prevent overwrite
                    For BrickX = 1 To Block_SizeX
                         For BrickY = 1 To Block_SizeY
                              Block( Block_Rotate , BrickY , BrickX ) = Block( Block_Current , BrickX , Block_SizeY-BrickY+1 )
                         Next
                    Next
          End Select
          Select Block_Collide ( Block_Rotate , Block_PosX , Block_PosY )
               Case Collide_None  ; Rotate normally
                    ; Put result back in block
                    For BrickX = 1 To Block_SizeX
                         For BrickY = 1 To Block_SizeY
                              Block( Block_Current , BrickX , BrickY ) = Block( Block_Rotate , BrickX , BrickY )
                         Next
                    Next
               Case Collide_Wall , Collide_Brick  ; Can't rotate
          End Select
     End Function

     Function Block_Drop ()  ; Move block down until collided
          While Not Block_Collide ( Block_Current , Block_PosX , Block_PosY + 1 )
               Block_PosY = Block_PosY + 1
          Wend
          Block_Integrate
          PlayField_Check
          Block_New
     End Function

     Function Block_Integrate ()  ; Get rid of block by integrating into playing field
          Local BrickX
          Local BrickY

          For BrickX = 1 To Block_SizeX
               For BrickY = 1 To Block_SizeY
                    If Block( Block_Current , BrickX , BrickY )
                         PlayField( Block_PosX + BrickX , Block_PosY + BrickY ) = True
                    End If
               Next
          Next
     End Function

     Function Block_Collide ( ThisBlock , PosX , PosY )  ; Test for collision between block and playing field
          ;- Note: 'ThisBlock' can indicate either the current block or the rotated block
          Local BrickX
          Local BrickY

          ; Check for collision with left wall of playing field
          If Block_LeftMostBrick ( ThisBlock ) + PosX < 1 Then Return Collide_Wall
          ; Check for collision with right wall of playing field
          If Block_RightMostBrick ( ThisBlock ) + PosX > Field_SizeX Then Return Collide_Wall
          ; Check for collision with bottom wall of playing field (pretend it's bricks so block will be placed)
          If Block_BottomBrick ( ThisBlock ) + PosY > Field_SizeY Then Return Collide_Brick
          ; Check for collision with bricks by searching overlapping bricks
          For BrickX = 1 To Block_SizeX
               For BrickY = 1 To Block_SizeY
                    If Block( ThisBlock , BrickX , BrickY )
                         If PlayField( PosX + BrickX , PosY + BrickY )
                              Return Collide_Brick
                         End If
                    End If
               Next
          Next

          ; Otherwise not colliding with anything
          Return Collide_None
     End Function
     ; Possible optimizations:
     ;  Cache leftmost/rightmost/bottom brick after block change.
     ;  Find leftmost/rightmost/bottom brick during initialization.

     Function Block_LeftMostBrick ( ThisBlock )  ; Find position of leftmost brick in block
          Local BrickX
          Local BrickY

          For BrickX = 1 To Block_SizeX
               For BrickY = 1 To Block_SizeY
                    If Block( ThisBlock , BrickX , BrickY ) Then Return BrickX
               Next
          Next
     End Function

     Function Block_RightMostBrick ( ThisBlock )  ; Find position of rightmost brick in block
          Local BrickX
          Local BrickY

          For BrickX = Block_SizeX To 1 Step -1
               For BrickY = 1 To Block_SizeY
                    If Block( ThisBlock , BrickX , BrickY ) Then Return BrickX
               Next
          Next
     End Function

     Function Block_BottomBrick ( ThisBlock )  ; Find position of bottom brick in block
          Local BrickX
          Local BrickY

          For BrickY = Block_SizeY To 1 Step -1
               For BrickX = 1 To Block_SizeX
                    If Block( ThisBlock , BrickX , BrickY ) Then Return BrickY
               Next
          Next
     End Function

     Function Block_Draw ()
          Local BrickX
          Local BrickY
          Local PosX
          Local PosY

          For BrickX = 1 To Block_SizeX
               For BrickY = 1 To Block_SizeY
                    If Block( Block_Current , BrickX , BrickY )
                         PosX = (Block_PosX + BrickX-1) * VisualBrick_SizeX
                         PosY = (Block_PosY + BrickY-1) * VisualBrick_SizeY
                         Rect PosX , PosY , VisualBrick_SizeX , VisualBrick_SizeY , False
                         Oval PosX , PosY , VisualBrick_SizeX , VisualBrick_SizeY , False
                    End If
               Next
          Next
     End Function

     Function PlayField_Check ()  ; Check if playfield contains filled horizontal lines
          Local FieldY

          For FieldY = 1 To Field_SizeY
               If PlayField_LineFilled ( FieldY )
                    PlayField_RemoveLine FieldY
                    Block_MoveDelay = Block_MoveDelay * Block_MoveDelay_IncFactor  ; Slower
                    Game_Score = Game_Score + 1
               End If
          Next
     End Function

     Function PlayField_LineFilled ( FieldY )
          Local FieldX

          For FieldX = 1 To Field_SizeX
               If Not PlayField( FieldX , FieldY ) Return False  ; If a gap was found, then it's not filled
          Next

          Return True  ; No gap was found, so filled
     End Function

     Function PlayField_RemoveLine ( RemoveY )
          Local FieldX
          Local FieldY

          For FieldX = 1 To Field_SizeX
               For FieldY = RemoveY-1 To 1 Step -1
                    PlayField( FieldX , FieldY+1 ) = PlayField( FieldX , FieldY )
               Next
          Next
     End Function

     Function PlayField_Erase ()
          Local FieldX
          Local FieldY

          For FieldX = 1 To Field_SizeX
               For FieldY = 1 To Field_SizeY
                    PlayField( FieldX , FieldY ) = False
               Next
          Next
     End Function

     Function PlayField_Draw ()
          Local BrickX
          Local BrickY
          Local PosX
          Local PosY

          ; Frame *around* the game area
          Rect OffsetX - 1 , OffsetY - 1 , Field_SizeX * VisualBrick_SizeX + 2 , Field_SizeY * VisualBrick_SizeY + 2 , False

          For BrickX = 1 To Field_SizeX
               For BrickY = 1 To Field_SizeY
                    If PlayField( BrickX , BrickY )
                         PosX = (BrickX-1) * VisualBrick_SizeX
                         PosY = (BrickY-1) * VisualBrick_SizeY
                         Rect PosX , PosY , VisualBrick_SizeX , VisualBrick_SizeY , True
                         Color 0 , 0 , 0
                         Rect PosX , PosY , VisualBrick_SizeX , VisualBrick_SizeY , False
                         Color 255 , 255 , 255
                    End If
               Next
          Next
     End Function

     Function Stats_Draw ()
          Color 0 , 255 , 0
          Text Screen_SizeX / 2 , 10 , "Score: " + Game_Score , True , False
          Text Screen_SizeX / 2 , Screen_SizeY - 25 , "Level: " + Block_MoveDelay , True , False
          Color 255 , 255 , 255
     End Function

     Function BlockBank_Load ()  ; Restore unique blocks from data into array for easy access
          Local BlockNumber
          Local BlockLineNumber  ; (BrickY)
          Local BlockLine$
          Local BrickX

          Restore BlockData
          For BlockNumber = 1 To Block_Count
               For BlockLineNumber = 1 To Block_SizeY
                    Read BlockLine
                    For BrickX = 1 To Block_SizeX
                         If Mid ( BlockLine , BrickX , 1 ) = "X"
                              BlockBank( BlockNumber , BrickX , BlockLineNumber ) = True
                         End If
                    Next
               Next
          Next
     End Function

;-->

Vlt hilft dir das





Ich würde es mit ner Tilemap machen <<
(Robsite => RPG Tut)
 

maerki

BeitragMi, Okt 15, 2008 19:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Wird die Funktion "Fallen" überhaupt in der Hauptschleife aufgerufen? Ich sehe da nur DrawStein().

mfg maerki

Dice of Darkness

Betreff: vergessen zu posten...

BeitragMi, Okt 15, 2008 20:05
Antworten mit Zitat
Benutzer-Profile anzeigen
@maerki: Tut mir leid das hatte ich vergessen zu posten, ich hatte die Function im Original aber schon in der Hauptschleife. Also daran kann es nicht liegen...

Was ist denn so eine Tilemap überhaupt? (hab da leider gar keine ahnung) und macht man die mit bb oder mit nem zeichenproggy?
Gratis Spiele, Musik, Tools

ozzi789

BeitragMi, Okt 15, 2008 20:17
Antworten mit Zitat
Benutzer-Profile anzeigen
(download http://www.robsite.de/daten/tutorials/rpgtut1.zip)

Erklärung, ist änhlich wie dein Code, nur begreif ich den ned ganz, schau dir mal das beispiel an
Wenn du das begriffen hast sollt es nicht schwer sein Smile





Code: [AUSKLAPPEN]
;RPG-TUTORIAL-1-VON BLITZMASTER                                                                                            ;13.10.01
;------------------------------


;EINFÜHRUNG
;----------

;Hallo, ihr werdet ab jetzt jede woche ein Stück näher in die Welt des RPG-Programmierens
;eintauchen. Also, wer interesse hat in 2-3 Monaten ein RPG zu programmieren
;muss einfach brav jede Woche meine Tutorials lesen und verstehen.


;GRUNDWISSEN
;-----------

;Also ich denke mal das jeder, der ein rpg-Tutorial liest auch ein RPG programmieren will.
;Rollenspiele sind ein sehr Schwieriges Thema, naja für mich nicht mehr aber für die meißten
;schon, ich glaube, das die meißten garnicht wissen, wie man so etwas überhaupt angeht.
;Ich werde euch vom anfang bis zum ende In diese Neue Welt entführen, sodass ihr
;nach allen tutorials fehig seid ein RPG wie Zelda auf dem Gameboy zu proggen,
;dafür müsst ihr aber gut aufpassen und möglichst die wichtigsten Dinge verstehen.
;Aber wenn man es kappiert hat ist es total easy.
;Ein rpg besteht aus folgenden Teilen:

;1.Storry
;2.Grafik
;3.Music und Soundeffecte
;4.Support
;5.Hilfedatei
;6.geringer Preis(wenn es kommerziel vertrieben wird)

;es gibt manche Leute die wollen ISO-Rpg´s wie Ultima-Online herstellen,
;sowas werde ich nicht anfangen, weil das meine fehigkeiten bei weitem übersteigt
;So erst mal zu den Maps(Tutorial 4) es gibt folgende Möglichkeiten eine Engine zu erstellen


;1. Die Ganze Karte auf einmal anzeigen und permanentes scrolling bei bewegung der spielfigur
;--------------------------------;
;                                ;
;    MAP                         ;
;                                ;
;                                ;
;                                ;
;             <> Spieler         ;
;                                ;
;                                ;
;                                ;
;                                ;
;                                ;
;                                ;
;                                ;
;                                ;
;                                ;
;                                ;
;________________________________;


;2. Wie Bei Zelda immer bei randberührung den nächsten Teil der karte Sichtbar machen
;--------------------------------;
;      ;                   ;     ;
;   MAP;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;      <> Spieler   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;      ;                   ;     ;
;________________________________;



;3. wenn der spieler den rand berührtscrollt die karte ein Stück in der mitte des
;Kästchens kann man sich frei bewegen, ohne dass es scrollt.
;--------------------------------;
;                                ;
;    MAP                         ;
;                                ;
;                                ;
;            ____________        ;
;           |  <> Spieler|       ;
;           |            |       ;
;           |            |       ;
;           |            |       ;
;           |            |       ;
;           |            |       ;
;           |            |       ;
;           |____________|       ;
;                                ;
;                                ;
;                                ;
;________________________________;


;Die ersten beiden werde ich besprechen aber das 3. nicht, da es eigentlich nichts 
;besonders dran ist.
;Ich werde in meinen Tutorials nur den Umgang mit tilemaps erklehren, weil das 
;meiner meinung nach das einfachste und beste ist, schließlich sind meine Lieblings-
;spiele ja Zelda,FinalFantasy und die Benutzen halt diese Technologie

;Jetzt zum scrolling, es gibt verschiedene arten des scrollings
;die erste die ich euch erklehren werde ist Tile-by-Tile scrolling(Tutorial 3),
;es ist das einfachste, aber auch das schlechteste. Es functioniert folgendermaßen

;ihr seid eine Figur und bewegt euch immer ein tile also 32 pixel vorwerts,
;so ist es auch ganz easy eine Kollision zu erzeugen.

;Später werde ich das pixel-by-pixel scrolling durchnehmen, das eigendlich nicht viel
;schwerer ist als die erste Methode, ist nur schwierig drauf zu kommen. Es functioniert
;so wie bei Zelda 3 - 4.man druckt die taste und bewegt sich entweder (einen)
;oder (2) pixel vorwerts. Wenn man sich einen Pixel vorwerts bewegen will muss man
;auch doppelt so viel text eingeben,da man ja auch eine Pixelgenaue kollision haben will.
 
;Später werde ich dann auch einige RPG´s, die in Q-Basic programmiert worden sind
;vorstellen damit man Ideen für seine Spiele Sammeln kann. Und Ideen sind Das
;Grundgerüst eine RPG´s.

;Oh, natürlich werde ich auch noch wichtige Themen, wie Intro,Benutzeroberfläche,
;Abspann und Kampfengines ankratzen.

;In 15 Wochen seid ihr nicht nur Profis in der Programmierung von Rollenspielen,
;sondern auch in allem was dazugehört(Arrays,Benutzeroberfläche,Trickfilme.....)
;Nur weil ich Heute sehr viel geschrieben habe, heißt das nicht dass in den
;nächsten folgen weniger kommt!

;So, dass wars leider für diese Woche Aber ihr könnt ja alles was hier steht 4,5 mal
;durchlesen.
;Den Quellcode solltet ihr verstehen(oder auswendig lernen) da er die Grundlage
;aller schöpfung ist


;THEMEN:
;-------


;also folgende Themen werden in meiner ersten Reihe Erklehrt.


; 1 = Eine einfache Tilemap, einführung und Ideen
; 2 = Kollisionsabfrage auf einer Tilemap
; 3 = Scrolling
; 4 = Maps laden und speichern
; 5 = Pixel-py-Pixel movement wie bei Zelda3 auf dem SuperNintendo
; 6 = Ein paar Q-basic Rollenspiele zum Ideen sammeln. und unterhaltung zwischen figuren.
; 7 = Kampf-engine teil1 ohne Grafik
; 8 = Kampf-engine teil2 wie FinalFantasy 4-6
; 9 = Kartenverbindungen
;10 = Zelda engine, also wenn man den bildschirmrand berührt nächster bildschirm
;11 = Wenn ich es schaffe Kampengine wie bei zelda Links Awakening
;12 = Multi-Layered-Maps!!!!!
;13 = NPC´s
;14 = Geld und Geschäfte in einem Rollenspiel
;15 = Benutzeroberfläche,Intro,Musikalische Gestaltung,Abspann
;16 = Laden und Speichern von Spielständen





;CODE ZUM ERSTELLEN EINER TILEMAP
;--------------------------------

;Mit diesem code solltet ihr ruhig ein bischen rumexperimentieren,
;damit ihr ihn versteht.


;das sollte eigendlich jeder wissen!
Graphics 1024,768,16,1

;läd das tileset, wobei jedes tile 32*32 pixel groß ist und das höchst tile ist nr.4,
;obwohl dort (,5) heißt das nur die anzahl der tiles von 0 an
tileset = LoadAnimImage("c:\tileset.bmp",32,32,0,5)


;diese function legt eine array mit zwei Werten an, also können in dieser array 2 variablen
;mit dem maximalwert 20 gespeichert werden.
Dim map(20,20)

;diese function ist ein ganz alter hut, einfach die map in ein datenfeld speichern,
;das ist leider sehr mühsam, wenn man karten mit den maßen 200*32 tiles anlegen möchte

;Legende:
; 0 = wiese
; 1 = wasser
; 2 = feuer
; 3 = erde
; 4 = feld

;ihr könnt die karte natürlich nach belieben verändern

Data 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 0,0,0,0,1,1,1,3,3,1,1,1,1,1,4,4,1,1,1,1,1
Data 0,0,0,0,1,1,1,3,3,1,1,1,1,1,4,4,1,1,1,1,1
Data 0,0,0,0,1,1,1,1,1,1,1,1,1,1,4,4,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,2,2,1,1,1,1,3,3,3,1,4,4,1,1
Data 1,1,1,1,0,0,1,1,1,1,1,1,1,3,3,3,1,4,4,1,1
Data 1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,4,4,1,1
Data 1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,4,4,1,1
Data 1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1


;diese function ist ganz einfach, in den for-next-schleifen wird die größe
;der map angegeben
For y = 0 To 20
For x = 0 To 20
;Read liest das datenfeld ein und speichert es in der array map(20=y,20=x)
Read map(x,y)
Next
Next

;die hauptschleife und die vorbereitungen werden getrofen, ich benutze immer diesen anfang
Repeat
;Den Backbuffer setzen
SetBuffer BackBuffer()
;Wird in den nächsten lektionen nicht mehr nötig sein
Cls
;ESC-Taste zum Beenden
If KeyDown(1) Then End

;diese function malt die karte wieder in einer for-next-schleife
;aber diesmal ist die karte ja schon eingelesen also müssen wir sie ausgeben,
;wir wollen sie ja schließlich sichtbar machen.
;das *32 heißt, dass die tiles in den abständen von 32*32 pixel gesetzt werden.
For y = 0 To 20
For x = 0 To 20
DrawImage tileset,x*32,y*32,map(x,y)
Next
Next
;flippen und zum anfang zurück
Flip
Forever
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5
 

maerki

BeitragMi, Okt 15, 2008 20:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe den Code noch einmal überflogen und dann folgendes Problem festgestellt:

Am Anfang wird y = 0 gesetzt:
Code: [AUSKLAPPEN]
Global y = 0


Dann wird in der Funktion Fallen() y alle 1000 Millisekunden um 32 erhöht:
Code: [AUSKLAPPEN]

If MilliSecs() - Blocktime >= 1000 Then
   If y < (480 - 32) Then           
      Blocktime = MilliSecs()
      y = y + 32   
   EndIf
EndIf
 


Nun zum Problem. In der Funktion DrawStein() wird y in der For-Schleife = 0 gesetzt:
Code: [AUSKLAPPEN]

For y = 0 To 3
   For x = 0 To 3
      If langer_stein(x,y) = 1 Then
         DrawBlock Stein,x*32,y*32
      EndIf
   Next
Next


Darum ist beim Zeichnen y immer 0! Beziehungsweise 1 bis 3 für die unteren Steine. Das heisst, man sollte für die For-Schleife andere Variablen verwenden. Folgende Lösung habe ich gefunden:
Code: [AUSKLAPPEN]

For iy = 0 To 3
   For ix = 0 To 3
      If langer_stein(ix,iy) = 1 Then
         DrawBlock Stein, ix*32,(iy*32)+y
      EndIf
   Next
Next

Mit diesem Code wird ix bzw iy für die Schleifen verwendet. Diese Variabeln malen dann die Steine an die richtige Position und "+y" bewirkt, dass die Steine immer um 32 Pixel nach unten wandern.

Ich hoffe ich konnte dir damit helfen.

mfg maerki

Dice of Darkness

Betreff: jetzt klappts!

BeitragDo, Okt 16, 2008 9:23
Antworten mit Zitat
Benutzer-Profile anzeigen
@maerki:

Vielen Dank! Das mit y=0 hatte ich übersehen, aber jetzt klappts!

Dice of Darkness
Gratis Spiele, Musik, Tools

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group