Created
May 11, 2012 18:17
-
-
Save shawn42/2661476 to your computer and use it in GitHub Desktop.
The guts of omg_aliens
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# src/actors/alien.rb | |
define_actor :alien do | |
has_attributes action: :march, view: :graphical_actor_view | |
has_behaviors do | |
animated frame_update_time: 900 | |
collidable shape: :polygon, cw_local_points: [[4,4],[44,4],[44,44],[4,44]] | |
projectile speed: 0.01, direction: vec2(1,0) | |
reversable_direction | |
increasing_speed accel: 0.001 | |
drops fall_amount: 25 | |
shooter shoots: :alien_missile, direction: vec2(0,-1) | |
end | |
end | |
# src/actors/alien_missile.rb | |
define_actor :alien_missile do | |
has_behaviors do | |
in_bounds_or_death bounds: [0,0,:viewport_width,:viewport_height] | |
projectile speed: 0.3, direction: vec2(0, 1) | |
collidable shape: :polygon, cw_local_points: [[0,0],[8,0],[4,10]] | |
end | |
view do | |
draw do |target, x_offset, y_offset, z| | |
target.fill(actor.x, actor.y, actor.x+actor.radius/2.0, actor.y-actor.radius*2, [0xff, 0xff, 0xff], z) | |
end | |
end | |
end | |
# src/actors/frickin_laser.rb | |
define_actor :frickin_laser do | |
has_behaviors do | |
in_bounds_or_death bounds: [0,30,:viewport_width,:viewport_height] | |
projectile speed: 0.4, direction: vec2(0, -1) | |
collidable shape: :circle, :radius => 4 | |
end | |
view do | |
draw do |target, x_offset, y_offset, z| | |
target.fill(actor.x, actor.y, actor.x+actor.radius/2.0, actor.y-actor.radius*2, [0xff, 0xff, 0xff], z) | |
end | |
end | |
end | |
# src/actors/player.rb | |
define_actor :player do | |
has_behaviors do | |
graphical | |
audible | |
keyboard_movement | |
keyboard_shooting | |
collidable shape: :circle, :radius => 20 | |
shooter shoots: :frickin_laser, direction: vec2(0,1) | |
mover speed: 0.14 | |
end | |
end | |
# src/actors/score_fade.rb | |
define_actor :score_fade do | |
# label fader behavior | |
behavior do | |
requires :director, :stage | |
setup do | |
actor.has_attributes initial_ttl: actor.ttl, | |
label: stage.create_actor(:label, actor.attributes.merge(text: actor.score, layer: 99)) | |
director.when :update do |time| | |
actor.ttl -= time | |
if actor.ttl <= 0 | |
actor.remove | |
else | |
percent_time_left = actor.ttl / actor.initial_ttl.to_f | |
color_val = 255 * percent_time_left | |
actor.label.color = Color.new color_val, color_val, color_val, color_val | |
end | |
end | |
actor.when :remove_me do | |
director.unsubscribe_all self | |
actor.label.remove | |
end | |
end | |
end | |
end | |
# src/actors/ufo.rb | |
define_actor :ufo do | |
has_behaviors do | |
graphical | |
audible | |
projectile speed: 0.12, direction: vec2(1, 0) | |
collidable shape: :circle, radius: 10 | |
in_bounds_or_death bounds: [0,0,:viewport_width,:viewport_height] | |
# TODO clean up viewport access? | |
end | |
behavior do | |
setup do | |
actor.react_to :play_sound, :ufo_flying, looping: true | |
actor.when :remove_me do | |
actor.react_to :stop_sound, :ufo_flying | |
end | |
end | |
end | |
end | |
# src/app.rb | |
#!/usr/bin/env ruby | |
$: << "#{File.dirname(__FILE__)}/../config" | |
require 'environment' | |
if $0 == __FILE__ | |
GameboxApp.run ARGV, ENV | |
end | |
# src/behaviors/drop_down.rb | |
define_behavior :drops do | |
setup do | |
actor.has_attributes fall_amount: opts[:fall_amount] | |
reacts_with :drop_down | |
end | |
helpers do | |
def drop_down | |
actor.y += actor.fall_amount | |
end | |
end | |
end | |
# src/behaviors/in_bounds_or_death.rb | |
define_behavior :in_bounds_or_death do | |
requires :director, :viewport | |
setup do | |
bounds = opts[:bounds].map do |v| | |
if v == :viewport_width | |
viewport.width | |
elsif v == :viewport_height | |
viewport.height | |
else | |
v | |
end | |
end | |
actor.has_attributes safe_bounds: Rect.new(bounds) | |
director.when :update do |time| | |
actor.remove unless actor.safe_bounds.collide_point? actor.x, actor.y | |
end | |
actor.when :remove_me do | |
director.unsubscribe_all self | |
end | |
end | |
end | |
# src/behaviors/increasing_speed.rb | |
define_behavior :increasing_speed do | |
requires :backstage | |
setup do | |
actor.has_attributes speed: 0, accel: 0 | |
reacts_with :increase_speed | |
end | |
helpers do | |
def increase_speed | |
actor.speed += actor.accel * backstage[:wave] | |
end | |
end | |
end | |
# src/behaviors/keyboard_movement.rb | |
define_behavior :keyboard_movement do | |
requires :input_manager | |
setup do | |
actor.has_attributes :move_left, :move_right | |
i = input_manager | |
i.while_pressed KbLeft, actor, :move_left | |
i.while_pressed KbRight, actor, :move_right | |
end | |
end | |
# src/behaviors/keyboard_shooting.rb | |
define_behavior :keyboard_shooting do | |
requires :input_manager | |
setup do | |
input_manager.reg :keyboard_down, KbSpace do | |
actor.react_to :shoot | |
end | |
end | |
end | |
# src/behaviors/mover.rb | |
define_behavior :mover do | |
requires_behaviors :positioned | |
requires :director, :viewport | |
setup do | |
actor.has_attributes speed: opts[:speed] | |
director.when :update do |time| | |
velocity = actor.speed * time | |
actor.x += velocity if actor.move_right? | |
actor.x -= velocity if actor.move_left? | |
stage_left = 0 | |
stage_right = viewport.width-20 | |
if actor.x > stage_right | |
actor.x = stage_right | |
elsif actor.x < stage_left | |
actor.x = stage_left | |
end | |
end | |
end | |
end | |
# src/behaviors/projectile.rb | |
define_behavior :projectile do | |
requires_behaviors :positioned | |
requires :director | |
setup do | |
actor.has_attributes direction: opts[:direction].dup, | |
speed: opts[:speed] | |
director.when :update do |time| | |
move_vector = actor.direction * time * actor.speed | |
actor.x += move_vector.x | |
actor.y += move_vector.y | |
end | |
end | |
end | |
# src/behaviors/reversable_direction.rb | |
define_behavior :reversable_direction do | |
setup do | |
actor.has_attributes direction: vec2(0,0).dup | |
reacts_with :reverse_direction | |
end | |
helpers do | |
def reverse_direction | |
# Ftor#reverse! | |
actor.direction.reverse! | |
end | |
end | |
end | |
# src/behaviors/shooter.rb | |
define_behavior :shooter do | |
requires :input_manager, :stage | |
requires_behaviors :positioned | |
setup do | |
actor.has_attributes can_shoot: true | |
reacts_with :shoot | |
end | |
helpers do | |
def shoot | |
if actor.can_shoot? | |
actor.can_shoot = false | |
actor.react_to :play_sound, :shoot | |
ammunition = stage.create_actor opts[:shoots], x: actor.x + (actor.image.width/2), y: actor.y | |
ammunition.when :remove_me do | |
actor.can_shoot = true | |
end | |
end | |
end | |
end | |
end | |
# src/demo_stage.rb | |
class DemoStage < Stage | |
def setup | |
super | |
backstage[:wave] ||= 0 | |
backstage[:wave] += 1 | |
@player = create_actor :player, x: 200, y: 550 | |
input_manager.reg :down, KbW do | |
@aliens = [] | |
end | |
@score = create_actor :score, x: 10, y: 10 | |
create_actor :fps, x: 400, y: 10 | |
create_actor :logo, x: 480, y: 460 | |
@aliens = [] | |
columns = 8 | |
rows = 2 + backstage[:wave] | |
columns.times do |c| | |
rows.times do |r| | |
alien = create_actor :alien, x: 20+c*60, y: 40+r*60 | |
alien.when :remove_me do | |
if @aliens.size % 3 == 0 | |
@aliens.each{|a|a.react_to :increase_speed} | |
end | |
end | |
@aliens << alien | |
end | |
end | |
input_manager.reg :down, KbP do | |
pause | |
end | |
on_unpause do | |
sound_manager.play_sound :pause | |
sound_manager.play_music :rush_remix | |
sound_manager.play_sound :ufo_flying, repeats: -1 if @ufo | |
@pause.remove | |
end | |
on_pause do | |
sound_manager.stop_sound :ufo_flying if @ufo and @ufo.alive? | |
sound_manager.pause_music :rush_remix | |
sound_manager.play_sound :pause | |
@pause = create_actor :label, text: "pause", x: 280, y: 300, size: 20 | |
input_manager.reg :down, KbP do | |
unpause | |
end | |
end | |
on_collision_of :ufo, :frickin_laser do |ufo,laser| | |
ufo_shot ufo, laser | |
end | |
on_collision_of :alien, :frickin_laser do |alien,laser| | |
alien_shot alien, laser | |
end | |
on_collision_of :player, [:alien,:alien_missile] do |player,bad_thing| | |
you_lose | |
end | |
add_timer :alien_shoot, (4-backstage[:wave])*1_000 do | |
@aliens[rand(@aliens.size)].react_to :shoot unless @aliens.empty? | |
end | |
add_timer :ufo_create_actor, 9_000 do | |
if @ufo.nil? | |
if (@aliens.size > 7) | |
@ufo = create_actor :ufo, x: 10, y: 30 | |
@ufo.when :remove_me do | |
@ufo = nil | |
end | |
end | |
end | |
end | |
sound_manager.play_music :rush_remix if backstage[:wave] == 1 | |
end | |
def ufo_shot(ufo, laser) | |
sound_manager.play_sound :ufo_death | |
create_actor :score_fade, x: ufo.x, y: ufo.y, score: 1000, ttl: 1000 | |
ufo.remove | |
laser.remove | |
@score.react_to :add, 1000 | |
@ufo = nil | |
end | |
def alien_shot(alien, laser) | |
create_actor :score_fade, x: alien.x, y: alien.y, score: 100, ttl: 1000 | |
@aliens.delete alien | |
alien.remove | |
laser.remove | |
sound_manager.play_sound :death | |
@score.react_to :add, 100 | |
end | |
def rebuild_bounding_box | |
return if @aliens.empty? | |
alien_x_values = @aliens.collect &:x | |
alien_y_values = @aliens.collect &:y | |
min_x = alien_x_values.min | |
max_x = alien_x_values.max | |
max_y = [email protected] | |
dir = @aliens.first.direction.x | |
if (max_x > [email protected] and dir == 1) or | |
(min_x < 20 and dir == -1) | |
@aliens.each{|a| | |
a.react_to :increase_speed | |
a.react_to :drop_down | |
a.react_to :reverse_direction | |
} | |
end | |
if max_y > @player.y | |
you_lose | |
end | |
end | |
def you_lose | |
if @player.alive? | |
sound_manager.play_sound :player_death | |
create_actor :label, text: "YOU LOSE!", x: 150, y: 100, size: 90 | |
@player.remove | |
add_timer :you_lose, 1_500 do | |
fire :prev_stage | |
end | |
end | |
end | |
def update(time) | |
super | |
rebuild_bounding_box | |
if @aliens.empty? | |
@player.remove | |
if backstage[:wave] == 3 | |
fire :next_stage | |
else | |
fire :restart_stage | |
end | |
end | |
end | |
def add_timer(*args, &blk) | |
timer_manager.add_timer *args, &blk | |
end | |
end | |
# src/win_stage.rb | |
class WinStage < Stage | |
def setup | |
super | |
create_actor :logo, :x => 480, :y => 360 | |
create_actor :label, :text => "YOU WIN!", :x => 150, :y => 100, :size => 90 | |
create_actor :label, :text => "SCORE:", :x => 40, :y => 200, :size => 90 | |
create_actor :label, :text => backstage[:score], :x => 300, :y => 200, :size => 90 | |
end | |
def draw(target) | |
target.fill [0]*3 | |
super | |
end | |
end | |
# config/environment.rb | |
APP_ROOT = "#{File.join(File.dirname(__FILE__),"..")}/" | |
require 'gamebox' | |
Gamebox.configure do |config| | |
config.config_path = APP_ROOT + "config/" | |
config.data_path = APP_ROOT + "data/" | |
config.music_path = APP_ROOT + "data/music/" | |
config.sound_path = APP_ROOT + "data/sounds/" | |
config.gfx_path = APP_ROOT + "data/graphics/" | |
config.fonts_path = APP_ROOT + "data/fonts" | |
config.gb_config_path = GAMEBOX_PATH + "config/" | |
config.gb_data_path = GAMEBOX_PATH + "data/" | |
config.gb_music_path = GAMEBOX_PATH + "data/music/" | |
config.gb_sound_path = GAMEBOX_PATH + "data/sounds/" | |
config.gb_gfx_path = GAMEBOX_PATH + "data/graphics/" | |
config.gb_fonts_path = GAMEBOX_PATH + "data/fonts" | |
config.stages = [:demo, :win] | |
config.game_name = "OMG Aliens" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment