mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 07:32:35 +00:00
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:
@@ -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/))
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 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.)
|
||||||
|
|||||||
11
assets/base/shared/sound/master.yaml
Normal file
11
assets/base/shared/sound/master.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
playlists:
|
||||||
|
- menus:
|
||||||
|
- nighttime:
|
||||||
|
- daytime:
|
||||||
|
music:
|
||||||
|
sounds:
|
||||||
|
-
|
||||||
|
name: shield_regen
|
||||||
|
type: sfx
|
||||||
|
path: sfx/shield_regen.wav
|
||||||
BIN
assets/base/shared/sound/sfx/shield_regen.wav
Normal file
BIN
assets/base/shared/sound/sfx/shield_regen.wav
Normal file
Binary file not shown.
125
i-mic-fps.rb
125
i-mic-fps.rb
@@ -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
|
||||||
|
|||||||
53
lib/managers/sound_manager.rb
Normal file
53
lib/managers/sound_manager.rb
Normal 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
|
||||||
@@ -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
19
lib/sound_effect.rb
Normal 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
|
||||||
32
lib/sound_effects/fade_in.rb
Normal file
32
lib/sound_effects/fade_in.rb
Normal 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
|
||||||
22
lib/sound_effects/fade_in_and_out.rb
Normal file
22
lib/sound_effects/fade_in_and_out.rb
Normal 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
|
||||||
9
lib/sound_effects/fade_out.rb
Normal file
9
lib/sound_effects/fade_out.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class IMICFPS
|
||||||
|
class SoundEffect
|
||||||
|
class FadeOut < FadeIn
|
||||||
|
def ratio
|
||||||
|
1.0 - super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
25
lib/sound_effects/shield_regen.rb
Normal file
25
lib/sound_effects/shield_regen.rb
Normal 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
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user