Skip to content

Commit

Permalink
Aim bombs in full circle
Browse files Browse the repository at this point in the history
  • Loading branch information
shawn42 committed Mar 17, 2014
1 parent d3e0598 commit 9a464c4
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 37 deletions.
77 changes: 63 additions & 14 deletions spec/acceptance/bomb_spec.rb
Expand Up @@ -13,6 +13,8 @@

let(:player_w) { 32 }
let(:player_h) { 60 }
let(:bomb) { game.actor(:bomb) }
let(:player) { game.actor(:player) }
let!(:props) { mock_tiles 'trippers/props.png', 32, 32 }

before do
Expand All @@ -29,8 +31,6 @@

describe 'throwing bombs' do
context 'no aiming' do
let(:bomb) { game.actor(:bomb) }
let(:player) { game.actor(:player) }

it 'throws right when looking right' do
look_right
Expand Down Expand Up @@ -83,29 +83,57 @@
end
end

it 'turns off walking when you are charging' do
while_charging_bomb do
last_position = player.position
walk_left 20
player.position.should == last_position
end
end

it 'throw faster the longer you hold' do
min_vel = bomb_velocity_from_min_throw
max_vel = bomb_velocity_from_max_throw
max_vel.magnitude.should > min_vel.magnitude
end

it 'can aim up/right'
it 'can aim up/right'
it 'can aim down/left'
it 'can aim down/left'
it 'can aim up/right' do
look_right
while_charging_bomb do
aim_up
end
see_bomb_is_up_and_right_of_player
end

it 'can aim up/left' do
look_left
while_charging_bomb do
aim_up
end
see_bomb_is_up_and_left_of_player
end

it 'can aim down/right' do
look_right
while_charging_bomb do
aim_down
end
see_bomb_is_down_and_right_of_player
end

it 'can aim down/left' do
look_left
while_charging_bomb do
aim_down
end
see_bomb_is_down_and_left_of_player
end

it 'locks to up when holding up'
it 'locks to right when holding right'
it 'locks to left when holding left'
end

def aim_up
hold_key KbW, 40, step: 20
end

def aim_down
hold_key KbS, 40, step: 20
end

def bomb_velocity_from_min_throw
throw_bomb 1
game.actors(:bomb).last.vel
Expand All @@ -129,6 +157,7 @@ def while_charging_bomb(&blk)
update 20
yield
release_key KbM
update 20
end

def see_no_reticle
Expand All @@ -142,6 +171,26 @@ def see_reticle_is_right_of_player
reticle.visible.should be_true
end

def see_bomb_is_up_and_right_of_player
see_bomb_is_right_of_player
see_bomb_is_above_player
end

def see_bomb_is_up_and_left_of_player
see_bomb_is_left_of_player
see_bomb_is_above_player
end

def see_bomb_is_down_and_right_of_player
see_bomb_is_right_of_player
see_bomb_is_below_player
end

def see_bomb_is_down_and_left_of_player
see_bomb_is_left_of_player
see_bomb_is_below_player
end

def see_bomb_is_right_of_player
bomb.x.should > player.x
end
Expand Down
8 changes: 7 additions & 1 deletion src/actors/gib.rb
Expand Up @@ -8,8 +8,14 @@
mover
tile_collision_detector
trivial_collision_point
short_lived ttl: 3000
end

behavior do
setup do
add_behavior :short_lived, ttl: (500..4_000).sample
end
end

has_attributes color: Color::RED

view do
Expand Down
134 changes: 125 additions & 9 deletions src/behaviors/bomber.rb
Expand Up @@ -2,7 +2,7 @@
# too much velocity
# charge may be a little slow
define_behavior :bomber do
requires :stage, :director, :bomb_coordinator
requires :stage, :director, :bomb_coordinator, :input_manager
setup do
# lets start with infinite bombs, fixed vel
actor.has_attributes bomb_charge: 0,
Expand All @@ -13,9 +13,17 @@
reticle_vector: nil,
bomb_kickback: opts[:kickback] || 0

# XXX HACK for playtesting XXX
input_manager.reg :down, KbSpace do
log "10 more bombs for #{actor.object_id}!"
actor.bombs_left += 10
end
director.when :first do |time, time_secs|
update_bombing time_secs if has_bombs_left?
end

actor.when :look_dir_changed do |was_looking, now_looking|
end
end

remove do
Expand All @@ -29,11 +37,8 @@

def update_bombing(time_secs)
if released_charged_bomb?
add_behavior :accelerator
release_bomb
elsif started_charging_bomb?
remove_behavior :accelerator
actor.vel = vec2(0,0) if actor.on_ground?
charge_bomb time_secs
elsif charging_bomb?
actor.vel = vec2(0,0) if actor.on_ground?
Expand All @@ -49,7 +54,7 @@ def reset_reticle
actor.bomb_reticle.react_to :hide
end

def update_reticle
def update_reticle(time_secs)
actor.bomb_reticle.react_to :show
min_dist_from_actor = 10
max_dist_from_actor = 40
Expand All @@ -59,14 +64,125 @@ def update_reticle
(max_dist_from_actor - min_dist_from_actor) *
(actor.bomb_charge / actor.max_bomb_charge.to_f)

reticle_vector = (actor.look_vector * dist_from_actor).
rotate(degrees_to_radians(rotation))
if actor.was_charging_bomb?
actor.reticle_vector.magnitude = dist_from_actor
else
actor.reticle_vector = (actor.look_vector * dist_from_actor).
rotate(degrees_to_radians(rotation))
end

actor.reticle_vector = reticle_vector
controller = actor.controller
if looking_up?
rotate_reticle_toward_up time_secs
elsif looking_down?
rotate_reticle_toward_down time_secs
elsif looking_right?
rotate_reticle_toward_right time_secs
elsif looking_left?
rotate_reticle_toward_left time_secs
end

actor.bomb_reticle.position = actor.position + actor.reticle_vector
end

def looking_up?
actor.controller.look_up?
end
def looking_down?
actor.controller.look_down?
end
def looking_right?
actor.controller.look_right?
end
def looking_left?
actor.controller.look_left?
end

def normalize_radians(radians)
log "raw player rotation: #{radians}"
if radians <= -2*Math::PI
radians = radians % (-2*Math::PI)
2*Math::PI + radians
elsif radians >= 2*Math::PI
radians % (2*Math::PI)
else
radians
end
end

def relative_reticle_angle
actor_look_right_vector = vec2(1,0).rotate!(degrees_to_radians(actor.rotation))
actor.reticle_vector.angle_with(actor_look_right_vector)
end

def rotate_reticle_toward_up(time_secs)
aim_speed = Math::PI
actor_look_right_vector = vec2(1,0).rotate!(degrees_to_radians(actor.rotation))
angle_difference = actor.reticle_vector.angle_with(actor_look_right_vector)
if angle_difference.abs < (Math::PI / 2)
actor.reticle_vector.rotate!(-aim_speed * time_secs)
else
actor.reticle_vector.rotate!(aim_speed * time_secs)
end
end

def rotate_reticle_toward_down(time_secs)
aim_speed = Math::PI
actor_look_right_vector = vec2(1,0).rotate!(degrees_to_radians(actor.rotation))
angle_difference = actor.reticle_vector.angle_with(actor_look_right_vector)
if angle_difference.abs < (Math::PI / 2)
actor.reticle_vector.rotate!(aim_speed * time_secs)
else
actor.reticle_vector.rotate!(-aim_speed * time_secs)
end
end

def flip_reticle
actor_look_up_vector = vec2(0,-1).rotate!(degrees_to_radians(actor.rotation))
actor_look_up_vector.magnitude = 100
projection = actor.reticle_vector.projected_onto actor_look_up_vector
rejection = projection - actor_look_up_vector
actor.reticle_vector = projection + (projection - actor.reticle_vector)
end

def reticle_on_left?
actor_look_right_vector = vec2(1,0).rotate!(degrees_to_radians(actor.rotation))
angle_difference = actor.reticle_vector.angle_with(actor_look_right_vector)
angle_difference.abs > (Math::PI / 2)
end

def reticle_on_right?
!reticle_on_left?
end

def rotate_reticle_toward_right(time_secs)
aim_speed = Math::PI

flip_reticle if reticle_on_left?

actor_look_up_vector = vec2(0,1).rotate!(degrees_to_radians(actor.rotation))
angle_difference = actor.reticle_vector.angle_with(actor_look_up_vector)
if angle_difference.abs < (Math::PI / 2)
actor.reticle_vector.rotate!(-aim_speed * time_secs)
else
actor.reticle_vector.rotate!(aim_speed * time_secs)
end
end

def rotate_reticle_toward_left(time_secs)
aim_speed = Math::PI

flip_reticle if reticle_on_right?

actor_look_up_vector = vec2(0,1).rotate!(degrees_to_radians(actor.rotation))
angle_difference = actor.reticle_vector.angle_with(actor_look_up_vector)
if angle_difference.abs < (Math::PI / 2)
actor.reticle_vector.rotate!(aim_speed * time_secs)
else
actor.reticle_vector.rotate!(-aim_speed * time_secs)
end
end

def plant_landmine
actor.bombs_left -= 1
points = actor.collision_points[4..5]
Expand Down Expand Up @@ -130,7 +246,7 @@ def release_bomb
end

def charge_bomb(time_secs)
update_reticle
update_reticle time_secs
actor.bomb_charge += time_secs
actor.bomb_charge = min(actor.max_bomb_charge, actor.bomb_charge)
actor.was_charging_bomb = true
Expand Down
2 changes: 1 addition & 1 deletion src/behaviors/die_by_bomb.rb
Expand Up @@ -15,7 +15,7 @@
def esplode(bomb, distance)
if distance < (bomb.radius * 0.666) && map_inspector.line_of_sight?(actor, bomb)
blast_vel = (vec2(actor.x, actor.y) - vec2(bomb.x, bomb.y))
delay = blast_vel.magnitude * 4
delay = blast_vel.magnitude * 2
blast_vel.magnitude = 130 / blast_vel.magnitude

timer_manager.add_timer die_timer_name, delay, false do
Expand Down
11 changes: 6 additions & 5 deletions src/behaviors/looker.rb
Expand Up @@ -47,21 +47,22 @@ def look_up
end

def update_look_point(time_secs)
controller = actor.controller
input = actor.controller

look_vector = if controller.look_left?
look_vector = if input.look_left?
Look::DIRECTIONS[:left]
elsif controller.look_right?
elsif input.look_right?
Look::DIRECTIONS[:right]
elsif controller.look_up?
elsif input.look_up?
Look::DIRECTIONS[:up]
elsif controller.look_down?
elsif input.look_down?
Look::DIRECTIONS[:down]
end

viewport = actor.viewport
current_vec = vec2(viewport.follow_offset_x, viewport.follow_offset_y)
if look_vector
actor.look_vector = look_vector
rot = actor.do_or_do_not(:rotation) || 0
offset_vec = current_vec - look_vector.rotate_deg(rot) * actor.look_distance * time_secs

Expand Down
9 changes: 2 additions & 7 deletions src/stages/level_play_stage.rb
Expand Up @@ -57,13 +57,8 @@
end

# F1 console watch values
player = @players[0]
if player
@console.react_to :watch, :p1rotvel do player.rotation_vel end
@console.react_to :watch, :p1gndnorm do player.ground_normal end
end
# @console.react_to :watch, :fps do Gosu.fps end
# @console.react_to :watch, :gc_stat do GC.stat.to_s end
@console.react_to :watch, :fps do Gosu.fps end
@console.react_to :watch, :gc_stat do GC.stat.to_s end
# @console.react_to :watch, :vel do player.vel end
end

Expand Down

0 comments on commit 9a464c4

Please sign in to comment.