Skip to content

Instantly share code, notes, and snippets.

@amirrajan
Last active September 17, 2019 20:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amirrajan/942ba515527e85c69700ffeb0c0bdb34 to your computer and use it in GitHub Desktop.
Save amirrajan/942ba515527e85c69700ffeb0c0bdb34 to your computer and use it in GitHub Desktop.
Vertical space shooter in DragonRuby Game Toolkit
def new_enemy args
{ x: 1280.randomize(:ratio),
starting_y: 800,
final_distance: 900,
duration: 60.randomize(:ratio) + 180,
created_at: args.state.tick_count,
size: 32,
fire_rate: (30.randomize(:ratio) + (60 - args.state.score)).to_i }
end
def new_bullet args, starting_x, starting_y, enemy_speed
b = { x: starting_x,
starting_y: starting_y,
final_distance: 900 + (800 - starting_y),
created_at: args.state.tick_count,
size: 5 }
b[:duration] = b[:final_distance] / (enemy_speed + 2.0 + (5.0 * args.state.score.fdiv(100)))
b
end
def new_player_bullet args, starting_x, starting_y, player_speed
b = { x: starting_x,
starting_y: starting_y,
final_distance: starting_y - 900,
created_at: args.state.tick_count,
size: 5 }
b[:duration] = (b[:final_distance] / (player_speed + 2.0)).abs
b
end
def defaults args
args.state.tick_count ||= Kernel.tick_count
args.state.score ||= 0
args.state.enemies ||= []
args.state.bullets ||= []
args.state.player_bullets ||= []
args.state.max_enemies = 10
args.state.player.x ||= 640
args.state.player.y ||= 100
args.state.player.size ||= 32
if args.state.enemies.length == 0
args.state.max_enemies.times do
s = new_enemy args
s[:created_at] += s[:duration].randomize(:ratio)
args.state.enemies << s
end
end
end
def input args
if args.inputs.keyboard.left
args.state.player.x -= 5
elsif args.inputs.keyboard.right
args.state.player.x += 5
end
if args.inputs.keyboard.up
args.state.player.y += 5
elsif args.inputs.keyboard.down
args.state.player.y -= 5
end
if args.inputs.keyboard.key_down.space
args.state.player_bullets << new_player_bullet(args,
args.state.player.x + args.state.player.size.half,
args.state.player.y + args.state.player.size, 5)
end
args.state.player.y = args.state.player.y.greater(0).lesser(720 - args.state.player.size)
args.state.player.x = args.state.player.x.greater(0).lesser(1280 - args.state.player.size)
end
def completed? entity
(entity[:created_at] + entity[:duration]).elapsed_time > 0
end
def move_enemies args
if (enemies_to_add = args.state.max_enemies - args.state.enemies.length) > 0
enemies_to_add.times { args.state.enemies << new_enemy(args) }
end
args.state.enemies = args.state.enemies.reject { |s| completed? s }
end
def move_bullets args
args.state.enemies.each do |e|
if args.state.tick_count.mod_zero?(e[:fire_rate])
args.state.bullets << new_bullet(args, e[:x] + e[:size].half, current_y(e), e[:final_distance] / e[:duration])
end
end
args.state.bullets = args.state.bullets.reject { |s| completed? s }
args.state.player_bullets = args.state.player_bullets.reject { |s| completed? s }
end
def intersect? entity_one, entity_two
return false if entity_one[:x] + entity_one[:size] < entity_two[:x]
return false if entity_one[:x] > entity_two[:x] + entity_two[:size]
return false if current_y(entity_one) + entity_one[:size] < current_y(entity_two)
return false if current_y(entity_one) > current_y(entity_two) + entity_two[:size]
return true
end
def kill args
bullets_hitting_enemies = []
args.state.player_bullets.each do |b|
args.state.enemies.each do |e|
bullets_hitting_enemies << [b, e] if intersect? b, e
end
end
args.state.score += bullets_hitting_enemies.length
bullets_hitting_enemies.flatten!
args.state.player_bullets.reject! { |b| bullets_hitting_enemies.flatten.include? b }
args.state.enemies.reject! { |e| bullets_hitting_enemies.flatten.include? e }
dead = args.state.bullets.any? { |b| [b[:x], current_y(b), b[:size], b[:size]].intersects_rect?([args.state.player.x, args.state.player.y, args.state.player.size, args.state.player.size]) }
return unless dead
args.state.hash.clear
defaults args
end
def calc args
move_enemies args
move_bullets args
kill args
end
def current_y entity
entity[:starting_y] - (entity[:final_distance] * entity[:created_at].ease(entity[:duration], :identity))
end
def render args
args.outputs.solids << args.state.enemies.map do |s|
[s[:x],
current_y(s),
s[:size], s[:size], 255, 0, 0]
end
args.outputs.solids << args.state.bullets.map do |b|
[b[:x],
current_y(b),
b[:size], b[:size], 255, 0, 0]
end
args.outputs.solids << args.state.player_bullets.map do |b|
[b[:x],
current_y(b),
b[:size], b[:size], 0, 0, 0]
end
args.solids << [args.state.player.x,
args.state.player.y,
args.state.player.size,
args.state.player.size, 0, 0, 0]
end
def tick args
defaults args
input args
calc args
render args
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment