diff --git a/app/scene.rb b/app/scene.rb index 53768ef..6f0b733 100644 --- a/app/scene.rb +++ b/app/scene.rb @@ -13,13 +13,9 @@ module Scene # changed to so any data is cleared out # ex: # Scene.switch(args, :gameplay) - def switch(args, scene, reset: false, return_to: nil) - args.state.scene_to_return_to = return_to if return_to - - if scene == :back && args.state.scene_to_return_to - scene = args.state.scene_to_return_to - args.state.scene_to_return_to = nil - end + def switch(args, scene, reset: false, push_or_pop: false) + # if we're here /not/ from push or pop, clear the scene stack + args.state.scene_stack.clear unless push_or_pop if reset args.state.send(scene)&.current_option_i = nil @@ -30,7 +26,22 @@ module Scene end args.state.scene = scene - raise FinishTick.new + raise FinishTick, 'finish tick early' + end + + # Change the current scene and push the previous scene onto the stack + def push(args, scene, reset: false) + puts "Pushing #{scene}" + args.state.scene_stack ||= [] + args.state.scene_stack.push(args.state.scene) + + switch(args, scene, reset: reset, push_or_pop: true) + end + + # Return to the previous scene on the stack + def pop(args, reset: false) + scene = !args.state.scene_stack || args.state.scene_stack.empty? ? :back : args.state.scene_stack.pop + switch(args, scene, reset: reset, push_or_pop: true) end end end diff --git a/app/scenes/cube_tube.rb b/app/scenes/cube_tube.rb index bbbbeb6..819a59d 100644 --- a/app/scenes/cube_tube.rb +++ b/app/scenes/cube_tube.rb @@ -1,37 +1,33 @@ +# frozen_string_literal: true + +# Extension to the scene class for the cube tube scene module Scene class << self def tick_cube_tube(args) + # call the gameplay scene tick method (handles pause menu, etc) tick_gameplay(args) - args.state.game ||= BlockTubeGame.new args + args.state.game ||= CubeTubeGame.new args args.state.game.tick end end end - -class BlockTubeGame +# +class CubeTubeGame 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 + @grid_x = 115 + @grid_y = ((1280 - (@grid_h * @blocksize)) / 2) + 143 + @start_grid_x = @grid_x + @start_grid_y = @grid_y + @bg_x = 0 + @bg_w = 1335 - @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], - ] + @next_piece_box = [2, -9.5, 7, 7] @sprite_index = [ Sprite.for(:black), @@ -61,12 +57,14 @@ class BlockTubeGame @lines_to_clear = [] @line_clear_timer = 0 + @music_queue = [] + reset_game end def reset_game @lines = 0 - @level = 9 + @level = 0 @current_speed = get_speed @next_move = @current_speed @gameover = false @@ -80,12 +78,16 @@ class BlockTubeGame @lines_to_clear = [] @line_clear_timer = 0 - for x in 0..@grid_w-1 do + @bg_x = 0 + + each 0..@grid_w - 1 do |x| @grid[x] = [] - for y in 0..@grid_h-1 do + each 0..@grid_h - 1 do |y| @grid[x][y] = 0 end end + + @music_queue = [:music1, :music2] end def render_grid_border x, y, w, h, color @@ -103,28 +105,54 @@ class BlockTubeGame def render_background # draw a solid black background - @args.outputs.solids << [ + @args.outputs.solids << [ 0, 0, 1280, 1280, - *@color_index[0] + 0, 0, 0 + ] + + @bg_x += (@level+1)*2 unless @gameover + if(@bg_x >= @bg_w) + @bg_x %= @bg_w + end + + @args.outputs.sprites << [@bg_x,0,@bg_w,720,Sprite.for(:tunnel)] + @args.outputs.sprites << [@bg_x-@bg_w,0,@bg_w,720,Sprite.for(:tunnel)] + + @args.outputs.sprites << [ + 0, + @grid_x - 64, + 1597, + 540, + Sprite.for(:train) + ] + end + + def render_foreground + @args.outputs.sprites << [ + 0, + @grid_x - 64, + 1597, + 540, + Sprite.for(:train_fore) ] 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), + (1280 - @grid_y) - (y * @blocksize) - 6, @grid_x + (x * @blocksize), - @blocksize, @blocksize, + @blocksize + 6, @blocksize, @sprite_index[color] ] end def render_grid - render_grid_border -1, -1, @grid_w + 2, @grid_h + 2, 8 + #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 @@ -148,14 +176,41 @@ class BlockTubeGame end def render_next_piece + + screen_x = @grid_y + 400 + screen_y = @grid_x + 80 + screen_w = 250 + screen_h = 200 + + @args.outputs.sprites << [ + screen_x, screen_y + 10, screen_w, screen_h + 10, + Sprite.for(:screen) + ] + next_piece = @line_clear_timer <= 0 ? @next_piece : @current_piece - render_grid_border *@next_piece_box, 8 + # 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 ] + @args.outputs.labels << [screen_x + 33, screen_y + screen_h - 8, "Next piece", 8, 255, 255, 255, 255 ] + + screen_s = case (@args.state.tick_count % 32) + when 0..7 + :screen_s1 + when 8..15 + :screen_s2 + when 16..23 + :screen_s3 + when 24..31 + :screen_s4 + end + + @args.outputs.sprites << [ + screen_x, screen_y + 10, screen_w, screen_h + 10, + Sprite.for(screen_s) + ] end def render_score @@ -174,6 +229,7 @@ class BlockTubeGame render_next_piece render_current_piece render_grid + render_foreground render_score render_gameover if @showgameover end @@ -245,17 +301,23 @@ class BlockTubeGame 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 + if (@lines%10).floor == 0 + @level += 1 + @args.audio[:music].looping = false + end end end select_next_piece if @lines_to_clear.empty? + play_sfx(@args, :drop) if current_piece_colliding @gameover = true + stop_music(@args) end else + play_sfx(@args, :clear) @current_speed = get_speed end @@ -283,6 +345,7 @@ class BlockTubeGame end def rotate_current_piece_left + play_sfx(@args, :rotate) @current_piece = @current_piece.transpose.map(&:reverse) if(@current_piece_x + @current_piece.length) >= @grid_w @current_piece_x = @grid_w - @current_piece.length @@ -290,6 +353,7 @@ class BlockTubeGame end def rotate_current_piece_right + play_sfx(@args, :rotate) @current_piece = @current_piece.transpose.map(&:reverse) @current_piece = @current_piece.transpose.map(&:reverse) @current_piece = @current_piece.transpose.map(&:reverse) @@ -330,9 +394,18 @@ class BlockTubeGame return end - if @line_clear_timer > 0 + if @args.audio[:music] + resume_music(@args) if @args.audio[:music].paused + @args.audio[:music].pitch = 1 + (@level * 0.125) + else + music = @music_queue.shift + @music_queue.push music + play_music(@args, music) + end + + if @line_clear_timer.positive? @line_clear_timer -= 1 - if @line_clear_timer == 0 + if @line_clear_timer.zero? for y in @lines_to_clear for i in y.downto(1) do for j in 0..@grid_w-1 @@ -343,6 +416,7 @@ class BlockTubeGame @grid[i][0] = 0 end end + play_sfx(@args, :drop) @lines_to_clear = [] end return @@ -352,21 +426,35 @@ class BlockTubeGame if @current_piece_x > 0 @current_piece_x -= 1 if current_piece_colliding + play_sfx(@args, :move_deny) @current_piece_x += 1 + else + play_sfx(@args, :move) end + else + play_sfx(@args, :move_deny) 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 + play_sfx(@args, :move_deny) @current_piece_x -= 1 + else + play_sfx(@args, :move) end + else + play_sfx(@args, :move_deny) 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.plus || k.key_down.equal_sign + @level += 1 + @current_speed = get_speed + end if k.key_down.q || c.key_down.a rotate_current_piece_left @@ -375,6 +463,13 @@ class BlockTubeGame rotate_current_piece_right end + case @args.state.tick_count % (@current_speed * 6) + when 0..3, (@current_speed * 2)..((@current_speed * 2) + 3) + @grid_x = @start_grid_x + 3 + else + @grid_x = @start_grid_x + end + @next_move -= 1 if @next_move <= 0 @next_move = @current_speed diff --git a/app/scenes/gameplay.rb b/app/scenes/gameplay.rb index 8dec146..5eea3a7 100644 --- a/app/scenes/gameplay.rb +++ b/app/scenes/gameplay.rb @@ -28,7 +28,7 @@ module Scene def pause(args) play_sfx(args, :select) - return Scene.switch(args, :paused, reset: true) + return Scene.push(args, :paused, reset: true) end def tick_pause_button(args, sprites) diff --git a/app/scenes/main_menu.rb b/app/scenes/main_menu.rb index 929581f..5cddb5d 100644 --- a/app/scenes/main_menu.rb +++ b/app/scenes/main_menu.rb @@ -10,7 +10,7 @@ module Scene }, { key: :settings, - on_select: -> (args) { Scene.switch(args, :settings, reset: true, return_to: :main_menu) } + on_select: -> (args) { Scene.push(args, :settings, reset: true) } }, ] diff --git a/app/scenes/paused.rb b/app/scenes/paused.rb index 4f712b5..814f861 100644 --- a/app/scenes/paused.rb +++ b/app/scenes/paused.rb @@ -7,11 +7,11 @@ module Scene options = [ { key: :resume, - on_select: -> (args) { Scene.switch(args, :gameplay) } + on_select: -> (args) { Scene.pop(args) } }, { key: :settings, - on_select: -> (args) { Scene.switch(args, :settings, reset: true, return_to: :paused) } + on_select: -> (args) { Scene.push(args, :settings, reset: true) } }, { key: :return_to_main_menu, @@ -28,9 +28,14 @@ module Scene Menu.tick(args, :paused, options) + if args.audio[:music] && !args.audio[:music].paused + pause_music(args) + end + if secondary_down?(args.inputs) play_sfx(args, :select) options.find { |o| o[:key] == :resume }[:on_select].call(args) + end args.outputs.labels << label(:paused, x: args.grid.w / 2, y: args.grid.top - 200, align: ALIGN_CENTER, size: SIZE_LG, font: FONT_BOLD) diff --git a/app/scenes/settings.rb b/app/scenes/settings.rb index 5ff9775..8a13c44 100644 --- a/app/scenes/settings.rb +++ b/app/scenes/settings.rb @@ -29,7 +29,7 @@ module Scene }, { key: :back, - on_select: -> (args) { Scene.switch(args, :back) } + on_select: -> (args) { Scene.pop(args) } }, ] diff --git a/app/sound.rb b/app/sound.rb index e0f5673..f565f1b 100644 --- a/app/sound.rb +++ b/app/sound.rb @@ -28,3 +28,8 @@ end def resume_music(args) args.audio[:music].paused = false end + +# stop the currently playing music track +def stop_music(args) + args.audio.delete(:music) +end \ No newline at end of file diff --git a/app/sprite.rb b/app/sprite.rb index 7304bde..5c1fb2e 100644 --- a/app/sprite.rb +++ b/app/sprite.rb @@ -2,24 +2,25 @@ module Sprite # annoying to track but useful for reloading with +i+ in debug mode; would be # nice to define a different way SPRITES = { - bullet: 'sprites/bullet.png', - enemy: 'sprites/enemy.png', - enemy_king: 'sprites/enemy_king.png', - enemy_super: 'sprites/enemy_super.png', - exp_chip: 'sprites/exp_chip.png', - familiar: 'sprites/familiar.png', - player: 'sprites/player.png', + train: 'sprites/train-1.png', + train_fore: 'sprites/train-2.png', + screen: 'sprites/screen.png', + screen_s1: 'sprites/screen-s1.png', + screen_s2: 'sprites/screen-s2.png', + screen_s3: 'sprites/screen-s3.png', + screen_s4: 'sprites/screen-s4.png', + tunnel: 'sprites/tunnel.png', pause: 'sprites/pause.png', - gray: 'sprites/square/gray.png', - black: 'sprites/square/black.png', - white: 'sprites/square/white.png', - red: 'sprites/square/red.png', - green: 'sprites/square/green.png', - blue: 'sprites/square/blue.png', - yellow: 'sprites/square/yellow.png', - indigo: 'sprites/square/indigo.png', - violet: 'sprites/square/violet.png', - orange: 'sprites/square/orange.png' + gray: 'sprites/box/gray.png', + black: 'sprites/box/black.png', + white: 'sprites/box/white.png', + red: 'sprites/box/red.png', + green: 'sprites/box/green.png', + blue: 'sprites/box/blue.png', + yellow: 'sprites/box/yellow.png', + indigo: 'sprites/box/indigo.png', + violet: 'sprites/box/violet.png', + orange: 'sprites/box/orange.png' } class << self diff --git a/app/tick.rb b/app/tick.rb index 3fc51f4..80ef8b8 100644 --- a/app/tick.rb +++ b/app/tick.rb @@ -11,7 +11,7 @@ def tick(args) args.outputs.background_color = TRUE_BLACK.values args.state.has_focus ||= true - args.state.scene ||= :main_menu + Scene.push(args, :main_menu, reset: true) if !args.state.scene track_swipe(args) if mobile? diff --git a/sounds/clear.wav b/sounds/clear.wav new file mode 100644 index 0000000..1f68c01 Binary files /dev/null and b/sounds/clear.wav differ diff --git a/sounds/drop.wav b/sounds/drop.wav new file mode 100644 index 0000000..9c24984 Binary files /dev/null and b/sounds/drop.wav differ diff --git a/sounds/menu.wav b/sounds/menu.wav index 46b19b7..a4a48cb 100644 Binary files a/sounds/menu.wav and b/sounds/menu.wav differ diff --git a/sounds/move.wav b/sounds/move.wav new file mode 100644 index 0000000..b33dd52 Binary files /dev/null and b/sounds/move.wav differ diff --git a/sounds/move_deny.wav b/sounds/move_deny.wav new file mode 100644 index 0000000..5ace13f Binary files /dev/null and b/sounds/move_deny.wav differ diff --git a/sounds/music1.ogg b/sounds/music1.ogg new file mode 100644 index 0000000..ab5679e Binary files /dev/null and b/sounds/music1.ogg differ diff --git a/sounds/music2.ogg b/sounds/music2.ogg new file mode 100644 index 0000000..44e8574 Binary files /dev/null and b/sounds/music2.ogg differ diff --git a/sounds/rotate.wav b/sounds/rotate.wav new file mode 100644 index 0000000..0b58e50 Binary files /dev/null and b/sounds/rotate.wav differ diff --git a/sounds/select.wav b/sounds/select.wav index 748bbf5..23863e0 100644 Binary files a/sounds/select.wav and b/sounds/select.wav differ diff --git a/sprites/box/black.png b/sprites/box/black.png new file mode 100644 index 0000000..9520c39 Binary files /dev/null and b/sprites/box/black.png differ diff --git a/sprites/box/blue.png b/sprites/box/blue.png new file mode 100644 index 0000000..bfdf41b Binary files /dev/null and b/sprites/box/blue.png differ diff --git a/sprites/box/gray.png b/sprites/box/gray.png new file mode 100644 index 0000000..fca68f1 Binary files /dev/null and b/sprites/box/gray.png differ diff --git a/sprites/box/green.png b/sprites/box/green.png new file mode 100644 index 0000000..33091c3 Binary files /dev/null and b/sprites/box/green.png differ diff --git a/sprites/box/indigo.png b/sprites/box/indigo.png new file mode 100644 index 0000000..f6c5147 Binary files /dev/null and b/sprites/box/indigo.png differ diff --git a/sprites/box/orange.png b/sprites/box/orange.png new file mode 100644 index 0000000..09b62ec Binary files /dev/null and b/sprites/box/orange.png differ diff --git a/sprites/box/red.png b/sprites/box/red.png new file mode 100644 index 0000000..c981494 Binary files /dev/null and b/sprites/box/red.png differ diff --git a/sprites/box/violet.png b/sprites/box/violet.png new file mode 100644 index 0000000..0c2e0dc Binary files /dev/null and b/sprites/box/violet.png differ diff --git a/sprites/box/white.png b/sprites/box/white.png new file mode 100644 index 0000000..cab8b4e Binary files /dev/null and b/sprites/box/white.png differ diff --git a/sprites/box/yellow.png b/sprites/box/yellow.png new file mode 100644 index 0000000..af589dc Binary files /dev/null and b/sprites/box/yellow.png differ diff --git a/sprites/screen-s1.png b/sprites/screen-s1.png new file mode 100644 index 0000000..1463010 Binary files /dev/null and b/sprites/screen-s1.png differ diff --git a/sprites/screen-s2.png b/sprites/screen-s2.png new file mode 100644 index 0000000..2b0f05e Binary files /dev/null and b/sprites/screen-s2.png differ diff --git a/sprites/screen-s3.png b/sprites/screen-s3.png new file mode 100644 index 0000000..7abc29b Binary files /dev/null and b/sprites/screen-s3.png differ diff --git a/sprites/screen-s4.png b/sprites/screen-s4.png new file mode 100644 index 0000000..99758ad Binary files /dev/null and b/sprites/screen-s4.png differ diff --git a/sprites/screen.png b/sprites/screen.png new file mode 100644 index 0000000..fb4ad62 Binary files /dev/null and b/sprites/screen.png differ diff --git a/sprites/train-1.png b/sprites/train-1.png new file mode 100644 index 0000000..714940c Binary files /dev/null and b/sprites/train-1.png differ diff --git a/sprites/train-2.png b/sprites/train-2.png new file mode 100644 index 0000000..d176e18 Binary files /dev/null and b/sprites/train-2.png differ diff --git a/sprites/tunnel.png b/sprites/tunnel.png new file mode 100644 index 0000000..3c03a26 Binary files /dev/null and b/sprites/tunnel.png differ