From b72ae89980010451c39e4d40b42004ea693cab27 Mon Sep 17 00:00:00 2001 From: Alex Clink Date: Wed, 17 Nov 2021 23:30:32 -0500 Subject: [PATCH] Add ship collision --- src/asteroids.cr | 45 ++++++++++++++++++++++++++++++++++++++------- src/ship.cr | 19 +++++++++++++++++-- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/asteroids.cr b/src/asteroids.cr index d5bd06a..3e7f78f 100644 --- a/src/asteroids.cr +++ b/src/asteroids.cr @@ -31,6 +31,7 @@ class Asteroids < Game @explosions = [] of Explosion @controller : Controller(LibSDL::Keycode) @asteroid_count = 3 + @restart_timer = 0.0 def initialize(*args) super @@ -39,7 +40,7 @@ class Asteroids < Game ship.position = Vector2.new(x: width / 2.0, y: height / 2.0) end - generate_asteroids + setup_round @controller = Controller(LibSDL::Keycode).new({ LibSDL::Keycode::UP => "Thrust", @@ -50,9 +51,15 @@ class Asteroids < Game end def generate_asteroids + center_size = Vector2.new(20.0, 20.0) + center_pos = Vector2.new((width.to_f / 2.0) - (center_size.x / 2.0), (height.to_f / 2.0) - (center_size.y / 2.0)) + @asteroid_count.times do @asteroids << Asteroid.build do |a| - a.position = Vector2.new(x: rand(0.0..width.to_f), y: rand(0.0..height.to_f)) + loop do + a.position = Vector2.new(x: rand(0.0..width.to_f), y: rand(0.0..height.to_f)) + break if (a.position.x < center_pos.x || a.position.x > center_pos.x + center_size.x) && (a.position.y < center_pos.y || a.position.y > center_pos.y + center_size.y) + end v_max = 30.0 a.velocity = Vector2.new(x: rand(-v_max..v_max), y: rand(-v_max..v_max)) a.rotation_speed = rand(-5.0..5.0) @@ -64,6 +71,17 @@ class Asteroids < Game end end + def setup_round + @restart_timer = 0.0 + @asteroids = [] of Asteroid + generate_asteroids + @bullets = [] of Bullet + @ship.blew_up = false + @ship.position = Vector2.new(x: width / 2.0, y: height / 2.0) + @ship.velocity = Vector2.new(0.0, 0.0) + @ship.rotation_speed = 0.0 + end + def wrap(position : Vector2) position.x = 0.0 if position.x > @width position.x = @width.to_f64 if position.x < 0.0 @@ -75,14 +93,14 @@ class Asteroids < Game end def update(dt : Float64) - if @asteroids.size == 0 + if @asteroids.size == 0 && !@ship.blew_up @asteroid_count += 1 - generate_asteroids - @ship.position = Vector2.new(x: width / 2.0, y: height / 2.0) - @ship.velocity = Vector2.new(0.0, 0.0) - @ship.rotation_speed = 0.0 + setup_round end + @restart_timer += dt if @ship.blew_up + setup_round if @restart_timer > 3.0 + @ship.rotate_right(dt) if @controller.action?("Rotate Right") @ship.rotate_left(dt) if @controller.action?("Rotate Left") @ship.thrust(dt) if @controller.action?("Thrust") @@ -159,6 +177,19 @@ class Asteroids < Game end @explosions.reject! { |e| e.emitting == false && e.particles.none? } + @asteroids.each do |a| + if @ship.collides_with?(a) + @ship.blew_up = true + @explosions << Explosion.build do |e| + e.size = 10.0 + e.position = @ship.position + e.velocity = @ship.velocity + e.emit_freq = 0.01 + e.strength = 30 + e.max_age = 1.0 + end + end + end end def draw diff --git a/src/ship.cr b/src/ship.cr index 48bdc4e..6b5a0c5 100644 --- a/src/ship.cr +++ b/src/ship.cr @@ -8,6 +8,8 @@ class Ship < Sprite @emitter : Emitter @l_emitter : Emitter @r_emitter : Emitter + @projected_points : Array(Vector2)? = nil + property blew_up : Bool = false def initialize super @@ -76,7 +78,20 @@ class Ship < Sprite @velocity.y += Math.sin(@rotation) * dt * @t_engine end + def projected_points + @projected_points ||= project_points(@frame) + end + + def collides_with?(asteroid : Asteroid) + return false if @blew_up + projected_points.any? do |point| + asteroid.position.distance(point) < asteroid.radius + end + end + def update(dt : Float64) + return if @blew_up + @projected_points = nil update_position(dt) @fire_cooldown -= dt unless can_fire? @@ -98,6 +113,7 @@ class Ship < Sprite end def draw(renderer) + return if @blew_up @emitter.draw(renderer) @emitter.emitting = false @l_emitter.draw(renderer) @@ -105,8 +121,7 @@ class Ship < Sprite @r_emitter.draw(renderer) @r_emitter.emitting = false - frame = project_points(@frame) renderer.draw_color = SDL::Color[255, 255, 255, 255] - draw_frame(renderer, frame) + draw_frame(renderer, projected_points) end end