Skip to content

Instantly share code, notes, and snippets.

@ashbb
Created April 11, 2012 11:54
Show Gist options
  • Save ashbb/2358860 to your computer and use it in GitHub Desktop.
Save ashbb/2358860 to your computer and use it in GitHub Desktop.
Asteroids game for Green and Purple Shoes
# asteroids game by lljk
# have fun!
# revised for Green and Purple Shoes by ashbb
# But in this code, the ship doesn't rotate on Green Shoes
class Shoes::Widget
def move x, y
@ele.move x, y
end
def clear
@ele.clear
end
end
class LaserBulletThing < Shoes::Widget
attr_accessor :x, :y, :x_vec, :y_vec
def initialize(x, y)
@x = x; @y = y
@x_vec = 0; @y_vec = 0
@ele = oval(0, 0, 5, 5)
self.move(@x, @y)
end
end
class FirstClassFlyingShip < Shoes::Widget
attr_accessor :center_x, :center_y, :shots, :paused
def initialize(x, y)
@paused = false
@x, @y = x, y
@center_x = x; @center_y = y
@shots = []
@x_vec = 0; @y_vec = 0
@start_angle = 0
@rotate_by = 0
draw_ship
@m = motion do |x, y|
unless @paused
@rads = Math.atan2(y - @center_y, x - @center_x)
degs = 270 - (@rads * (180 / Math::PI)).round(2)
@rotate_by = degs - @start_angle
@start_angle = degs
draw_ship
end
end
@c = click do |btn, x, y|
unless @paused
shoot if btn == 1
if btn == 3
@x_vec += 1 if x > @x + 20
@x_vec -= 1 if x < @x
@y_vec +=1 if y > @y + 24
@y_vec -= 1 if y < @y
end
end
end
end
def clear
[*@shots, @m, @c].each{|e| e.clear if e}
@shots.clear
super
end
def draw_ship
@ele = shape(left: 350, top: 315, width: 20, height: 24){
move_to(10, 0)
line_to(20, 24)
line_to(10, 20)
line_to(0, 24)
line_to(10, 0)
} unless @ele
@ele.rotate = [-@start_angle, @ele.left+10, @ele.top+12] # Need to comment out this line for Green Shoes
end
def move_ship
@x += @x_vec
@y += @y_vec
@x = 0 if @x > 700; @y = 0 if @y > 600
@x = 700 if @x < 0; @y = 600 if @y < 0
@center_x = @x + 10; @center_y = @y + 12
@ele.move(@x, @y)
draw_shots unless @shots.empty?
end
def shoot
if @rads
bullet_x = ((15 * Math.cos(@rads)) + @center_x).round
bullet_y = ((15 * Math.sin(@rads)) + @center_y).round
bullet = laser_bullet_thing(bullet_x, bullet_y)
bullet.x_vec = bullet_x - @center_x
bullet.y_vec = bullet_y - @center_y
@shots << bullet
end
end
def draw_shots
@shots.each{|bullet|
bullet.x += bullet.x_vec
bullet.y += bullet.y_vec
if bullet.x < 0 || bullet.x > 695 || bullet.y < 0 || bullet.y > 595
bullet.clear
@shots.delete(bullet)
else
bullet.move(bullet.x, bullet.y)
end
}
end
end
class Asteroid < Shoes::Widget
attr_accessor :x, :y, :x_vec, :y_vec, :size, :area
def initialize(size, x, y)
@size = size
@x_vec = 0; @y_vec = 0
until @x_vec != 0
@x_vec = (30 / size).round + ((rand(5) - 2) * (rand(3) - 1))
end
until @y_vec != 0
@y_vec = (30 / size).round + ((rand(5) - 2) * (rand(3) - 1))
end
x1 = rand(size * 0.1).round + (size * 0.1); y1 = rand(size * 0.1).round + (size * 0.1)
x2 = x1 + rand(size * 0.4).round; y2 = 0
x3 = size - (rand(size * 0.1).round + (size * 0.1)); y3 = rand(size * 0.1).round + (size * 0.1)
x4 = size - (rand(size * 0.1).round + (size * 0.1)); y4 = rand(size * 0.1).round + (size * 0.1)
x5 = size; y5 = y4 + rand(size * 0.4).round
x6 = size - (rand(size * 0.1).round + (size * 0.1)); y6 = size - (rand(size * 0.1).round + (size * 0.1))
x7 = size - (rand(size * 0.1).round + (size * 0.1)); y7 = size - (rand(size * 0.1).round + (size * 0.1))
x8 = x7 - rand(size * 0.4).round; y8 = size
x9 = rand(size * 0.1).round + (size * 0.1); y9 = size - (rand(size * 0.1).round + (size * 0.1))
x10 = rand(size * 0.1).round + (size * 0.1); y10 = size - (rand(size * 0.1).round + (size * 0.1))
x11 = 0; y11 = y10 - rand(size * 0.4).round
x12 = rand(size * 0.1).round + (size * 0.1); y12 = rand(size * 0.1).round + (size * 0.1)
@ele = shape do
move_to(x1, y1)
line_to(x2, y2)
line_to(x3, y3)
line_to(x4, y4)
line_to(x5, y5)
line_to(x6, y6)
line_to(x7, y7)
line_to(x8, y8)
line_to(x9, y9)
line_to(x10, y10)
line_to(x11, y11)
line_to(x12, y12)
line_to(x1, y1)
end
set_coords(x, y)
end
def set_coords(x, y)
x = 0 if x > 700; x = 700 if x < 0 - @size
y = 0 if y > 630; y = 630 if y < 0
@x = x; @y = y
@area = [@x..(@x + @size), @y..(@y + @size)]
self.move(@x, @y)
end
def move_asteroid
x = @x + @x_vec; y = @y + @y_vec
set_coords(x, y)
end
def check_hits(x, y)
if @area[0].include?(x) && @area[1].include?(y)
@hit = true
end
end
def hit?
@hit
end
end
#######################
Shoes.app width: 700, height: 630 do
[Shoes::Title, Shoes::Banner, Shoes::Para].each{|klass| style klass, stroke: lime, align: "center"}
stroke lime
background black
def init_game
@lives = 3
@score = 0
@level = 1
@rocks = []
@game_over = false
status_area = flow height: 30 do
border lime
@status_info = para " ", top: 5
end
init_level(1)
end
def init_level(level)
update_status(@lives, @score, @level)
unless @rocks.empty?
@rocks.each{|rock| rock.clear}
@rocks.clear
end
unless @level == 1 || @no_congrats
salutations = ["Hey There", "Woah", "Nice One", "Well Done", "Awesome"]
names = ["Dude", "Buddy", "Pal", "Friend", "Amigo"]
actions = ["Rocked", "Destroyed", "Annihilated", "Kicked Butt On", "Creamed"]
@congrats = title "#{salutations[rand(5)]} #{names[rand(5)]}, ",
"You #{actions[rand(5)]} Level #{@level - 1}! On To...", top: 100
timer(3){@congrats.clear}
end
@level_info = banner "level #{@level}", top: 280
timer(3){
@level_info.clear
@ship = first_class_flying_ship(350, 315)
n = @level
n.times{
@rock = asteroid(60, rand(80) - 70, rand(80) - 70)
@rocks << @rock
}
@no_congrats = false
start_motion
}
end
def update_status(lives, level, score)
@status_info.text = "lives: #{@lives} score: #{@score} level: #{@level}"
end
def break_rock(size, x, y)
case size
when 60
self.append{@rock1 = asteroid(30, x + 25, y)}
self.append{@rock2 = asteroid(30, x -25, y)}
@rocks << @rock1 << @rock2
@score += 25
when 30
self.append{@rock1 = asteroid(15, x + 25, y)}
self.append{@rock2 = asteroid(15, x - 25, y)}
self.append{@rock3 = asteroid(15, x, y - 25)}
@rocks << @rock1 << @rock2 << @rock3
@score += 50
when 15
@score += 100
end
update_status(@lives, @score, @level)
new_level if @rocks.empty?
end
def new_level
@game_motion.stop
@level += 1
update_status(@lives, @score, @level)
@ship.clear
init_level(@level)
end
def destroy_ship
@game_motion.stop
@ship.clear
@debris = []
50.times{
blasted_bit = oval(@ship.center_x + (rand(51) - 25), (@ship.center_y + (rand(51) - 25) + 30), 3, 3, fill: lime)
@debris << blasted_bit
}
@lives -= 1
update_status(@lives, @score, @level)
if @lives == 0
game_over
else
@no_congrats = true
timer(3){
@debris.each{|bit| bit.clear}
@debris.clear
init_level(@level)
}
end
end
def game_over
@game_over = true
@go_msg = []
@go_msg << banner("GAME OVER", top: 200)
@go_msg << title("press space to restart", top: 250)
end
def start_motion
@game_motion = animate 16 do
unless @game_motion.pause?
@ship.move_ship
@rocks.each{|rock|
rock.move_asteroid
rock.check_hits(@ship.center_x, @ship.center_y)
if rock.hit?
destroy_ship
end
}
unless @ship.shots.empty?
@ship.shots.each{|bullet|
@rocks.each{|rock|
rock.check_hits(bullet.x, bullet.y)
if rock.hit?
@rocks.delete(rock); rock.clear
@ship.shots.delete(bullet); bullet.clear
break_rock(rock.size, rock.x, rock.y)
end
}
}
end
end
end
end
@first_run = true
stack width: 700, margin_top: 100 do
stack do
banner "ASTEROIDS!\n"
para "move mouse to rotate ship"
para "use right mouse button to accelerate towards the pointer"
para "use left mouse button to shoot\n\n"
title "press space to start and pause"
end
end
@pause_message = title("paused", top: 230)
@pause_message.hide
keypress{|key|
if key == " "
if @game_over
[@go_msg, @debris, @rocks].each do |a|
a.each &:clear
a.clear
end
@status_info.clear
@first_run = true
end
if @first_run
clear{init_game}
@first_run = false
elsif @paused
@pause_message.hide
@game_motion.pause; @paused = false; @ship.paused = false
else
@game_motion.pause; @paused = true; @ship.paused = true
@pause_message.show
end
end
}
end
@ashbb
Copy link
Author

ashbb commented Apr 11, 2012

Original code, Asteroids Game for Red Shoes, was created by lljk (j. kaiden).

I've just revised the code for Green and Purple Shoes. Watch the following streaming flash demo.

Note: This revised code works both with Green and Purple. But in Green, need to comment out line 76. The ship doesn't rotate well in this code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment