Grundprinzip von Tetris?

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Travis

Betreff: Grundprinzip von Tetris?

BeitragDo, März 18, 2004 0:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Zum Spiel Tetris hätte ich mal eine Frage an alle, die das schon einmal programmiert haben.

Bei meinem Versuch habe ich jetzt die Spielblöcke aus einzelnen kleineren quadraten zusammengesetzt. Das habe ich gemacht, weil ich ja einzelne Zeilen (also Blockteile) löschen muss, wenn eine Reihe voll ist. Jetzt kann ich die Blöcke aber nicht mehr drehen, weil sie ja aus mehreren Einzelbildern bestehen.

Und wenn ich für jeden Block ein einzelnes Bild nehmen würde, kann ich sie zwar prima drehen, aber nicht mehr teilweise löschen. Ihr versteht was ich meine?

Wie habt ihr eure Tetrisvarianten aufgebaut?
www.funforge.org

Ich hasse WASD-Steuerung.

Man kann alles sagen, man muss es nur vernünftig begründen können.
 

Dreamora

BeitragDo, März 18, 2004 0:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum kannst du den block nicht mehr drehen?

wenn du das tetris feld als 2 dimensionalen Array anlegst und dir einfach merkst, welcher block wo liegt (wenns farbig is) oder besetzt / nicht besetzt, dann kannst du auch die steine drehen, musst dir nur das muster beim drehen merken und gucken ob eine entsprechende drehung möglich is Smile

Travis

BeitragDo, März 18, 2004 0:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich kann ihn nicht drehen, weil dieser Block ja aus mehreren einzelnen Teilen zusammengesetzt ist.

Diese Einzelteile, werden dann beim Erstellen so angeordnet, dass eine bestimmte Form entsteht (Tetrisblock). Die einzelnen Teile werden für jeden Block mit einer eigenen ID gekennzeichnet, damit mann weis welche Teile zu einem Block zusammengefasst sind.

Diese Aufteilung der Blöcke halte ich für nötig da ich ja später, wenn eine vollständige Reihe aufgebaut ist, einige Blöcke nur Teilweise löschen muss. Und da ich jetzt den ganzen Block in eigenständige Objekte zerölegt habe, weis ich nicht, wie ich das Gesamtobjekt drehen soll.

Vielleicht bin ich mit diesem Prinzip ja auch auf dem Holzweg und es gibt eine bessere Lösung. Ich bitte um eure Hilfe.
www.funforge.org

Ich hasse WASD-Steuerung.

Man kann alles sagen, man muss es nur vernünftig begründen können.
 

Dreamora

BeitragDo, März 18, 2004 1:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Form dieser Blöcke (T, Linie, Z etc) speicherst du eifach als ein Muster, welches du dann jeweils um 90 Grad drehst ... und wenn du das ganze Feld als Array anlegst, wird es kein allzugrosses Problem diese zu "drehen"

du drehst keine Grafiken dabei sondern die positionen der Grafiken.

BladeRunner

Moderator

BeitragDo, März 18, 2004 2:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Also vom Grundprinzip würde ich das so machen, dass ich für den aktuell fallenden Stein ein Array füllen würde.
Code: [AUSKLAPPEN]
dim akt_stein(3,3)

Wieso 4*4 Felder ? Weil das grösste Teil das Lange gerade ist, vier lang, eins Breit, und dass muss ja in allen Richtungen darzustellen sein.
Nun wird dieses Feld bestückt, je nach Teil dass fällt, z.B.:
Code: [AUSKLAPPEN]

.L_Stein_re
data 0,0,0,0
data 1,0,0,0
data 1,0,0,0
data 1,1,0,0
.
.
.
if teil=1 then ;angenommen 1 stünde für L-re
   restore  L_Stein_re
for y = 0 to 3
  for x = 0 to 3
    read teil_gesetzt
    akt_teil(x,y)=teil_gesetzt
  next
next

Du könntest sogar (theoretisch) alle Steine schon in allen Ausrichtungen definieren, aber eine rotate_teil()-Funktion wird es genauso tun.

Wichtig: im Sinne der Fairness für den Spieler (und damit das Teil nicht "springt"') sollte das rotate so ausgelegt werden, dass immer das Ergebnis Links und Unten bündig liegt, Bsp.:
Zitat:

Falsch:
0010
1110
0000
0000

Richtig:
0000
0000
0010
1110

Ein Entwurf für das rotate_teil() [nicht geprüft, bin auf der Arbeit und hab das zwischen Tür und Angel zusammengeschraubt]:
Code: [AUSKLAPPEN]

dim rotate_speicher(3,3)

Function rotate_teil(wie_oft)
for wieder = 1 to wie_oft
for y = 0 to 3
  for x = 0 to 3
    rotate_speicher(y,(3-x))=akt_teil(x,y) ;90° links drehen
  next
next
for x=0 to 3
  for y= 0 to 3
    akt_teil(x,y)=rotate_speicher(x,y) ;übertragen in Teilspeicher
  next
next
.upschieb
status=0
for x= 0 to 3
  if akt_teil(x,3)=1 then Status=1 ;ist ein Teil in der untersten Zeile?
next
if status =0 then ;wenn nein schiebe die oberen runter:
  for y=2 to 0 step -1
    for x = 0 to 3
      akt_teil(x,y+1)=akt_teil(x,y)
    next
   next
   for i=0 to 3: akt_teil(i,0)=0:next ;oberste Zeile "säubern"
   goto upschieb
end if
status=0

.leftschieb
for y= 0 to 3
  if akt_teil(0,y)=1 then Status=1 ;ist ein Teil in der linken Spalte?
next
if status =0 then ;wenn nein schiebe die rechten nach:
  for x=1 to 3
    for y = 0 to 3
      akt_teil(x-1,y)=akt_teil(x,y)
    next
   next
   for i=0 to 3: akt_teil(3,i)=0:next
   goto leftschieb
end if
next

end function

mit rotate_teil(x) wird das Teil nun x*90° links gedreht.

Fallen lässt du die Teile etwas anders: du weist akt_teil eine x und y Koordinate zu. x ändert sich durch Eingaben des Spielers, Y auch durch die Zeit (Alle xyz Millisecs() wird y erhöht).
Dabei prüfst du für alle Felder von akt_teil, ob die Neue Koordinate schon belegt wäre, wenn ja, liegt das Teil auf und das nächste Teil kann starten.

Wie prüfst du das ?
Ich empfehle ein Feld
Code: [AUSKLAPPEN]

Dim Spielfeld (11,39)
, wobei die X und Y Ausdehnung natürlich deinen Wünschen entsprechen sollte.
Du kannst jetzt also jedes Dieser Felder belegen und Auch Überschneidungen testen.
Hier lass ich mal deine Kreativität zum Zug kommen - es ist aber im Grunde nix andres als ne Tilemap.

hoffe ich konnte helfen,
muß jetzt weiterarbeiten.... Crying or Very sad
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
  • Zuletzt bearbeitet von BladeRunner am Do, März 18, 2004 6:59, insgesamt einmal bearbeitet

soli

BeitragDo, März 18, 2004 3:50
Antworten mit Zitat
Benutzer-Profile anzeigen
.....im letzten Forum hatten wir ein gut funktionierendes Tetris im Code-Archiv.

Code: [AUSKLAPPEN]

;==============================================================
;Game   : Text-Tetris in Blitzbasic
;Version: 1.0
;Author   : Patrick Mächler aka Valio
;Email   : valio@visionsinteractive.ch
;Legal   : (c) 2003 by Patrick Mächler
;        Free use for educational purposes
;        I coded this in about an hour, 'cause I was bored.
;
;Control: Shift Block Left   - Left Arrow
;        Shift Block Right   - Right Arrow
;        Turn Block Left   - Up Arrow
;        Turn Block Right   - Down Arrow
;        Shift Block Down   - Space
;        Pause/Resume      - Enter
;        End Game         - Esc
;
;Note   : There's no Gameover. You maybe just can't move the
;        blocks to somwhere anymore.
;        The speedformula is quite simple, so on Level 20 it
;        will be impossible to play.
;==============================================================
Const Fall$="#"
Const Full$=""
Const Free$=" "
Const Wall$="¦"
Const Floor$="-"
Const Erase$="+"

Const FieldX=11
Const FieldY=13

Dim GameField(FieldX,FieldY)
Dim Block(4,4)
Dim NBlock(4,4)

Global OriginX=40
Global OriginY=40

Global BlockX, BlockY
Global BlockTime, Level=1, Score=0, Speed=1000, Pause=False

SetBuffer BackBuffer()
SeedRnd MilliSecs()

Fillfield()
NewBlock()
NewBlock()

While Not(KeyHit(1))
   Cls
   DrawField()
   If Pause=False Then MoveBlock()
   If KeyHit(28) Then
      If Pause=False Then
         Pause = True
         BlockTime = BlockTime - MilliSecs()
      Else
         BlockTime = BlockTime + MilliSecs()
         Pause = False
      EndIf
   EndIf
   DrawBlock()
   DrawGUI()
   Flip
Wend
End

;==============================================================
;Called at the beginnig, puts walls and floor in the GameField
;array.
;==============================================================

Function Fillfield()
Local x
   For x=0 To FieldY
      GameField(0,x)=2 ;2=wall
      GameField(FieldX,x)=2 ;2=wall
   Next
   For x=1 To FieldX-1
      GameField(x,FieldY)=3 ;3 =floor
   Next
End Function

;==============================================================
;This swaps the data in the NBlock (next block) array to the
;Block array and fills NBlock with data of another randomly
;chosen block.
;==============================================================

Function NewBlock()
Local x,y,r
   BlockTime=MilliSecs()
   BlockX=5
   BlockY=-2
   r=Rand(5)
   Select r
      Case 1: Restore Block1
      Case 2: Restore Block2
      Case 3: Restore Block3
      Case 4: Restore Block4
      Case 5: Restore Block5
   End Select
   For y=0 To 4
      For x=0 To 4
         Block(x,y) = NBlock(x,y)
         Read NBlock(x,y)
      Next
   Next
End Function

;==============================================================
;Analyze all game related userinputs and controls the moving
;block.
;==============================================================

Function MoveBlock()
Local t
   If KeyHit(203) Then
      BlockX=BlockX-1
      If Collide() Then BlockX=BlockX+1
   EndIf
   If KeyHit(205) Then
      BlockX=BlockX+1
      If Collide() Then BlockX=BlockX-1
   EndIf
   If KeyHit(200) Then
      RotateLeft()
      If Collide() Then RotateRight()
   EndIf
   If KeyHit(208) Then
      RotateRight()
      If Collide() Then RotateLeft()
   EndIf
   If KeyDown(57) Then BlockTime = BlockTime - Speed/3
   t=MilliSecs()
   If t>BlockTime Then
      BlockY = BlockY+1
      BlockTime = BlockTime + Speed
      If Collide() Then BlockY = BlockY-1: SetBlock(): LineCheck(): NewBlock()
   EndIf
End Function

;==============================================================
;Transfers the data in the Block array to the GameField array.
;==============================================================

Function SetBlock()
Local x,y
   For x = 0 To 4
      For y = 0 To 4
         SetField(x,y)
      Next
   Next
End Function

;---------------------------------
;Helpfunction for SetBlock().
;---------------------------------

Function SetField(x,y)
Local tx,ty
   tx = BlockX+x
   ty = BlockY+y
   If tx<0 Or tx>FieldX Or ty<0 Or ty>FieldY Then Return
   If Block(x,y)<>0 Then GameField(tx,ty)=1
   Return False
End Function

;==============================================================
;Checks if one or some rows in the game field are upfilled and
;if so, calls EraseLine() to delete the rows.
;==============================================================

Function LineCheck()
Local x,y,l,e
   For y=0 To FieldY-1
      l=0
      For x=0 To FieldX
         If GameField(x,y)<>0 Then l=l+1
      Next
      If l=FieldX+1 Then
         e = e + 1
      Else
         EraseLine(y,e)
         e = 0
      EndIf
   Next
   EraseLine(y,e)
End Function

;==============================================================
;Erases the e rows over row y, with some blinky effects and
;calls AddScore to add some score for the well done job.
;==============================================================

Function EraseLine(y,e)
Local t,m,x
   If e=0 Then Return
   m=0
   t = MilliSecs()
   For x=1 To e
      ChangeLine(y-x,1,-1)
   Next
   Repeat
      If MilliSecs()-t>300 Then
         For x=1 To e
            If (m Mod 2)=0 Then
               ChangeLine(y-x,-1,0)
            Else
               ChangeLine(y-x,0,-1)
            EndIf
         Next
         t = MilliSecs()
         m=m+1
      EndIf
      Cls
      DrawField()
      DrawGUI()
      Flip
   Until m=9
   For m=y-1 To e Step -1
      For x=0 To FieldX
         GameField(x,m)=GameField(x,m-e)
      Next
   Next
   For m=m To 0 Step -1
      ChangeLine(m,1,0)
   Next
   AddScore(e)
End Function

;---------------------------------
;Helpfunction for EraseLine().
;---------------------------------

Function ChangeLine(y,f,t)
Local x
   For x=0 To FieldX
      If GameField(x,y)=f Then GameField(x,y)=t
   Next
End Function

;==============================================================
;Adds score for the l erased rows and updates speed and level.
;==============================================================

Function AddScore(l)
   Score = Score + 10*(l^2)
   Level = 1 + Score/100
   Speed = 2200 - Level*200
End Function

;==============================================================
;Checks if the block array currently collides with the game
;field.
;==============================================================

Function Collide()
Local x,y
   For x = 0 To 4
      For y=0 To 4
         If CollideField(x,y) Then Return True
      Next
   Next
   Return False
End Function

;---------------------------------
;Helpfunction for Collide().
;---------------------------------

Function CollideField(x,y)
Local tx,ty
   tx = BlockX+x
   ty = BlockY+y
   If tx<0 Or tx>FieldX Or ty<0 Or ty>FieldY Then Return False
   If Block(x,y)<>0 And GameField(tx,ty)<>0 Then Return True
   Return False
End Function

;==============================================================
;Rotates the data in the Block array counter clockwise.
;==============================================================

Function RotateLeft()
Local x,y,swap
   For x=0 To 1
      For y=0 To 1
         swap=Block(x,y)
         Block(x,y)=Block(4-y,x)
         Block(4-y,x)=Block(4-y,4-x)
         Block(4-y,4-x)=Block(y,4-x)
         Block(y,4-x)=swap
      Next
      swap=Block(x,2)
      Block(x,2)=Block(2,x)
      Block(2,x)=Block(4-x,2)
      Block(4-x,2)=Block(2,4-x)
      Block(2,4-x)=swap
   Next
End Function

;==============================================================
;Rotates the data in the Block array clockwise.
;==============================================================

Function RotateRight()
Local x,y,swap
   For x=0 To 1
      For y=0 To 1
         swap=Block(y,4-x)
         Block(y,4-x)=Block(4-y,4-x)
         Block(4-y,4-x)=Block(4-y,x)
         Block(4-y,x)=Block(x,y)
         Block(x,y)=swap
      Next
      swap=Block(2,4-x)
      Block(2,4-x)=Block(4-x,2)
      Block(4-x,2)=Block(2,x)
      Block(2,x)=Block(x,2)
      Block(x,2)=swap
   Next
End Function

;==============================================================
;Draws the graphical user interface (GUI).
;==============================================================

Function DrawGUI()
Local p$
   ;Locate OriginX+200,OriginY
   ;print "Score : "+Score
   Text OriginX+200,OriginY,"Score: "+Score
   ;Locate OriginX+200,OriginY+20
   ;print "Level: "+Level
   Text OriginX+200,OriginY+20,"Level: "+Level
   ;Locate OriginX+200,OriginY+40
   Text OriginX+200,OriginY+40,"Speed: "+Speed
   ;print "Speed: "+Speed
   ;Locate OriginX+200,OriginY+80
   Text OriginX+200,OriginY+80,"Next Block:"
   ;print "Next Block:"
   DrawNextBlock(OriginX+200,OriginY+100)
   p$ = "PAUSE +++++ "
   If Pause Then Text (-MilliSecs()/12 Mod StringWidth(p$)), 280, String(p$,10)
End Function

;---------------------------------
;Helpfunction for DrawGUI().
;---------------------------------

Function DrawNextBlock(OX,OY)
Local s$,x,y
   For y=0 To 4
      s$ = ""
      For x=0 To 4
         If NBlock(x,y)=1 Then s$ = s$ + full Else s$ = s$ + free
      Next
      ;Locate OX,OY+y*FontHeight()
      ;Print s$
         Text OX,OY+y*FontHeight(),s$
   Next
End Function

;==============================================================
;Draw the data in the Block array.
;==============================================================

Function DrawBlock()
Local s$,x,y
   For y=0 To 4
      s$ = ""
      For x=0 To 4
         If Block(x,y)=1 Then s$ = s$ + fall Else s$ = s$ + free
      Next
      ;Locate OriginX+BlockX*FontWidth(),OriginY+(y+BlockY)*FontHeight()
      ;Print s$
      Text OriginX+BlockX*FontWidth(),OriginY+(y+BlockY)*FontHeight(),s$
   Next
End Function

;==============================================================
;Draw the game field (data in the GameField array).
;==============================================================

Function DrawField()
Local x,y,s$
   For y=0 To FieldY
      s$=""
      For x=0 To FieldX
         Select GameField(x,y)
            Case 1: s$ = s$ + full
            Case 2: s$ = s$ + wall
            Case 3: s$ = s$ + Floor
            Case -1: s$ = s$ + Erase
            Default: s$ = s$ + free
         End Select
      Next
      ;Locate OriginX,OriginY+y*FontHeight()
      ;Print s$
      Text OriginX,OriginY+y*FontHeight(),s$
   Next
End Function

;==============================================================
;Data for blocks to fill in the Block array.
;==============================================================

.Block1
Data 0,0,1,0,0
Data 0,0,1,0,0
Data 0,0,1,0,0
Data 0,0,1,0,0
Data 0,0,0,0,0

.Block2
Data 0,0,1,0,0
Data 0,0,1,0,0
Data 0,0,1,1,0
Data 0,0,0,0,0
Data 0,0,0,0,0

.Block3
Data 0,0,1,0,0
Data 0,0,1,0,0
Data 0,1,1,0,0
Data 0,0,0,0,0
Data 0,0,0,0,0

.Block4
Data 0,0,0,0,0
Data 0,0,1,0,0
Data 0,1,1,1,0
Data 0,0,0,0,0
Data 0,0,0,0,0

.Block5
Data 0,0,0,0,0
Data 0,1,1,0,0
Data 0,1,1,0,0
Data 0,0,0,0,0
Data 0,0,0,0,0


Vielleicht hilft dir das weiter
solitaire

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group