/* cColorTetris.
txt
* -> Created by Catalyst
* -> v1.1 (Mobile update)
* -> import Games/cColorTetris
*
* You also can play widh W and H parameters to change field size,
* and figure_glyph_a/b to chane block sprite
*
*/
var is_game_ended = false
var score = 0
var lines = 0
var ticks = 0
var W = 10 // field width
var H = 20 + 1 // field height
var figure_glyph_a = "[" // any ascii symbol
var figure_glyph_b = "]" // [] () {} ██
var game_x = screen.w/2 - (W*2 + 18)/2
var game_y = screen.h/2 - H/2
?sys.isMobile
game_x = screen.w/2 - W // center x only by bottle
var gui_x = game_x + 2*W + 3
var gui_y = game_y
var figure_x = W/2 - 2
var figure_y = 0
var figure_max_x = 22
var figure_min_x = -2
var figure = 15
var figure_next = 1
var figure_color = 7
var figure_next_color = 2
var clear_line = ""
var full_line = ""
var lower_border = " "
var figures = []
var field = []
var field_colors = []
var colors = [#white, #yellow, #cyan, #green, #red, #f80, #blue, #f0f]
var button_left = 0
var button_right = 1
var button_rotate = 2
var button_down = 3
var button_restart = 4
var button_exit = 5
// enum
var x = 0
var y = 1
var w = 2
var h = 3
var is_pressed = 4
var key_name = 5
var icon = 6
var buttons = [
// x, y, w, h, is_pressed, key, icon
[0, screen.h/2, 11, 5, false, primaryBegin, "<"], // left
[11, screen.h/2, 11, 5, false, primaryBegin, ">"], // right
[screen.w-22, screen.h/2, 11, 5, false, primaryBegin, "O"], // rotate
[screen.w-11, screen.h/2, 11, 5, false, primary, "v"], // down
[screen.w-21, screen.h - 3, 11, 3, false, primaryEnd, "restart"], // restart
[screen.w-10, screen.h - 3, 10, 3, false, primaryEnd, "exit"], // exit
]
?sys.isMobile
// get input from buttons
for i = 0..5
?key = buttons[i][key_name] &
^input.x >= buttons[i][x] & input.x < buttons[i][x] + buttons[i][w] &
^input.y >= buttons[i][y] & input.y < buttons[i][y] + buttons[i][h]
buttons[i][is_pressed] = true
:
buttons[i][is_pressed] = false
func coutField()
// field
for y = 0..H-1
>`@game_x@,@game_y+y@,#white,|
>`@game_x+W*2+1@,@game_y+y@,#white,|
?field[y] ! clear_line
for x = 0..W-1
?string.Sub(field[y], x, 1) = figure_glyph_a
>`@game_x+x*2+1@,@game_y+y@,@colors[field_colors[y*W+x]]@,@figure_glyph_a@@figure_g
lyph_b@
>`@game_x@,@game_y+H@,#white,@lower_border@
// next figure
>`@gui_x@,@gui_y + 1@,#white,Lines: @lines@
>`@gui_x@,@gui_y + 2@,#white,Score: @score@
>`@gui_x@,@gui_y + 3@,#white,Next figure:
var render_line = ""
for y = 0..3
render_line = ""
for x = 0..3
?string.Sub(figures[figure_next], y*4+x, 1) = "@"
render_line += figure_glyph_a + figure_glyph_b
:
render_line += " "
>`@gui_x@,@gui_y + 4 + y@,@colors[figure_next_color]@,@render_line@
?sys.isPC | sys.isConsole
?is_game_ended
>`@gui_x@,@gui_y + H - 5@,#yellow,game is ended
>`@gui_x@,@gui_y + H - 4@,#666,[Z] - restart game
// controls
>`@gui_x@,@gui_y + H - 3@,#666,[A], [D] - move
>`@gui_x@,@gui_y + H - 2@,#666,[C] - rotate
>`@gui_x@,@gui_y + H - 1@,#666,[X] - exit
// draw buttons for phones
?sys.isMobile
var pivot_x = 0
var pivot_y = 0
for i = 0..5
?!is_game_ended & i = button_restart
continue
draw.Box(buttons[i][x], buttons[i][y], buttons[i][w], buttons[i][h], #white)
pivot_x = buttons[i][x] + (buttons[i][w] - string.Size(buttons[i][icon])) / 2
pivot_y = buttons[i][y] + buttons[i][h] / 2
>`@pivot_x@,@pivot_y@,#white,@buttons[i][icon]@
/* debug /
>`@gui_x@,@gui_y + 10@,#yellow,x, y: @figure_x@, @figure_y@ GX, GY: @game_x@,
@game_y@
>`@gui_x@,@gui_y + 11@,#yellow,figure: @figure@, next: @figure_next@
>`@gui_x@,@gui_y + 12@,#yellow,totaltime: @totaltime@,
>`@gui_x@,@gui_y + 13@,#yellow,ticks: @ticks@, upd: @(30 - score/100)@
?totaltime % 2 = 0
>`@gui_x@,@gui_y + 14@,#yellow,█
// */
func setFigure()
for y = 0..3
for x = 0..3
?string.Sub(figures[figure], x+y*4, 1) = "@"
>`@game_x+figure_x*2+x*2+1@,@game_y+figure_y+y@,@colors[figure_color]@,@figure_glyp
h_a@@figure_glyph_b@
func setMaxXY()
// max
?[0, 2, 10, 14, 18].Contains(figure)
figure_max_x = W-3
:
figure_max_x = W-4
// min
?[2, 4, 6, 8, 12, 16].Contains(figure)
figure_min_x = -2
:?figure = 1
figure_min_x = 0
:
figure_min_x = -1
// x normalization, especially when rotating
?figure_x < figure_min_x
figure_x = figure_min_x
?figure_x > figure_max_x
figure_x = figure_max_x
func rotate()
var figure_heap = figure
var figure_x_heap = figure_x
var figure_y_heap = figure_y
// O I S Z L J T
var rotations = [0, 2, 1, 4, 3, 6, 5, 10, 7, 8, 9, 14, 11, 12, 13, 18, 15, 16,
17]
figure = rotations[figure]
// if rotate is not possible
setMaxXY()
for y = 0..3
for x = 0..3
?string.Sub(figures[figure], x+y*4, 1) = "@" & (figure_y+y>H-1 |
string.Sub(field[figure_y+y], figure_x+x, 1) = figure_glyph_a)
figure = figure_heap
figure_x = figure_x_heap
figure_y = figure_y_heap
setMaxXY()
return
func move(move_direction)
?figure_x + move_direction < figure_min_x | figure_x + move_direction >
figure_max_x
return
for y = 3..0
for x = 0..3
?string.Sub(figures[figure], x+y*4, 1) = "@" & (string.Sub(field[figure_y+y],
figure_x+x+move_direction, 1) = figure_glyph_a)
return
figure_x += move_direction
func checkCollision()
var figures_id = [0, 1, 3, 5, 7, 11, 15]
var clip = false
for y = 3..0
for x = 0..3
?string.Sub(figures[figure], x+y*4, 1) = "@" & (figure_y+y = H-1 |
string.Sub(field[figure_y+y+1], figure_x+x, 1) = figure_glyph_a)
clip = true
play pickup_bronze
break
?!clip
return
for y = 3..0
for x = 0..3
// place figure
?string.Sub(figures[figure], x+y*4, 1) = "@"
field[figure_y+y] = string.Sub(field[figure_y+y], 0, figure_x+x) +
figure_glyph_a + string.Sub(field[figure_y+y], figure_x+x+1)
field_colors[figure_y*W + y*W + figure_x + x] = figure_color
for y = 3..0
for x = 0..3
// if new figure can't be spawned
?string.Sub(figures[figure_next], x+y*4, 1) = "@" & string.Sub(field[y], W/2
- 2+x, 1) = figure_glyph_a
is_game_ended = true
play uulaa_voice
break
figure_x = W/2 - 2
figure_y = -1
figure = figure_next
figure_color = figure_next_color
figure_next = rng % 7
figure_next_color = figure_next
figure_next_color = figure_next_color + 1
figure_next = figures_id[figure_next]
func checkLines()
for y = H-1..0
?field[y] = full_line
play quest_stone_jump
score += 10
lines++
field[y] = clear_line
for yy = y-1..0
for x = 0..W-1
field_colors[(yy+1)*W + x] = field_colors[yy*W + x]
field[yy+1] = field[yy]
return
func init()
// generate figures
figures.Add(".....@@..@@.....") // O
figures.Add("....@@@@........") // I
figures.Add("..@...@...@...@.")
figures.Add("......@@.@@.....") // S
figures.Add("..@...@@...@....")
figures.Add(".....@@...@@....") // Z
figures.Add("...@..@@..@.....")
figures.Add(".....@@@.@......") // L
figures.Add("..@...@...@@....")
figures.Add("...@.@@@........")
figures.Add(".@@...@...@.....")
figures.Add(".....@@@...@....") // J
figures.Add("..@@..@...@.....")
figures.Add(".@...@@@........")
figures.Add("..@...@..@@.....")
figures.Add(".....@@@..@.....") // T
figures.Add("..@...@@..@.....")
figures.Add("..@..@@@........")
figures.Add("..@..@@...@.....")
// generate lines
for x = 0..W-1
clear_line += " "
full_line += figure_glyph_a
lower_border += "--"
// generate field
for y = 0..H-1
field.Add(clear_line)
// generate colors
for xy = 0..W*H - 1
field_colors.Add(0)
func gameLoop()
?key = backBegin | buttons[button_exit][is_pressed] // X
loc.Leave()
?!is_game_ended
?totaltime % (30 - score/100) = 0 | key = down | buttons[button_down]
[is_pressed] // S
setMaxXY()
checkCollision()
checkLines()
figure_y++
ticks++
?ticks % 10 = 0
score += 1
?key = bumpRBegin | buttons[button_rotate][is_pressed] // C
rotate()
play grappling_idle
?key = leftBegin | buttons[button_left][is_pressed] // A
move(-1)
?key = rightBegin | buttons[button_right][is_pressed] // D
move(1)
:?key = bumpLEnd | buttons[button_restart][is_pressed] // Z
is_game_ended = false
score = 0
ticks = 0
lines = 0
field.Clear()
field_colors.Clear()
for y = 0..H-1
field.Add(clear_line)
for xy = 0..W*H - 1
field_colors.Add(0)
// update board
draw.Clear()
coutField()
?!is_game_ended
setFigure()
?loc.begin
disable abilities
disable pause
disable hud
disable banner
disable loadout input
disable player
ambient.Stop()
init()
:
gameLoop()