Posted: 29th Sep 2005 11:35
Thanks for you help I'll try the sync commands. Just for info heres the code. Please note I am artistically challenged hence the real basic sprites
<CODE>
Rem * Title : Tetris clone
Rem * Author : Mark Winfield
Rem * Date : Sep 2005
Rem Load all the bitmaps, blank is just a black square as we are using sprites for the board this is the empty value
Rem Bitmaps are just a square 25 x 25 pixels filled with appropriate colour
Load image "blank.bmp",1
Load image "redblock.bmp",2
load image "greenblock.bmp",3
load image "cyanblock.bmp",4
load image "greyblock.bmp",5
load image "blueblock.bmp",6
load image "purpleblock.bmp",7
load image "orangeblock.bmp",8
sync rate 0
sync on
Rem Set boundaries of the board
BoardX=10
BoardY=23
Rem setup arrays for playing area, the blocks and the current piece
dim board(BoardX,BoardY)
dim pieces(7,4,4)
dim CurrentPiece(1,4,4)
rem Initalise variables. I have put them in a seperate subroutine as they are called after a game over event as well
gosub initvars
set text opaque
Rem The Main Loop
Rem The bit processes key presses and updates all the relevant bits
do
Rem The upkey is used to pause or restart the game
Rem Playing = 1 means game is happening
if upkey()= 1
if playing = 0
playing = 1
else
playing = 0
endif
endif
if playing = 1
if leftkey()= 1 then gosub MoveLeft
if rightkey()= 1 then gosub MoveRight
if downkey() = 1 then gosub MoveDown
if spacekey() = 1 then gosub RotatePiece
gosub MoveDown
endif
Rem Update all on screen messages
set text opaque
text 300,0,"Score:" + str$(score)
text 300,20,"Next Block:"
text 300,140,"Lines Cleared:" +str$(Lines)
loop
initvars:
Rem Playing indicates if game is running or paused
playing=0
Rem Score (say no more)
score=0
rem StartX and StartY initial position of block
startx = 80
starty = 0
Rem Currentx and Currenty current position of block
currentx = 80
currenty = 0
Rem nextpiece holds value of nextpiece
nextpiece = 0
Rem Lines is amount of lines cleared
lines = 0
Rem Level is the current Level
Level = 1
Rem CurrentHeight is height of highest block on board (used to check if game over)
CurrentHeight = 380
Rem Top,Bottom, Left and Right are piece bounds used in collision checking
Top = 0
Bottom = 0
Left = 0
Right = 0
Rem Initialise the array of blocks
gosub InitPieces
Rem Draw the screen
gosub DrawBoard
Rem Select what piece is next
gosub NextPiece
return
gameover:
Rem This is all that happens when the game is over
Rem needs to be improved for play again etc.
text 50,305,"G A M E O V E R"
text 50,325,"You scored:" +str$(score)
text 20,345,"Press Any Key to Play again"
suspend for key
cls
gosub initvars
return
DrawBoard:
Rem Firstly draw the frame
ink rgb(100,100,100),0
box 0,0,220,4
box 0,0,4,479
box 216,0,220,479
box 0,474,220,479
ink rgb(255,214,150),0
Rem Next initialise a sprite at each position on board so we can switch them on or off as required
for i=1 to BoardX
for j=1 to BoardY
sprnum =(i*BoardY)+j
sprite sprnum,(i*20)-10,(j*20)-10,1
scale sprite sprnum,75
next j
next i
Rem Setup sprites to hold picture of next piece
Rem Start sprite number at 1000 to avoid conflicts with board
for i = 1 to 4
for j = 1 to 4
sprnum = (i*4)+ 1000 + j
sprite sprnum, 300+(i*20)-10, 30+(j*20) - 10,1
scale sprite sprnum,75
next j
next i
Rem Pick a random piece to start with
randomize timer()
a=rnd(7)
if a = 0 then a=1
CurrentPiece(1,0,0) = a
Rem SelectPiece transfers a copy of the selected piece into the current piece array
gosub Selectpiece
Rem DrawPiece draws the piece on the screen
gosub DrawPiece
Rem next part initialises the board so no blocks are present i.e. sprite bitmap 0 is set for all sprites on board
for i = 1 to BoardX
for j = 1 to BoardY
Board(i,j) = 0
next j
next i
ink RGB(255,200,125),0
return
InitPieces:
rem This is the bit where the various blocks are defined
rem Firstly we will initialise the whole structure to 0 as 0 indicates empty space
for i = 1 to 7
for j = 1 to 4
for k = 1 to 4
Pieces(i,j,k) = 0
next k
next j
next i
Rem Initialise Piece 1
pieces(1,2,1) =1
pieces(1,2,2) = 1
pieces(1,2,3) = 1
pieces(1,2,4) = 1
Rem Initialise Piece 2
pieces(2,2,1) = 1
pieces(2,2,2) = 1
pieces(2,3,2) = 1
pieces(2,3,3) = 1
rem Initialise Piece 3
pieces(3,3,1) = 1
pieces(3,2,2) = 1
pieces(3,3,2) =1
pieces(3,2,3) =1
rem Initialise Piece 4
pieces(4,2,1) = 1
pieces(4,3,1) = 1
pieces(4,4,1) = 1
pieces(4,3,2) = 1
rem Initialise Piece 5
pieces(5,2,2) = 1
pieces(5,3,2) = 1
pieces(5,2,3) = 1
pieces(5,3,3) = 1
rem Initialise Piece 6
pieces(6,2,1) = 1
pieces(6,3,1) = 1
pieces(6,2,2) = 1
pieces(6,2,3) = 1
rem Initialise Piece 7
pieces(7,2,1) = 1
pieces(7,3,1) = 1
pieces(7,3,2) = 1
pieces(7,3,3) = 1
return
Nextpiece:
Rem This bit chooses the next piece to be used
Rem There are 7 different pieces
rem random bit to pick a piece
nextpiece = nextpiece + 1
if nextpiece >7 then nextpiece = 1
Rem Clear Next Piece block
for i = 1 to 4
for j = 1 to 4
sprnum = (i*4)+ 1000 + j
sprite sprnum, 300+(i*20)-10, 30+(j*20) - 10,1
next j
next i
Rem Draw the next block
for i = 1 to 4
for j = 1 to 4
if pieces(nextpiece,i,j) = 1
sprnum = (i*4)+ 1000 + j
sprite sprnum, 300+(i*20)-10, 30+(j*20) - 10,nextpiece + 1
endif
next j
next i
return
SelectPiece:
Rem This bit sets current piece to be the chosen piece
for i = 1 to 4
for j = 1 to 4
CurrentPiece(1,i,j) = pieces(CurrentPiece(1,0,0),i,j)
next j
next i
Rem Although piece is defined as 4x4 setbounds sets the actual boundaries within the 4x4 grid
gosub SetBounds
return
SetBounds:
Rem Set the bounds for collision detection etc
Top = 0
i = 1
j = 1
While Top = 0
if Currentpiece(1,i,j) =1 then Top = j
i = i + 1
if i>4
i =1
j=j+1
endif
endwhile
Bottom = 0
i = 1
j = 4
While Bottom = 0
if Currentpiece(1,i,j) =1 then Bottom = j
i = i + 1
if i>4
i =1
j=j-1
endif
endwhile
Left = 0
i = 1
j = 1
While Left = 0
if Currentpiece(1,i,j) =1 then Left = i
j = j + 1
if j>4
j =1
i=i+1
endif
endwhile
Right = 0
i = 4
j = 1
While Right = 0
if Currentpiece(1,i,j) =1 then Right = i
j = j + 1
if j>4
j =1
i=i-1
endif
endwhile
return
DrawPiece:
Rem Work our way through the array and draw the piece
for i = 1 to 4
for j = 1 to 4
if Currentpiece(1,i,j) = 1
sprnum = (i*BoardY)+ j
sprite sprnum, Currentx+(i*20)-10, currenty+(j*20) - 10,(CurrentPiece(1,0,0) + 1)
scale sprite sprnum,75
endif
next j
next i
return
MoveLeft:
Rem This routine checks for valid moves and then updates the board
gosub CheckMoveLeft
gosub UpdateBoard
gosub DrawPiece
return
MoveRight:
Rem This routine checks for valid moves and the updates the board
gosub CheckMoveRight
gosub UpdateBoard
gosub DrawPiece
return
MoveDown:
Rem Check for valid moves and update the board
Gosub CheckMoveDown
gosub UpdateBoard
gosub DrawPiece
return
RotatePiece:
rem This is a really basic rotation that I will update (one day)
Rem Basically all it does is rotate the current piece 90 degrees anti clockwise
dim temp(1,4,4)
temp(1,1,1) = CurrentPiece(1,1,4)
temp(1,1,2) = CurrentPiece(1,2,4)
temp(1,1,3) = CurrentPiece(1,3,4)
temp(1,1,4) = CurrentPiece(1,4,4)
temp(1,2,1) = CurrentPiece(1,1,3)
temp(1,2,2) = CurrentPiece(1,2,3)
temp(1,2,3) = CurrentPiece(1,3,3)
temp(1,2,4) = CurrentPiece(1,4,3)
temp(1,3,1) = CurrentPiece(1,1,2)
temp(1,3,2) = CurrentPiece(1,2,2)
temp(1,3,3) = CurrentPiece(1,3,2)
temp(1,3,4) = CurrentPiece(1,4,2)
temp(1,4,1) = CurrentPiece(1,1,1)
temp(1,4,2) = CurrentPiece(1,2,1)
temp(1,4,3) = CurrentPiece(1,3,1)
temp(1,4,4) = CurrentPiece(1,4,1)
for i = 1 to 4
for j =1 to 4
CurrentPiece(1,i,j) = temp(1,i,j)
next j
next i
gosub updateBoard
gosub SetBounds
if currentx <=0-(Left*20) then currentx = 20-(Left*20)
if currentx >=220 - (Right*20) then currentx = 200 - (Right*20)
if currenty >=380 + ((4-Bottom) *20) then currenty = 380 + ((4-Bottom) *20)
gosub DrawPiece
return
UpdateBoard:
Rem this routine redraws all the sprites that make up the board. It is called everytime the board is updated
for i=1 to BoardX
for j=1 to BoardY
sprnum =(i*BoardY)+j
sprite sprnum,(i*20)-10,(j*20)-10,board(i,j)
scale sprite sprnum,75
next j
next i
return
SelectNextPiece:
Rem First Reset Current X and Y to start values
CurrentX=StartX
CurrentY= StartY
Rem Take the Value from next piece to be current Piece
CurrentPiece(1,0,0) = nextpiece
Rem Create and Draw the new Playing Piece
gosub SelectPiece
gosub DrawPiece
gosub NextPiece
Return
SetHeight:
Rem This routine works out where the highest point is on the board
Rem Start at the bottom and works up checking for a clear row
Rem Works on the basis the only clear rows will exist at the highest point
Row = BoardY
AllClear = 0
repeat
NotClear = 0
i = 1
repeat
if board(i,Row) <> 0
Rem Row is not Clear
NotClear= 1
endif
i = i + 1
until NotClear = 1 or i>BoardX
if NotClear = 1
Row=Row -1
else
AllClear = 1
endif
until AllClear = 1
Rem This bit checks if Rows are at the top and then a game over event is called
if Row <1 then goto gameOver
CurrentHeight = (Row-1) * 20
return
CheckMoveDown:
Rem This function checks to see if we can move down
Rem Check from the bottom up
Landed = 0
Move = 1
for i = 1 to 4
for j = 1 to 4
if currentPiece(1,i,j) <> 0
Rem Found Part of Block
TempY = int(CurrentY/20)+1
TempX = int(CurrentX/20)
Rem Check Below brick
if Board(TempX+i,TempY + J) > 0
Move=0
Landed = 1
endif
endif
next j
next i
Rem Move is still 1 if all tests past so it can move down
if Move = 1 then currentY= CurrentY + 20
Rem These are the values I have worked out for the maximum y value
if currenty >=380 + ((4-Bottom) *20)
currenty = 380 + ((4-Bottom) *20)
Rem We are on the bottom so land Piece
gosub LandPiece
endif
if landed=1 then gosub LandPiece
return
CheckMoveLeft:
Rem This function checks to see if we can move down
Rem Check from the Left hand side
Move = 1
for i = 1 to 4
for j = 1 to 4
if currentPiece(1,i,j) <> 0
Rem Found Part of Block
TempY = int(CurrentY/20)
TempX = int(CurrentX/20)-1
Rem Check To Left of brick
if Board(TempX+i,TempY + j) > 0
Move=0
endif
endif
next j
next i
Rem If move is still 1 after all that it is ok to move
if Move= 1 then currentx = currentx - 20
if currentx <=0-(Left*20)
currentx = 20-(Left*20)
endif
return
CheckMoveRight:
Rem This function checks to see if we can move down
Rem Check from the Right hand side
Move = 1
for i = 1 to 4
for j = 1 to 4
if currentPiece(1,i,j) <> 0
Rem Found Part of Block
TempY = int(CurrentY/20)
TempX = int(CurrentX/20)+1
Rem Check To Right of brick
if Board(TempX+i,TempY + j) > 0
Move=0
endif
endif
next j
next i
Rem If move is still 1 its ok to move
if Move= 1 then currentx = currentx + 20
if currentx >=220 - (Right*20)
currentx = 200 - (Right*20)
endif
return
LandPiece:
Rem This routine is called when the block has landed on something
Rem First calculate where we are for updating the board
MapX = int(Currentx /20)
MapY = int(Currenty/20)
Rem Now transpose the piece into the board
For i= 1 to 4
For j= 1 to 4
if CurrentPiece(1,i,j) = 1
board((MapX+i),MapY+j) = (CurrentPiece(1,0,0)+1)
endif
Next j
next i
Rem Next Check to see if we have completed any lines
gosub CheckLines
Rem Pick next piece
gosub SelectNextPiece
Rem Update the height and check for game over
gosub SetHeight
return
CheckLines:
Rem This part checks to see if there are any complete lines and if so removes them
Rem L = number of lines removed in this pass so it can be factored into the score as a bonus
l = 0
i=1
repeat
Rem scans across the X axis to check if all board sprites are greater than the default
ClearLine = 1
j=1
repeat
If board(j,i) = 0 then ClearLine = 0
j=j+1
if j >(BoardX+1)
Rem We have found a complete row so lets do something with it
Rem First Clear Complete Row
for col = 1 to BoardX
Board(col,i) = 0
next col
Rem Next move everything down
Row = i
repeat
For col = 1 to BoardX
Board(col,row)= Board(col,row-1)
next col
row = row -1
until row <=0
l=l +1
lines = lines + 1
Score = score + (10*l)
ClearLine = 0
endif
until ClearLine = 0
i=i+1
until i> BoardY
Rem Update the height of the board now we have dealt with any lines
gosub SetHeight
return
</CODE>