From d77677ae6a2d62c4f6032684a4624c8f1c7c934b Mon Sep 17 00:00:00 2001 From: Gordon Pedersen Date: Wed, 8 Mar 2023 14:44:14 +1100 Subject: [PATCH] Added current code from tetris tutorial --- app/main.rb | 2 + app/scenes/cube_tube.rb | 393 +++++++++++++++++++++++++++++++++++++ app/scenes/gameplay.rb | 2 +- app/scenes/main_menu.rb | 2 +- metadata/game_metadata.txt | 8 +- sprites/square/black.png | Bin 0 -> 326 bytes sprites/square/blue.png | Bin 0 -> 329 bytes sprites/square/gray.png | Bin 0 -> 325 bytes sprites/square/green.png | Bin 0 -> 329 bytes sprites/square/indigo.png | Bin 0 -> 335 bytes sprites/square/orange.png | Bin 0 -> 335 bytes sprites/square/red.png | Bin 0 -> 335 bytes sprites/square/violet.png | Bin 0 -> 334 bytes sprites/square/white.png | Bin 0 -> 325 bytes sprites/square/yellow.png | Bin 0 -> 319 bytes 15 files changed, 401 insertions(+), 6 deletions(-) create mode 100644 app/scenes/cube_tube.rb create mode 100644 sprites/square/black.png create mode 100644 sprites/square/blue.png create mode 100644 sprites/square/gray.png create mode 100644 sprites/square/green.png create mode 100644 sprites/square/indigo.png create mode 100644 sprites/square/orange.png create mode 100644 sprites/square/red.png create mode 100644 sprites/square/violet.png create mode 100644 sprites/square/white.png create mode 100644 sprites/square/yellow.png diff --git a/app/main.rb b/app/main.rb index b513062..5f27c1b 100644 --- a/app/main.rb +++ b/app/main.rb @@ -14,6 +14,8 @@ require "app/scenes/main_menu.rb" require "app/scenes/paused.rb" require "app/scenes/settings.rb" +require "app/scenes/cube_tube.rb" + # NOTE: add all requires above this require "app/tick.rb" diff --git a/app/scenes/cube_tube.rb b/app/scenes/cube_tube.rb new file mode 100644 index 0000000..67fef63 --- /dev/null +++ b/app/scenes/cube_tube.rb @@ -0,0 +1,393 @@ +module Scene + class << self + def tick_cube_tube(args) + tick_gameplay(args) + args.state.game ||= BlockTubeGame.new args + args.state.game.tick + end + end +end + + +class BlockTubeGame + def initialize args + @args = args + + @blocksize = 30 + @grid_w = 10 + @grid_h = 20 + @grid_x = (720 - (@grid_w * @blocksize)) / 2 + @grid_y = ((1280 - (@grid_h * @blocksize)) / 2) + 150 + + @next_piece_box = [-1, -9, 7, 7] + + @color_index = [ + [000, 000, 000], + [255, 000, 000], + [000, 255, 000], + [000, 000, 255], + [255, 255, 000], + [000, 255, 255], + [255, 000, 255], + [255, 127, 000], + [127, 127, 127], + ] + + @sprite_index = [ + "sprites/square/black.png", + "sprites/square/red.png", + "sprites/square/green.png", + "sprites/square/blue.png", + "sprites/square/yellow.png", + "sprites/square/indigo.png", + "sprites/square/violet.png", + "sprites/square/orange.png", + "sprites/square/gray.png", + ] + + @grid = [] + + @lines = 0 + @level = 0 + @current_speed = 0 + @next_move = 0 + @gameover = false + @showgameover = false + + @current_piece_x = 0 + @current_piece_y = 0 + @current_piece = nil + @next_piece = nil + @lines_to_clear = [] + @line_clear_timer = 0 + + reset_game + end + + def reset_game + @lines = 0 + @level = 9 + @current_speed = get_speed + @next_move = @current_speed + @gameover = false + @showgameover = false + + @current_piece_x = 4 + @current_piece_y = -1 + @current_piece = nil + @next_piece = nil + select_next_piece + @lines_to_clear = [] + @line_clear_timer = 0 + + for x in 0..@grid_w-1 do + @grid[x] = [] + for y in 0..@grid_h-1 do + @grid[x][y] = 0 + end + end + end + + def render_grid_border x, y, w, h, color + + for i in x..(x+w)-1 do + render_block i, y, color + render_block i, (y + h - 1), color + end + + for i in y..(y+h)-1 do + render_block x, i, color + render_block (x + w - 1), i, color + end + end + + def render_background + # draw a solid black background + @args.outputs.solids << [ + 0, + 0, + 1280, + 1280, + *@color_index[0] + ] + end + + # x and y are positions in the grid, not pixels + def render_block x, y, color + @args.outputs.sprites << [ + (1280 - @grid_y) - (y * @blocksize), + @grid_x + (x * @blocksize), + @blocksize, @blocksize, + @sprite_index[color] + ] + end + + def render_grid + + render_grid_border -1, -1, @grid_w + 2, @grid_h + 2, 8 + + for x in 0..@grid_w-1 do + for y in 0..@grid_h-1 do + render_block x, y, @grid[x][y] if @grid[x][y] != 0 && (!@lines_to_clear.include?(y) || (@line_clear_timer % 14) < 7) + end + end + + end + + def render_piece piece, piece_x, piece_y + + for x in 0..piece.length-1 do + for y in 0..piece[x].length-1 do + render_block piece_x + x, piece_y + y, piece[x][y] if piece[x][y] != 0 + end + end + end + + def render_current_piece + render_piece @current_piece, @current_piece_x, @current_piece_y if @line_clear_timer <= 0 + end + + def render_next_piece + next_piece = @line_clear_timer <= 0 ? @next_piece : @current_piece + render_grid_border *@next_piece_box, 8 + centerx = (@next_piece_box[2] - next_piece.length) / 2 + centery = (@next_piece_box[3] - next_piece[0].length) / 2 + + render_piece next_piece, @next_piece_box[0] + centerx, @next_piece_box[1] + centery + + @args.outputs.labels << [ 892, 431, "Next piece", 10, 255, 255, 255, 255 ] + end + + def render_score + @args.outputs.labels << [ 200, 600, "Lines: #{@lines}", 10, 255, 255, 255, 255 ] + @args.outputs.labels << [ 400, 600, "Level: #{@level}", 10, 255, 255, 255, 255 ] + @args.outputs.labels << [ 400, 563, "(Speed: #{(1/(@current_speed/60)).round 2} L/s)", 0.1, 255, 255, 255, 255 ] + end + + def render_gameover + @args.outputs.solids << [ 0, 245, 1280, 200, 0, 0, 0, 255] + @args.outputs.labels << [ 200, 450, "GAME OVER", 100, 255, 255, 255, 255 ] + end + + def render + render_background + render_next_piece + render_current_piece + render_grid + render_score + render_gameover if @showgameover + end + + def current_piece_colliding + for x in 0..@current_piece.length-1 do + for y in 0..@current_piece[x].length-1 do + if (@current_piece[x][y] != 0) && ((@current_piece_y + y >= @grid_h) || ((@current_piece_y + y) >= 0 && @grid[@current_piece_x + x][@current_piece_y + y] != 0 )) + return true + end + end + end + return false + end + + def get_speed + return case @level + when 0 then 53 + when 1 then 49 + when 2 then 45 + when 3 then 41 + when 4 then 37 + when 5 then 33 + when 6 then 28 + when 7 then 22 + when 8 then 17 + when 9 then 11 + when 10 then 10 + when 11 then 9 + when 12 then 8 + when 13 then 7 + when 14 then 6 + when 15 then 6 + when 16 then 5 + when 17 then 5 + when 18 then 4 + when 19 then 4 + when 20 then 3 + else 3 + end + end + + def plant_current_piece + rows_to_check = [] + + for x in 0..@current_piece.length-1 do + for y in 0..@current_piece[x].length-1 do + if @current_piece[x][y] != 0 + col = @current_piece_x + x + row = @current_piece_y + y + @grid[col][row] = @current_piece[x][y] + rows_to_check << row if !rows_to_check.include? row + end + end + end + + @lines_to_clear = [] + + # see if any rows need to be cleared out + for y in 0..@grid_h-1 + full = true + for x in 0..@grid_w-1 + if @grid[x][y] == 0 + full = false + break + end + end + + if full # no empty space in the row + @lines_to_clear.push y + @lines += 1 + @level += 1 if (@lines%10).floor == 0 + @line_clear_timer = 70 + end + end + + select_next_piece + if @lines_to_clear.empty? + if current_piece_colliding + @gameover = true + end + else + @current_speed = get_speed + end + + @next_move = @current_speed + 2 + end + + def select_next_piece + + @current_piece = @next_piece + + @current_piece_x = 4 + @current_piece_y = -1 + + r = (rand 7) + 1 + @next_piece = case r + when 1 then [ [r, 0], [r, r], [0, r]] + when 2 then [ [0, r], [r, r], [r, 0]] + when 3 then [ [r, r, r], [r, 0, 0]] + when 4 then [ [r, r], [r, r] ] + when 5 then [ [r], [r], [r], [r]] + when 6 then [ [r, 0], [r, r], [r, 0]] + when 7 then [ [r, 0, 0], [r, r, r]] + end + select_next_piece if @current_piece == nil + end + + def rotate_current_piece_left + @current_piece = @current_piece.transpose.map(&:reverse) + if(@current_piece_x + @current_piece.length) >= @grid_w + @current_piece_x = @grid_w - @current_piece.length + end + end + + def rotate_current_piece_right + @current_piece = @current_piece.transpose.map(&:reverse) + @current_piece = @current_piece.transpose.map(&:reverse) + @current_piece = @current_piece.transpose.map(&:reverse) + end + + def fill_grid + b = false + for y in 0..@grid_h-1 do + for x in 0..@grid_w-1 do + if @grid[x][y] == 0 + @grid[x][y] = (rand 7) + 1 + b = true + end + end + return if b + end + @showgameover = true + end + + def restart_game + reset_game + end + + def iterate + + # check input first + k = @args.inputs.keyboard + c = @args.inputs.controller_one + + if @gameover + if @showgameover + if k.key_down.space || k.key_down.enter || c.key_down.start + restart_game + end + else + fill_grid + end + return + end + + if @line_clear_timer > 0 + @line_clear_timer -= 1 + if @line_clear_timer == 0 + for y in @lines_to_clear + for i in y.downto(1) do + for j in 0..@grid_w-1 + @grid[j][i] = @grid[j][i-1] + end + end + for i in 0..@grid_w-1 + @grid[i][0] = 0 + end + end + @lines_to_clear = [] + end + return + end + + if k.key_down.down || k.key_down.s || c.key_down.down + if @current_piece_x > 0 + @current_piece_x -= 1 + if current_piece_colliding + @current_piece_x += 1 + end + end + end + if k.key_down.up || k.key_down.w || c.key_down.up + if (@current_piece_x + @current_piece.length) < @grid_w + @current_piece_x += 1 + if current_piece_colliding + @current_piece_x -= 1 + end + end + end + if k.key_down.left || k.key_held.left || k.key_down.a || k.key_held.a || c.key_down.left || c.key_held.left + @next_move -= @current_speed / 3 + end + + if k.key_down.q || c.key_down.a + rotate_current_piece_left + end + if k.key_down.e || c.key_down.b + rotate_current_piece_right + end + + @next_move -= 1 + if @next_move <= 0 + @next_move = @current_speed + @current_piece_y += 1 + if current_piece_colliding + @current_piece_y -= 1 + plant_current_piece + end + end + end + + def tick + iterate + render + end +end \ No newline at end of file diff --git a/app/scenes/gameplay.rb b/app/scenes/gameplay.rb index 56c89b4..8dec146 100644 --- a/app/scenes/gameplay.rb +++ b/app/scenes/gameplay.rb @@ -21,7 +21,7 @@ module Scene draw_bg(args, BLACK) - labels << label("GAMEPLAY", x: 40, y: args.grid.top - 40, size: SIZE_LG, font: FONT_BOLD) + # labels << label("GAMEPLAY", x: 40, y: args.grid.top - 40, size: SIZE_LG, font: FONT_BOLD) args.outputs.labels << labels args.outputs.sprites << sprites end diff --git a/app/scenes/main_menu.rb b/app/scenes/main_menu.rb index a20201f..929581f 100644 --- a/app/scenes/main_menu.rb +++ b/app/scenes/main_menu.rb @@ -6,7 +6,7 @@ module Scene options = [ { key: :start, - on_select: -> (args) { Scene.switch(args, :gameplay, reset: true) } + on_select: -> (args) { Scene.switch(args, :cube_tube, reset: true) } }, { key: :settings, diff --git a/metadata/game_metadata.txt b/metadata/game_metadata.txt index 4f614fe..300de3e 100644 --- a/metadata/game_metadata.txt +++ b/metadata/game_metadata.txt @@ -1,7 +1,7 @@ -devid=myitchusername -devtitle=My Name -gameid=my-game-title -gametitle=My Game Title +devid=death.au +devtitle=death.au +gameid=cube-tube +gametitle=Cube Tube version=0.1-dev icon=metadata/icon.png diff --git a/sprites/square/black.png b/sprites/square/black.png new file mode 100644 index 0000000000000000000000000000000000000000..1a80bda68e04892925b66850d6e8fd8948c31bdf GIT binary patch literal 326 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdoh8VC405aSW-L^Y)HoUz3A~!$CP? z@rK{?1^X5hu1s>O5nhyhRgOdd?uMT)=NlfY{IF?qNpHi%hKuk2KD}&Gd&^oTEB5;A z9Nrll>X2 zZcI=p|5My9E9qLxD@K+c(qY-zV-^=bS!x>y0pYDbY;~_Yr>-xUR+qx<4zxflxrh7s XJdx7x>1gTe~DWM4fUaf7X literal 0 HcmV?d00001 diff --git a/sprites/square/blue.png b/sprites/square/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..3194ff5c96d4c0e7eb566416f5eb0833e8aeca15 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdoh8U=;9laSW-L^Y)H+-XQ}Khrr;C zE)r8%4>i2o*pWC}!8JzYqh&f@;JP;zpPrnRcwAnvUH_#NqcY>-w@;q$e%!tH(5X7U z`g!KO6}F-0?!W*3h=0S)`D*n^-0n9G5-*pzh+PS?k~#G7D5I> d8zhor7~0i^*6rcEu>}}J44$rjF6*2UngE#Zhr|E? literal 0 HcmV?d00001 diff --git a/sprites/square/gray.png b/sprites/square/gray.png new file mode 100644 index 0000000000000000000000000000000000000000..b94f1ddb9e1b4d4bd6810921cb3a668112480d2d GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdoh8VC3<1aSW-L^Y)HoUz3A~!$CRY z<*lC&l$z>=`gG(wm8`kN{BWtXnf+hmV;1~zWs}wk8VDKu+Pl9da+-g2yYt!4HJ^91 zH-uj{`Mdr5KjGKA?Cu;B>tpF*=`q{i_u+FEW+WXhj@@kd{@L7T;%g6h zK;aAJ|A*Xt&&&$2ZD^QCGQ7C%ri6NwT{^296A;e6e<0s><0sK`m-=%af-FetDP;Wq XO6aBQTiH{<;9>A|^>bP0l+XkKw#a{L literal 0 HcmV?d00001 diff --git a/sprites/square/green.png b/sprites/square/green.png new file mode 100644 index 0000000000000000000000000000000000000000..d14a892046d42f9b368b8724c53a219ec4696e23 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdoh8U=;9laSW-L^Y)H+-XQ}Khrr;C zjx(mR9_rEC*pWC}!8JzYqh&f@;JP;zpPrnRcwAnvUH_#NqcY>-w@;oQzuUd{&?!Fq z`g!KO6}F-K&cFZuh<}6STlM-RZg(a(Cb!M^5Bz`j?Vox?kyu3I#0Jvg#YHz~q<{AL z+#Qyn0)<~DE&mWDyjd+ITmdcylOs%T$uK+CJ8gR;*fkg5n12Y)U$duu_ZQ`83n2rc d4HC&Q42CK~8;{rIhXaF%!PC{xWt~$(69C6qhDHDY literal 0 HcmV?d00001 diff --git a/sprites/square/indigo.png b/sprites/square/indigo.png new file mode 100644 index 0000000000000000000000000000000000000000..f66aa4693a8be5f6a72f974bb13cfa8291410a85 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdoh8U=;IoaSW-L^Y)IT-ysKyhKmym zWNpRXebCu8Ir(6tfllKrlbU6WmHGG0{u*7*`*-HF#AAycH@$Yb9q>4iQCs=*+1Jk( z?HBfoE7znYu#&;z9ElXOL9)_ePA%l}N;20~=OS*Fs( z`R_98E^_s-K%v|x{XJKXtl_-M$|1o?GCVu0w{X$Z_iKQz1H13X8uhSyha!JX)Rh4m e7SUr^#}M{cxJCMNglW literal 0 HcmV?d00001 diff --git a/sprites/square/orange.png b/sprites/square/orange.png new file mode 100644 index 0000000000000000000000000000000000000000..bf023bc003066c1d3c1e0daff0a5f4192e46d314 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdoh8U=;IoaSW-L^Y)IT-ysKyhKmz7 zTyTEC`q84w(URqjfllKrlbU6WmHGG0{u*7*`*-HF#AAycH@$Yb9q>4iQCs=*U-9RR z_ZwDh@4tKV@j9k?d-C@Gzg_*m^YHcGS95b7dVo}YlCH?idT-xs`JYMKK!^-D%T&5J z|6OL?MXnweD3tr8zvs%4HJn#jIV3nqhG%E>7A|`FehtudVE6r4qaJqeP~@+Px-vk+ dB6FVdQ&MBb@0JzX^WB>pF literal 0 HcmV?d00001 diff --git a/sprites/square/white.png b/sprites/square/white.png new file mode 100644 index 0000000000000000000000000000000000000000..7a233ea0320777b9cac05feebaca9d71db0c3725 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdoh8VC3<1aSW-L^Y)HoR&#)e!^QlQ zTzCFU-EC4myh8M4>yb;v%M=x+|1bSiaakf+_Rp>9CA|$38!jgQ{$Bdk%f{IE^6B-v z8~i`p)c-JipBXvrZt>1T6F~|dS{J;2@$Nr+_&!#@1Qjx1Nv7Geymu!1U$D3_L1FzT z?LX@}BZXJxE0Aa4F}Kt6EgQk^%M;yWdgA%E>v(F}H_7qC5DVwlP&_Kw*YTv%P-EZFN|G8FD_iyL+ z27dMDr`Ejw^6iRPA4?BQ&$IoF>(jpdi;pM}i)ftKKsvm*>E?{JH!u8IBr3rPg>OHL z{JVN&4d>PO!axU*3Zu-VAG@9IUvt0%2s8dk|5$Gxw(f!6-xFX5>l~9P7s=+`o^)-& RBVfQVc)I$ztaD0e0s!KkeuV%4 literal 0 HcmV?d00001