Added require_all method to replace explicitly requiring every source file, added SoundManager and sound effects, added sound for shield/health regen

This commit is contained in:
2020-05-08 19:03:45 -05:00
parent bc695df4a1
commit e3a2c9abe0
13 changed files with 197 additions and 106 deletions

View File

@@ -1,7 +1,7 @@
# I-MIC FPS # I-MIC FPS
Creating a multiplayer first-person-shooter in pure Ruby; Using C extensions only for Rendering, Sound, and Input. ([Gosu](https://libgosu.org) and [opengl-bindings](https://github.com/vaiorabbit/ruby-opengl/)) Creating a multiplayer first-person-shooter in pure Ruby; Using C extensions only for Rendering, Sound, and Input. ([Gosu](https://libgosu.org) and [opengl-bindings](https://github.com/vaiorabbit/ruby-opengl/))
![](https://raw.githubusercontent.com/cyberarm/i-mic-fps/master/screenshots/screenshot-game.png) ![screenshot](https://raw.githubusercontent.com/cyberarm/i-mic-fps/master/screenshots/screenshot-game.png)
## Using ## Using
Requires a Ruby runtime that supports the gosu and opengl-bindings C-extensions (truffleruby 1.0.0-rc12 did not work when tested. Rubinus was not tested.) Requires a Ruby runtime that supports the gosu and opengl-bindings C-extensions (truffleruby 1.0.0-rc12 did not work when tested. Rubinus was not tested.)

View File

@@ -0,0 +1,11 @@
---
playlists:
- menus:
- nighttime:
- daytime:
music:
sounds:
-
name: shield_regen
type: sfx
path: sfx/shield_regen.wav

Binary file not shown.

View File

@@ -20,118 +20,35 @@ end
Dir.chdir(File.dirname(__FILE__)) Dir.chdir(File.dirname(__FILE__))
require_relative "lib/ext/numeric"
require_relative "lib/ext/load_opengl"
include CyberarmEngine include CyberarmEngine
include OpenGL include OpenGL
include GLU include GLU
require_relative "lib/version" def require_all(directory)
require_relative "lib/constants" files = Dir["#{directory}/**/*.rb"].sort!
require_relative "lib/common_methods"
require_relative "lib/trees/aabb_tree_debug" begin
require_relative "lib/trees/aabb_tree" failed = []
require_relative "lib/trees/aabb_node" first_name_error = nil
require_relative "lib/managers/input_mapper" files.each do |file|
require_relative "lib/managers/entity_manager" begin
require_relative "lib/managers/light_manager" require_relative file
require_relative "lib/managers/network_manager" rescue NameError => name_error
require_relative "lib/managers/collision_manager" failed << file
require_relative "lib/managers/physics_manager" first_name_error ||= name_error
end
end
require_relative "lib/renderer/renderer" if failed.size == files.size
require_relative "lib/renderer/g_buffer" raise first_name_error
require_relative "lib/renderer/opengl_renderer" else
require_relative "lib/renderer/bounding_box_renderer" files = failed
end
require_relative "lib/states/game_state" end until( failed.empty? )
require_relative "lib/ui/menu"
require_relative "lib/ui/command"
require_relative "lib/ui/subcommand"
Dir.glob("#{IMICFPS::GAME_ROOT_PATH}/lib/ui/commands/*.rb").each do |cmd|
require_relative cmd
end end
require_relative "lib/ui/console"
require_relative "lib/ui/menus/main_menu"
require_relative "lib/ui/menus/settings_menu"
require_relative "lib/ui/menus/extras_menu"
require_relative "lib/ui/menus/multiplayer_menu"
require_relative "lib/ui/menus/level_select_menu"
require_relative "lib/ui/menus/game_pause_menu"
require_relative "lib/states/game_states/boot" require_all "lib"
require_relative "lib/states/game_states/close"
require_relative "lib/states/game_states/game"
require_relative "lib/states/game_states/loading_state"
require_relative "lib/hud"
require_relative "lib/hud/widget"
require_relative "lib/hud/widgets/ammo"
require_relative "lib/hud/widgets/radar"
require_relative "lib/hud/widgets/health"
require_relative "lib/subscription"
require_relative "lib/publisher"
require_relative "lib/event"
require_relative "lib/event_handler"
require_relative "lib/event_handlers/input"
require_relative "lib/event_handlers/entity_moved"
require_relative "lib/event_handlers/entity_lifecycle"
require_relative "lib/scripting"
require_relative "lib/scripting/sandbox"
require_relative "lib/scripting/whitelist"
require_relative "lib/component"
require_relative "lib/components/building"
require_relative "lib/game_objects/entity"
require_relative "lib/game_objects/light"
require_relative "lib/game_objects/particle_emitter"
require_relative "lib/game_objects/camera"
require_relative "lib/game_objects/entities/player"
require_relative "lib/game_objects/entities/skydome"
require_relative "lib/game_objects/entities/terrain"
require_relative "lib/texture"
require_relative "lib/model"
require_relative "lib/model_cache"
require_relative "lib/model/parser"
require_relative "lib/model/model_object"
require_relative "lib/model/material"
require_relative "lib/model/parsers/wavefront_parser"
require_relative "lib/model/parsers/collada_parser"
require_relative "lib/map_parser"
require_relative "lib/manifest"
require_relative "lib/map"
require_relative "lib/scene"
require_relative "lib/scenes/turn_table"
require_relative "lib/crosshair"
require_relative "lib/demo"
require_relative "lib/networking/director"
require_relative "lib/networking/packet_handler"
require_relative "lib/networking/client"
require_relative "lib/networking/server"
require_relative "lib/networking/connection"
require_relative "lib/networking/backends/memory_server"
require_relative "lib/networking/backends/memory_connection"
require_relative "lib/overlay"
require_relative "lib/window"
require_relative "lib/tools/asset_viewer"
require_relative "lib/tools/map_editor"
# Don't launch game if IMICFPS_SERVER_MODE is defined # Don't launch game if IMICFPS_SERVER_MODE is defined
# or if game is being packaged # or if game is being packaged
@@ -167,4 +84,4 @@ unless prevent_launch?[0]
end end
else else
puts prevent_launch?[1] puts prevent_launch?[1]
end end

View File

@@ -0,0 +1,53 @@
class IMICFPS
module SoundManager
extend CyberarmEngine::Common
MASTERS = {}
EFFECTS = []
PLAYLISTS = {}
def self.master_volume
1.0
end
def self.music_volume
0.25 * master_volume
end
def self.sfx_volume
0.5 * master_volume
end
def self.load_master(package)
return if MASTERS.dig(package)
yaml = YAML.load_file( "#{IMICFPS.assets_path}/#{package}/shared/sound/master.yaml" )
MASTERS[package] = yaml
end
def self.sound(package, name)
if data = sound_data(package, name.to_s)
get_sample("#{IMICFPS.assets_path}/#{package}/shared/sound/#{data["path"]}")
else
raise "Missing sound: '#{name}' in package '#{package}'"
end
end
def self.sound_data(package, name)
load_master(package)
if master = MASTERS.dig(package)
return master["sounds"].find { |s| s["name"] == name }
end
return nil
end
def self.sound_effect(klass, options)
EFFECTS << klass.new(options)
end
def self.update
EFFECTS.each { |e| e.update; EFFECTS.delete(e) if e.done? }
end
end
end

View File

@@ -29,7 +29,7 @@ class IMICFPS
if window.config.get(:options, :fps) if window.config.get(:options, :fps)
create_slot "FPS: #{Gosu.fps}" create_slot "FPS: #{Gosu.fps}"
create_slot "Frame time: #{Gosu.milliseconds - window.delta_time}ms" if window.config.get(:debug_options, :stats) create_slot "Frame time: #{(Gosu.milliseconds - window.delta_time).to_s.rjust(3, "0")}ms" if window.config.get(:debug_options, :stats)
end end
if window.config.get(:debug_options, :stats) if window.config.get(:debug_options, :stats)

19
lib/sound_effect.rb Normal file
View File

@@ -0,0 +1,19 @@
class IMICFPS
class SoundEffect
attr_reader :sound, :options
def initialize(options = {})
raise "expected Hash, got #{options.class}" unless options.is_a?(Hash)
@options = options
raise "sound not specified!" unless @options[:sound]
setup
end
def setup
end
def update
end
end
end

View File

@@ -0,0 +1,32 @@
class IMICFPS
class SoundEffect
class FadeIn < SoundEffect
def setup
@start_time = Gosu.milliseconds
@duration = @options[:duration] # in milliseconds
@initial_volume = @options[:volume] ? @options[:volume] : 0.0
@sound = @options[:sound]
raise "duration not specified!" unless @duration
@channel = @sound.play(calculate_volume)
end
def ratio
(Gosu.milliseconds - @start_time.to_f) / @duration
end
def calculate_volume
volume = (SoundManager.sfx_volume - @initial_volume) * ratio
end
def update
@channel.volume = calculate_volume
end
def done?
(Gosu.milliseconds - @start_time.to_f) / @duration >= 1.0
end
end
end
end

View File

@@ -0,0 +1,22 @@
class IMICFPS
class SoundEffect
class FadeInAndOut < FadeIn
def setup
@hang_time = @options[:hang_time] ? @options[:hang_time] : 0.0
super
end
# TODO: Handle hang time
def ratio
r = super
if r < 0.5
r * 2
else
2.0 - (r * 2)
end
end
end
end
end

View File

@@ -0,0 +1,9 @@
class IMICFPS
class SoundEffect
class FadeOut < FadeIn
def ratio
1.0 - super
end
end
end
end

View File

@@ -0,0 +1,25 @@
class IMICFPS
class SoundEffect
class ShieldRegen < SoundEffect
def setup
@sound = SoundManager.sound("base", :shield_regen)
@player = @options[:player]
@channel = @sound.play(0.0, 0.0, true)
end
def ratio
@player.health
end
def update
@channel.speed = 0.5 + ratio / 2
@channel.volume = 1.0 - ratio / 2
end
def done?
ratio >= 1.0
end
end
end
end

View File

@@ -7,6 +7,7 @@ class IMICFPS
@start_time = Gosu.milliseconds @start_time = Gosu.milliseconds
@time_to_live = 3_000 @time_to_live = 3_000
# SoundManager.sound_effect(SoundEffect::FadeIn, sound: SoundManager.sound("base", :shield_regen), duration: 3_000.0)
window.needs_cursor = false window.needs_cursor = false
end end
@@ -32,6 +33,7 @@ class IMICFPS
@title.draw @title.draw
fill(Gosu::Color.rgba(0,0,0, 255 * (1.2 - fraction_left)))
end end
end end

View File

@@ -68,6 +68,7 @@ class IMICFPS
@console.update if @show_console @console.update if @show_console
@overlay.update @overlay.update
SoundManager.update
@number_of_vertices = 0 @number_of_vertices = 0
@delta_time = Gosu.milliseconds @delta_time = Gosu.milliseconds