mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
tetris stuff
This commit is contained in:
parent
3a6fae4447
commit
9be70bcbe7
@ -1,8 +1,12 @@
|
|||||||
|
|
||||||
; TehTriz - a Tetris clone.
|
; TehTriz - a Tetris clone.
|
||||||
;
|
;
|
||||||
; @todo: hold block.
|
|
||||||
|
; @todo: holding a block.
|
||||||
; @todo: show next 2 blocks instead of just 1.
|
; @todo: show next 2 blocks instead of just 1.
|
||||||
|
; @todo: how to deal with rotation when block is against a wall or another block ('bump' off the wall?)
|
||||||
|
; @todo: should not give the same block more than twice in a row?
|
||||||
|
; @todo: simple sound effects? slight click when moving, swish when rotating/dropping, soft explosion when lines are cleared, buzz at game over
|
||||||
|
|
||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
@ -30,15 +34,88 @@ waitkey:
|
|||||||
c64.TIME_LO = 0
|
c64.TIME_LO = 0
|
||||||
if blocklogic.canMoveDown(xpos, ypos) {
|
if blocklogic.canMoveDown(xpos, ypos) {
|
||||||
|
|
||||||
; @todo re-enable down movement
|
; slowly move the block down
|
||||||
;drawBlock(xpos, ypos, 32)
|
drawBlock(xpos, ypos, 32)
|
||||||
;ypos++ ; descend
|
ypos++
|
||||||
;drawBlock(xpos, ypos, 160)
|
drawBlock(xpos, ypos, 160)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
; block can't move further down!
|
; block can't move further down!
|
||||||
; check if the game area is full, if not, spawn the next block at the top.
|
; check if the game area is full, if not, spawn the next block at the top.
|
||||||
if blocklogic.isGameOver() {
|
if blocklogic.isGameOver(xpos, ypos) {
|
||||||
|
game_over()
|
||||||
|
} else {
|
||||||
|
spawnNextBlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ubyte key=c64.GETIN() ; @todo: joystick support as well. (doesn't joy1 input characters as well?)
|
||||||
|
if_z goto waitkey
|
||||||
|
|
||||||
|
if key>='1' and key<='7' {
|
||||||
|
; select block type, reset to start pos
|
||||||
|
; @todo remove this feature it is for testing purposes only
|
||||||
|
xpos = startXpos
|
||||||
|
ypos = startYpos
|
||||||
|
drawBlock(xpos, ypos, 32)
|
||||||
|
blocklogic.newCurrentBlock(key-'1')
|
||||||
|
drawBlock(xpos, ypos, 160)
|
||||||
|
}
|
||||||
|
else if key==157 or key==',' {
|
||||||
|
; move left
|
||||||
|
if blocklogic.canMoveLeft(xpos, ypos) {
|
||||||
|
drawBlock(xpos, ypos, 32)
|
||||||
|
xpos--
|
||||||
|
drawBlock(xpos, ypos, 160)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if key==29 or key=='.' {
|
||||||
|
; move right
|
||||||
|
if blocklogic.canMoveRight(xpos, ypos) {
|
||||||
|
drawBlock(xpos, ypos, 32)
|
||||||
|
xpos++
|
||||||
|
drawBlock(xpos, ypos, 160)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if key==17 or key=='m' {
|
||||||
|
; move down faster
|
||||||
|
if blocklogic.canMoveDown(xpos, ypos) {
|
||||||
|
drawBlock(xpos, ypos, 32)
|
||||||
|
ypos++
|
||||||
|
drawBlock(xpos, ypos, 160)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if key==145 or key==' ' {
|
||||||
|
; drop down immediately
|
||||||
|
drawBlock(xpos, ypos, 32)
|
||||||
|
ypos = boardOffsetY+boardHeight-4 ; @todo determine proper y position
|
||||||
|
drawBlock(xpos, ypos, 160)
|
||||||
|
}
|
||||||
|
else if key=='z' {
|
||||||
|
; rotate counter clockwise
|
||||||
|
if blocklogic.canRotateCCW(xpos, ypos) {
|
||||||
|
drawBlock(xpos, ypos, 32)
|
||||||
|
blocklogic.rotateCCW()
|
||||||
|
drawBlock(xpos, ypos, 160)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if key=='x' {
|
||||||
|
; rotate clockwise
|
||||||
|
if blocklogic.canRotateCW(xpos, ypos) {
|
||||||
|
drawBlock(xpos, ypos, 32)
|
||||||
|
blocklogic.rotateCW()
|
||||||
|
drawBlock(xpos, ypos, 160)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
; @todo check if line(s) are full -> flash/clear line(s) + add score + move rest down
|
||||||
|
|
||||||
|
goto waitkey
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub game_over() {
|
||||||
c64scr.PLOT(7, 7)
|
c64scr.PLOT(7, 7)
|
||||||
c64.CHROUT('U')
|
c64.CHROUT('U')
|
||||||
c64scr.print("────────────────────────")
|
c64scr.print("────────────────────────")
|
||||||
@ -49,72 +126,16 @@ waitkey:
|
|||||||
c64.CHROUT('J')
|
c64.CHROUT('J')
|
||||||
c64scr.print("────────────────────────")
|
c64scr.print("────────────────────────")
|
||||||
c64.CHROUT('K')
|
c64.CHROUT('K')
|
||||||
} else {
|
while(true) {
|
||||||
spawnNextBlock()
|
; endless loop
|
||||||
|
; @todo restart game on pressing F1/firebutton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ubyte key=c64.GETIN()
|
|
||||||
if_z goto waitkey
|
|
||||||
|
|
||||||
if key>='1' and key<='7' {
|
|
||||||
; select block type, reset to start pos
|
|
||||||
xpos = startXpos
|
|
||||||
ypos = startYpos
|
|
||||||
drawBlock(xpos, ypos, 32)
|
|
||||||
blocklogic.newCurrentBlock(key-'1')
|
|
||||||
drawBlock(xpos, ypos, 160)
|
|
||||||
}
|
|
||||||
else if key==157 or key==',' {
|
|
||||||
if blocklogic.canMoveLeft(xpos, ypos) {
|
|
||||||
drawBlock(xpos, ypos, 32)
|
|
||||||
xpos-- ; move left
|
|
||||||
drawBlock(xpos, ypos, 160)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if key==29 or key=='.' {
|
|
||||||
if blocklogic.canMoveRight(xpos, ypos) {
|
|
||||||
drawBlock(xpos, ypos, 32)
|
|
||||||
xpos++ ; move right
|
|
||||||
drawBlock(xpos, ypos, 160)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if key==17 or key=='m' {
|
|
||||||
if blocklogic.canMoveDown(xpos, ypos) {
|
|
||||||
drawBlock(xpos, ypos, 32)
|
|
||||||
ypos++ ; descend
|
|
||||||
drawBlock(xpos, ypos, 160)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if key==145 or key==' ' {
|
|
||||||
; drop down immediately
|
|
||||||
drawBlock(xpos, ypos, 32)
|
|
||||||
ypos = boardOffsetY+boardHeight-4
|
|
||||||
drawBlock(xpos, ypos, 160)
|
|
||||||
}
|
|
||||||
else if key=='z' {
|
|
||||||
if blocklogic.canRotateCCW() {
|
|
||||||
drawBlock(xpos, ypos, 32)
|
|
||||||
blocklogic.rotateCCW()
|
|
||||||
drawBlock(xpos, ypos, 160)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if key=='x' {
|
|
||||||
if blocklogic.canRotateCW() {
|
|
||||||
drawBlock(xpos, ypos, 32)
|
|
||||||
blocklogic.rotateCW()
|
|
||||||
drawBlock(xpos, ypos, 160)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto waitkey
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
sub spawnNextBlock() {
|
sub spawnNextBlock() {
|
||||||
c64.TIME_LO = 0
|
c64.TIME_LO = 0
|
||||||
blocklogic.newCurrentBlock(nextBlock)
|
blocklogic.newCurrentBlock(nextBlock)
|
||||||
nextBlock = rnd() % 7
|
nextBlock = (rnd() + c64.RASTER) % 7
|
||||||
drawNextBlock()
|
drawNextBlock()
|
||||||
xpos = startXpos
|
xpos = startXpos
|
||||||
ypos = startYpos
|
ypos = startYpos
|
||||||
@ -167,9 +188,9 @@ waitkey:
|
|||||||
c64scr.setcc(boardOffsetX+boardWidth, i, 84, 11)
|
c64scr.setcc(boardOffsetX+boardWidth, i, 84, 11)
|
||||||
}
|
}
|
||||||
|
|
||||||
for ubyte b in 7 to 0 step -1 {
|
for i in 7 to 0 step -1 {
|
||||||
blocklogic.newCurrentBlock(b)
|
blocklogic.newCurrentBlock(i)
|
||||||
drawBlock(3, 3+b*3, 102) ; 102 = stipple
|
drawBlock(3, 3+i*3, 102) ; 102 = stipple
|
||||||
}
|
}
|
||||||
drawScore()
|
drawScore()
|
||||||
}
|
}
|
||||||
@ -335,89 +356,73 @@ waitkey:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub canRotateCW() -> ubyte {
|
|
||||||
rotateCW()
|
|
||||||
ubyte okay=true ; TODO determine
|
|
||||||
rotateCCW()
|
|
||||||
return okay
|
|
||||||
}
|
|
||||||
|
|
||||||
sub canRotateCCW() -> ubyte {
|
|
||||||
rotateCCW()
|
|
||||||
ubyte okay=true ; TODO determine
|
|
||||||
rotateCW()
|
|
||||||
return okay
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
; For movement checking it is not needed to clamp the x/y coordinates,
|
; For movement checking it is not needed to clamp the x/y coordinates,
|
||||||
; because we have to check for brick collisions anyway.
|
; because we have to check for brick collisions anyway.
|
||||||
; The full play area is bordered by (in)visible characters that will collide.
|
; The full play area is bordered by (in)visible characters that will collide.
|
||||||
|
; Collision is determined by reading the screen data directly.
|
||||||
|
; This means the current position of the block on the screen has to be cleared first,
|
||||||
|
; and redrawn after the collision result has been determined.
|
||||||
|
|
||||||
|
sub canRotateCW(ubyte xpos, ubyte ypos) -> ubyte {
|
||||||
|
main.drawBlock(xpos, ypos, 32)
|
||||||
|
rotateCW()
|
||||||
|
ubyte collision = collides(xpos, ypos)
|
||||||
|
rotateCCW()
|
||||||
|
main.drawBlock(xpos, ypos, 160)
|
||||||
|
return not collision
|
||||||
|
}
|
||||||
|
|
||||||
|
sub canRotateCCW(ubyte xpos, ubyte ypos) -> ubyte {
|
||||||
|
main.drawBlock(xpos, ypos, 32)
|
||||||
|
rotateCCW()
|
||||||
|
ubyte collision = collides(xpos, ypos)
|
||||||
|
rotateCW()
|
||||||
|
main.drawBlock(xpos, ypos, 160)
|
||||||
|
return not collision
|
||||||
|
}
|
||||||
|
|
||||||
sub canMoveLeft(ubyte xpos, ubyte ypos) -> ubyte {
|
sub canMoveLeft(ubyte xpos, ubyte ypos) -> ubyte {
|
||||||
|
|
||||||
main.drawBlock(xpos, ypos, 32)
|
main.drawBlock(xpos, ypos, 32)
|
||||||
ubyte result = canActuallyMoveLeft(xpos, ypos)
|
ubyte collision = collides(xpos-1, ypos)
|
||||||
main.drawBlock(xpos, ypos, 160)
|
main.drawBlock(xpos, ypos, 160)
|
||||||
return result
|
return not collision
|
||||||
|
|
||||||
sub canActuallyMoveLeft(ubyte xpos, ubyte ypos) -> ubyte {
|
|
||||||
; @todo make this a generic subroutine that also works to check right and bottom collisions...
|
|
||||||
|
|
||||||
return not (currentBlock[0] and c64scr.getchr(xpos-1, ypos)!=32
|
|
||||||
or currentBlock[1] and c64scr.getchr(xpos, ypos)!=32
|
|
||||||
or currentBlock[2] and c64scr.getchr(xpos+1, ypos)!=32
|
|
||||||
or currentBlock[3] and c64scr.getchr(xpos+2, ypos)!=32
|
|
||||||
or currentBlock[4] and c64scr.getchr(xpos-1, ypos+1)!=32
|
|
||||||
or currentBlock[5] and c64scr.getchr(xpos, ypos+1)!=32
|
|
||||||
or currentBlock[6] and c64scr.getchr(xpos+1, ypos+1)!=32
|
|
||||||
or currentBlock[7] and c64scr.getchr(xpos+2, ypos+1)!=32
|
|
||||||
or currentBlock[8] and c64scr.getchr(xpos-1, ypos+2)!=32
|
|
||||||
or currentBlock[9] and c64scr.getchr(xpos, ypos+2)!=32
|
|
||||||
or currentBlock[10] and c64scr.getchr(xpos+1, ypos+2)!=32
|
|
||||||
or currentBlock[11] and c64scr.getchr(xpos+2, ypos+2)!=32
|
|
||||||
or currentBlock[12] and c64scr.getchr(xpos-1, ypos+3)!=32
|
|
||||||
or currentBlock[13] and c64scr.getchr(xpos, ypos+3)!=32
|
|
||||||
or currentBlock[14] and c64scr.getchr(xpos+1, ypos+3)!=32
|
|
||||||
or currentBlock[15] and c64scr.getchr(xpos+2, ypos+3)!=32)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub canMoveRight(ubyte xpos, ubyte ypos) -> ubyte {
|
sub canMoveRight(ubyte xpos, ubyte ypos) -> ubyte {
|
||||||
|
|
||||||
main.drawBlock(xpos, ypos, 32)
|
main.drawBlock(xpos, ypos, 32)
|
||||||
ubyte result = canActuallyMoveRight(xpos, ypos)
|
ubyte collision = collides(xpos+1, ypos)
|
||||||
main.drawBlock(xpos, ypos, 160)
|
main.drawBlock(xpos, ypos, 160)
|
||||||
return result
|
return not collision
|
||||||
|
|
||||||
sub canActuallyMoveRight(ubyte xpos, ubyte ypos) -> ubyte {
|
|
||||||
|
|
||||||
; @todo use the generic subroutine that also works to check right and bottom collisions...
|
|
||||||
|
|
||||||
return not (currentBlock[0] and c64scr.getchr(xpos+1, ypos)!=32
|
|
||||||
or currentBlock[1] and c64scr.getchr(xpos+2, ypos)!=32
|
|
||||||
or currentBlock[2] and c64scr.getchr(xpos+3, ypos)!=32
|
|
||||||
or currentBlock[3] and c64scr.getchr(xpos+4, ypos)!=32
|
|
||||||
or currentBlock[4] and c64scr.getchr(xpos+1, ypos+1)!=32
|
|
||||||
or currentBlock[5] and c64scr.getchr(xpos+2, ypos+1)!=32
|
|
||||||
or currentBlock[6] and c64scr.getchr(xpos+3, ypos+1)!=32
|
|
||||||
or currentBlock[7] and c64scr.getchr(xpos+4, ypos+1)!=32
|
|
||||||
or currentBlock[8] and c64scr.getchr(xpos+1, ypos+2)!=32
|
|
||||||
or currentBlock[9] and c64scr.getchr(xpos+2, ypos+2)!=32
|
|
||||||
or currentBlock[10] and c64scr.getchr(xpos+3, ypos+2)!=32
|
|
||||||
or currentBlock[11] and c64scr.getchr(xpos+4, ypos+2)!=32
|
|
||||||
or currentBlock[12] and c64scr.getchr(xpos+1, ypos+3)!=32
|
|
||||||
or currentBlock[13] and c64scr.getchr(xpos+2, ypos+3)!=32
|
|
||||||
or currentBlock[14] and c64scr.getchr(xpos+3, ypos+3)!=32
|
|
||||||
or currentBlock[15] and c64scr.getchr(xpos+4, ypos+3)!=32)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub canMoveDown(ubyte xpos, ubyte ypos) -> ubyte {
|
sub canMoveDown(ubyte xpos, ubyte ypos) -> ubyte {
|
||||||
return ypos<main.boardOffsetY+main.boardHeight-4 ; TODO deal with actual block/border collision, use generic check routine
|
main.drawBlock(xpos, ypos, 32)
|
||||||
|
ubyte collision = collides(xpos, ypos+1)
|
||||||
|
main.drawBlock(xpos, ypos, 160)
|
||||||
|
return not collision
|
||||||
}
|
}
|
||||||
|
|
||||||
sub isGameOver() -> ubyte {
|
sub collides(ubyte xpos, ubyte ypos) -> ubyte {
|
||||||
return false ; TODO determine fail state
|
return currentBlock[0] and c64scr.getchr(xpos, ypos)!=32
|
||||||
|
or currentBlock[1] and c64scr.getchr(xpos+1, ypos)!=32
|
||||||
|
or currentBlock[2] and c64scr.getchr(xpos+2, ypos)!=32
|
||||||
|
or currentBlock[3] and c64scr.getchr(xpos+3, ypos)!=32
|
||||||
|
or currentBlock[4] and c64scr.getchr(xpos, ypos+1)!=32
|
||||||
|
or currentBlock[5] and c64scr.getchr(xpos+1, ypos+1)!=32
|
||||||
|
or currentBlock[6] and c64scr.getchr(xpos+2, ypos+1)!=32
|
||||||
|
or currentBlock[7] and c64scr.getchr(xpos+3, ypos+1)!=32
|
||||||
|
or currentBlock[8] and c64scr.getchr(xpos, ypos+2)!=32
|
||||||
|
or currentBlock[9] and c64scr.getchr(xpos+1, ypos+2)!=32
|
||||||
|
or currentBlock[10] and c64scr.getchr(xpos+2, ypos+2)!=32
|
||||||
|
or currentBlock[11] and c64scr.getchr(xpos+3, ypos+2)!=32
|
||||||
|
or currentBlock[12] and c64scr.getchr(xpos, ypos+3)!=32
|
||||||
|
or currentBlock[13] and c64scr.getchr(xpos+1, ypos+3)!=32
|
||||||
|
or currentBlock[14] and c64scr.getchr(xpos+2, ypos+3)!=32
|
||||||
|
or currentBlock[15] and c64scr.getchr(xpos+3, ypos+3)!=32
|
||||||
|
}
|
||||||
|
|
||||||
|
sub isGameOver(ubyte xpos, ubyte ypos) -> ubyte {
|
||||||
|
return ypos==main.startYpos and not canMoveDown(xpos, ypos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
; @todo see problem in looplabelproblem.p8
|
; @todo see problem in looplabelproblem.p8
|
||||||
|
|
||||||
|
; @todo when using -noopt, the error "can only push address of string that is a variable on the heap" appears when using strings
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
uword w = 12345
|
uword w = 12345
|
||||||
|
Loading…
Reference in New Issue
Block a user