View Single Post
Old 19 April 2015, 21:01   #66
Cylon
Registered User
 
Join Date: Oct 2014
Location: Europe
Posts: 473
tetris main and processinputs + some framework

Here is the snipd src from my conversion (03-07-15) regarding keyb input and input handling.
Please note that there are still bugs, e.g. faded blocks and timing and so on.
I hope it helps, anyway.
Please keep me noticed if you encounter problems.

(Please note i have removed lines that are already known to make it easier to find what you are looking for).
First startup:
Code:
;tetris clone example code


;by WolRon

;converted for blitz2(the AMIGA) by Cylon(at)eab

WBStartup
;SetErr:End:End SetErr
.
.init

DEFTYPE.l        ;make sure all boolean vars are real fix (0/-1)!!


;set up graphics
;Graphics 800, 600
;SetBuffer BackBuffer()

; no doublebuffer yet !
;
 #Width        =$80000023
 #Height       =$80000024
 #Dpth         =$80000025
 #Typ          =$8000002D
 #DisplayID    =$80000032
 #Overscan     =$80000034
 #AutoScroll   =$80000039
 #LikeWorkbench=$80000047

 ;NOTE:We use an AGA (classic chipset) screen mode Workbench!!!
._Display
 ScreenTags1,"tetris test",#LikeWorkbench,True,#Width,800,#Height,600,#Dpth,5,#AutoScroll,True,0,0
 Window1,0,0,800,600,$1900,"",2,1
 ScreensBitMap1,1
 WindowOutput1      ;Print to window

._Dims
;set up arrays
Dim Board (9, 22)
Dim BlockColor (99, 2) ;99 cols is enough? we use them as color index
Dim Piece (28, 3, 3)
Dim LineToErase (4)


._DataRead
;
._SetOrigins

EndOfGame = True

._DefKeys
;declare keys
;--------------------------------------------

;keyboard constants

#KEY_BSP=8   ;backspace
#KEY_RET=13  ;return

#KEY_ESC=27  ;escape

#KEY_CUP=28  ;cursor up
#KEY_CDN=29  ;cursor down
#KEY_CRT=30  ;cursor right
#KEY_CLT=31  ;cursor left

#KEY_DEL=127
#KEY_HLP=139

#KEY_F1 =129
#KEY_F2 =130
#KEY_F3 =131
#KEY_F4 =132
#KEY_F5 =133
#KEY_F6 =134
#KEY_F7 =135
#KEY_F8 =136
#KEY_F9 =137
#KEY_F10=138

;keyboard QUALIFIERs (extra keys)

#q_none    =$ 0
#q_caps    =$ 4
#q_control =$ 8

#q_shiftl  =$ 1
#q_shiftr  =$ 2

#q_altl    =$10
#q_altr    =$20

#q_amigal  =$40
#q_amigar  =$80
;--------------------------------------------
;adapt my constants to org src

KeyEsc         =#KEY_ESC  ;=27
KeyPause       =Asc("p")
KeyRotate      =Asc("x")
KeyRotateLeft  =Asc("c")
KeyLeft        =#KEY_CLT  ;=31
KeyRight       =#KEY_CRT  ;=30
KeyDwn         =#KEY_CDN  ;=29
KeyInstantDrop =32        ;" " ;space
KeyN           =Asc("n")
KeyQ           =Asc("q")

._Macros
...
Code:
.funcs
._EraseBoard
Statement EraseBoard{}
!myshared
  ;erase board

  !Origin {OrigBoardX, OrigBoardY + 75}

  ;Color 255, 0, 0                 ;red
  ;Rect -3, -3, 255, 505, 0
  Boxf xx-2,yy-2,xx+254,yy +504,#cblack
  Box xx-3,yy-3,xx+255,yy +505,#cred

End Statement
Note: EraseBoard{} was added to avoid entire clear and redraw of screen (see main).
Code:
._DropPiece
Function DropPiece{}
!myshared
  For yiter = 3 To 0 Step -1
    For xiter = 0 To 3
      If Piece(CurrentPiece + (CurPieceRot * 7), xiter, yiter) <> 0
        If CurPieceY+yiter+1 > 22 Then Function Return False
        If Board(CurPieceX+xiter, CurPieceY+yiter+1) <> 0 Then Function Return False
      EndIf
    Next
  Next
  CurPieceY = CurPieceY + 1
  CalcGhostPosition {}
  Function Return True
End Function

._PlacePiece
Function PlacePiece{}
!myshared
  ;Local outofbounds
  For yiter = 0 To 3
    For xiter = 0 To 3
      If Piece(CurrentPiece + (CurPieceRot * 7), xiter, yiter) <> 0
        Board(CurPieceX+xiter, CurPieceY+yiter) = CurrentPiece
        If CurPieceY+yiter < 3 Then outofbounds = True;above the 10x20 playing area
      EndIf
    Next
  Next
  If outofbounds Then Function Return False
  ;check if any lines were created
  CheckForLines {}
  If NOT ClearLines
    ResetPiece{}
  EndIf
  Function Return True
End Function
...
Now, the ProcessInputs{}:
Code:
._ProcessInputs
Statement ProcessInputs{ev.l}
!myshared

  If ev = $400  ;keyboard event
  ;Stop      ;or BeepScreen!
  ;BeepScreen1

  inp.w=Asc(Inkey$)   ;get input from window (!)

  If NOT EndOfGame

    Select inp          ;switch keys

      Case KeyRotate     :RotatePiece{False} ;space key or X key
      Case KeyRotateLeft :RotatePiece{True}; C key (Z key)

      Case KeyInstantDrop:CurPieceY = GhostPieceY
      Case KeyEsc        :End

      Default

        ;If (NOT KeyLeft) AND (NOT KeyRight)
        If inp = NOT (KeyLeft OR KeyRight)

          RepeatDelay = True
        Else
          If RepeatSpeed < NowTime
            If RepeatDelay
              RepeatSpeed = NowTime + 50 ;150
              RepeatDelay = False
            Else
              RepeatSpeed = NowTime + 10 ;30
            EndIf

            If inp = KeyLeft  Then MoveLeft{}
            If inp = KeyRight Then MoveRight{}

          EndIf
        EndIf

        If (inp = KeyEsc) OR (inp = KeyPause)

          If GamePaused
            ;Stop
            GamePaused = 0
            LastDropTime = LastDropTime + Ticks - PauseTime ; MilliSecs() - PauseTime
          Else
            GamePaused = True
            PauseTime = Ticks ;MilliSecs()
          EndIf
        EndIf

    End Select
  Else  ;EndOfGame
    Select inp
      Case KeyQ          :EndGame{}  ;quit game
      Case KeyN          :StartNewGame{}  ;new game
      Case KeyEsc        :End
    End Select
  EndIf
  EndIf ;ev
End Statement
As you can see i've added an argument to the statement call! This argument is provided from within the main routine:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   Main Game loop   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.main
DrawInfo{}
ResetTimer
Repeat
  Delay_5;make it a levelspeed-loop!
;:Cls
  EraseBoard{}
  DrawBoard{}

  If GamePaused
    DrawPauseMessage{}
  Else
    DrawBoardBlocks{}
    DrawNextPiece{}
    If NOT ClearLines
      If NOT EndOfGame Then DrawGhostPiece{}
      DrawCurrentPiece{}
    EndIf
  EndIf

  ProcessInputs{Event}

  If EndOfGame=0
    If ClearLines=0
      If GamePaused=0
        If Inkey$=Chr$(KeyDwn)  ;****
          DropDelay = 35
        Else
          DropDelay = DropSpeed
        EndIf

        NowTime = Ticks; MilliSecs()

        If (NowTime > LastDropTime + DropDelay) OR KeyInstantDrop
          LastDropTime = NowTime
          If NOT DropPiece{}
            If NOT PlacePiece{}
              EndGame{}
            EndIf
          EndIf
        EndIf

      EndIf
    Else
      LineClearer{}
    EndIf
  Else
    PrintGameOver{}
  EndIf

  ;Flip no dbuffer
Until exit;Esc key
.mloop
.
End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;   End of main loop   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
._colsdat

._piecedat
;piece descriptions

.eof
The Event in main is the key part. It provides any input coming from mouse, keyboard, windowhandling and so on. You just have to filter what is coming in. We do this in processinputs{} by looking only for $400 type events, which are keyboard inputs.
Please also note the reduced timing values in main and processinputs{}!

(w.i.p.)

Last edited by Cylon; 25 April 2015 at 04:24.
Cylon is offline  
 
Page generated in 0.04613 seconds with 10 queries