Skip to content

Instantly share code, notes, and snippets.

@amirrajan
Last active May 8, 2019 21:53
Show Gist options
  • Save amirrajan/60ccfc0285333dd6b5e1efdf9e445ebe to your computer and use it in GitHub Desktop.
Save amirrajan/60ccfc0285333dd6b5e1efdf9e445ebe to your computer and use it in GitHub Desktop.
subspace2.rb
# Press escape the open up the DragonRuby Hud and type the following code
def after_tick game_state
game_state.solids << [0, 0, 100, 100, 255, 0, 0]
end
# after typing the code above press Shift+Enter
class Game
attr_accessor :_
def tick
defaults
render
calc
input
end
def defaults
default_coordinate_system
_.flames ||= []
_.bullets ||= []
_.ship_blue_score ||= 0
_.ship_red_score ||= 0
_.ship_blue ||= default_ship(-400, 0, 0)
_.ship_red ||= default_ship( 400, 0, 180)
default_universe
end
def render
render_score
render_universe
render_ships
render_flames
render_bullets
end
def calc
calc_thrusts
calc_ships
calc_bullets
calc_winner
end
def input
input_accelerate
input_turn
input_bullets_and_mines
end
def default_ship x, y, heading
_.new(:ship) do |s|
s.x = x
s.y = y
s.dy = 0
s.dx = 0
s.damage = 0
s.dead = false
s.heading = heading
end
end
def red_color
[255, 90, 90]
end
def blue_color
[110, 140, 255]
end
def default_universe
_.stars ||= 100.times.map do |i|
size = 1 * rand + 1
[rand * _.screen.w_half * [1, -1].sample,
rand * _.screen.h_half * [1, -1].sample, size, size, 128 * rand + 128, 255, 255]
end
end
def default_coordinate_system
_.origin_x = 640
_.origin_y = 360
_.pos_y_direction = -1
_.pos_x_direction = 1
end
def render_score
_.labels << [-_.screen.w.fdiv(2) + 80, _.screen.h.fdiv(2) - 80, _.ship_blue_score, 2, 1, *blue_color]
_.labels << [ _.screen.w.fdiv(2) - 80, _.screen.h.fdiv(2) - 80, _.ship_red_score, 2, 1, *red_color]
end
def render_universe
_.solids << [-_.screen.w, -_.screen.h, _.screen.w * 2, _.screen.h * 2, 0, 0, 0]
_.solids += _.stars
end
def apply_round_finished_alpha entity
return entity unless _.round_finished_debounce
entity[-1] *= _.round_finished_debounce.fdiv_perc(120)
return entity
end
def update_sprite path, ship
ship.sprite =
apply_round_finished_alpha [path,
ship.x - 16, ship.y - 16, 33, 33,
ship.heading,
ship.dead ? 0 : 255 * ship.__elapsed_ticks_since_creation__.fdiv_perc(120)]
end
def render_ships
_.sprites << update_sprite('ship_blue.png', _.ship_blue)
_.sprites << update_sprite('ship_red.png', _.ship_red)
_.labels << apply_round_finished_alpha([_.ship_blue.x, _.ship_blue.y + 20, "." * (5 - _.ship_blue.damage), 0, 1, *blue_color, 255])
_.labels << apply_round_finished_alpha([_.ship_red.x, _.ship_red.y + 20, "." * (5 - _.ship_red.damage), 0, 1, *red_color, 255])
end
def render_flames
_.solids += _.flames.map do |p|
percentage = p.lifetime.minus(p.__elapsed_ticks_since_creation__).fdiv_perc(p.lifetime)
max_alpha = p.max_alpha || 255
apply_round_finished_alpha [-1 + p.x, -1 + p.y, 3, 3, 255, 200, 75, max_alpha * percentage]
end
end
def render_bullets
_.solids += _.bullets.map do |b|
max_alpha = b.max_alpha || 255
bullet_sprite = if b.owner == _.ship_blue.__id__
[-2 + b.x, -2 + b.y, 5, 5, *blue_color, max_alpha]
elsif b.owner == _.ship_red.__id__
[-2 + b.x, -2 + b.y, 5, 5, *red_color, max_alpha]
else
[-2 + b.x, -2 + b.y, 5, 5, 255, 255, 255, 0]
end
apply_round_finished_alpha bullet_sprite
end
end
def calc_wrap_location location
location.x = _.screen.w_half * -1 if location.x > _.screen.w_half
location.x = _.screen.w_half if location.x < _.screen.w_half * -1
location.y = _.screen.h_half * -1 if location.y > _.screen.h_half
location.y = _.screen.h_half if location.y < _.screen.h_half * -1
end
def calc_thrusts
_.flames.each do |p|
p.speed *= 0.9
p.y += p.speed * p.heading.y_vector
p.x += p.speed * p.heading.x_vector
calc_wrap_location p
end
_.flames.reject! { |p| p.__elapsed_ticks_since_creation__ >= p.lifetime }
end
def all_ships
[_.ship_blue, _.ship_red]
end
def calc_bullet bullet
bullet.y += bullet.speed * bullet.heading.y_vector
bullet.x += bullet.speed * bullet.heading.x_vector
calc_wrap_location bullet
explode_bullet bullet if bullet.__elapsed_ticks_since_creation__ >= bullet.lifetime
return if bullet.exploded
all_ships.reject { |s| s.dead || s.__id__ == bullet.owner }.each do |s|
if s.sprite[1..4].intersects_rect?([bullet.x - 2, bullet.y - 2, 5, 5])
explode_bullet bullet, 20, 5, 30
s.damage += 1
end
end
end
def calc_bullets
_.bullets.each { |b| calc_bullet b }
_.bullets.reject! { |b| b.exploded }
end
def create_explosion type, entity, flame_count, max_speed, lifetime
flame_count.times do
_.flames << _.new(type) do |s|
s.heading = 360 * rand
s.speed = max_speed * rand
s.lifetime = lifetime
s.x = entity.x
s.y = entity.y
end
end
end
def explode_bullet bullet, flame_override = 5, max_speed = 5, lifetime = 10
bullet.exploded = true
create_explosion :bullet_explosion, bullet, flame_override, max_speed, lifetime
end
def calc_ship ship
ship.x += ship.dx
ship.y += ship.dy
calc_wrap_location ship
end
def calc_ships
all_ships.each { |s| calc_ship s }
return if all_ships.any? { |s| s.dead }
if _.ship_blue.sprite[1..4].intersects_rect?(_.ship_red.sprite[1..4])
_.ship_blue.damage = 5
_.ship_red.damage = 5
end
end
def create_thruster_flames ship
_.flames << _.new(:ship_thruster) do |s|
s.heading = ship.heading + 180 + [1, -1].sample.mult(rand * 20)
s.speed = 10 * rand
s.max_alpha = 255 * ship.__elapsed_ticks_since_creation__.fdiv_perc(120)
s.lifetime = 30
s.x = ship.x + 19 * s.heading.x_vector
s.y = ship.y + 19 * s.heading.y_vector
end
end
def input_accelerate_ship should_move_ship, ship
return if ship.dead
if should_move_ship
create_thruster_flames ship
ship.dx += 0.050 * ship.heading.x_vector
ship.dy += 0.050 * ship.heading.y_vector
else
ship.dx *= 0.99
ship.dy *= 0.99
end
end
def input_accelerate
input_accelerate_ship _.player_1_r1_key_held, _.ship_blue
input_accelerate_ship _.player_2_r1_key_held, _.ship_red
end
def input_turn_ship direction, ship
ship.heading += 3 * direction
end
def input_turn
input_turn_ship( 1, _.ship_blue) if _.player_1_left_key_held
input_turn_ship(-1, _.ship_blue) if _.player_1_right_key_held
input_turn_ship( 1, _.ship_red) if _.player_2_left_key_held
input_turn_ship(-1, _.ship_red) if _.player_2_right_key_held
end
def input_bullet create_bullet, ship
return unless create_bullet
return if ship.dead
_.bullets << _.new(:ship_bullet) do |s|
s.owner = ship.__id__
s.heading = ship.heading
s.max_alpha = 255 * ship.__elapsed_ticks_since_creation__.fdiv_perc(120)
s.speed = 5 + ship.dx.mult(ship.heading.x_vector) + ship.dy.mult(ship.heading.y_vector)
s.lifetime = 120
s.x = ship.x + ship.heading.x_vector * 15
s.y = ship.y + ship.heading.y_vector * 15
end
end
def input_mine create_mine, ship
return unless create_mine
return if ship.dead
_.bullets << _.new(:ship_bullet) do |s|
s.owner = ship.__id__
s.heading = 360 * rand
s.max_alpha = 255 * ship.__elapsed_ticks_since_creation__.fdiv_perc(120)
s.speed = 0.02
s.lifetime = 600
s.x = ship.x + ship.heading.x_vector * -20
s.y = ship.y + ship.heading.y_vector * -20
end
end
def input_bullets_and_mines
input_bullet(_.player_1_a_key_down && _.tick_count.mod_zero?(10) ||
_.player_1_a_key_down == _.tick_count - 1,
_.ship_blue)
input_mine(_.player_1_b_key_down && _.tick_count.mod_zero?(10) ||
_.player_1_b_key_down == _.tick_count - 1,
_.ship_blue)
input_bullet(_.player_2_a_key_down && _.tick_count.mod_zero?(10) ||
_.player_2_a_key_down == _.tick_count - 1,
_.ship_red)
input_mine(_.player_2_b_key_down && _.tick_count.mod_zero?(10) ||
_.player_2_b_key_down == _.tick_count - 1,
_.ship_red)
end
def calc_kill_ships
all_ships.each do |s|
if s.damage >= 5
create_explosion :ship_explosion, s, 20, 20, 30 if !s.dead
s.dead = true
end
end
end
def calc_score
return if _.round_over
alive_ships = all_ships.find_all { |s| !s.dead }
return if alive_ships.length > 1
if alive_ships.length == 1
if alive_ships.first.__id__ == _.ship_red.__id__
_.ship_red_score += 1
elsif alive_ships.first.__id__ == _.ship_blue.__id__
_.ship_blue_score += 1
end
end
_.round_over = true
end
def calc_new_round
_.ship_blue = default_ship(-400, [-300, 300].sample * rand, 0)
_.ship_red = default_ship( 400, [-300, 300].sample * rand, 180)
_.round_over = false
_.round_finished_debounce = nil
_.flames.clear
_.bullets.clear
end
def calc_reset_ships
return unless _.round_over
_.round_finished_debounce ||= 120
_.round_finished_debounce -= 1
return if _.round_finished_debounce > 0
calc_new_round
end
def calc_winner
calc_kill_ships
calc_score
calc_reset_ships
end
end
$game = Game.new
def tick game_state
$game._ = game_state
$game.tick
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment