refactored sound and music
This commit is contained in:
parent
6b3ac755de
commit
4f81bab8ef
15 changed files with 326 additions and 65 deletions
|
@ -9,6 +9,9 @@ Metrics/AbcSize:
|
|||
# 10-line methods are /way/ too short
|
||||
Metrics/MethodLength:
|
||||
Max: 100
|
||||
# As are 100 line classes
|
||||
Metrics/ClassLength:
|
||||
Max: 1000
|
||||
# Yeah, I've got constants with mutables in them. Doesn't bother me.
|
||||
Style/MutableConstant:
|
||||
Enabled: false
|
||||
|
|
|
@ -5,15 +5,19 @@ require 'lib/coalesce.rb'
|
|||
|
||||
# then, some basic classes required for lists of assets
|
||||
require 'app/sprite_instance.rb'
|
||||
require 'app/sound_instance.rb'
|
||||
|
||||
# then, asset lists
|
||||
require 'sprites/_list.rb'
|
||||
require 'sounds/_list.rb'
|
||||
require 'music/_list.rb'
|
||||
|
||||
# then, utility classes
|
||||
require 'app/input.rb'
|
||||
require 'app/sprite.rb'
|
||||
require 'app/util.rb'
|
||||
require 'app/sound.rb'
|
||||
require 'app/music.rb'
|
||||
|
||||
require 'app/constants.rb'
|
||||
require 'app/menu.rb'
|
||||
|
|
|
@ -55,7 +55,7 @@ module Menu
|
|||
|
||||
if args.inputs.mouse.up && args.inputs.mouse.inside_rect?(button_border)
|
||||
o = options.find { |o| o[:key] == l[:key] }
|
||||
play_sfx(args, :menu)
|
||||
Sound.play(args, :menu)
|
||||
o[:on_select].call(args) if o
|
||||
end
|
||||
end
|
||||
|
@ -75,7 +75,7 @@ module Menu
|
|||
menu_state.hold_delay -= 1
|
||||
|
||||
if menu_state.hold_delay <= 0
|
||||
play_sfx(args, :menu)
|
||||
Sound.play(args, :menu)
|
||||
index = menu_state.current_option_i
|
||||
if move == :up
|
||||
index -= 1
|
||||
|
@ -94,7 +94,7 @@ module Menu
|
|||
end
|
||||
|
||||
if primary_down?(args.inputs)
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
options[menu_state.current_option_i][:on_select].call(args)
|
||||
end
|
||||
end
|
||||
|
|
66
app/music.rb
Normal file
66
app/music.rb
Normal file
|
@ -0,0 +1,66 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Module for managing and interacting with music.
|
||||
module Music
|
||||
class << self
|
||||
def queue
|
||||
@queue ||= {}
|
||||
@queue
|
||||
end
|
||||
|
||||
def queue_up(key, channel = 0)
|
||||
@queue[channel] ||= []
|
||||
@queue[channel].push(MUSIC.fetch(key))
|
||||
end
|
||||
|
||||
def for(key)
|
||||
MUSIC.fetch(key)
|
||||
end
|
||||
|
||||
def play(args, key, opts = { channel: 0 })
|
||||
MUSIC.fetch(key).play_music(args, opts)
|
||||
end
|
||||
|
||||
def stopped(args, channel = 0)
|
||||
!args.audio.key?("MUSIC_CHANNEL_#{channel}")
|
||||
end
|
||||
|
||||
def paused(args, channel = 0)
|
||||
args.audio["MUSIC_CHANNEL_#{channel}"].paused
|
||||
end
|
||||
|
||||
def stop(args, channel = 0)
|
||||
args.audio.delete("MUSIC_CHANNEL_#{channel}")
|
||||
end
|
||||
|
||||
def pause(args, channel = 0)
|
||||
args.audio["MUSIC_CHANNEL_#{channel}"].paused = true
|
||||
end
|
||||
|
||||
def resume(args, channel = 0)
|
||||
args.audio["MUSIC_CHANNEL_#{channel}"].paused = false
|
||||
end
|
||||
|
||||
def set_volume(args, volume, channel = 0)
|
||||
args.audio["MUSIC_CHANNEL_#{channel}"].gain = volume
|
||||
end
|
||||
|
||||
def tick(args)
|
||||
queue.each do |channel, value|
|
||||
unless value.empty?
|
||||
if args.audio["MUSIC_CHANNEL_#{channel}"]
|
||||
puts "THERE'S MUSIC CURRENTLY PLAYING #{args.audio["MUSIC_CHANNEL_#{channel}"]}"
|
||||
if args.audio["MUSIC_CHANNEL_#{channel}"].looping
|
||||
puts "CANCEL THE LOOP ON CURRENT MUSIC"
|
||||
args.audio["MUSIC_CHANNEL_#{channel}"].looping = false
|
||||
end
|
||||
else
|
||||
puts "PLAY THAT FUNKY MUSIC! #{value}"
|
||||
value.shift.play_music(args, { channel: channel, gain: args.state.setting.music ? 0.8 : 0.0 })
|
||||
puts "Now, the queue is #{value}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -57,7 +57,7 @@ class CubeTubeGame
|
|||
@lines_to_clear = []
|
||||
@line_clear_timer = 0
|
||||
|
||||
@music_queue = []
|
||||
@current_music = :music1
|
||||
|
||||
reset_game
|
||||
end
|
||||
|
@ -87,7 +87,8 @@ class CubeTubeGame
|
|||
end
|
||||
end
|
||||
|
||||
@music_queue = [:music1, :music2]
|
||||
@current_music = :music1
|
||||
Music.play(@args, @current_music)
|
||||
end
|
||||
|
||||
def render_grid_border x, y, w, h, color
|
||||
|
@ -257,6 +258,16 @@ class CubeTubeGame
|
|||
end
|
||||
end
|
||||
|
||||
def change_music
|
||||
if @current_music == :music1
|
||||
@current_music = :music2
|
||||
else
|
||||
@current_music = :music1
|
||||
end
|
||||
queue = Music.queue
|
||||
Music.queue_up(@current_music)
|
||||
end
|
||||
|
||||
def plant_current_piece
|
||||
rows_to_check = []
|
||||
|
||||
|
@ -288,21 +299,21 @@ class CubeTubeGame
|
|||
@lines += 1
|
||||
@line_clear_timer = 70
|
||||
if (@lines%10).floor == 0
|
||||
@level += 1
|
||||
@args.audio[:music].looping = false
|
||||
@level += 1
|
||||
change_music
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
select_next_piece
|
||||
if @lines_to_clear.empty?
|
||||
play_sfx(@args, :drop)
|
||||
Sound.play(@args, :drop)
|
||||
if current_piece_colliding
|
||||
@gameover = true
|
||||
stop_music(@args)
|
||||
Music.stop(@args)
|
||||
end
|
||||
else
|
||||
play_sfx(@args, :clear)
|
||||
Sound.play(@args, :clear)
|
||||
@current_speed = get_speed
|
||||
end
|
||||
|
||||
|
@ -330,7 +341,7 @@ class CubeTubeGame
|
|||
end
|
||||
|
||||
def rotate_current_piece_left
|
||||
play_sfx(@args, :rotate)
|
||||
Sound.play(@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
|
||||
|
@ -338,7 +349,7 @@ class CubeTubeGame
|
|||
end
|
||||
|
||||
def rotate_current_piece_right
|
||||
play_sfx(@args, :rotate)
|
||||
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)
|
||||
|
@ -379,13 +390,8 @@ class CubeTubeGame
|
|||
return
|
||||
end
|
||||
|
||||
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)
|
||||
unless Music.stopped(@args)
|
||||
Music.resume(@args) if Music.paused(@args)
|
||||
end
|
||||
|
||||
if @line_clear_timer.positive?
|
||||
|
@ -401,7 +407,7 @@ class CubeTubeGame
|
|||
@grid[i][0] = 0
|
||||
end
|
||||
end
|
||||
play_sfx(@args, :drop)
|
||||
Sound.play(@args, :drop)
|
||||
@lines_to_clear = []
|
||||
end
|
||||
return
|
||||
|
@ -411,26 +417,26 @@ class CubeTubeGame
|
|||
if @current_piece_x > 0
|
||||
@current_piece_x -= 1
|
||||
if current_piece_colliding
|
||||
play_sfx(@args, :move_deny)
|
||||
Sound.play(@args, :move_deny)
|
||||
@current_piece_x += 1
|
||||
else
|
||||
play_sfx(@args, :move)
|
||||
Sound.play(@args, :move)
|
||||
end
|
||||
else
|
||||
play_sfx(@args, :move_deny)
|
||||
Sound.play(@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)
|
||||
Sound.play(@args, :move_deny)
|
||||
@current_piece_x -= 1
|
||||
else
|
||||
play_sfx(@args, :move)
|
||||
Sound.play(@args, :move)
|
||||
end
|
||||
else
|
||||
play_sfx(@args, :move_deny)
|
||||
Sound.play(@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
|
||||
|
|
|
@ -27,7 +27,7 @@ module Scene
|
|||
end
|
||||
|
||||
def pause(args)
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
return Scene.push(args, :paused, reset: true)
|
||||
end
|
||||
|
||||
|
|
|
@ -28,12 +28,10 @@ module Scene
|
|||
|
||||
Menu.tick(args, :paused, options)
|
||||
|
||||
if args.audio[:music] && !args.audio[:music].paused
|
||||
pause_music(args)
|
||||
end
|
||||
Music.pause(args) unless Music.stopped(args)
|
||||
|
||||
if secondary_down?(args.inputs)
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
options.find { |o| o[:key] == :resume }[:on_select].call(args)
|
||||
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ module Scene
|
|||
on_select: -> (args) do
|
||||
GameSetting.save_after(args) do |args|
|
||||
args.state.setting.music = !args.state.setting.music
|
||||
set_music_vol(args)
|
||||
Music.set_volume(args, args.state.setting.music ? 0.8 : 0.0)
|
||||
end
|
||||
end
|
||||
},
|
||||
|
@ -50,7 +50,7 @@ module Scene
|
|||
Menu.tick(args, :settings, options)
|
||||
|
||||
if secondary_down?(args.inputs)
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
options.find { |o| o[:key] == :back }[:on_select].call(args)
|
||||
end
|
||||
|
||||
|
|
83
app/sound.rb
83
app/sound.rb
|
@ -1,35 +1,62 @@
|
|||
# play a sound effect. the file in sounds/ must match the key name. ex:
|
||||
# play_sfx(args, :select)
|
||||
def play_sfx(args, key)
|
||||
if args.state.setting.sfx
|
||||
args.outputs.sounds << "sounds/#{key}.wav"
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Module for managing and interacting with sounds.
|
||||
module Sound
|
||||
class << self
|
||||
def for(key)
|
||||
SOUNDS.fetch(key)
|
||||
end
|
||||
|
||||
def play(args, key, opts = {})
|
||||
SOUNDS.fetch(key).play(args, opts)
|
||||
end
|
||||
|
||||
def stop(args, key)
|
||||
SOUNDS.fetch(key).stop(args)
|
||||
end
|
||||
|
||||
def pause(args, key)
|
||||
SOUNDS.fetch(key).pause(args)
|
||||
end
|
||||
|
||||
def resume(args, key)
|
||||
SOUNDS.fetch(key).resume(args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# play the specified music track, the key must correspond to the
|
||||
# `sounds/#{key}.ogg` file naming scheme.
|
||||
def play_music(args, key)
|
||||
args.audio[:music] = { input: "sounds/#{key}.ogg", looping: true, }
|
||||
set_music_vol(args)
|
||||
end
|
||||
# # play a sound effect. the file in sounds/ must match the key name. ex:
|
||||
# # play_sfx(args, :select)
|
||||
# def play_sfx(args, key)
|
||||
# if args.state.setting.sfx
|
||||
# args.outputs.sounds << "sounds/#{key}.wav"
|
||||
# end
|
||||
# end
|
||||
|
||||
# sets the music vol based on whether or not music is enabled or disabled
|
||||
def set_music_vol(args)
|
||||
vol = args.state.setting.music ? 0.8 : 0.0
|
||||
args.audio[:music]&.gain = vol
|
||||
end
|
||||
# # play the specified music track, the key must correspond to the
|
||||
# # `sounds/#{key}.ogg` file naming scheme.
|
||||
# def play_music(args, key)
|
||||
# args.audio[:music] = { input: "sounds/#{key}.ogg", looping: true, }
|
||||
# set_music_vol(args)
|
||||
# end
|
||||
|
||||
# pause the currently playing music track
|
||||
def pause_music(args)
|
||||
args.audio[:music].paused = true
|
||||
end
|
||||
# # sets the music vol based on whether or not music is enabled or disabled
|
||||
# def set_music_vol(args)
|
||||
# vol = args.state.setting.music ? 0.8 : 0.0
|
||||
# args.audio[:music]&.gain = vol
|
||||
# end
|
||||
|
||||
# pause the current music track
|
||||
def resume_music(args)
|
||||
args.audio[:music].paused = false
|
||||
end
|
||||
# # pause the currently playing music track
|
||||
# def pause_music(args)
|
||||
# args.audio[:music].paused = true
|
||||
# end
|
||||
|
||||
# stop the currently playing music track
|
||||
def stop_music(args)
|
||||
args.audio.delete(:music)
|
||||
end
|
||||
# # pause the current music track
|
||||
# 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
|
||||
|
|
134
app/sound_instance.rb
Normal file
134
app/sound_instance.rb
Normal file
|
@ -0,0 +1,134 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# class to represent sound files
|
||||
class SoundInstance
|
||||
def initialize(opts)
|
||||
@input = opts[:input]._? opts[:path]
|
||||
@key = opts[:key]._? @input
|
||||
@x = opts[:x]._? 0.0
|
||||
@y = opts[:y]._? 0.0
|
||||
@z = opts[:z]._? 0.0
|
||||
@gain = opts[:gain]._? opts[:volume]._? 1.0
|
||||
@pitch = opts[:pitch]._? 1.0
|
||||
@paused = opts[:paused]._? false
|
||||
@looping = opts[:looping]._? false
|
||||
end
|
||||
|
||||
attr_reader :key, :input, :x, :y, :z, :gain, :pitch, :paused, :looping
|
||||
|
||||
def input=(input)
|
||||
args.audio[@key].input = input if args.audio[@key]
|
||||
@input = input
|
||||
end
|
||||
|
||||
def x=(xval)
|
||||
args.audio[@key].x = xval if args.audio[@key]
|
||||
@x = xval
|
||||
end
|
||||
|
||||
def y=(yval)
|
||||
args.audio[@key].y = yval if args.audio[@key]
|
||||
@y = yval
|
||||
end
|
||||
|
||||
def z=(zval)
|
||||
args.audio[@key].z = zval if args.audio[@key]
|
||||
@z = zval
|
||||
end
|
||||
|
||||
def xyz(xval, yval, zval)
|
||||
if args.audio[@key]
|
||||
args.audio[@key].x = xval
|
||||
args.audio[@key].y = yval
|
||||
args.audio[@key].z = zval
|
||||
end
|
||||
@x = xval
|
||||
@y = yval
|
||||
@z = zval
|
||||
end
|
||||
|
||||
def xyz=(xyz=[])
|
||||
xyz(xyz[0], xyz[1], xyz[2])
|
||||
end
|
||||
|
||||
def gain=(gain)
|
||||
args.audio[@key].gain = gain if args.audio[@key]
|
||||
@gain = gain
|
||||
end
|
||||
|
||||
def pitch=(pitch)
|
||||
args.audio[@key].pitch = pitch if args.audio[@key]
|
||||
@pitch = pitch
|
||||
end
|
||||
|
||||
def paused=(paused)
|
||||
args.audio[@key].paused = paused if args.audio[@key]
|
||||
@paused = paused
|
||||
end
|
||||
|
||||
def looping=(looping)
|
||||
args.audio[@key].looping = looping if args.audio[@key]
|
||||
@looping = looping
|
||||
end
|
||||
|
||||
def playtime
|
||||
args.audio[@key].playtime._?(0.0)
|
||||
end
|
||||
|
||||
def playtime=(playtime)
|
||||
args.audio[@key].playtime = playtime
|
||||
end
|
||||
|
||||
# convenience getter for 'path' (@input)
|
||||
def path
|
||||
@input
|
||||
end
|
||||
|
||||
# convenience setter for 'path' (@input)
|
||||
def path=(path)
|
||||
input(path)
|
||||
end
|
||||
|
||||
# convenience getter for 'volume' (@gain)
|
||||
def volume
|
||||
@gain
|
||||
end
|
||||
|
||||
# convenience setter for 'volume' (@gain)
|
||||
def volume=(volume)
|
||||
gain(volume)
|
||||
end
|
||||
|
||||
def play(args, opts = {})
|
||||
obj = {
|
||||
input: opts[:input]._?(opts[:path]._?(@input)),
|
||||
x: opts[:x]._?(@x),
|
||||
y: opts[:y]._?(@y),
|
||||
z: opts[:z]._?(@z),
|
||||
gain: opts[:gain]._?(opts[:volume]._?(@gain)),
|
||||
pitch: opts[:pitch]._?(@pitch),
|
||||
paused: opts[:paused]._?(@paused),
|
||||
looping: opts[:looping]._?(@looping),
|
||||
playtime: opts[:playtime]._?(0.0)
|
||||
}
|
||||
args.audio[@key] = obj
|
||||
end
|
||||
|
||||
def play_music(args, opts = { channel: 0 })
|
||||
@looping = true
|
||||
@key = "MUSIC_CHANNEL_#{opts[:channel]}"
|
||||
play(args, opts)
|
||||
end
|
||||
|
||||
def stop(args)
|
||||
args.audio.delete(@key)
|
||||
end
|
||||
|
||||
def pause(args)
|
||||
args.audio[@key].paused = true
|
||||
end
|
||||
|
||||
def resume(args)
|
||||
args.audio[@key].paused = false
|
||||
end
|
||||
end
|
10
app/tick.rb
10
app/tick.rb
|
@ -16,6 +16,8 @@ def tick(args)
|
|||
track_swipe(args) if mobile?
|
||||
|
||||
Scene.send("tick_#{args.state.scene}", args)
|
||||
|
||||
Music.tick(args)
|
||||
|
||||
debug_tick(args)
|
||||
rescue FinishTick
|
||||
|
@ -36,23 +38,23 @@ def debug_tick(args)
|
|||
|
||||
|
||||
if args.inputs.keyboard.key_down.zero
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
args.state.render_debug_details = !args.state.render_debug_details
|
||||
end
|
||||
|
||||
if args.inputs.keyboard.key_down.i
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
Sprite.reset_all(args)
|
||||
args.gtk.notify!("Sprites reloaded")
|
||||
end
|
||||
|
||||
if args.inputs.keyboard.key_down.r
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
$gtk.reset
|
||||
end
|
||||
|
||||
if args.inputs.keyboard.key_down.m
|
||||
play_sfx(args, :select)
|
||||
Sound.play(args, :select)
|
||||
args.state.simulate_mobile = !args.state.simulate_mobile
|
||||
msg = if args.state.simulate_mobile
|
||||
"Mobile simulation on"
|
||||
|
|
8
music/_list.rb
Normal file
8
music/_list.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Music
|
||||
MUSIC = {
|
||||
music1: SoundInstance.new({ path: 'music/music1.ogg', looping: true }),
|
||||
music2: SoundInstance.new({ path: 'music/music2.ogg', looping: true })
|
||||
}
|
||||
end
|
13
sounds/_list.rb
Normal file
13
sounds/_list.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Sound
|
||||
SOUNDS = {
|
||||
menu: SoundInstance.new({ path: 'sounds/menu.wav' }),
|
||||
select: SoundInstance.new({ path: 'sounds/select.wav' }),
|
||||
clear: SoundInstance.new({ path: 'sounds/clear.wav' }),
|
||||
drop: SoundInstance.new({ path: 'sounds/drop.wav' }),
|
||||
move: SoundInstance.new({ path: 'sounds/move.wav' }),
|
||||
move_deny: SoundInstance.new({ path: 'sounds/move_deny.wav' }),
|
||||
rotate: SoundInstance.new({ path: 'sounds/rotate.wav' })
|
||||
}
|
||||
end
|
Loading…
Reference in a new issue