mirror of
https://github.com/SleepingInsomniac/asteroids
synced 2024-11-15 19:48:28 +01:00
Add emitter
This commit is contained in:
parent
6d450f1871
commit
f219e74a40
7 changed files with 140 additions and 49 deletions
|
@ -72,7 +72,7 @@ end
|
|||
puts "Copying Info.plist"
|
||||
FileUtils.cp 'Info.plist', "#{BUILD_DIR}/"
|
||||
|
||||
build_cmd = %{shards build --release --link-flags="-rpath @executable_path/../Frameworks -L #{`brew --prefix sfml`.chomp}/lib/ -mmacosx-version-min=10.14 -headerpad_max_install_names"}
|
||||
build_cmd = %{shards build --release --link-flags="-rpath @executable_path/../Frameworks -L #{`brew --prefix sdl2`.chomp}/lib/ -mmacosx-version-min=10.14 -headerpad_max_install_names"}
|
||||
puts "Building: `#{build_cmd}`"
|
||||
puts `#{build_cmd}`
|
||||
|
||||
|
|
|
@ -50,8 +50,7 @@ class Asteroids < Game
|
|||
end
|
||||
|
||||
@bullets.each do |bullet|
|
||||
bullet.update
|
||||
bullet.age += dt
|
||||
bullet.update(dt)
|
||||
end
|
||||
|
||||
@bullets = @bullets.reject { |b| b.age >= 4.0 }
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
class Bullet < Sprite
|
||||
property age : Float64 = 0.0
|
||||
|
||||
def update
|
||||
@position += @velocity
|
||||
def update(dt : Float64)
|
||||
update_position(dt)
|
||||
@age += dt
|
||||
end
|
||||
|
||||
def draw(renderer)
|
||||
|
|
45
src/lx_game/emitter.cr
Normal file
45
src/lx_game/emitter.cr
Normal file
|
@ -0,0 +1,45 @@
|
|||
require "./sprite"
|
||||
require "./particle"
|
||||
|
||||
module LxGame
|
||||
class Emitter < Sprite
|
||||
property emitting : Bool = true
|
||||
property particles = [] of Particle
|
||||
property max_age : Float64 = 1.0
|
||||
property emit_freq : Float64 = 0.05
|
||||
property strength : Float64 = 50.0
|
||||
@last_emitted : Float64 = 0.0
|
||||
property emit_angle : Float64 = 1.0
|
||||
|
||||
def generate_particle
|
||||
Particle.build do |particle|
|
||||
particle.position = @position
|
||||
direction = rand((@rotation - @emit_angle)..(@rotation + @emit_angle))
|
||||
particle.velocity = @velocity + Vector2.new(Math.cos(direction), Math.sin(direction)) * @strength
|
||||
particle.lifespan = @max_age
|
||||
end
|
||||
end
|
||||
|
||||
def update(dt : Float64)
|
||||
update_position(dt)
|
||||
|
||||
@last_emitted += dt
|
||||
|
||||
if @emitting && @last_emitted >= @emit_freq
|
||||
@last_emitted = 0.0
|
||||
@particles << generate_particle
|
||||
end
|
||||
|
||||
@particles.each { |particle| particle.update(dt) }
|
||||
@particles.reject! { |particle| particle.dead? }
|
||||
end
|
||||
|
||||
def draw(renderer : SDL::Renderer)
|
||||
renderer.draw_color = SDL::Color[255, 255, 0, 255]
|
||||
|
||||
@particles.each do |particle|
|
||||
particle.draw(renderer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
26
src/lx_game/particle.cr
Normal file
26
src/lx_game/particle.cr
Normal file
|
@ -0,0 +1,26 @@
|
|||
require "./sprite"
|
||||
|
||||
module LxGame
|
||||
class Particle < Sprite
|
||||
property age : Float64 = 0.0
|
||||
property lifespan : Float64 = 4.0
|
||||
@dead : Bool = false
|
||||
|
||||
def dead?
|
||||
@age >= @lifespan
|
||||
end
|
||||
|
||||
def update(dt : Float64)
|
||||
return if dead?
|
||||
update_position(dt)
|
||||
@age += dt
|
||||
end
|
||||
|
||||
def draw(renderer : SDL::Renderer)
|
||||
return if dead?
|
||||
brightness = ((@lifespan - @age) / @lifespan) * 255
|
||||
renderer.draw_color = SDL::Color[brightness / 2, brightness / 2, brightness / 2]
|
||||
renderer.draw_point(@position.x.to_i, @position.y.to_i)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -18,6 +18,12 @@ module LxGame
|
|||
@rotation_speed = 0.0
|
||||
end
|
||||
|
||||
def update_position(dt : Float64)
|
||||
@rotation += @rotation_speed * dt
|
||||
@position += @velocity * dt
|
||||
end
|
||||
|
||||
abstract def update(dt : Float64)
|
||||
abstract def draw(renderer : SDL::Renderer)
|
||||
end
|
||||
end
|
||||
|
|
102
src/ship.cr
102
src/ship.cr
|
@ -1,12 +1,16 @@
|
|||
class Ship < VectorSprite
|
||||
getter frame : Array(Vector2)
|
||||
@last_fired : Float64
|
||||
@fire_cooldown : Float64 = 0.0
|
||||
@fire_rate : Float64 = 0.2
|
||||
@emitter : Emitter
|
||||
@l_emitter : Emitter
|
||||
@r_emitter : Emitter
|
||||
|
||||
def initialize
|
||||
super
|
||||
|
||||
@r_engine = 0.03
|
||||
@t_engine = 0.1
|
||||
@r_engine = 10.0
|
||||
@t_engine = 20.0
|
||||
|
||||
@frame = [
|
||||
Vector2.new(5.0, 0.0),
|
||||
|
@ -14,85 +18,95 @@ class Ship < VectorSprite
|
|||
Vector2.new(-3.0, -3.0),
|
||||
]
|
||||
|
||||
@jet_left = [Vector2.new(2.0, -5.0), Vector2.new(2.0, -3.5)]
|
||||
@jet_right = [Vector2.new(2.0, 3.5), Vector2.new(2.0, 5.0)]
|
||||
@jet_rear = [Vector2.new(-7.0, 0.0), Vector2.new(-3.0, 0.0)]
|
||||
@emitter = Emitter.build do |e|
|
||||
e.position = @position
|
||||
e.emit_freq = 0.01
|
||||
e.emit_angle = 0.5
|
||||
e.strength = 50.0
|
||||
e.max_age = 0.25
|
||||
end
|
||||
|
||||
@thrusting_left = false
|
||||
@thrusting_right = false
|
||||
@thrusting_forward = false
|
||||
@l_emitter = Emitter.build do |e|
|
||||
e.position = @position
|
||||
e.emit_freq = 0.01
|
||||
e.emit_angle = 0.3
|
||||
e.strength = 25.0
|
||||
e.max_age = 0.25
|
||||
end
|
||||
|
||||
@last_fired = Time.monotonic.total_milliseconds
|
||||
@r_emitter = Emitter.build do |e|
|
||||
e.position = @position
|
||||
e.emit_freq = 0.01
|
||||
e.emit_angle = 0.3
|
||||
e.strength = 25.0
|
||||
e.max_age = 0.25
|
||||
end
|
||||
end
|
||||
|
||||
def can_fire?
|
||||
now = Time.monotonic.total_milliseconds
|
||||
now - @last_fired > 100.0
|
||||
@fire_cooldown <= 0.0
|
||||
end
|
||||
|
||||
def fire
|
||||
@last_fired = Time.monotonic.total_milliseconds
|
||||
@fire_cooldown = @fire_rate
|
||||
@velocity.x -= Math.cos(@rotation) * 3.0
|
||||
@velocity.y -= Math.sin(@rotation) * 3.0
|
||||
Bullet.build do |bullet|
|
||||
bullet.position = project_points([@frame[0]]).first
|
||||
bullet.velocity = @velocity + Vector2.new(Math.cos(@rotation), Math.sin(@rotation)) * 0.1
|
||||
bullet.velocity = @velocity + Vector2.new(Math.cos(@rotation), Math.sin(@rotation)) * 100.0
|
||||
end
|
||||
end
|
||||
|
||||
def rotate_right(dt : Float64, amount = @r_engine)
|
||||
@thrusting_left = true
|
||||
@l_emitter.emitting = true
|
||||
@rotation_speed += amount * dt
|
||||
end
|
||||
|
||||
def rotate_left(dt : Float64, amount = @r_engine)
|
||||
@thrusting_right = true
|
||||
@r_emitter.emitting = true
|
||||
@rotation_speed -= amount * dt
|
||||
end
|
||||
|
||||
def thrust(dt : Float64)
|
||||
@thrusting_forward = true
|
||||
@emitter.emitting = true
|
||||
@velocity.x += Math.cos(@rotation) * dt * @t_engine
|
||||
@velocity.y += Math.sin(@rotation) * dt * @t_engine
|
||||
end
|
||||
|
||||
def update(dt : Float64)
|
||||
@rotation += @rotation_speed
|
||||
@position += @velocity
|
||||
@fire_cooldown -= dt unless can_fire?
|
||||
update_position(dt)
|
||||
|
||||
# @rotation_speed = 0.0 if @rotation_speed < 0.001 && @rotation_speed > -0.001
|
||||
# rotate_left(dt, 0.01) if @rotation_speed >= 0.01
|
||||
# rotate_right(dt, 0.01) if @rotation_speed <= -0.01
|
||||
@emitter.update(dt)
|
||||
@emitter.position = project_points([Vector2.new(-3.0, 0.0)]).first
|
||||
@emitter.velocity = @velocity
|
||||
@emitter.rotation = @rotation - Math::PI
|
||||
|
||||
@l_emitter.update(dt)
|
||||
@l_emitter.position = project_points([Vector2.new(3.0, -1.0)]).first
|
||||
@l_emitter.velocity = @velocity
|
||||
@l_emitter.rotation = @rotation - 1.5
|
||||
|
||||
@r_emitter.update(dt)
|
||||
@r_emitter.position = project_points([Vector2.new(3.0, 1.0)]).first
|
||||
@r_emitter.velocity = @velocity
|
||||
@r_emitter.rotation = @rotation + 1.5
|
||||
end
|
||||
|
||||
def draw(renderer)
|
||||
@emitter.draw(renderer)
|
||||
@emitter.emitting = false
|
||||
@l_emitter.draw(renderer)
|
||||
@l_emitter.emitting = false
|
||||
@r_emitter.draw(renderer)
|
||||
@r_emitter.emitting = false
|
||||
frame = project_points(@frame)
|
||||
|
||||
renderer.draw_color = SDL::Color[128, 128, 128, 255]
|
||||
|
||||
if @thrusting_left
|
||||
@thrusting_left = false
|
||||
jet_left = project_points(@jet_left, @rotation + rand(-0.5..0.5))
|
||||
draw_line(renderer, jet_left[0], jet_left[1])
|
||||
end
|
||||
|
||||
if @thrusting_right
|
||||
@thrusting_right = false
|
||||
jet_right = project_points(@jet_right, @rotation + rand(-0.5..0.5))
|
||||
draw_line(renderer, jet_right[0], jet_right[1])
|
||||
end
|
||||
|
||||
if @thrusting_forward
|
||||
@thrusting_forward = false
|
||||
jet_rear = project_points(@jet_rear, @rotation + rand(-0.5..0.5))
|
||||
draw_line(renderer, jet_rear[0], jet_rear[1])
|
||||
end
|
||||
|
||||
renderer.draw_color = SDL::Color[255, 255, 255, 255]
|
||||
|
||||
draw_line(renderer, frame[0], frame[1])
|
||||
draw_line(renderer, frame[1], frame[2])
|
||||
draw_line(renderer, frame[2], frame[0])
|
||||
|
||||
# renderer.draw_color = SDL::Color[255, 255, 0, 255]
|
||||
# renderer.draw_point(@position.x.to_i, @position.y.to_i)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue