Skip to content

Commit

Permalink
remove directions to cardinal points
Browse files Browse the repository at this point in the history
get emeny attacking and tracking when active
  • Loading branch information
David Henry committed Feb 13, 2012
1 parent ce4f86b commit d0b7a5c
Show file tree
Hide file tree
Showing 13 changed files with 272 additions and 35 deletions.
8 changes: 4 additions & 4 deletions lib/game/input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ def read
end

def bind_keys
bind_key(:w) { @player.move(:up) }
bind_key(:s) { @player.move(:down) }
bind_key(:a) { @player.move(:left) }
bind_key(:d) { @player.move(:right) }
bind_key(:w) { @player.move(Game::Map::NORTH) }
bind_key(:s) { @player.move(Game::Map::SOUTH) }
bind_key(:a) { @player.move(Game::Map::EAST) }
bind_key(:d) { @player.move(Game::Map::WEST) }

bind_key(:' ') { @player.take_action }

Expand Down
5 changes: 5 additions & 0 deletions lib/game/map.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
class Game
class Map
NORTH = :north
SOUTH = :south
EAST = :east
WEST = :west

def self.load_map(filename)
new(filename)
end
Expand Down
19 changes: 19 additions & 0 deletions lib/game/object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

class Game
class Object
IDLE = :idle
ACTIVE = :active

class << self
def instance(name, options={})
unless const_defined?(name)
Expand All @@ -37,6 +40,22 @@ def store(instance)
def objects
@objects ||= []
end

def engine_objects(level)
@game_objects ||= {}
@game_objects[level] ||= {Game::Object::IDLE => [],
Game::Object::ACTIVE => []}
@game_objects[level]
end

def add(level, status, obj)
engine_objects(level)[status] << obj
end

def clear
@game_objects = {}
@objects = []
end
end
end
end
1 change: 1 addition & 0 deletions lib/game/object/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ def self.included(base)
end

def initialize(options)
super
@options = options
end

Expand Down
52 changes: 50 additions & 2 deletions lib/game/object/enemy.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,63 @@
class Game
class Object
module Enemy
IDLE = :idle
def self.included(base)
base.send :attr_reader, :direction
end

def initialize(*args)
super
@direction = Game::Map::NORTH
Game::Object.add(Game::Engine.instance.map.name, status, self)
end

def passible?
false
end

def range
@options['range'] || 4
end

def status
IDLE
@status ||= Game::Object::IDLE
end

def active_turn
raise 'This should not happen.. only call when status is active..' unless status == Game::Object::ACTIVE
@direction = player_direction

if player_in_front?
Game::Player.instance.damage(attack)
elsif !player_in_range?
Game::Object.remove(Game::Engine.instance.map.name, status, self)
@status = Game::Object::IDLE
Game::Object.add(Game::Engine.instance.map.name, status, self)
elsif (tile = @tile.at(@direction)).passible?
move_to(tile)
end
end

def move_to(tile)
@tile.remove(self)
@tile = tile
@tile.add(self)
end

def player_in_range?
@tile.in_range?(Game::Player.instance.tile, range)
end
private :player_in_range?

def player_in_front?
@tile.at(@direction).has_object?(Game::Player)
end
private :player_in_front?

def player_direction
@tile.direction_to(Game::Player.instance.tile)
end
private :player_direction
end
end
end
26 changes: 22 additions & 4 deletions lib/game/tile/movement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,32 @@ class Game
class Tile
module Movement
def at(direction)
tile = Game::Tile.at(@x - 1, @y) if direction == :up
tile = Game::Tile.at(@x + 1, @y) if direction == :down
tile = Game::Tile.at(@x, @y - 1) if direction == :left
tile = Game::Tile.at(@x, @y + 1) if direction == :right
tile = Game::Tile.at(@x - 1, @y) if direction == Game::Map::NORTH
tile = Game::Tile.at(@x + 1, @y) if direction == Game::Map::SOUTH
tile = Game::Tile.at(@x, @y - 1) if direction == Game::Map::EAST
tile = Game::Tile.at(@x, @y + 1) if direction == Game::Map::WEST

tile.try(:end_point) || Game::Tile::Edge.instance
end

def direction_to(tile)
diff_x = x - tile.x
diff_y = y - tile.y

if diff_x.abs > diff_y.abs
diff_x > 0 ? Game::Map::NORTH : Game::Map::SOUTH
else
diff_y > 0 ? Game::Map::WEST : Game::Map::EAST
end
end

def in_range?(tile, max=10)
diff_x = x - tile.x
diff_y = y - tile.y

((diff_x * diff_x) + (diff_y * diff_y)) <= (max * max)
end

def end_point
if has_object?(Game::Object::TileModifier)
Game::Tile.at(*get_object(Game::Object::TileModifier).end_point)
Expand Down
2 changes: 1 addition & 1 deletion lib/game/tile/passible.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Game
class Tile
module Passible
def passible?(player_objects)
def passible?(player_objects=[])
objects.all?{|obj| !obj.respond_to?(:passible?) || obj.passible? }
end
end
Expand Down
8 changes: 4 additions & 4 deletions lib/render/console/draw_tile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ def draw_player(base)
return base unless tile.has_object?(Game::Player)
base[0] +
case Game::Player.instance.direction
when :up
when Game::Map::NORTH
'^'
when :down
when Game::Map::SOUTH
'v'
when :left
when Game::Map::EAST
'<'
when :right
when Game::Map::WEST
'>'
else
'*'
Expand Down
91 changes: 89 additions & 2 deletions spec/game/object/enemy_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
require 'spec_helper'

describe Game::Object::Enemy do
subject { Game::Object.instance('TestEnemy', 'modules' => ['Enemy'])}
subject { Game::Object.instance('TestEnemy', 'modules' => ['Enemy'], 'attack' => 10)}
let(:engine) { mock(:engine, :map => map) }
let(:map) { mock(:map, :name => 'map_name') }
before do
Game::Engine.stub(:instance => engine)
end

describe '#passible?' do
it 'is false' do
Expand All @@ -11,7 +16,89 @@

describe '#status' do
it 'is idle when left alone' do
subject.status.should == Game::Object::Enemy::IDLE
subject.status.should == Game::Object::IDLE
end
end

describe '#initialization' do
it 'added as an idle object' do
Game::Object.should_receive(:add).with('map_name', Game::Object::IDLE, subject)
subject
end
end

describe '#active_turn' do
let(:front_tile) { Game::Tile.build(0, 0, 1) }
let(:tile) { Game::Tile.build(0, 1, 1) }
let(:back_tile) { Game::Tile.build(0, 2, 1) }
let(:distant_tile) { Game::Tile.build(0, 3, 1) }
let(:range_tile) { Game::Tile.build(0, 11, 1) }
let(:player) { Game::Player.new }
before do
tile.add(subject)
front_tile
back_tile
distant_tile
range_tile
subject.instance_variable_set(:@status, Game::Object::ACTIVE)
end

it 'return raise an eror is status is not active' do
subject.instance_variable_set(:@status, Game::Object::IDLE)
expect { subject.active_turn }.to raise_error
end

context 'player directly in front' do
before do
tile.stub(:direction_to => Game::Map::NORTH, :in_range => true)
end

it 'attacks' do
front_tile.add(player)
player.should_receive(:damage).with(10)
subject.active_turn
end
end

context 'player out of active distance' do
before do
range_tile.add(player)
tile.stub(:in_range? => false)
tile.stub(:direction_to => Game::Map::NORTH, :range => true)
end

it 'sets the enemy unit to idle' do
tile.should_receive(:direction_to).with(range_tile)
Game::Object.should_receive(:remove).with('map_name', Game::Object::ACTIVE, subject)
Game::Object.should_receive(:add).with('map_name', Game::Object::IDLE, subject)
subject.active_turn
end
end

context 'player not in front' do
before do
tile.stub(:direction_to => Game::Map::SOUTH, :in_range? => true)
end

it 'turn to face the player' do
back_tile.add(player)
tile.should_receive(:direction_to).with(back_tile)
subject.active_turn
subject.direction.should == Game::Map::SOUTH
end

it 'attack the player if in the new direction' do
back_tile.add(player)
player.should_receive(:damage).with(10)
subject.active_turn
end

it 'move in the next direction if player is not directly there' do
distant_tile.add(player)
tile.should_receive(:remove).with(subject)
back_tile.should_receive(:add).with(subject)
subject.active_turn
end
end
end
end
10 changes: 10 additions & 0 deletions spec/game/object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,15 @@
Game::Object.objects.should include(passage)
end
end

describe '#add' do
before { Game::Object.clear }

it 'adds the object to the list of engine run objects' do
Game::Object.add('test_map', Game::Object::IDLE, :object_here)

Game::Object.engine_objects('test_map').should == {Game::Object::IDLE => [:object_here], Game::Object::ACTIVE => []}
end
end
end
end
14 changes: 7 additions & 7 deletions spec/game/player/movements_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@
end

it 'delegates the movement to the current tile' do
tile.should_receive(:at).with(:up)
subject.move(:up)
tile.should_receive(:at).with(Game::Map::NORTH)
subject.move(Game::Map::NORTH)
end

context 'the new tile is passible' do
it 'moves the player' do
subject.move(:up)
subject.move(Game::Map::NORTH)
subject.tile.should == passible_tile
end

it 'move the player object from the old tile to the new tile' do
tile.should_receive(:remove).with(subject)
passible_tile.should_receive(:add).with(subject)
subject.move(:up)
subject.move(Game::Map::NORTH)
end

it 'process and automatic actions' do
subject.should_receive(:take_auto_action)
subject.move(:up)
subject.move(Game::Map::NORTH)
end
end

Expand All @@ -55,13 +55,13 @@

it 'does not move the player' do
subject.stub(:print => true)
subject.move(:up)
subject.move(Game::Map::NORTH)
subject.tile.should == tile
end

it 'plays a beep' do
subject.should_receive(:print).with("\a")
subject.move(:up)
subject.move(Game::Map::NORTH)
end
end
end
Expand Down
Loading

0 comments on commit d0b7a5c

Please sign in to comment.