Refactor weapon system: implement WeaponHandler to manage LorentzField and prepare for additional weapons; update shader to incorporate lorentz_field uniform for visual effects.
This commit is contained in:
+11
-6
@@ -1,12 +1,12 @@
|
|||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
uniform vec2 player_pos;
|
|
||||||
uniform vec2 resolution; // 720x480
|
uniform vec2 resolution; // 720x480
|
||||||
uniform vec2 offset; // padding in pixels
|
uniform vec2 offset; // padding in pixels
|
||||||
uniform float scale; // scale factor
|
uniform float scale; // scale factor
|
||||||
uniform vec2 torch_lights[32];
|
uniform vec2 torch_lights[32];
|
||||||
uniform int num_torches;
|
uniform int num_torches;
|
||||||
uniform float time_sec;
|
uniform float time_sec;
|
||||||
|
uniform float lorentz_field;
|
||||||
|
|
||||||
// External snippet
|
// External snippet
|
||||||
// Simplex 2D noise
|
// Simplex 2D noise
|
||||||
@@ -49,8 +49,14 @@ void main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float p_i_radius = 100.0;
|
// tint
|
||||||
float p_o_radius = 340.0;
|
vec3 lf_color = vec3(3.0/255.0, 9.0/255.0, 42.0/255.0);
|
||||||
|
vec3 tint = mix(vec3(0.0), lf_color, lorentz_field);
|
||||||
|
|
||||||
|
// radii
|
||||||
|
float p_i_radius = mix(100.0, 120.0, lorentz_field);
|
||||||
|
float p_o_radius = mix(340.0, 235.0, lorentz_field);
|
||||||
|
|
||||||
float t_i_radius = 10.0;
|
float t_i_radius = 10.0;
|
||||||
float t_o_radius = 160.0;
|
float t_o_radius = 160.0;
|
||||||
|
|
||||||
@@ -84,11 +90,10 @@ void main() {
|
|||||||
light_strength = clamp(light_strength, 0.0, 1.0);
|
light_strength = clamp(light_strength, 0.0, 1.0);
|
||||||
|
|
||||||
// Noise
|
// Noise
|
||||||
vec2 world_coord = (virtual_coord + player_pos - resolution / 2.0) * 0.005;
|
float noise = (snoise(virtual_coord / resolution * 3.0 + vec2(time_sec * 0.25, 0)) + 1.0) / 2.0;
|
||||||
float noise = (snoise(world_coord + vec2(time_sec / 5.0, time_sec / 6.0)) + 1.0) / 2.0;
|
|
||||||
|
|
||||||
float t = 1.0 - light_strength;
|
float t = 1.0 - light_strength;
|
||||||
float alpha = clamp(t * (1.0 + noise), 0.0, 1.0);
|
float alpha = clamp(t * (1.0 + noise), 0.0, 1.0);
|
||||||
|
|
||||||
gl_FragColor = vec4(0.0, 0.0, 0.0, alpha);
|
gl_FragColor = vec4(tint, alpha);
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ require_relative 'maze'
|
|||||||
require_relative 'hud/layer'
|
require_relative 'hud/layer'
|
||||||
require_relative 'props/handler'
|
require_relative 'props/handler'
|
||||||
require_relative 'enemy/handler'
|
require_relative 'enemy/handler'
|
||||||
|
require_relative 'weapons/handler'
|
||||||
require_relative 'character'
|
require_relative 'character'
|
||||||
|
|
||||||
require 'perlin'
|
require 'perlin'
|
||||||
@@ -17,6 +18,7 @@ class Game < Scene
|
|||||||
@character = Character.new
|
@character = Character.new
|
||||||
@enemies = EnemyHandler.new
|
@enemies = EnemyHandler.new
|
||||||
@props = PropsHandler.new
|
@props = PropsHandler.new
|
||||||
|
@weapons = WeaponHandler.new
|
||||||
|
|
||||||
@hud = HUDLayer.new
|
@hud = HUDLayer.new
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ class Game < Scene
|
|||||||
@props.draw
|
@props.draw
|
||||||
$bus.emit(:shade) if $bus.get(:settings, :fog)
|
$bus.emit(:shade) if $bus.get(:settings, :fog)
|
||||||
@hud.draw
|
@hud.draw
|
||||||
|
@weapons.draw
|
||||||
draw_debug! if $bus.get(:settings, :debug)
|
draw_debug! if $bus.get(:settings, :debug)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -71,6 +74,7 @@ class Game < Scene
|
|||||||
@character.update(dt)
|
@character.update(dt)
|
||||||
@enemies.update(dt)
|
@enemies.update(dt)
|
||||||
@props.update(dt)
|
@props.update(dt)
|
||||||
|
@weapons.update(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_down(id, pos)
|
def button_down(id, pos)
|
||||||
@@ -78,5 +82,8 @@ class Game < Scene
|
|||||||
|
|
||||||
return if @hud.button_down(id, pos)
|
return if @hud.button_down(id, pos)
|
||||||
return if @props.button_down(id, pos)
|
return if @props.button_down(id, pos)
|
||||||
|
#return if @weapons.button_down(id, pos)
|
||||||
|
|
||||||
|
#@character.button_down(id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
require_relative 'lorentz_field'
|
||||||
|
#require_relative 'occams_razor'
|
||||||
|
#require_relative 'quantum_bow'
|
||||||
|
#require_relative 'blade_of_recursion'
|
||||||
|
|
||||||
|
class WeaponHandler
|
||||||
|
def initialize
|
||||||
|
@weapons = {
|
||||||
|
lorentz_field: LorentzField.new,
|
||||||
|
#occams_razor: OccamsRazor.new,
|
||||||
|
#quantum_bow: QuantumBow.new,
|
||||||
|
#blade_of_recursion: BladeOfRecursion.new
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def update(dt)
|
||||||
|
@weapons.each_value { |weapon| weapon.update(dt) }
|
||||||
|
|
||||||
|
selected_item = $bus.get(:selected_item)
|
||||||
|
return unless @weapons.key?(selected_item)
|
||||||
|
|
||||||
|
weapon = @weapons[selected_item]
|
||||||
|
if $bus.get(:count, selected_item) > 0 && Gosu.button_down?(Gosu::KB_SPACE)
|
||||||
|
weapon.attack
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
@weapons.each_value(&:draw)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,16 +1,56 @@
|
|||||||
class LorentzField < Weapon
|
class LorentzField
|
||||||
|
BASE_TIME = 25 # Base time for the field to be active in seconds
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super(
|
@time = 0
|
||||||
name: "Lorentz Field",
|
@active = false
|
||||||
description: "A defensive weapon that creates a time distortion field around the user. While active, the field slows down incoming projectiles and enemies, giving the user a chance to react and evade. The field lasts for a short duration and has a cooldown period before it can be used again.",
|
@font = Gosu::Font.new(24, name: "assets/fonts/tn.ttf")
|
||||||
image_path: "assets/images/lorentz_field.png",
|
|
||||||
cooldown: 5.0,
|
$bus.on(:lorentz_field) do
|
||||||
damage: 0,
|
if @active
|
||||||
range: 0,
|
t = @time
|
||||||
area_of_effect: 0
|
remaining = BASE_TIME - t
|
||||||
)
|
|
||||||
|
if t < 4
|
||||||
|
# fade in
|
||||||
|
next t / 4.0
|
||||||
|
elsif remaining < 4
|
||||||
|
# fade out
|
||||||
|
next remaining / 4.0
|
||||||
|
else
|
||||||
|
# fully active
|
||||||
|
next 1.0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
next 0.0
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def activate(user)
|
def attack
|
||||||
|
return if @active
|
||||||
|
$bus.emit(:consume, :lorentz_field, 1)
|
||||||
|
@active = true
|
||||||
|
@time = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def update(dt)
|
||||||
|
return unless @active
|
||||||
|
|
||||||
|
@time += dt
|
||||||
|
if @time >= BASE_TIME
|
||||||
|
@time = 0
|
||||||
|
@active = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw
|
||||||
|
# for now draw the time
|
||||||
|
return unless @active
|
||||||
|
|
||||||
|
remaining = BASE_TIME - @time
|
||||||
|
text = "Lorentz Field: #{remaining.round(1)}s"
|
||||||
|
|
||||||
|
@font.draw_text(text, SCREEN_SIZE[0] / 2 - @font.text_width(text) / 2, 10, Float::INFINITY, 1, 1, Gosu::Color::CYAN)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class OccamsRazor
|
||||||
|
def initialize
|
||||||
|
#
|
||||||
|
end
|
||||||
|
|
||||||
|
def attack(dt)
|
||||||
|
#
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -75,6 +75,8 @@ class Window < Gosu::Window
|
|||||||
torch_lights = torches.map { |t| [t[0] - cam_x, SCREEN_SIZE[1] - (t[1] - cam_y)] }.flatten
|
torch_lights = torches.map { |t| [t[0] - cam_x, SCREEN_SIZE[1] - (t[1] - cam_y)] }.flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
|
lorentz_field = $bus.get(:lorentz_field) || 0.0
|
||||||
|
|
||||||
torch_lights = torch_lights.first(32)
|
torch_lights = torch_lights.first(32)
|
||||||
torch_count = torch_lights.size / 2
|
torch_count = torch_lights.size / 2
|
||||||
torch_lights += [0.0] * (32 - torch_lights.size)
|
torch_lights += [0.0] * (32 - torch_lights.size)
|
||||||
@@ -95,9 +97,6 @@ class Window < Gosu::Window
|
|||||||
scale_loc = GL.GetUniformLocation(@shader, "scale")
|
scale_loc = GL.GetUniformLocation(@shader, "scale")
|
||||||
GL.Uniform1f(scale_loc, scale)
|
GL.Uniform1f(scale_loc, scale)
|
||||||
|
|
||||||
player_loc = GL.GetUniformLocation(@shader, "player_pos")
|
|
||||||
GL.Uniform2f(player_loc, SCREEN_SIZE[0] / 2, SCREEN_SIZE[1] / 2)
|
|
||||||
|
|
||||||
torches_loc = GL.GetUniformLocation(@shader, "torch_lights")
|
torches_loc = GL.GetUniformLocation(@shader, "torch_lights")
|
||||||
GL.Uniform2fv(torches_loc, torch_lights.size / 2, torch_lights.pack("f*"))
|
GL.Uniform2fv(torches_loc, torch_lights.size / 2, torch_lights.pack("f*"))
|
||||||
|
|
||||||
@@ -107,6 +106,9 @@ class Window < Gosu::Window
|
|||||||
time_loc = GL.GetUniformLocation(@shader, "time_sec")
|
time_loc = GL.GetUniformLocation(@shader, "time_sec")
|
||||||
GL.Uniform1f(time_loc, Gosu.milliseconds / 1000.0)
|
GL.Uniform1f(time_loc, Gosu.milliseconds / 1000.0)
|
||||||
|
|
||||||
|
lorentz_loc = GL.GetUniformLocation(@shader, "lorentz_field")
|
||||||
|
GL.Uniform1f(lorentz_loc, lorentz_field)
|
||||||
|
|
||||||
GL.Begin(GL::QUADS)
|
GL.Begin(GL::QUADS)
|
||||||
GL.Vertex2f(-1, -1)
|
GL.Vertex2f(-1, -1)
|
||||||
GL.Vertex2f( 1, -1)
|
GL.Vertex2f( 1, -1)
|
||||||
|
|||||||
Reference in New Issue
Block a user