lotu 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/examples/hello_world/moving_portraits.rb +92 -0
- data/examples/screen_cursor/mouse_and_keyboard_cursors.rb +141 -0
- data/examples/steering_behaviors/pursuit_and_evade.rb +109 -0
- data/examples/steering_behaviors/pursuit_and_evade_multiple.rb +116 -0
- data/lib/lotu/actor.rb +39 -9
- data/lib/lotu/cursor.rb +2 -2
- data/lib/lotu/game.rb +34 -10
- data/lib/lotu/systems/steering_system.rb +31 -9
- data/lib/lotu/systems/transformation_system.rb +122 -0
- data/lib/lotu/text_box.rb +14 -2
- data/lib/lotu.rb +1 -1
- data/lotu.gemspec +11 -8
- metadata +12 -9
- data/examples/hello_world/hello_world.rb +0 -77
- data/examples/mouse_pointer/mouse_pointer.rb +0 -92
- data/examples/steering_behaviors/steering.rb +0 -86
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.1.
|
|
1
|
+
0.1.12
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# Hello world for lotu
|
|
4
|
+
# Here you will learn about:
|
|
5
|
+
# * Loading image resources
|
|
6
|
+
# * Binding keys to window and actors
|
|
7
|
+
# * How to display text on screen using a text box
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
LIB_PATH = File.join(File.dirname(__FILE__), '..', '..', 'lib', 'lotu.rb')
|
|
11
|
+
require File.expand_path(LIB_PATH)
|
|
12
|
+
|
|
13
|
+
include Gosu
|
|
14
|
+
include Lotu
|
|
15
|
+
|
|
16
|
+
# We want to move something around the screen so we create a new Actor
|
|
17
|
+
# subclass, set the image all instances of it are going to use and
|
|
18
|
+
# define the movement methods
|
|
19
|
+
class Lobo < Actor
|
|
20
|
+
|
|
21
|
+
def initialize(opts={})
|
|
22
|
+
# It's important to call super so we take advantage of automatic
|
|
23
|
+
# management for this object (being added to draw and update queue)
|
|
24
|
+
super
|
|
25
|
+
# Use the image which filename is "lobo_tuerto.png", and scale
|
|
26
|
+
# it's appearance to half width and half height
|
|
27
|
+
set_image 'lobo_tuerto.png', :factor_x => 0.5, :factor_y => 0.5
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Let's define some basic movement methods
|
|
31
|
+
def move_right; @x += 1 end
|
|
32
|
+
def move_left; @x -= 1 end
|
|
33
|
+
def move_up; @y -= 1 end
|
|
34
|
+
def move_down; @y += 1 end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Let's subclass the Game class and write some code!
|
|
39
|
+
class Portraits < Game
|
|
40
|
+
|
|
41
|
+
def initialize
|
|
42
|
+
# This will call the hooks:
|
|
43
|
+
# load_resources, setup_systems, setup_input and setup_actors
|
|
44
|
+
# declared in the parent class
|
|
45
|
+
super
|
|
46
|
+
# When the Escape key is pressed, call the close method on
|
|
47
|
+
# instance of class Portraits, when D key is pressed turn on
|
|
48
|
+
# debug, we pass false into the array to tell the input system we
|
|
49
|
+
# don't want autofire on, else pass the number of milliseconds
|
|
50
|
+
# (zero and no array is the same)
|
|
51
|
+
set_keys(KbEscape => :close,
|
|
52
|
+
KbD => [:debug!, false])
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# This method is called when we call super inside initialize
|
|
56
|
+
def load_resources
|
|
57
|
+
# From this file,
|
|
58
|
+
with_path_from_file(__FILE__) do
|
|
59
|
+
# go back one dir and search inside media/images
|
|
60
|
+
load_images '../media/images'
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# This method is called when we call super inside initialize
|
|
65
|
+
def setup_actors
|
|
66
|
+
# Create a lobo in the middle of the screen
|
|
67
|
+
@lobo1 = Lobo.new(:x => width/2, :y => height/2)
|
|
68
|
+
# Map keys to some methods
|
|
69
|
+
@lobo1.set_keys(KbRight => :move_right,
|
|
70
|
+
KbLeft => :move_left,
|
|
71
|
+
KbUp => :move_up,
|
|
72
|
+
KbDown => :move_down)
|
|
73
|
+
|
|
74
|
+
# Rinse and repeat... but invert some keys
|
|
75
|
+
@lobo2 = Lobo.new(:x => width/2, :y => height/2)
|
|
76
|
+
@lobo2.set_keys(KbRight => :move_left,
|
|
77
|
+
KbLeft => :move_right,
|
|
78
|
+
KbUp => :move_up,
|
|
79
|
+
KbDown => :move_down)
|
|
80
|
+
|
|
81
|
+
# Create a TextBox so we can display a message on screen
|
|
82
|
+
@info = TextBox.new
|
|
83
|
+
# Add some text
|
|
84
|
+
@info.text("Hello world!")
|
|
85
|
+
# Add more text, but specify the color and size in pixels
|
|
86
|
+
@info.text("Move the portraits around with arrow keys", :size => 16, :color => 0xff33ccff)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Create and show the app
|
|
92
|
+
Portraits.new.show
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# lotu's cursors
|
|
4
|
+
# Here you will learn about:
|
|
5
|
+
# * The Cursor class included in lotu
|
|
6
|
+
# * How to register events
|
|
7
|
+
# * How to use the systems provided by lotu
|
|
8
|
+
|
|
9
|
+
LIB_PATH = File.join(File.dirname(__FILE__), '..', '..', 'lib', 'lotu.rb')
|
|
10
|
+
require File.expand_path(LIB_PATH)
|
|
11
|
+
|
|
12
|
+
include Gosu
|
|
13
|
+
include Lotu
|
|
14
|
+
|
|
15
|
+
# Create a class for displaying something on screen
|
|
16
|
+
class Lobo < Actor
|
|
17
|
+
def initialize(opts={})
|
|
18
|
+
super
|
|
19
|
+
set_image 'lobo_tuerto.png', :width => 100
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Define a method for teleporting our instances around
|
|
23
|
+
def teleport(x, y)
|
|
24
|
+
@x, @y = x, y
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class Cursors < Game
|
|
29
|
+
def initialize
|
|
30
|
+
# This will call the hooks:
|
|
31
|
+
# load_resources, setup_systems, setup_input and setup_actors
|
|
32
|
+
# declared in the parent class
|
|
33
|
+
super
|
|
34
|
+
# Custom setup methods for this class
|
|
35
|
+
setup_events
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def load_resources
|
|
39
|
+
with_path_from_file(__FILE__) do
|
|
40
|
+
load_images '../media/images'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def setup_systems
|
|
45
|
+
# It's important to call super here to setup the InputSystem in
|
|
46
|
+
# the parent class
|
|
47
|
+
super
|
|
48
|
+
# To use the systems lotu provides, you just "use" them
|
|
49
|
+
# Let's activate the FPS system, so we can track the frames per
|
|
50
|
+
#second our app is pushing out
|
|
51
|
+
use(FpsSystem)
|
|
52
|
+
# Activate the stalker system to track how many objects of these
|
|
53
|
+
# classes are around
|
|
54
|
+
use(StalkerSystem, :stalk => [Actor, Cursor, TextBox, Lobo, Object])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Setup some input handling for our Cursors app
|
|
58
|
+
def setup_input
|
|
59
|
+
set_keys(KbEscape => :close,
|
|
60
|
+
KbD => [:debug!, false],
|
|
61
|
+
KbT => [:toggle_text, false])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Now onto define some events
|
|
65
|
+
def setup_events
|
|
66
|
+
# When the left mouse button is clicked (as defined below in
|
|
67
|
+
# setup_actors) call the teleport method in @lobo
|
|
68
|
+
@cursor1.on(:click) do |x,y|
|
|
69
|
+
@lobo.teleport(x,y)
|
|
70
|
+
end
|
|
71
|
+
# When the space bar is pressed (see below in setup_actors) call
|
|
72
|
+
# the teleport method in @lobo
|
|
73
|
+
@cursor2.on(:click) do |x,y|
|
|
74
|
+
@lobo.teleport(x,y)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def setup_actors
|
|
79
|
+
# Create a portrait to teleport around with "clicks"
|
|
80
|
+
@lobo = Lobo.new(:x => width/2, :y => height/2)
|
|
81
|
+
|
|
82
|
+
# The cursor class defines a method named (you guessed) "click",
|
|
83
|
+
# when this method is called, it fires an event named (again)
|
|
84
|
+
# "click", that's why we attached some code to that event in
|
|
85
|
+
# setup_events
|
|
86
|
+
@cursor1 = Cursor.new(:image => 'crosshair-1.png',
|
|
87
|
+
:keys => {MsLeft => [:click, false]},
|
|
88
|
+
:width => 100,
|
|
89
|
+
:rand_color => true,
|
|
90
|
+
:mode => :additive)
|
|
91
|
+
@cursor1.transform_angle(:init => 0, :end => 359, :duration => 10, :loop => true)
|
|
92
|
+
|
|
93
|
+
@cursor2 = Cursor.new(:image => 'crosshair-2.png',
|
|
94
|
+
:use_mouse => false,
|
|
95
|
+
:keys => {
|
|
96
|
+
KbSpace => [:click, false],
|
|
97
|
+
KbUp => :up,
|
|
98
|
+
KbDown => :down,
|
|
99
|
+
KbLeft => :left,
|
|
100
|
+
KbRight => :right},
|
|
101
|
+
:width => 100,
|
|
102
|
+
:rand_color => true,
|
|
103
|
+
:mode => :additive)
|
|
104
|
+
@cursor2.transform_angle(:init => 359, :end => 0, :duration => 1, :loop => true)
|
|
105
|
+
|
|
106
|
+
# Center @cursor2 vertically and move it to the right 3/4 of the
|
|
107
|
+
# screen
|
|
108
|
+
@cursor2.x = width*3/4
|
|
109
|
+
@cursor2.y = height/2
|
|
110
|
+
|
|
111
|
+
# Here we tell the TextBox to watch some objects, the TextBox will
|
|
112
|
+
# call the to_s method on the objects it's watching
|
|
113
|
+
# Create a TextBox with default option :size => 15
|
|
114
|
+
@info = TextBox.new(:size => 15)
|
|
115
|
+
@info.text("Press T to hide this text", :size => 24)
|
|
116
|
+
# Watch the FPS, so we get a nice FPS report on the screen
|
|
117
|
+
@info.watch(@systems[FpsSystem], :size => 20)
|
|
118
|
+
# Watch the Stalker system, so we know how many objects of the
|
|
119
|
+
# classes we specified up in setup_systems are around
|
|
120
|
+
@info.watch(@systems[StalkerSystem], :color => 0xff3ffccf)
|
|
121
|
+
# We can change the size for a specific line of text
|
|
122
|
+
@info.text("@cursor1 data:", :size => 20)
|
|
123
|
+
@info.text("move with Mouse | click with LeftMouseButton")
|
|
124
|
+
# And color
|
|
125
|
+
@info.watch(@cursor1, :color => @cursor1.color)
|
|
126
|
+
|
|
127
|
+
# Lets watch @cursor2 too
|
|
128
|
+
@info.text("@cursor2 data:", :size => 20)
|
|
129
|
+
@info.text("move with Arrow keys | click with Space")
|
|
130
|
+
@info.watch(@cursor2, :color => @cursor2.color)
|
|
131
|
+
@info.text("click to teleport the portrait!")
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def toggle_text
|
|
135
|
+
@info.toggle!
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Create and start the game loop by showing the app
|
|
141
|
+
Cursors.new.show
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# Here you will learn about:
|
|
4
|
+
# * The steering system
|
|
5
|
+
# * How to play animations
|
|
6
|
+
# * How to attach a text box to an actor
|
|
7
|
+
|
|
8
|
+
LIB_PATH = File.join(File.dirname(__FILE__), '..', '..', 'lib', 'lotu.rb')
|
|
9
|
+
require File.expand_path(LIB_PATH)
|
|
10
|
+
|
|
11
|
+
include Gosu
|
|
12
|
+
include Lotu
|
|
13
|
+
|
|
14
|
+
# Let's define a Missile class that will use a Steering system to
|
|
15
|
+
# control it's movement
|
|
16
|
+
class Missile < Actor
|
|
17
|
+
def initialize(opts={})
|
|
18
|
+
super
|
|
19
|
+
# Activate the steering system and pass the opts, since they might
|
|
20
|
+
# have some config info for the system
|
|
21
|
+
use(SteeringSystem, opts)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def teleport(x, y)
|
|
25
|
+
@pos.x, @pos.y = x, y
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The main app class
|
|
30
|
+
class SteeringMissiles < Game
|
|
31
|
+
def initialize
|
|
32
|
+
# This will call the hooks:
|
|
33
|
+
# load_resources, setup_systems, setup_input and setup_actors
|
|
34
|
+
# declared in the parent class
|
|
35
|
+
super
|
|
36
|
+
# Custom setup methods for this class
|
|
37
|
+
setup_events
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Let's load some images and animations, check out the animations
|
|
41
|
+
# directory, the animation there was created with:
|
|
42
|
+
# {Sprite Sheet Packer}[http://spritesheetpacker.codeplex.com/]
|
|
43
|
+
def load_resources
|
|
44
|
+
with_path_from_file(__FILE__) do
|
|
45
|
+
load_images '../media/images'
|
|
46
|
+
load_animations '../media/animations'
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def setup_input
|
|
51
|
+
set_keys(KbEscape => :close,
|
|
52
|
+
MsRight => :teleport_big_missile_to_midscreen,
|
|
53
|
+
KbD => [:debug!, false],
|
|
54
|
+
KbT => [:toggle_missile_info, false])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def setup_systems
|
|
58
|
+
# It's important to call super here to setup the InputSystem
|
|
59
|
+
super
|
|
60
|
+
use(FpsSystem)
|
|
61
|
+
use(StalkerSystem, :stalk => [Actor, Missile, Vector2d, Object])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def setup_actors
|
|
65
|
+
@big_missile = Missile.new(:mass => 0.3, :max_speed => 100, :max_turn_rate => 140)
|
|
66
|
+
@big_missile.teleport(width/2, height/2)
|
|
67
|
+
@big_missile.activate(:evade)
|
|
68
|
+
@big_missile.play_animation('missile.png')
|
|
69
|
+
|
|
70
|
+
@little_missile = Missile.new
|
|
71
|
+
@little_missile.activate(:pursuit)
|
|
72
|
+
@little_missile.play_animation('missile.png', :fps => 60, :height => 20)
|
|
73
|
+
|
|
74
|
+
@cursor = Cursor.new(:image => 'crosshair-3.png',
|
|
75
|
+
:keys => {MsLeft => [:click, false]},
|
|
76
|
+
:rand_color => true)
|
|
77
|
+
|
|
78
|
+
@window_info = TextBox.new(:size => 15)
|
|
79
|
+
@window_info.text("Press T to hide this text", :size => 24)
|
|
80
|
+
@window_info.watch(@systems[FpsSystem], :size => 20)
|
|
81
|
+
@window_info.watch(@systems[StalkerSystem], :color => 0xff33ccff)
|
|
82
|
+
@window_info.watch(@cursor, :color => @cursor.color)
|
|
83
|
+
@window_info.text("Click to start the simulation", :color => 0xffffff00)
|
|
84
|
+
@window_info.text("One will pursuit while the other evades, right click to center evader on screen")
|
|
85
|
+
|
|
86
|
+
@missile_info = TextBox.new(:attach_to => @big_missile, :size => 14)
|
|
87
|
+
@missile_info.watch(@big_missile)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def setup_events
|
|
91
|
+
@cursor.on(:click) do |x,y|
|
|
92
|
+
@big_missile.pursuer = @little_missile
|
|
93
|
+
@little_missile.evader = @big_missile
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def teleport_big_missile_to_midscreen
|
|
98
|
+
@big_missile.pos.x = width/2
|
|
99
|
+
@big_missile.pos.y = height/2
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def toggle_missile_info
|
|
103
|
+
@missile_info.toggle!
|
|
104
|
+
@window_info.toggle!
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Create and start the application
|
|
109
|
+
SteeringMissiles.new.show
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# Here you will learn about:
|
|
4
|
+
# * The steering system pursuit, and evade_multiple behaviors
|
|
5
|
+
# * How to play animations
|
|
6
|
+
# * How to attach a text box to an actor
|
|
7
|
+
|
|
8
|
+
LIB_PATH = File.join(File.dirname(__FILE__), '..', '..', 'lib', 'lotu.rb')
|
|
9
|
+
require File.expand_path(LIB_PATH)
|
|
10
|
+
|
|
11
|
+
include Gosu
|
|
12
|
+
include Lotu
|
|
13
|
+
|
|
14
|
+
# Let's define a Missile class that will use a Steering system to
|
|
15
|
+
# control it's movement
|
|
16
|
+
class Missile < Actor
|
|
17
|
+
def initialize(opts={})
|
|
18
|
+
super
|
|
19
|
+
# Activate the steering system and pass the opts, since they might
|
|
20
|
+
# have some config info for the system
|
|
21
|
+
use(SteeringSystem, opts)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def teleport(x, y)
|
|
25
|
+
@pos.x, @pos.y = x, y
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The main app class
|
|
30
|
+
class EvadeMultiple < Game
|
|
31
|
+
def initialize
|
|
32
|
+
# This will call the hooks:
|
|
33
|
+
# load_resources, setup_systems, setup_input and setup_actors
|
|
34
|
+
# declared in the parent class
|
|
35
|
+
super
|
|
36
|
+
# Custom setup methods for this class
|
|
37
|
+
setup_events
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Let's load some images and animations, check out the animations
|
|
41
|
+
# directory, the animation there was created with:
|
|
42
|
+
# {Sprite Sheet Packer}[http://spritesheetpacker.codeplex.com/]
|
|
43
|
+
def load_resources
|
|
44
|
+
with_path_from_file(__FILE__) do
|
|
45
|
+
load_images '../media/images'
|
|
46
|
+
load_animations '../media/animations'
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def setup_input
|
|
51
|
+
set_keys(KbEscape => :close,
|
|
52
|
+
MsRight => :teleport_big_missile_to_midscreen,
|
|
53
|
+
KbD => [:debug!, false],
|
|
54
|
+
KbT => [:toggle_info, false],
|
|
55
|
+
KbSpace => [:pause!, false])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def setup_systems
|
|
59
|
+
# It's important to call super here to setup the InputSystem
|
|
60
|
+
super
|
|
61
|
+
use(FpsSystem)
|
|
62
|
+
use(StalkerSystem, :stalk => [Actor, Missile, Vector2d, Object])
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def setup_actors
|
|
66
|
+
@big_missile = Missile.new(:mass => 0.3, :max_speed => 100, :max_turn_rate => 140)
|
|
67
|
+
@big_missile.teleport(width/2, height/2)
|
|
68
|
+
@big_missile.activate(:evade_multiple)
|
|
69
|
+
@big_missile.play_animation('missile.png')
|
|
70
|
+
|
|
71
|
+
@little_missiles = []
|
|
72
|
+
5.times do |i|
|
|
73
|
+
@little_missiles << Missile.new(:x => 200 - rand(400), :y => 200 - rand(400), :rand_color => true)
|
|
74
|
+
@little_missiles[i].activate(:pursuit)
|
|
75
|
+
@little_missiles[i].play_animation('missile.png', :fps => 60+rand(60), :height => 10+rand(30))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
@cursor = Cursor.new(:image => 'crosshair-3.png',
|
|
79
|
+
:keys => {MsLeft => [:click, false]},
|
|
80
|
+
:rand_color => true)
|
|
81
|
+
|
|
82
|
+
@window_info = TextBox.new(:size => 15)
|
|
83
|
+
@window_info.text("Press T to hide this text", :size => 24)
|
|
84
|
+
@window_info.watch(@systems[FpsSystem], :size => 20)
|
|
85
|
+
@window_info.watch(@systems[StalkerSystem], :color => 0xff33ccff)
|
|
86
|
+
@window_info.watch(@cursor, :color => @cursor.color)
|
|
87
|
+
@window_info.text("Click to start the simulation", :color => 0xffffff00)
|
|
88
|
+
@window_info.text("Little missiles will pursuit while the big one evades, right click to center big one on screen")
|
|
89
|
+
|
|
90
|
+
@missile_info = TextBox.new(:attach_to => @big_missile, :size => 14)
|
|
91
|
+
@missile_info.watch(@big_missile)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def setup_events
|
|
95
|
+
@cursor.on(:click) do |x,y|
|
|
96
|
+
@big_missile.pursuers = @little_missiles
|
|
97
|
+
@little_missiles.each do |lil_missile|
|
|
98
|
+
lil_missile.evader = @big_missile
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def teleport_big_missile_to_midscreen
|
|
104
|
+
@big_missile.pos.x = width/2
|
|
105
|
+
@big_missile.pos.y = height/2
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def toggle_info
|
|
109
|
+
@missile_info.toggle!
|
|
110
|
+
@window_info.toggle!
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Create and start the application
|
|
116
|
+
EvadeMultiple.new.show
|
data/lib/lotu/actor.rb
CHANGED
|
@@ -27,12 +27,16 @@ module Lotu
|
|
|
27
27
|
@parent.manage_me(self)
|
|
28
28
|
set_image(opts[:image], opts) if opts[:image]
|
|
29
29
|
parse_options(opts)
|
|
30
|
+
@color = rand_color if opts[:rand_color]
|
|
30
31
|
@systems = {}
|
|
31
32
|
|
|
33
|
+
set_keys(opts[:keys]) unless opts[:keys].nil?
|
|
34
|
+
|
|
32
35
|
# Add extra functionality
|
|
33
36
|
self.extend Eventful
|
|
34
37
|
self.extend Collidable
|
|
35
38
|
use(AnimationSystem)
|
|
39
|
+
use(TransformationSystem)
|
|
36
40
|
end
|
|
37
41
|
|
|
38
42
|
# Easy access to delta-time
|
|
@@ -50,36 +54,60 @@ module Lotu
|
|
|
50
54
|
@factor_x = opts[:factor_x] || @factor_x
|
|
51
55
|
@factor_y = opts[:factor_y] || @factor_y
|
|
52
56
|
@color = opts[:color] || @color
|
|
57
|
+
if @color.kind_of?(Integer)
|
|
58
|
+
@color = Gosu::Color.new(opts[:color])
|
|
59
|
+
end
|
|
53
60
|
@mode = opts[:mode] || @mode
|
|
54
61
|
end
|
|
55
62
|
|
|
63
|
+
def rand_color
|
|
64
|
+
Gosu::Color.from_hsv(rand(360), 1, 1)
|
|
65
|
+
end
|
|
66
|
+
|
|
56
67
|
def set_image(image, opts={})
|
|
57
68
|
@image = @parent.image(image)
|
|
58
|
-
|
|
69
|
+
if @image.nil?
|
|
70
|
+
puts "Image \"#{image}\" not found".red
|
|
71
|
+
return
|
|
72
|
+
end
|
|
59
73
|
parse_options(opts)
|
|
60
|
-
|
|
61
|
-
@height = opts[:height] || @image.height
|
|
74
|
+
adjust_width_and_height(opts)
|
|
62
75
|
calc_zoom
|
|
63
76
|
end
|
|
64
77
|
|
|
65
78
|
def set_gosu_image(image, opts={})
|
|
66
79
|
@image = image
|
|
67
80
|
parse_options(opts)
|
|
68
|
-
|
|
69
|
-
@height = opts[:height] || @image.height
|
|
81
|
+
adjust_width_and_height(opts)
|
|
70
82
|
calc_zoom
|
|
71
83
|
end
|
|
72
84
|
|
|
73
85
|
def width=(width)
|
|
74
|
-
@width = width
|
|
86
|
+
@width = Float(width)
|
|
75
87
|
calc_zoom
|
|
76
88
|
end
|
|
77
89
|
|
|
78
90
|
def height=(height)
|
|
79
|
-
@height = height
|
|
91
|
+
@height = Float(height)
|
|
80
92
|
calc_zoom
|
|
81
93
|
end
|
|
82
94
|
|
|
95
|
+
def adjust_width_and_height(opts)
|
|
96
|
+
if(opts[:width] && opts[:height])
|
|
97
|
+
@width = Float(opts[:width])
|
|
98
|
+
@height = Float(opts[:height])
|
|
99
|
+
elsif(opts[:width])
|
|
100
|
+
@width = Float(opts[:width])
|
|
101
|
+
@height = @width * @image.height / @image.width
|
|
102
|
+
elsif(opts[:height])
|
|
103
|
+
@height = Float(opts[:height])
|
|
104
|
+
@width = @height * @image.width / @image.height
|
|
105
|
+
else
|
|
106
|
+
@width = Float(@image.width)
|
|
107
|
+
@height = Float(@image.height)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
83
111
|
def calc_zoom
|
|
84
112
|
@zoom_x = Float(@width)/@image.width
|
|
85
113
|
@zoom_y = Float(@height)/@image.height
|
|
@@ -97,8 +125,10 @@ module Lotu
|
|
|
97
125
|
end
|
|
98
126
|
|
|
99
127
|
def draw
|
|
100
|
-
|
|
101
|
-
|
|
128
|
+
unless @image.nil?
|
|
129
|
+
@image.draw_rot(@x, @y, @z, @angle, @center_x, @center_y, @factor_x*@zoom_x, @factor_y*@zoom_y, @color, @mode)
|
|
130
|
+
draw_debug if $lotu.debug?
|
|
131
|
+
end
|
|
102
132
|
end
|
|
103
133
|
|
|
104
134
|
def draw_debug
|
data/lib/lotu/cursor.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Lotu
|
|
|
7
7
|
def initialize(opts={})
|
|
8
8
|
default_opts = {
|
|
9
9
|
:use_mouse => true,
|
|
10
|
-
:speed =>
|
|
10
|
+
:speed => 300,
|
|
11
11
|
:x => $lotu.width/2,
|
|
12
12
|
:y => $lotu.height/2
|
|
13
13
|
}
|
|
@@ -18,10 +18,10 @@ module Lotu
|
|
|
18
18
|
@clicked_x = @clicked_y = 0
|
|
19
19
|
@speed = opts[:speed]
|
|
20
20
|
@use_mouse = opts[:use_mouse]
|
|
21
|
-
set_keys(opts[:keys]) unless opts[:keys].nil?
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
def update
|
|
24
|
+
super
|
|
25
25
|
if @use_mouse
|
|
26
26
|
@x = $lotu.mouse_x
|
|
27
27
|
@y = $lotu.mouse_y
|
data/lib/lotu/game.rb
CHANGED
|
@@ -7,12 +7,18 @@ module Lotu
|
|
|
7
7
|
|
|
8
8
|
include SystemUser
|
|
9
9
|
|
|
10
|
-
def initialize(
|
|
11
|
-
|
|
10
|
+
def initialize(opts={})
|
|
11
|
+
default_opts = {
|
|
12
|
+
:width => 1024,
|
|
13
|
+
:height => 768,
|
|
14
|
+
:fullscreen => false
|
|
15
|
+
}
|
|
16
|
+
opts = default_opts.merge!(opts)
|
|
17
|
+
super(opts[:width], opts[:height], opts[:fullscreen])
|
|
12
18
|
|
|
13
19
|
# Handy global window variable
|
|
14
20
|
$lotu = self
|
|
15
|
-
@debug = false
|
|
21
|
+
@debug = opts[:debug] || false
|
|
16
22
|
setup_containers
|
|
17
23
|
|
|
18
24
|
# For timer initialization
|
|
@@ -27,6 +33,14 @@ module Lotu
|
|
|
27
33
|
setup_input
|
|
28
34
|
end
|
|
29
35
|
|
|
36
|
+
def pause!
|
|
37
|
+
@pause = !@pause
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def paused?
|
|
41
|
+
@pause
|
|
42
|
+
end
|
|
43
|
+
|
|
30
44
|
def debug!
|
|
31
45
|
@debug = !@debug
|
|
32
46
|
end
|
|
@@ -75,7 +89,7 @@ module Lotu
|
|
|
75
89
|
# Update each actor
|
|
76
90
|
@update_queue.each do |actor|
|
|
77
91
|
actor.update
|
|
78
|
-
end
|
|
92
|
+
end unless paused?
|
|
79
93
|
end
|
|
80
94
|
|
|
81
95
|
# Main draw loop
|
|
@@ -140,24 +154,34 @@ module Lotu
|
|
|
140
154
|
end
|
|
141
155
|
|
|
142
156
|
def load_images(path)
|
|
157
|
+
count = 0
|
|
143
158
|
with_files(/\.png|\.jpg|\.bmp/, path) do |file_name, file_path|
|
|
159
|
+
count += 1
|
|
144
160
|
@images[file_name] = Gosu::Image.new($lotu, file_path)
|
|
145
161
|
end
|
|
162
|
+
puts "\n#{count} image(s) loaded."
|
|
146
163
|
end
|
|
147
164
|
|
|
148
165
|
def load_sounds(path)
|
|
166
|
+
count = 0
|
|
149
167
|
with_files(/\.ogg|\.mp3|\.wav/, path) do |file_name, file_path|
|
|
168
|
+
count += 1
|
|
150
169
|
@sounds[file_name] = Gosu::Sample.new($lotu, file_path)
|
|
151
170
|
end
|
|
171
|
+
puts "\n#{count} sounds(s) loaded."
|
|
152
172
|
end
|
|
153
173
|
|
|
154
174
|
def load_songs(path)
|
|
175
|
+
count = 0
|
|
155
176
|
with_files(/\.ogg|\.mp3|\.wav/, path) do |file_name, file_path|
|
|
177
|
+
count += 1
|
|
156
178
|
@songs[file_name] = Gosu::Song.new($lotu, file_path)
|
|
157
179
|
end
|
|
180
|
+
puts "\n#{count} song(s) loaded."
|
|
158
181
|
end
|
|
159
182
|
|
|
160
183
|
def load_animations(path)
|
|
184
|
+
count = 0
|
|
161
185
|
coords = Hash.new{|h,k| h[k] = []}
|
|
162
186
|
|
|
163
187
|
with_files(/\.txt/, path) do |file_name, file_path|
|
|
@@ -167,14 +191,17 @@ module Lotu
|
|
|
167
191
|
coords[name] << line.scan(/\d+/).map!(&:to_i)
|
|
168
192
|
end
|
|
169
193
|
end
|
|
194
|
+
false
|
|
170
195
|
end
|
|
171
196
|
|
|
172
197
|
with_files(/\.png|\.jpg|\.bmp/, path) do |file_name, file_path|
|
|
173
198
|
name, extension = file_name.split('.')
|
|
199
|
+
count += 1 if coords[name]
|
|
174
200
|
coords[name].each do |index, x, y, width, height|
|
|
175
201
|
@animations[file_name] << Gosu::Image.new($lotu, file_path, true, x, y, width, height)
|
|
176
202
|
end
|
|
177
203
|
end
|
|
204
|
+
puts "\n#{count} animation(s) loaded."
|
|
178
205
|
end
|
|
179
206
|
|
|
180
207
|
def with_path_from_file(path, &blk)
|
|
@@ -184,20 +211,17 @@ module Lotu
|
|
|
184
211
|
|
|
185
212
|
def with_files(regexp, path)
|
|
186
213
|
path = File.expand_path(File.join(@path, path))
|
|
187
|
-
puts "\nLoading from: #{path}"
|
|
214
|
+
puts "\nLoading from: #{path}".blue if @debug
|
|
188
215
|
|
|
189
|
-
count = 0
|
|
190
216
|
Dir.entries(path).grep(regexp).each do |entry|
|
|
191
217
|
begin
|
|
192
|
-
yield(entry, File.join(path, entry))
|
|
193
|
-
|
|
194
|
-
print '.'.green
|
|
218
|
+
report = yield(entry, File.join(path, entry))
|
|
219
|
+
print '.'.green if report
|
|
195
220
|
rescue Exception => e
|
|
196
221
|
print '.'.red
|
|
197
222
|
puts e, File.join(path, entry) if @debug
|
|
198
223
|
end
|
|
199
224
|
end
|
|
200
|
-
puts "\n#{count} file(s) loaded."
|
|
201
225
|
end
|
|
202
226
|
|
|
203
227
|
end
|
|
@@ -135,6 +135,23 @@ module Lotu
|
|
|
135
135
|
return flee
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
+
def evade_multiple
|
|
139
|
+
return @zero if @user.pursuers.empty?
|
|
140
|
+
combined_velocities = Vector2d.new
|
|
141
|
+
combined_positions = Vector2d.new
|
|
142
|
+
@user.pursuers.each do |p|
|
|
143
|
+
combined_velocities += p.vel
|
|
144
|
+
combined_positions += p.pos
|
|
145
|
+
end
|
|
146
|
+
combined_velocities /= @user.pursuers.length
|
|
147
|
+
combined_positions /= @user.pursuers.length
|
|
148
|
+
to_pursuers = combined_positions - @user.pos
|
|
149
|
+
look_ahead_time = to_pursuers.length / (@user.max_speed + combined_velocities.length)
|
|
150
|
+
predicted_position = combined_positions + combined_velocities * look_ahead_time
|
|
151
|
+
@user.target = combined_positions
|
|
152
|
+
return flee
|
|
153
|
+
end
|
|
154
|
+
|
|
138
155
|
# TODO: Fix wander
|
|
139
156
|
def wander
|
|
140
157
|
wander_jitter = 10
|
|
@@ -166,9 +183,11 @@ module Lotu
|
|
|
166
183
|
attr_accessor :mass, :pos, :heading, :vel, :accel,
|
|
167
184
|
:max_speed, :max_turn_rate, :max_force,
|
|
168
185
|
:wander_radius, :wander_distance, :wander_target,
|
|
169
|
-
:target, :evader, :pursuer
|
|
186
|
+
:target, :evader, :pursuer, :pursuers
|
|
170
187
|
end
|
|
171
188
|
|
|
189
|
+
# TODO: move these inside the SteeringSystem?
|
|
190
|
+
# and just delegate with accessors?
|
|
172
191
|
# Some defaults
|
|
173
192
|
@pos = Vector2d.new(@x, @y)
|
|
174
193
|
offset_x = Gosu.offset_x(@angle, 1)
|
|
@@ -177,6 +196,13 @@ module Lotu
|
|
|
177
196
|
@vel = Vector2d.new
|
|
178
197
|
@accel = Vector2d.new
|
|
179
198
|
@wander_target = Vector2d.new
|
|
199
|
+
@pursuers = []
|
|
200
|
+
|
|
201
|
+
@colors = {
|
|
202
|
+
:position => 0xff666666,
|
|
203
|
+
:heading => 0xffff0000,
|
|
204
|
+
:target => rand_color
|
|
205
|
+
}
|
|
180
206
|
end
|
|
181
207
|
|
|
182
208
|
def activate(behavior)
|
|
@@ -191,15 +217,11 @@ module Lotu
|
|
|
191
217
|
@heading.facing_to?(@target - @pos)
|
|
192
218
|
end
|
|
193
219
|
|
|
194
|
-
def draw
|
|
195
|
-
super
|
|
196
|
-
draw_debug if $lotu.debug?
|
|
197
|
-
end
|
|
198
|
-
|
|
199
220
|
def draw_debug
|
|
200
|
-
|
|
201
|
-
$lotu.draw_line(
|
|
202
|
-
$lotu.draw_line(@pos.x, @pos.y,
|
|
221
|
+
super
|
|
222
|
+
$lotu.draw_line(0, 0, @colors[:position], @pos.x, @pos.y, @colors[:position])
|
|
223
|
+
$lotu.draw_line(@pos.x, @pos.y, @colors[:heading], (@pos + @heading*50).x, (@pos+@heading*50).y, @colors[:heading])
|
|
224
|
+
$lotu.draw_line(@pos.x, @pos.y, @colors[:target], @target.x, @target.y, @colors[:target]) if @target
|
|
203
225
|
end
|
|
204
226
|
|
|
205
227
|
# to_s utility methods
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
module Lotu
|
|
2
|
+
class TransformationSystem < System
|
|
3
|
+
|
|
4
|
+
def initialize(user, opts={})
|
|
5
|
+
super
|
|
6
|
+
user.extend(UserMethods)
|
|
7
|
+
@transformations = []
|
|
8
|
+
@tagged_for_deletion = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def transform(object, property, opts)
|
|
12
|
+
transformation = {
|
|
13
|
+
:object => object,
|
|
14
|
+
:property_getter => property,
|
|
15
|
+
:property_setter => "#{property}=",
|
|
16
|
+
:accum_time => 0,
|
|
17
|
+
:calc => 0,
|
|
18
|
+
:init => opts[:init],
|
|
19
|
+
:end => opts[:end],
|
|
20
|
+
:duration => opts[:duration] || 1,
|
|
21
|
+
:start_in => opts[:start_in] || 0,
|
|
22
|
+
:on_result => opts[:on_result],
|
|
23
|
+
:loop => opts[:loop]
|
|
24
|
+
}
|
|
25
|
+
@transformations << transformation
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def update
|
|
29
|
+
@transformations.each do |t|
|
|
30
|
+
t[:accum_time] += dt
|
|
31
|
+
if t[:accum_time] > t[:start_in]
|
|
32
|
+
step = (t[:end] - t[:init])/t[:duration] * dt
|
|
33
|
+
t[:calc] += step
|
|
34
|
+
if step > 0
|
|
35
|
+
if t[:init] + t[:calc] > t[:end]
|
|
36
|
+
if t[:loop]
|
|
37
|
+
t[:calc] = 0
|
|
38
|
+
else
|
|
39
|
+
t[:calc] = t[:end] - t[:init]
|
|
40
|
+
tag_for_deletion(t)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
if t[:init] + t[:calc] < t[:end]
|
|
45
|
+
if t[:loop]
|
|
46
|
+
t[:calc] = 0
|
|
47
|
+
else
|
|
48
|
+
t[:calc] = t[:end] - t[:init]
|
|
49
|
+
tag_for_deletion(t)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
value = t[:init] + t[:calc]
|
|
54
|
+
value = value.send(t[:on_result]) if t[:on_result]
|
|
55
|
+
t[:object].send(t[:property_setter], value)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
@tagged_for_deletion.each do |to_delete|
|
|
60
|
+
@transformations.delete(to_delete)
|
|
61
|
+
end.clear
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def tag_for_deletion(transform)
|
|
65
|
+
@tagged_for_deletion << transform
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_s
|
|
69
|
+
["@transformations.length #{@transformations.length}",
|
|
70
|
+
"@tagged_for_deletion.length #{@tagged_for_deletion.length}"]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
module UserMethods
|
|
74
|
+
def transform(object, property, opts)
|
|
75
|
+
@systems[TransformationSystem].transform(object, property, opts)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Image helpers
|
|
79
|
+
def transform_angle(opts)
|
|
80
|
+
transform(self, :angle, opts)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def transform_width(opts)
|
|
84
|
+
transform(self, :width, opts)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def transform_height(opts)
|
|
88
|
+
transform(self, :height, opts)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Color helpers
|
|
92
|
+
def transform_alpha(opts)
|
|
93
|
+
transform(@color, :alpha, opts.merge!(:on_result => :to_i))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def transform_red(opts)
|
|
97
|
+
transform(@color, :red, opts.merge!(:on_result => :to_i))
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def transform_green(opts)
|
|
101
|
+
transform(@color, :green, opts.merge!(:on_result => :to_i))
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def transform_blue(opts)
|
|
105
|
+
transform(@color, :blue, opts.merge!(:on_result => :to_i))
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def transform_hue(opts)
|
|
109
|
+
transform(@color, :hue, opts)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def transform_saturation(opts)
|
|
113
|
+
transform(@color, :saturation, opts)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def transform_value(opts)
|
|
117
|
+
transform(@color, :value, opts)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
end
|
data/lib/lotu/text_box.rb
CHANGED
|
@@ -13,21 +13,32 @@ module Lotu
|
|
|
13
13
|
@watch_list = []
|
|
14
14
|
@size = opts[:size]
|
|
15
15
|
@attached_to = opts[:attach_to]
|
|
16
|
+
@hiding = false
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
def
|
|
19
|
-
|
|
19
|
+
def hide!
|
|
20
|
+
@hiding = true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def show!
|
|
24
|
+
@hiding = false
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def toggle!
|
|
28
|
+
@hiding = !@hiding
|
|
20
29
|
end
|
|
21
30
|
|
|
22
31
|
def watch(subject, opts={})
|
|
23
32
|
@watch_list << [subject, opts]
|
|
24
33
|
end
|
|
34
|
+
alias :text :watch
|
|
25
35
|
|
|
26
36
|
def attach_to(actor)
|
|
27
37
|
@attached_to = actor
|
|
28
38
|
end
|
|
29
39
|
|
|
30
40
|
def update
|
|
41
|
+
return if @hiding
|
|
31
42
|
unless @attached_to.nil?
|
|
32
43
|
@x = @attached_to.x + @attached_to.image.width / 2
|
|
33
44
|
@y = @attached_to.y - @attached_to.image.height / 2
|
|
@@ -35,6 +46,7 @@ module Lotu
|
|
|
35
46
|
end
|
|
36
47
|
|
|
37
48
|
def draw
|
|
49
|
+
return if @hiding
|
|
38
50
|
pos_y = 0
|
|
39
51
|
@watch_list.each do |watched, opts|
|
|
40
52
|
my_size = opts[:size] || @size
|
data/lib/lotu.rb
CHANGED
|
@@ -5,4 +5,4 @@ require 'gosu'
|
|
|
5
5
|
%w{vector2d string}.each{|file| require "misc/#{file}"}
|
|
6
6
|
%w{system_user collidable controllable eventful}.each{|file| require "behaviors/#{file}"}
|
|
7
7
|
%w{game system actor cursor text_box}.each{|file| require file}
|
|
8
|
-
%w{animation_system input_system stalker_system fps_system collision_system steering_system}.each{|file| require "systems/#{file}"}
|
|
8
|
+
%w{transformation_system animation_system input_system stalker_system fps_system collision_system steering_system}.each{|file| require "systems/#{file}"}
|
data/lotu.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{lotu}
|
|
8
|
-
s.version = "0.1.
|
|
8
|
+
s.version = "0.1.12"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["lobo_tuerto"]
|
|
12
|
-
s.date = %q{2010-03-
|
|
12
|
+
s.date = %q{2010-03-28}
|
|
13
13
|
s.description = %q{lotu aims to bring an agile and simple game development framework to life. It provides useful abstractions so you can concentrate on developing your game.}
|
|
14
14
|
s.email = %q{dev@lobotuerto.com}
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
|
24
24
|
"README.rdoc",
|
|
25
25
|
"Rakefile",
|
|
26
26
|
"VERSION",
|
|
27
|
-
"examples/hello_world/
|
|
27
|
+
"examples/hello_world/moving_portraits.rb",
|
|
28
28
|
"examples/media/animations/missile.png",
|
|
29
29
|
"examples/media/animations/missile.txt",
|
|
30
30
|
"examples/media/images/cohete-big.png",
|
|
@@ -36,8 +36,9 @@ Gem::Specification.new do |s|
|
|
|
36
36
|
"examples/media/images/lobo_tuerto.png",
|
|
37
37
|
"examples/media/images/missile-med.png",
|
|
38
38
|
"examples/media/images/silo.png",
|
|
39
|
-
"examples/
|
|
40
|
-
"examples/steering_behaviors/
|
|
39
|
+
"examples/screen_cursor/mouse_and_keyboard_cursors.rb",
|
|
40
|
+
"examples/steering_behaviors/pursuit_and_evade.rb",
|
|
41
|
+
"examples/steering_behaviors/pursuit_and_evade_multiple.rb",
|
|
41
42
|
"lib/lotu.rb",
|
|
42
43
|
"lib/lotu/actor.rb",
|
|
43
44
|
"lib/lotu/behaviors/collidable.rb",
|
|
@@ -55,6 +56,7 @@ Gem::Specification.new do |s|
|
|
|
55
56
|
"lib/lotu/systems/input_system.rb",
|
|
56
57
|
"lib/lotu/systems/stalker_system.rb",
|
|
57
58
|
"lib/lotu/systems/steering_system.rb",
|
|
59
|
+
"lib/lotu/systems/transformation_system.rb",
|
|
58
60
|
"lib/lotu/text_box.rb",
|
|
59
61
|
"lotu.gemspec",
|
|
60
62
|
"test/actor_test.rb"
|
|
@@ -66,9 +68,10 @@ Gem::Specification.new do |s|
|
|
|
66
68
|
s.summary = %q{A simple, agile Ruby game development framework.}
|
|
67
69
|
s.test_files = [
|
|
68
70
|
"test/actor_test.rb",
|
|
69
|
-
"examples/steering_behaviors/
|
|
70
|
-
"examples/
|
|
71
|
-
"examples/
|
|
71
|
+
"examples/steering_behaviors/pursuit_and_evade.rb",
|
|
72
|
+
"examples/steering_behaviors/pursuit_and_evade_multiple.rb",
|
|
73
|
+
"examples/hello_world/moving_portraits.rb",
|
|
74
|
+
"examples/screen_cursor/mouse_and_keyboard_cursors.rb"
|
|
72
75
|
]
|
|
73
76
|
|
|
74
77
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
|
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
|
5
5
|
segments:
|
|
6
6
|
- 0
|
|
7
7
|
- 1
|
|
8
|
-
-
|
|
9
|
-
version: 0.1.
|
|
8
|
+
- 12
|
|
9
|
+
version: 0.1.12
|
|
10
10
|
platform: ruby
|
|
11
11
|
authors:
|
|
12
12
|
- lobo_tuerto
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
|
14
14
|
bindir: bin
|
|
15
15
|
cert_chain: []
|
|
16
16
|
|
|
17
|
-
date: 2010-03-
|
|
17
|
+
date: 2010-03-28 00:00:00 -06:00
|
|
18
18
|
default_executable:
|
|
19
19
|
dependencies:
|
|
20
20
|
- !ruby/object:Gem::Dependency
|
|
@@ -48,7 +48,7 @@ files:
|
|
|
48
48
|
- README.rdoc
|
|
49
49
|
- Rakefile
|
|
50
50
|
- VERSION
|
|
51
|
-
- examples/hello_world/
|
|
51
|
+
- examples/hello_world/moving_portraits.rb
|
|
52
52
|
- examples/media/animations/missile.png
|
|
53
53
|
- examples/media/animations/missile.txt
|
|
54
54
|
- examples/media/images/cohete-big.png
|
|
@@ -60,8 +60,9 @@ files:
|
|
|
60
60
|
- examples/media/images/lobo_tuerto.png
|
|
61
61
|
- examples/media/images/missile-med.png
|
|
62
62
|
- examples/media/images/silo.png
|
|
63
|
-
- examples/
|
|
64
|
-
- examples/steering_behaviors/
|
|
63
|
+
- examples/screen_cursor/mouse_and_keyboard_cursors.rb
|
|
64
|
+
- examples/steering_behaviors/pursuit_and_evade.rb
|
|
65
|
+
- examples/steering_behaviors/pursuit_and_evade_multiple.rb
|
|
65
66
|
- lib/lotu.rb
|
|
66
67
|
- lib/lotu/actor.rb
|
|
67
68
|
- lib/lotu/behaviors/collidable.rb
|
|
@@ -79,6 +80,7 @@ files:
|
|
|
79
80
|
- lib/lotu/systems/input_system.rb
|
|
80
81
|
- lib/lotu/systems/stalker_system.rb
|
|
81
82
|
- lib/lotu/systems/steering_system.rb
|
|
83
|
+
- lib/lotu/systems/transformation_system.rb
|
|
82
84
|
- lib/lotu/text_box.rb
|
|
83
85
|
- lotu.gemspec
|
|
84
86
|
- test/actor_test.rb
|
|
@@ -115,6 +117,7 @@ specification_version: 3
|
|
|
115
117
|
summary: A simple, agile Ruby game development framework.
|
|
116
118
|
test_files:
|
|
117
119
|
- test/actor_test.rb
|
|
118
|
-
- examples/steering_behaviors/
|
|
119
|
-
- examples/
|
|
120
|
-
- examples/
|
|
120
|
+
- examples/steering_behaviors/pursuit_and_evade.rb
|
|
121
|
+
- examples/steering_behaviors/pursuit_and_evade_multiple.rb
|
|
122
|
+
- examples/hello_world/moving_portraits.rb
|
|
123
|
+
- examples/screen_cursor/mouse_and_keyboard_cursors.rb
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
LIB_PATH = File.join(File.dirname(__FILE__), '..', '..', 'lib', 'lotu.rb')
|
|
3
|
-
require File.expand_path(LIB_PATH)
|
|
4
|
-
|
|
5
|
-
include Gosu::Button
|
|
6
|
-
include Lotu
|
|
7
|
-
|
|
8
|
-
class MovingRuby < Actor
|
|
9
|
-
|
|
10
|
-
def initialize(opts={})
|
|
11
|
-
super
|
|
12
|
-
# Use the image which filename is CptnRuby Gem.png
|
|
13
|
-
set_image 'lobo_tuerto.png', :factor_x => 0.5, :factor_y => 0.5
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Let's define some basic movement methods
|
|
17
|
-
def move_right
|
|
18
|
-
@x += 1
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def move_left
|
|
22
|
-
@x -= 1
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def move_up
|
|
26
|
-
@y -= 1
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def move_down
|
|
30
|
-
@y += 1
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
class Example < Game
|
|
36
|
-
|
|
37
|
-
def initialize
|
|
38
|
-
# This will call the hooks:
|
|
39
|
-
# load_resources, setup_systems and setup_actors
|
|
40
|
-
# declared in the parent class
|
|
41
|
-
super
|
|
42
|
-
# When the Escape key is pressed, call the close method on class Example
|
|
43
|
-
set_keys(KbEscape => :close,
|
|
44
|
-
KbD => [:debug!, false])
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def load_resources
|
|
48
|
-
# From this file,
|
|
49
|
-
with_path_from_file(__FILE__) do
|
|
50
|
-
# go back one dir and search inside media/
|
|
51
|
-
load_images '../media/images'
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def setup_actors
|
|
56
|
-
# Create a ruby in the middle of the screen
|
|
57
|
-
@ruby = MovingRuby.new(:x => width/2, :y => height/2)
|
|
58
|
-
# Map keys to some methods
|
|
59
|
-
@ruby.set_keys(KbRight => :move_right,
|
|
60
|
-
KbLeft => :move_left,
|
|
61
|
-
KbUp => :move_up,
|
|
62
|
-
KbDown => :move_down)
|
|
63
|
-
@ruby2 = MovingRuby.new(:x => width/2, :y => height/2)
|
|
64
|
-
# Map keys to some methods
|
|
65
|
-
@ruby2.set_keys(KbRight => :move_left,
|
|
66
|
-
KbLeft => :move_right,
|
|
67
|
-
KbUp => :move_up,
|
|
68
|
-
KbDown => :move_down)
|
|
69
|
-
# Create a TextBox so we can display a message on screen
|
|
70
|
-
@info = TextBox.new
|
|
71
|
-
@info.text("Hello world!")
|
|
72
|
-
@info.text("Move around with arrow keys", :size => 16, :color => 0xff33ccff)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
Example.new.show
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
LIB_PATH = File.join(File.dirname(__FILE__), '..', '..', 'lib', 'lotu.rb')
|
|
3
|
-
require File.expand_path(LIB_PATH)
|
|
4
|
-
|
|
5
|
-
include Gosu::Button
|
|
6
|
-
include Lotu
|
|
7
|
-
|
|
8
|
-
class WarpingRuby < Actor
|
|
9
|
-
def initialize(opts={})
|
|
10
|
-
super
|
|
11
|
-
set_image 'lobo_tuerto.png', :factor_x => 0.3, :factor_y => 0.3
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def warp(x, y)
|
|
15
|
-
@x, @y = x, y
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
class Example < Game
|
|
20
|
-
def initialize
|
|
21
|
-
# This will call the hooks:
|
|
22
|
-
# load_resources, setup_systems and setup_actors
|
|
23
|
-
# declared in the parent class
|
|
24
|
-
super
|
|
25
|
-
# Custom setup methods for this class
|
|
26
|
-
setup_events
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def load_resources
|
|
30
|
-
with_path_from_file(__FILE__) do
|
|
31
|
-
load_images '../media/images'
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def setup_systems
|
|
36
|
-
# It's important to call super here to setup the InputSystem
|
|
37
|
-
super
|
|
38
|
-
use(FpsSystem)
|
|
39
|
-
use(StalkerSystem, :stalk => [Actor, Cursor, TextBox, WarpingRuby, Object])
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def setup_input
|
|
43
|
-
set_keys(KbEscape => :close,
|
|
44
|
-
KbD => [:debug!, false])
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def setup_events
|
|
48
|
-
@cursor1.on(:click) do |x,y|
|
|
49
|
-
@ruby.warp(x,y)
|
|
50
|
-
end
|
|
51
|
-
@cursor2.on(:click) do |x,y|
|
|
52
|
-
@ruby.warp(x,y)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def setup_actors
|
|
57
|
-
@ruby = WarpingRuby.new(:x => width/2, :y => height/2)
|
|
58
|
-
@cursor1 = Cursor.new(:image => 'crosshair-1.png',
|
|
59
|
-
:keys => {MsLeft => [:click, false]},
|
|
60
|
-
:color => 0xff0099ff,
|
|
61
|
-
:width => 100,
|
|
62
|
-
:height => 100)
|
|
63
|
-
@cursor2 = Cursor.new(:image => 'crosshair-2.png',
|
|
64
|
-
:use_mouse => false,
|
|
65
|
-
:keys => {
|
|
66
|
-
KbSpace => [:click, false],
|
|
67
|
-
KbUp => :up,
|
|
68
|
-
KbDown => :down,
|
|
69
|
-
KbLeft => :left,
|
|
70
|
-
KbRight => :right},
|
|
71
|
-
:color => 0xff99ff00,
|
|
72
|
-
:factor_x => 0.5,
|
|
73
|
-
:factor_y => 0.5)
|
|
74
|
-
@cursor2.x = width*3/4
|
|
75
|
-
@cursor2.y = height/2
|
|
76
|
-
|
|
77
|
-
# Create a TextBox with default option :size => 15
|
|
78
|
-
@info = TextBox.new(:size => 15)
|
|
79
|
-
@info.watch(@systems[FpsSystem])
|
|
80
|
-
@info.watch(@systems[StalkerSystem], :color => 0xff3ffccf)
|
|
81
|
-
# We can change the size for a specific line of text
|
|
82
|
-
@info.watch("@cursor1 data:", :size => 20)
|
|
83
|
-
# Color too
|
|
84
|
-
@info.watch(@cursor1, :color => 0xff0099ff)
|
|
85
|
-
@info.watch("@cursor2 data:", :size => 20)
|
|
86
|
-
@info.watch(@cursor2, :color => 0xff99ff00)
|
|
87
|
-
@info.text("Move @cursor1 with mouse and @cursor2 with arrow keys (click with space!)")
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
Example.new.show
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
LIB_PATH = File.join(File.dirname(__FILE__), '..', '..', 'lib', 'lotu.rb')
|
|
3
|
-
require File.expand_path(LIB_PATH)
|
|
4
|
-
|
|
5
|
-
include Gosu::Button
|
|
6
|
-
include Lotu
|
|
7
|
-
|
|
8
|
-
class SteeringRuby < Actor
|
|
9
|
-
def initialize(opts={})
|
|
10
|
-
super
|
|
11
|
-
use(SteeringSystem, opts)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def warp(x, y)
|
|
15
|
-
@pos.x, @pos.y = x, y
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
class Example < Game
|
|
20
|
-
def initialize
|
|
21
|
-
# This will call the hooks:
|
|
22
|
-
# load_resources, setup_systems and setup_actors
|
|
23
|
-
# declared in the parent class
|
|
24
|
-
super
|
|
25
|
-
# Custom setup methods for this class
|
|
26
|
-
setup_events
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def load_resources
|
|
30
|
-
with_path_from_file(__FILE__) do
|
|
31
|
-
load_images '../media/images'
|
|
32
|
-
load_animations '../media/animations'
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def setup_input
|
|
37
|
-
set_keys(KbEscape => :close,
|
|
38
|
-
MsRight => :reset_ruby,
|
|
39
|
-
KbD => [:debug!, false])
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def setup_systems
|
|
43
|
-
# It's important to call super here to setup the InputSystem
|
|
44
|
-
super
|
|
45
|
-
use(FpsSystem)
|
|
46
|
-
use(StalkerSystem, :stalk => [Actor, Vector2d, Object])
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def setup_actors
|
|
50
|
-
@ruby = SteeringRuby.new(:mass => 0.3, :max_speed => 100, :max_turn_rate => 140)
|
|
51
|
-
@ruby.warp(width/2, height/2)
|
|
52
|
-
@ruby.activate(:evade)
|
|
53
|
-
@ruby.play_animation('missile.png')
|
|
54
|
-
|
|
55
|
-
@ruby2 = SteeringRuby.new
|
|
56
|
-
@ruby2.activate(:pursuit)
|
|
57
|
-
@ruby2.play_animation('missile.png', :factor_x => 0.5, :factor_y => 0.5, :fps => 60)
|
|
58
|
-
|
|
59
|
-
@cursor = Cursor.new(:image => 'crosshair-1.png',
|
|
60
|
-
:keys => {MsLeft => [:click, false]})
|
|
61
|
-
|
|
62
|
-
@window_info = TextBox.new(:size => 15)
|
|
63
|
-
@window_info.watch(@systems[FpsSystem])
|
|
64
|
-
@window_info.watch(@systems[StalkerSystem])
|
|
65
|
-
@window_info.watch(@cursor, :color => 0xffff0000)
|
|
66
|
-
@window_info.text("Click to start the simulation")
|
|
67
|
-
@window_info.text("One will pursuit while the other evades, right click to center evader on screen")
|
|
68
|
-
|
|
69
|
-
@ruby_info = TextBox.new(:attach_to => @ruby, :size => 14)
|
|
70
|
-
@ruby_info.watch(@ruby)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def setup_events
|
|
74
|
-
@cursor.on(:click) do |x,y|
|
|
75
|
-
@ruby.pursuer = @ruby2
|
|
76
|
-
@ruby2.evader = @ruby
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def reset_ruby
|
|
81
|
-
@ruby.pos.x = width/2
|
|
82
|
-
@ruby.pos.y = height/2
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
Example.new.show
|