A bunch of polish

- lock delay
- wall kick tests
- an entirely new music track that changes per level
- Changes to how the music class works (especially when not passing a specific channel)
- New sound effects for getting a tetris, changing levels and game over
- Change piece colours to match the commonly accepted ones
I really should commit more often...
This commit is contained in:
Gordon Pedersen 2023-05-08 09:35:52 +10:00
parent 6e967fb2e5
commit b05fb1e0db
54 changed files with 318 additions and 71 deletions

View file

@ -115,7 +115,7 @@ class SoundInstance
end end
def play_music(args, opts = { channel: 0 }) def play_music(args, opts = { channel: 0 })
@looping = true # @looping = true
@key = "MUSIC_CHANNEL_#{opts[:channel]}" @key = "MUSIC_CHANNEL_#{opts[:channel]}"
play(args, opts) play(args, opts)
end end

View file

@ -21,13 +21,13 @@ class CubeTubeGame < GameplayScene
@sprite_index = [ @sprite_index = [
Sprite.for(:black), Sprite.for(:black),
Sprite.for(:red), Sprite.for(:cyan),
Sprite.for(:green),
Sprite.for(:blue), Sprite.for(:blue),
Sprite.for(:yellow),
Sprite.for(:indigo),
Sprite.for(:violet),
Sprite.for(:orange), Sprite.for(:orange),
Sprite.for(:yellow),
Sprite.for(:green),
Sprite.for(:violet),
Sprite.for(:red),
Sprite.for(:gray) Sprite.for(:gray)
] ]
@ -43,11 +43,63 @@ class CubeTubeGame < GameplayScene
@current_piece_x = 0 @current_piece_x = 0
@current_piece_y = 0 @current_piece_y = 0
@current_piece = nil @current_piece = nil
@current_piece_rotation = 0
@next_piece = nil @next_piece = nil
@lines_to_clear = [] @lines_to_clear = []
@line_clear_timer = 0 @line_clear_timer = 0
@lock_delay = 30
@lock_timer = 0
@current_music = :music1 @current_song = 0
@current_song_progress = 0
@cursor_down = nil
@cursor_down_tick = nil
@cursor_piece_x_origin = nil
@cursor_piece_y_origin = nil
# wall kick tests taken from https://tetris.fandom.com/wiki/SRS#Wall_Kicks
@wall_kick_tests = {
[0, 1] => [[-1, 0], [-1, 1], [0, -2], [-1, -2]],
[1, 0] => [[1, 0], [1, -1], [0, 2], [1, 2]],
[1, 2] => [[1, 0], [1, -1], [0, 2], [1, 2]],
[2, 1] => [[-1, 0], [-1, 1], [0, -2], [-1, -2]],
[2, 3] => [[1, 0], [1, 1], [0, -2], [1, -2]],
[3, 2] => [[-1, 0], [-1, -1], [0, 2], [-1, 2]],
[3, 0] => [[-1, 0], [-1, -1], [0, 2], [-1, 2]],
[0, 3] => [[1, 0], [1, 1], [0, -2], [1, -2]],
}
@wall_kick_tests_i = {
[0, 1] => [[-2, 0], [1, 0], [-2, -1], [1, 2]],
[1, 0] => [[2, 0], [-1, 0], [2, 1], [-1, -2]],
[1, 2] => [[-1, 0], [2, 0], [-1, 2], [2, -1]],
[2, 1] => [[1, 0], [-2, 0], [1, -2], [-2, 1]],
[2, 3] => [[2, 0], [-1, 0], [2, 1], [-1, -2]],
[3, 2] => [[-2, 0], [1, 0], [-2, -1], [1, 2]],
[3, 0] => [[1, 0], [-2, 0], [1, -2], [-2, 1]],
[0, 3] => [[-1, 0], [2, 0], [-1, 2], [2, -1]],
}
@song = [
[
[:underscore_b, :underscore2_a, :underscore2_b, :underscore_bridge1, :underscore_bridge2_a, :underscore_b, :underscore_a],
[:silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar],
],[
[:lead_beats, :lead_beats, :lead_beats, :lead_beats, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :lead_beats, :lead_beats],
[:underscore_a, :underscore_b, :underscore2_a, :underscore2_b, :underscore_bridge1, nil, :underscore_bridge2_a, nil, nil, :underscore_b]
],[
[:fill1, :fill1, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar],
[nil, nil, :lead1, nil, nil, nil, :lead2, nil, nil, nil]
],[
[:silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar],
[:post_lead, nil, :post_lead2, nil, :loop1_a, :loop1_b, :loop1_a, :loop1_b, :loop2_a, :loop2_b, :loop2_a, :loop2_b],
],[
[:fill1, :fill1, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar, :silent_bar],
[nil, nil, :lead1, nil, nil, nil, :lead2, nil, nil, nil, :post_lead, nil, :post_lead2, nil, :loop1_a, :loop1_b, :loop1_a, :loop1_b, :loop2_a, :loop2_b, :loop2_a, :loop2_b]
]
]
reset(args) reset(args)
end end
@ -107,7 +159,7 @@ class CubeTubeGame < GameplayScene
(y - @current_piece_y).between?(0, @current_piece[x - @current_piece_x].length - 1) && (y - @current_piece_y).between?(0, @current_piece[x - @current_piece_x].length - 1) &&
!@current_piece[x - @current_piece_x][y - @current_piece_y].zero? !@current_piece[x - @current_piece_x][y - @current_piece_y].zero?
# render the current piece # render the current piece
render_block(x, y, @current_piece[x - @current_piece_x][y - @current_piece_y]) render_block(x, y, @current_piece[x - @current_piece_x][y - @current_piece_y]) if @lines_to_clear.empty?
end end
end end
end end
@ -191,12 +243,14 @@ class CubeTubeGame < GameplayScene
render_gameover if @showgameover render_gameover if @showgameover
end end
def current_piece_colliding def piece_colliding(piece, piece_x, piece_y)
(0..@current_piece.length - 1).each do |x| return true if (piece_x + piece.length) > @grid_w || piece_x < 0
(0..@current_piece[x].length - 1).each do |y|
next if @current_piece[x][y].zero? (0..piece.length - 1).each do |x|
if (@current_piece_y + y >= @grid_h) || (0..piece[x].length - 1).each do |y|
((@current_piece_y + y) >= 0 && @grid[@current_piece_x + x][@current_piece_y + y] != 0) next if piece[x][y].zero?
if (piece_y + y >= @grid_h) ||
((piece_y + y) >= 0 && @grid[piece_x + x][piece_y + y] != 0)
return true return true
end end
end end
@ -204,6 +258,20 @@ class CubeTubeGame < GameplayScene
false false
end end
def current_piece_colliding
piece_colliding(@current_piece, @current_piece_x, @current_piece_y)
# (0..@current_piece.length - 1).each do |x|
# (0..@current_piece[x].length - 1).each do |y|
# next if @current_piece[x][y].zero?
# if (@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
# false
end
def get_speed def get_speed
case @level case @level
when 0 then 53 when 0 then 53
@ -228,8 +296,19 @@ class CubeTubeGame < GameplayScene
end end
def change_music def change_music
@current_music = @current_music == :music1 ? :music2 : :music1 @current_song = (@current_song + 1) % @song.length
Music.queue_up(@current_music) @current_song_progress = 0
case @level
when 5
Music.queue_up(:bridge)
when 10
Music.queue_up(:bridge)
when 15
Music.queue_up(:bridge)
when 20
Music.queue_up(:bridge)
end
end end
def line_full?(row) def line_full?(row)
@ -240,6 +319,13 @@ class CubeTubeGame < GameplayScene
end end
def plant_current_piece def plant_current_piece
@lock_timer -= 1
return unless @lock_timer <= 0
@cursor_down = nil
@cursor_piece_x_origin = nil
@cursor_piece_y_origin = nil
(0..@current_piece.length - 1).each do |x| (0..@current_piece.length - 1).each do |x|
(0..@current_piece[x].length - 1).each do |y| (0..@current_piece[x].length - 1).each do |y|
next if @current_piece[x][y].zero? next if @current_piece[x][y].zero?
@ -260,7 +346,8 @@ class CubeTubeGame < GameplayScene
@line_clear_timer = 70 @line_clear_timer = 70
if (@lines % 10).floor.zero? if (@lines % 10).floor.zero?
@level += 1 @level += 1
change_music change_music()
Sound.play(@args, :horn)
end end
end end
@ -274,6 +361,7 @@ class CubeTubeGame < GameplayScene
end end
else else
Sound.play(@args, :clear) Sound.play(@args, :clear)
Sound.play(@args, :fourlines) if @lines_to_clear.length == 4
@current_speed = get_speed @current_speed = get_speed
end end
@ -285,32 +373,70 @@ class CubeTubeGame < GameplayScene
@current_piece_x = 4 @current_piece_x = 4
@current_piece_y = -1 @current_piece_y = -1
@current_piece_rotation = 0
@lock_timer = @lock_delay
r = (rand 7) + 1 r = (rand 7) + 1
@next_piece = @next_piece =
case r case r
when 1 then [[r, 0], [r, r], [0, r]] when 1 then [[r], [r], [r], [r]] # I
when 2 then [[0, r], [r, r], [r, 0]] when 2 then [[0, r], [0, r], [r, r]] # J
when 3 then [[r, r, r], [r, 0, 0]] when 3 then [[r, r], [0, r], [0, r]] # L
when 4 then [[r, r], [r, r] ] when 4 then [[r, r], [r, r]] # O
when 5 then [[r], [r], [r], [r]] when 5 then [[r, 0], [r, r], [0, r]] # S
when 6 then [[r, 0], [r, r], [r, 0]] when 6 then [[0, r], [r, r], [0, r]] # T
when 7 then [[r, 0, 0], [r, r, r]] when 7 then [[0, r], [r, r], [r, 0]] # Z
end end
select_next_piece if @current_piece.nil? select_next_piece if @current_piece.nil?
end end
def rotate_current_piece_left def wall_kick(new_piece, old_rotation, new_rotation)
is_i = new_piece.length == 1 || (new_piece.length == 4 && new_piece[0].length == 1)
kick_test_set = is_i ? @wall_kick_tests_i : @wall_kick_tests
kick_test = kick_test_set[[old_rotation, new_rotation]]
kick_test.each do |t|
collide = piece_colliding(new_piece, @current_piece_x + t[0], @current_piece_y + t[1])
next if collide
@current_piece_x += t[0]
@current_piece_y += t[1]
return true
end
false
end
def rotate_current_piece(new_piece, new_rotation)
should_rotate = false
if piece_colliding(new_piece, @current_piece_x, @current_piece_y)
should_rotate = wall_kick(new_piece, @current_piece_rotation, new_rotation)
else
should_rotate = true
end
if should_rotate
@lock_timer = @lock_delay
@current_piece_rotation = new_rotation
@current_piece = new_piece
Sound.play(@args, :rotate) Sound.play(@args, :rotate)
@current_piece = @current_piece.transpose.map(&:reverse) else
@current_piece_x = @grid_w - @current_piece.length if (@current_piece_x + @current_piece.length) >= @grid_w # wall kick failed. Don't do the rotation
Sound.play(@args, :move_deny)
end
end
def rotate_current_piece_left
new_piece = @current_piece.transpose.map(&:reverse)
new_rotation = (@current_piece_rotation - 1) % 4
rotate_current_piece(new_piece, new_rotation)
end end
def rotate_current_piece_right def rotate_current_piece_right
Sound.play(@args, :rotate)
@current_piece = @current_piece.transpose.map(&:reverse) @current_piece = @current_piece.transpose.map(&:reverse)
@current_piece = @current_piece.transpose.map(&:reverse) @current_piece = @current_piece.transpose.map(&:reverse)
@current_piece = @current_piece.transpose.map(&:reverse) @current_piece = @current_piece.transpose.map(&:reverse)
new_rotation = (@current_piece_rotation + 1) % 4
rotate_current_piece(new_piece, new_rotation)
end end
def fill_grid def fill_grid
@ -339,6 +465,7 @@ class CubeTubeGame < GameplayScene
@current_piece_x -= 1 @current_piece_x -= 1
else else
Sound.play(@args, :move) Sound.play(@args, :move)
@lock_timer = @lock_delay
end end
else else
Sound.play(@args, :move_deny) Sound.play(@args, :move_deny)
@ -353,6 +480,7 @@ class CubeTubeGame < GameplayScene
@current_piece_x += 1 @current_piece_x += 1
else else
Sound.play(@args, :move) Sound.play(@args, :move)
@lock_timer = @lock_delay
end end
else else
Sound.play(@args, :move_deny) Sound.play(@args, :move_deny)
@ -376,6 +504,7 @@ class CubeTubeGame < GameplayScene
end end
end end
Sound.play(@args, :drop) Sound.play(@args, :drop)
@lock_timer = @lock_delay
@lines_to_clear = [] @lines_to_clear = []
false false
end end
@ -384,15 +513,70 @@ class CubeTubeGame < GameplayScene
restart_game if Input.pressed?(@args, :primary) && @gameover && @showgameover restart_game if Input.pressed?(@args, :primary) && @gameover && @showgameover
return if @gameover return if @gameover
if @lines_to_clear.empty?
move_current_piece_down if Input.pressed?(@args, :down) move_current_piece_down if Input.pressed?(@args, :down)
move_current_piece_up if Input.pressed?(@args, :up) move_current_piece_up if Input.pressed?(@args, :up)
@next_move -= @current_speed / 3 if Input.pressed_or_held?(@args, :left) if Input.pressed_or_held?(@args, :left)
@next_move -= @current_speed / 3
@lock_timer -= @current_speed / 3 if @lock_timer > 0
end
rotate_current_piece_left if Input.pressed?(@args, :rotate_left) rotate_current_piece_left if Input.pressed?(@args, :rotate_left)
rotate_current_piece_right if Input.pressed?(@args, :rotate_right) rotate_current_piece_right if Input.pressed?(@args, :rotate_right)
if @args.inputs.mouse.button_left || @args.inputs.finger_one
if @cursor_down.nil?
@cursor_down = @args.inputs.mouse.button_left ? @args.inputs.mouse.point : @args.inputs.finger_one
@cursor_down_tick = @args.state.tick_count
@cursor_piece_x_origin = @current_piece_x
@cursor_piece_y_origin = @current_piece_y
end
cursor = @args.inputs.mouse.button_left ? @args.inputs.mouse.point : @args.inputs.finger_one
delta_x = cursor.x - @cursor_down.x
if delta_x.negative? && delta_x.abs > (@blocksize * 2) && @cursor_piece_x_origin == @current_piece_x
@next_move -= @current_speed / 3
@lock_timer -= @current_speed / 3 if @lock_timer.positive?
return
end
delta_y = cursor.y - @cursor_down.y
delta_block = (delta_y / @blocksize).floor
max_delta = 0
if delta_block.negative?
@cursor_piece_x_origin.downto((@cursor_piece_x_origin + delta_block)) do |i|
break if piece_colliding(@current_piece, i, @current_piece_y)
max_delta = i
end
else
@cursor_piece_x_origin.upto((@cursor_piece_x_origin + delta_block)) do |i|
break if piece_colliding(@current_piece, i, @current_piece_y)
max_delta = i
end
end
@current_piece_x = max_delta
else
if !@cursor_down.nil? && (@cursor_down_tick + 30) >= @args.state.tick_count && @cursor_piece_x_origin == @current_piece_x
rotate_current_piece_left
end
@cursor_down = nil
@cursor_down_tick = nil
@cursor_piece_x_origin = nil
@cursor_piece_y_origin = nil
end
if @args.inputs.mouse.click
rotate_current_piece_left if @cursor_piece_x_origin.nil?
end
end
if @args.inputs.keyboard.key_down.equal_sign if @args.inputs.keyboard.key_down.equal_sign
@level += 1 @level += 1
@lines += 10 @lines += 10
change_music()
Sound.play(@args, :horn)
end end
end end
@ -411,13 +595,29 @@ class CubeTubeGame < GameplayScene
@next_move -= 1 @next_move -= 1
return unless @next_move <= 0 return unless @next_move <= 0
@next_move = @current_speed
@current_piece_y += 1 @current_piece_y += 1
return unless current_piece_colliding if current_piece_colliding
@current_piece_y -= 1 @current_piece_y -= 1
plant_current_piece plant_current_piece
else
@lock_timer = @lock_delay
@next_move = @current_speed
end
end
def iterate_music
Music.resume(@args) if !Music.stopped?(@args) && Music.paused?(@args)
return unless Music.stopped?(@args, 0) && (!Music.queue[0] || Music.queue[0].empty?)
song_length = @song[@current_song][0].length
@current_song_progress = @current_song_progress % song_length # just in case we changed to a shorter song
@song[@current_song].each_with_index do |track, i|
if @current_song_progress < track.length && !track[@current_song_progress].nil?
Music.play(@args, track[@current_song_progress], { channel: i })
end
end
@current_song_progress = (@current_song_progress + 1) % song_length
end end
def iterate def iterate
@ -428,8 +628,7 @@ class CubeTubeGame < GameplayScene
# skip the rest if it's game over # skip the rest if it's game over
return if @gameover return if @gameover
# resume music if it's paused iterate_music
Music.resume(@args) if !Music.stopped(@args) && Music.paused(@args)
iterate_train_bounce iterate_train_bounce
@ -461,6 +660,7 @@ class CubeTubeGame < GameplayScene
@current_piece_x = 4 @current_piece_x = 4
@current_piece_y = -1 @current_piece_y = -1
@current_piece = nil @current_piece = nil
@current_piece_rotation = 0
@next_piece = nil @next_piece = nil
select_next_piece select_next_piece
@lines_to_clear = [] @lines_to_clear = []
@ -475,8 +675,10 @@ class CubeTubeGame < GameplayScene
end end
end end
@current_music = :music1 @current_song = 0
Music.play(args, @current_music) @current_song_progress = 0
Music.set_volume(args, args.state.setting.music ? 0.8 : 0.0) Music.stop(args)
Music.set_volume(args, args.state.setting.music ? 0.6 : 0.0)
Music.play(args, :underscore_a)
end end
end end

View file

@ -30,7 +30,7 @@ class MainMenu < MenuScene
# actual menu logic is handled by the MenuScene super class # actual menu logic is handled by the MenuScene super class
super super
Music.play(args, :ambience) if args.state.setting.music && Music.stopped(args) Music.play(args, :ambience) if args.state.setting.music && Music.stopped?(args)
@next_announcement ||= 0 @next_announcement ||= 0
if @next_announcement <= args.state.tick_count if @next_announcement <= args.state.tick_count
next_sec = random(20..50) next_sec = random(20..50)

View file

@ -32,6 +32,6 @@ class PauseMenu < MenuScene
# called every tick of the game loop # called every tick of the game loop
def tick(args) def tick(args)
super super
Music.pause(args) unless Music.stopped(args) || Music.paused(args) Music.pause(args) unless Music.stopped?(args) || Music.paused?(args)
end end
end end

View file

@ -9,6 +9,9 @@ end
# Code that runs every game tick (mainly just calling other ticks) # Code that runs every game tick (mainly just calling other ticks)
def tick(args) def tick(args)
init(args) if args.state.tick_count.zero? init(args) if args.state.tick_count.zero?
Music.tick(args)
# this looks good on non 16:9 resolutions; game background is different # this looks good on non 16:9 resolutions; game background is different
args.outputs.background_color = TRUE_BLACK.values args.outputs.background_color = TRUE_BLACK.values
@ -22,8 +25,6 @@ def tick(args)
scene.tick(args) if scene.tick_in_background || scene == args.state.scene_stack.last scene.tick(args) if scene.tick_in_background || scene == args.state.scene_stack.last
end end
Music.tick(args)
debug_tick(args) debug_tick(args)
rescue FinishTick rescue FinishTick
end end

View file

@ -21,40 +21,64 @@ module Music
MUSIC.fetch(key).play_music(args, opts) MUSIC.fetch(key).play_music(args, opts)
end end
def stopped(args, channel = 0) def stopped?(args, channel = nil)
!args.audio.key?("MUSIC_CHANNEL_#{channel}") channel_names(args, channel).none? do |c|
args.audio.key?(c)
end
end end
def paused(args, channel = 0) def paused?(args, channel = nil)
args.audio["MUSIC_CHANNEL_#{channel}"].paused unless stopped(args, channel) channel_names(args, channel).all? do |c|
args.audio.key?(c) && args.audio[c].paused
end
end end
def stop(args, channel = 0) def stop(args, channel = nil)
args.audio.delete("MUSIC_CHANNEL_#{channel}") channel_names(args, channel).each do |c|
args.audio.delete(c)
end
end end
def pause(args, channel = 0) def pause(args, channel = nil)
args.audio["MUSIC_CHANNEL_#{channel}"].paused = true unless stopped(args, channel) channel_names(args, channel).each do |c|
args.audio[c].paused = true unless stopped?(args, c)
end
end end
def resume(args, channel = 0) def resume(args, channel = nil)
args.audio["MUSIC_CHANNEL_#{channel}"].paused = false unless stopped(args, channel) channel_names(args, channel).each do |c|
args.audio[c].paused = false unless stopped?(args, c)
end
end end
def set_volume(args, volume, channel = 0) def set_volume(args, volume, channel = nil)
args.audio["MUSIC_CHANNEL_#{channel}"].gain = volume unless stopped(args, channel) channel_names(args, channel).each do |c|
args.audio[c].gain = volume
end
end
def channel_names(args, channel = nil)
if channel.nil?
args.audio.keys.select do |key|
key.start_with? 'MUSIC_CHANNEL_'
end
elsif channel.is_a?(String)
[channel]
elsif channel.is_a?(Numeric)
["MUSIC_CHANNEL_#{channel}"]
else
channel
end
end end
def tick(args) def tick(args)
queue.each do |channel, value| queue.each do |channel, value|
unless value.empty? next if value.empty?
if args.audio["MUSIC_CHANNEL_#{channel}"] if args.audio["MUSIC_CHANNEL_#{channel}"]
if args.audio["MUSIC_CHANNEL_#{channel}"].looping args.audio["MUSIC_CHANNEL_#{channel}"].looping = false if args.audio["MUSIC_CHANNEL_#{channel}"].looping
args.audio["MUSIC_CHANNEL_#{channel}"].looping = false
end
else else
value.shift.play_music(args, { channel: channel, gain: args.state.setting.music ? 0.8 : 0.0 }) value.shift.play_music(args, { channel: channel, gain: args.state.setting.music ? 0.8 : 0.0, paused: false })
end
end end
end end
end end

View file

@ -16,14 +16,14 @@ icon=metadata/icon.png
# compile_ruby=false # compile_ruby=false
# Uncomment the entry below to specify the package name for your APK # Uncomment the entry below to specify the package name for your APK
# packageid=org.dev.gamename packageid=au.death.cubetube
# Setting this property to true will enable High DPI rendering (try in combination with scale_quality to see what looks best) # Setting this property to true will enable High DPI rendering (try in combination with scale_quality to see what looks best)
# highdpi=false # highdpi=false
# === Portrait Mode === # === Portrait Mode ===
# The orientation can be set to either landscape (1280x720) or portrait (720x1280) # The orientation can be set to either landscape (1280x720) or portrait (720x1280)
# orientation=landscape orientation=landscape
# === HD Mode === # === HD Mode ===

View file

@ -2,8 +2,24 @@
module Music module Music
MUSIC = { MUSIC = {
music1: SoundInstance.new({ path: 'music/music1.ogg', looping: true }), ambience: SoundInstance.new({ path: 'music/ambience1.ogg', looping: true }),
music2: SoundInstance.new({ path: 'music/music2.ogg', looping: true }), underscore_a: SoundInstance.new({ path: 'music/pyramids/underscore1_a.ogg', looping: false }),
ambience: SoundInstance.new({ path: 'music/ambience1.ogg', looping: true }) underscore_b: SoundInstance.new({ path: 'music/pyramids/underscore1_b.ogg', looping: false }),
underscore2_a: SoundInstance.new({ path: 'music/pyramids/underscore2_a.ogg', looping: false }),
underscore2_b: SoundInstance.new({ path: 'music/pyramids/underscore2_b.ogg', looping: false }),
underscore_bridge1: SoundInstance.new({ path: 'music/pyramids/underscore_bridge1.ogg', looping: false }),
underscore_bridge2_a: SoundInstance.new({ path: 'music/pyramids/underscore_bridge2+a.ogg', looping: false }),
lead_beats: SoundInstance.new({ path: 'music/pyramids/lead_beats.ogg', looping: false }),
fill1: SoundInstance.new({ path: 'music/pyramids/fill1.ogg', looping: false }),
lead1: SoundInstance.new({ path: 'music/pyramids/lead1.ogg', looping: false }),
lead2: SoundInstance.new({ path: 'music/pyramids/lead2.ogg', looping: false }),
loop1_a: SoundInstance.new({ path: 'music/pyramids/loop1_a.ogg', looping: false }),
loop1_b: SoundInstance.new({ path: 'music/pyramids/loop1_b.ogg', looping: false }),
loop2_a: SoundInstance.new({ path: 'music/pyramids/loop1_a.ogg', looping: false }),
loop2_b: SoundInstance.new({ path: 'music/pyramids/loop1_b.ogg', looping: false }),
post_lead: SoundInstance.new({ path: 'music/pyramids/post_lead.ogg', looping: false }),
post_lead2: SoundInstance.new({ path: 'music/pyramids/post_lead2.ogg', looping: false }),
bridge: SoundInstance.new({ path: 'music/pyramids/underscore_bridge2+a.ogg', looping: false }),
silent_bar: SoundInstance.new({ path: 'music/pyramids/silent_bar.ogg', looping: false }),
} }
end end

Binary file not shown.

Binary file not shown.

BIN
music/pyramids/fill1.ogg Normal file

Binary file not shown.

BIN
music/pyramids/lead1.ogg Normal file

Binary file not shown.

BIN
music/pyramids/lead2.ogg Normal file

Binary file not shown.

Binary file not shown.

BIN
music/pyramids/loop1_a.ogg Normal file

Binary file not shown.

BIN
music/pyramids/loop1_b.ogg Normal file

Binary file not shown.

BIN
music/pyramids/loop2_a.ogg Normal file

Binary file not shown.

BIN
music/pyramids/loop2_b.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -5,13 +5,16 @@ module Sound
menu: SoundInstance.new({ path: 'sounds/menu.wav' }), menu: SoundInstance.new({ path: 'sounds/menu.wav' }),
select: SoundInstance.new({ path: 'sounds/select.wav' }), select: SoundInstance.new({ path: 'sounds/select.wav' }),
clear: SoundInstance.new({ path: 'sounds/clear.wav' }), clear: SoundInstance.new({ path: 'sounds/clear.wav' }),
fourlines: SoundInstance.new({ path: 'sounds/fourlines.wav' }),
drop: SoundInstance.new({ path: 'sounds/drop.wav' }), drop: SoundInstance.new({ path: 'sounds/drop.wav' }),
move: SoundInstance.new({ path: 'sounds/move.wav' }), move: SoundInstance.new({ path: 'sounds/move.wav' }),
move_deny: SoundInstance.new({ path: 'sounds/move_deny.wav' }), move_deny: SoundInstance.new({ path: 'sounds/move_deny.wav' }),
rotate: SoundInstance.new({ path: 'sounds/rotate.wav' }), rotate: SoundInstance.new({ path: 'sounds/rotate.wav' }),
gameover: SoundInstance.new({ path: 'sounds/gameover.wav' }),
train_stop: SoundInstance.new({ path: 'sounds/train_stop.wav' }), train_stop: SoundInstance.new({ path: 'sounds/train_stop.wav' }),
train_stop2: SoundInstance.new({ path: 'sounds/train_stop2.wav' }), train_stop2: SoundInstance.new({ path: 'sounds/train_stop2.wav' }),
train_leave: SoundInstance.new({ path: 'sounds/train_leave.wav' }), train_leave: SoundInstance.new({ path: 'sounds/train_leave.wav' }),
horn: SoundInstance.new({ path: 'sounds/horn.wav' }),
chime: SoundInstance.new({ path: 'sounds/please_stand_clear.wav' }), chime: SoundInstance.new({ path: 'sounds/please_stand_clear.wav' }),
ambient1: SoundInstance.new({ path: 'sounds/announcement.ogg', loop: false }), ambient1: SoundInstance.new({ path: 'sounds/announcement.ogg', loop: false }),
ambient2: SoundInstance.new({ path: 'sounds/announcement2.ogg', loop: false }), ambient2: SoundInstance.new({ path: 'sounds/announcement2.ogg', loop: false }),

BIN
sounds/fourlines.wav Normal file

Binary file not shown.

BIN
sounds/gameover.wav Normal file

Binary file not shown.

BIN
sounds/horn.wav Normal file

Binary file not shown.

View file

@ -15,6 +15,7 @@ module Sprite
red: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/red.png' }), red: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/red.png' }),
green: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/green.png' }), green: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/green.png' }),
blue: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/blue.png' }), blue: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/blue.png' }),
cyan: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/cyan.png' }),
yellow: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/yellow.png' }), yellow: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/yellow.png' }),
indigo: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/indigo.png' }), indigo: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/indigo.png' }),
violet: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/violet.png' }), violet: SpriteInstance.new({ w: 176, h: 148, path: 'sprites/box/violet.png' }),

BIN
sprites/box/cyan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB