ippa-chingu 0.2.0
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/History.txt +5 -0
- data/Manifest.txt +34 -0
- data/README.rdoc +329 -0
- data/Rakefile +19 -0
- data/chingu.gemspec +34 -0
- data/examples/example1.rb +30 -0
- data/examples/example2.rb +76 -0
- data/examples/example3.rb +37 -0
- data/examples/example4.rb +110 -0
- data/examples/media/Parallax-scroll-example-layer-0.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-1.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-2.png +0 -0
- data/examples/media/Parallax-scroll-example-layer-3.png +0 -0
- data/examples/media/background1.png +0 -0
- data/examples/media/fire_bullet.png +0 -0
- data/examples/media/spaceship.png +0 -0
- data/examples/media/stickfigure.bmp +0 -0
- data/examples/media/stickfigure.png +0 -0
- data/lib/chingu/animation.rb +109 -0
- data/lib/chingu/assets.rb +50 -0
- data/lib/chingu/chipmunk_object.rb +117 -0
- data/lib/chingu/data_structures.rb +6 -0
- data/lib/chingu/fpscounter.rb +21 -0
- data/lib/chingu/game_object.rb +101 -0
- data/lib/chingu/game_state.rb +39 -0
- data/lib/chingu/game_state_manager.rb +84 -0
- data/lib/chingu/helpers.rb +41 -0
- data/lib/chingu/input.rb +100 -0
- data/lib/chingu/named_resource.rb +254 -0
- data/lib/chingu/parallax.rb +80 -0
- data/lib/chingu/rect.rb +612 -0
- data/lib/chingu/text.rb +46 -0
- data/lib/chingu/window.rb +161 -0
- data/lib/chingu.rb +29 -0
- metadata +99 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Chingu
|
2
|
+
#
|
3
|
+
# The Animation-class helps you load and manage a tileanimation.
|
4
|
+
# A Tileanimation is a file where all the frames are put after eachother.
|
5
|
+
#
|
6
|
+
# An easy to use program to create tileanimations is http://tilestudio.sourceforge.net/
|
7
|
+
#
|
8
|
+
class Animation
|
9
|
+
attr_accessor :frames
|
10
|
+
|
11
|
+
#
|
12
|
+
# Create a new Animation.
|
13
|
+
#
|
14
|
+
# - loop: [true|false]. After the last frame is used, start from the beginning.
|
15
|
+
# - bounce: [true|false]. After the last frame is used, play it backwards untill the first frame is used again, then start playing forwards again.
|
16
|
+
# - file: Tile-file to cut up animation frames from.
|
17
|
+
# - width: width of each frame in the tileanimation
|
18
|
+
# - height: width of each frame in the tileanimation
|
19
|
+
#
|
20
|
+
#
|
21
|
+
def initialize(options)
|
22
|
+
@loop = options[:loop] || true
|
23
|
+
@bounce = options[:bounce] || false
|
24
|
+
@file = options[:file]
|
25
|
+
@height = options[:height] || 32
|
26
|
+
@width = options[:width] || 32
|
27
|
+
@index = options[:index] || 0
|
28
|
+
@delay = options[:delay] || 100
|
29
|
+
@ticks = 0
|
30
|
+
|
31
|
+
@frame_actions = []
|
32
|
+
@frames = Gosu::Image.load_tiles($window, @file, @width, @height, true)
|
33
|
+
@step = 1
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Fetch a certain frame (a Gosu#Image), starts at 0.
|
38
|
+
#
|
39
|
+
def [](index)
|
40
|
+
@frames[index]
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Get the current frame (a Gosu#Image)
|
45
|
+
#
|
46
|
+
def image
|
47
|
+
@frames[@index]
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Resets the animation, re-starts it at frame 0
|
52
|
+
#
|
53
|
+
def reset!
|
54
|
+
@index = 0
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# Returns a new animation with the frames from the original animation.
|
59
|
+
# Specify which frames you want with "range", for example "0..3" for the 4 first frames.
|
60
|
+
#
|
61
|
+
def new_from_frames(range)
|
62
|
+
new_animation = self.dup
|
63
|
+
new_animation.frames = []
|
64
|
+
range.each do |nr|
|
65
|
+
new_animation.frames << self.frames[nr]
|
66
|
+
end
|
67
|
+
return new_animation
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Propelles the animation forward. Usually called in #update within the class which holds the animation.
|
72
|
+
# #next! will look at bounce and loop flags to always return a correct frame (a Gosu#Image)
|
73
|
+
#
|
74
|
+
def next!
|
75
|
+
if (@ticks += $window.tick) > @delay
|
76
|
+
@ticks = 0
|
77
|
+
@index += @step
|
78
|
+
|
79
|
+
# Has the animation hit end or beginning... time for bounce or loop?
|
80
|
+
if (@index >= @frames.size || @index < 0)
|
81
|
+
if @bounce
|
82
|
+
if @step == 1
|
83
|
+
@step = -1
|
84
|
+
else
|
85
|
+
@step = 1
|
86
|
+
end
|
87
|
+
@index += @step
|
88
|
+
elsif @loop
|
89
|
+
@index = 0
|
90
|
+
end
|
91
|
+
end
|
92
|
+
@frame_actions[@index].call if @frame_actions[@index]
|
93
|
+
end
|
94
|
+
@frames[@index]
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Execute a certain block of code when a certain frame in the animation is active.
|
99
|
+
# This could be used for pixel perfect animation/movement.
|
100
|
+
#
|
101
|
+
def on_frame(frames, &block)
|
102
|
+
if frames.kind_of? Array
|
103
|
+
frames.each { |frame| @frame_actions[frame] = block }
|
104
|
+
else
|
105
|
+
@frame_actions[frames] = block
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#
|
2
|
+
# Rubygames Named Resources for GOSU
|
3
|
+
# Assumes a global variable $window having the Gosu::Window instance.
|
4
|
+
# Quick 'n easy access to sprites, sounds and tiles!
|
5
|
+
#
|
6
|
+
module Chingu
|
7
|
+
|
8
|
+
def media_path(file)
|
9
|
+
File.join($window.root, "media", file)
|
10
|
+
end
|
11
|
+
|
12
|
+
def image_path(file)
|
13
|
+
File.join($window.root, "gfx", file)
|
14
|
+
end
|
15
|
+
|
16
|
+
class ImagePath
|
17
|
+
include Chingu::NamedResource
|
18
|
+
|
19
|
+
def self.autoload(name)
|
20
|
+
find_file(name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Gosu
|
26
|
+
class Image
|
27
|
+
include Chingu::NamedResource
|
28
|
+
|
29
|
+
def self.autoload(name)
|
30
|
+
(path = find_file(name)) ? Gosu::Image.new($window, path, true) : nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Sample
|
35
|
+
include Chingu::NamedResource
|
36
|
+
|
37
|
+
def self.autoload(name)
|
38
|
+
(path = find_file(name)) ? Gosu::Sample.new($window, path) : nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
Sound = Sample
|
42
|
+
|
43
|
+
class Tile
|
44
|
+
include Chingu::NamedResource
|
45
|
+
|
46
|
+
def self.autoload(name)
|
47
|
+
(path = find_file(name)) ? Gosu::Image.load_tiles($window, path, 32, 32, true) : nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Chingu
|
2
|
+
#
|
3
|
+
# A basic class, all your gameobjects / actors should be built on this. Encapsulates
|
4
|
+
# Gosus draw_rot and it's parameters.
|
5
|
+
#
|
6
|
+
# All objects that inherits from this class will automaticly be updated and drawn.
|
7
|
+
#
|
8
|
+
class Actor
|
9
|
+
attr_accessor :image, :x, :y, :angle, :center_x, :center_y, :factor_x, :factor_y, :mode
|
10
|
+
attr_accessor :update, :draw, :keymap
|
11
|
+
attr_reader :options
|
12
|
+
|
13
|
+
#
|
14
|
+
# Class-level default values.
|
15
|
+
# This allows you to set default-values that affect all created actors after that.
|
16
|
+
# You might want to draw screenobjects from the top-left @ x/y instead of putting it's center there:
|
17
|
+
#
|
18
|
+
# in Gosu::Window#initialize: Actor.center_x = Actor.center_y = 0
|
19
|
+
#
|
20
|
+
@@zorder = 100
|
21
|
+
@@center_x = 0.5
|
22
|
+
@@center_y = 0.5
|
23
|
+
@@factor_x = 1.0
|
24
|
+
@@factor_y = 1.0
|
25
|
+
|
26
|
+
def self.zorder; @@zorder; end
|
27
|
+
def self.zorder=(value); @@zorder = value; end
|
28
|
+
|
29
|
+
def self.center_x; @@center_x; end
|
30
|
+
def self.center_x=(value); @@center_x = value; end
|
31
|
+
|
32
|
+
def self.center_y; @@center_y; end
|
33
|
+
def self.center_y=(value); @@center_y = value; end
|
34
|
+
|
35
|
+
def self.factor_x; @@factor_x; end
|
36
|
+
def self.factor_x=(value); @@factor_x = value; end
|
37
|
+
|
38
|
+
def self.factor_y; @@factor_y; end
|
39
|
+
def self.factor_y=(value); @@factor_y = value; end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Create a new Actor. Arguments are given in hash-format:
|
43
|
+
#
|
44
|
+
# :x screen x-coordinate (default 0, to the left)
|
45
|
+
# :y screen y-coordinate (default 0, top of screen)
|
46
|
+
# :angle angle of object, used in draw_rot, (default 0, no rotation)
|
47
|
+
# :zorder a gameclass "foo" with higher zorder then gameclass "bar" is drawn on top of "foo".
|
48
|
+
# :center_x relative horizontal position of the rotation center on the image.
|
49
|
+
# 0 is the left border, 1 is the right border, 0.5 is the center (default 0.5)
|
50
|
+
# :center_y see center_x. (default 0.5)
|
51
|
+
# :factor_x horizontal zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
52
|
+
# :factor_y vertical zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
53
|
+
#
|
54
|
+
# :update [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
55
|
+
# :draw [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
56
|
+
#
|
57
|
+
def initialize(options = {})
|
58
|
+
@options = options
|
59
|
+
|
60
|
+
# draw_rot arguments
|
61
|
+
@image = options[:image] if options[:image].is_a? Gosu::Image
|
62
|
+
@image = Image[options[:image]] if options[:image].is_a? String
|
63
|
+
|
64
|
+
@x = options[:x] || 0
|
65
|
+
@y = options[:y] || 0
|
66
|
+
@angle = options[:angle] || 0
|
67
|
+
@zorder = options[:zorder] || @@zorder
|
68
|
+
@center_x = options[:center_x] || options[:center] || @@center_x
|
69
|
+
@center_y = options[:center_y] || options[:center] || @@center_y
|
70
|
+
@factor_x = options[:factor_x] || options[:factor] || @@factor_x
|
71
|
+
@factor_y = options[:factor_y] || options[:factor] || @@factor_y
|
72
|
+
@mode = options[:mode] || :additive
|
73
|
+
|
74
|
+
# gameloop logic
|
75
|
+
@update = options[:update] || true
|
76
|
+
@draw = options[:draw] || true
|
77
|
+
|
78
|
+
automatic_update! if @update
|
79
|
+
automatic_draw! if @draw
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Add self to the list of objects that Chingu calls #update on each update-loop.
|
84
|
+
# This is done by default except if you create a gameobject with {:update => false}
|
85
|
+
#
|
86
|
+
def automatic_update!
|
87
|
+
$window.automatic_update_for(self)
|
88
|
+
end
|
89
|
+
#
|
90
|
+
# Add self to the list of objects that Chingu calls #draw on each update-loop.
|
91
|
+
# This is done by default except if you create a gameobject with {:draw => false}
|
92
|
+
#
|
93
|
+
def automatic_draw!
|
94
|
+
$window.automatic_draw_for(self)
|
95
|
+
end
|
96
|
+
|
97
|
+
def keymap=(keymap)
|
98
|
+
@keymap = keymap
|
99
|
+
$window.key_recievers << self unless $window.key_recievers.include? self
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Override this with your own actor/game-logic
|
104
|
+
#
|
105
|
+
def update
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
#
|
110
|
+
# The core of the gameclass, the draw_rot encapsulation. Draws the sprite on screen.
|
111
|
+
# Calling #to_i on @x and @y enables thoose to be Float's, for subpixel slow movement in #update
|
112
|
+
#
|
113
|
+
def draw
|
114
|
+
@image.draw_rot(@x.to_i, @y.to_i, @zorder, @angle, @center_x, @center_y, @factor_x, @factor_y, @mode)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Chingu
|
2
|
+
class FPSCounter
|
3
|
+
attr_reader :fps
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@current_second = Gosu::milliseconds / 1000
|
7
|
+
@accum_fps = 0
|
8
|
+
@fps = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def register_tick
|
12
|
+
@accum_fps += 1
|
13
|
+
current_second = Gosu::milliseconds / 1000
|
14
|
+
if current_second != @current_second
|
15
|
+
@current_second = current_second
|
16
|
+
@fps = @accum_fps
|
17
|
+
@accum_fps = 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Chingu
|
2
|
+
#
|
3
|
+
# A basic class, all your ingame objects should be built on this. Encapsulates
|
4
|
+
# Gosus draw_rot and it's parameters.
|
5
|
+
#
|
6
|
+
# All objects that inherits from this class will automaticly be updated and drawn.
|
7
|
+
#
|
8
|
+
class GameObject
|
9
|
+
attr_accessor :image, :x, :y, :angle, :center_x, :center_y, :factor_x, :factor_y, :mode
|
10
|
+
attr_accessor :update, :draw, :input
|
11
|
+
attr_reader :options
|
12
|
+
|
13
|
+
#
|
14
|
+
# Class-level default values.
|
15
|
+
# This allows you to set default-values that affect all created GameObjects after that.
|
16
|
+
# You might want to draw gameobjects from the top-left @ x/y instead of putting it's center there:
|
17
|
+
#
|
18
|
+
# in Gosu::Window#initialize: GameObject.center_x = GameObject.center_y = 0
|
19
|
+
#
|
20
|
+
@@zorder = 100
|
21
|
+
@@center_x = 0.5
|
22
|
+
@@center_y = 0.5
|
23
|
+
@@factor_x = 1.0
|
24
|
+
@@factor_y = 1.0
|
25
|
+
|
26
|
+
def self.zorder; @@zorder; end
|
27
|
+
def self.zorder=(value); @@zorder = value; end
|
28
|
+
|
29
|
+
def self.center_x; @@center_x; end
|
30
|
+
def self.center_x=(value); @@center_x = value; end
|
31
|
+
|
32
|
+
def self.center_y; @@center_y; end
|
33
|
+
def self.center_y=(value); @@center_y = value; end
|
34
|
+
|
35
|
+
def self.factor_x; @@factor_x; end
|
36
|
+
def self.factor_x=(value); @@factor_x = value; end
|
37
|
+
|
38
|
+
def self.factor_y; @@factor_y; end
|
39
|
+
def self.factor_y=(value); @@factor_y = value; end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Create a new GameObject. Arguments are given in hash-format:
|
43
|
+
#
|
44
|
+
# :x screen x-coordinate (default 0, to the left)
|
45
|
+
# :y screen y-coordinate (default 0, top of screen)
|
46
|
+
# :angle angle of object, used in draw_rot, (default 0, no rotation)
|
47
|
+
# :zorder a gameclass "foo" with higher zorder then gameclass "bar" is drawn on top of "foo".
|
48
|
+
# :center_x relative horizontal position of the rotation center on the image.
|
49
|
+
# 0 is the left border, 1 is the right border, 0.5 is the center (default 0.5)
|
50
|
+
# :center_y see center_x. (default 0.5)
|
51
|
+
# :factor_x horizontal zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
52
|
+
# :factor_y vertical zoom-factor, use >1.0 to zoom in. (default 1.0, no zoom).
|
53
|
+
#
|
54
|
+
# :update [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
55
|
+
# :draw [true|false] Automaticly call #update on object each gameloop. Default +true+.
|
56
|
+
#
|
57
|
+
def initialize(options = {})
|
58
|
+
@options = options
|
59
|
+
|
60
|
+
# draw_rot arguments
|
61
|
+
@image = options[:image] if options[:image].is_a? Gosu::Image
|
62
|
+
@image = Image[options[:image]] if options[:image].is_a? String
|
63
|
+
|
64
|
+
@x = options[:x] || 0
|
65
|
+
@y = options[:y] || 0
|
66
|
+
@angle = options[:angle] || 0
|
67
|
+
@zorder = options[:zorder] || @@zorder
|
68
|
+
@center_x = options[:center_x] || options[:center] || @@center_x
|
69
|
+
@center_y = options[:center_y] || options[:center] || @@center_y
|
70
|
+
@factor_x = options[:factor_x] || options[:factor] || @@factor_x
|
71
|
+
@factor_y = options[:factor_y] || options[:factor] || @@factor_y
|
72
|
+
@color = options[:color] || 0xFFFFFFFF
|
73
|
+
@mode = options[:mode] || :default # :additive is also available.
|
74
|
+
|
75
|
+
# gameloop/framework logic
|
76
|
+
@update = options[:update] || true
|
77
|
+
@draw = options[:draw] || true
|
78
|
+
@input = options[:input] || nil
|
79
|
+
|
80
|
+
#
|
81
|
+
# A GameObject can either belong to a GameState or our mainwindow ($window)
|
82
|
+
# .. or live in limbo with manual updates
|
83
|
+
#
|
84
|
+
@parent = $window.game_state_manager.inside_state || $window
|
85
|
+
@parent.add_game_object(self) if @parent
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
def update
|
90
|
+
# Objects gamelogic here
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# The core of the gameclass, the draw_rot encapsulation. Draws the sprite on screen.
|
95
|
+
# Calling #to_i on @x and @y enables thoose to be Float's, for subpixel slow movement in #update
|
96
|
+
#
|
97
|
+
def draw
|
98
|
+
@image.draw_rot(@x.to_i, @y.to_i, @zorder, @angle, @center_x, @center_y, @factor_x, @factor_y, @color, @mode)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Chingu
|
2
|
+
class GameState
|
3
|
+
include Chingu::GameStateHelpers # Easy access to the global game_state-queue
|
4
|
+
include Chingu::DrawHelpers # Adds fill(), fade() etc to each gamestate.
|
5
|
+
|
6
|
+
attr_reader :options # so jac can access his :level-number
|
7
|
+
attr_reader :game_objects
|
8
|
+
attr_accessor :input
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = options
|
12
|
+
@game_objects = Array.new
|
13
|
+
@input = options[:input]
|
14
|
+
$window.game_state_manager.inside_state = self
|
15
|
+
setup
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_game_object(game_object)
|
19
|
+
@game_objects.push(game_object) unless @game_objects.include?(game_object)
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup
|
23
|
+
end
|
24
|
+
|
25
|
+
def button_down(id)
|
26
|
+
end
|
27
|
+
|
28
|
+
def button_up(id)
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
@game_objects.each { |object| object.update }
|
33
|
+
end
|
34
|
+
|
35
|
+
def draw
|
36
|
+
@game_objects.each { |object| object.draw }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Chingu
|
2
|
+
class GameStateManager
|
3
|
+
attr_accessor :inside_state
|
4
|
+
attr_reader :states
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@inside_state = nil
|
8
|
+
@states = []
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# Gets the currently active gamestate (top of stack)
|
13
|
+
#
|
14
|
+
def state
|
15
|
+
@states.last
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Adds a state to the gamestate-stack
|
20
|
+
#
|
21
|
+
def push_state(state)
|
22
|
+
@states.push(state)
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Pops a state off the gamestate-stack
|
27
|
+
#
|
28
|
+
def pop_state
|
29
|
+
@states.pop
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Returns the previous gamestate
|
34
|
+
#
|
35
|
+
def previous_state
|
36
|
+
@states[@states.index(state)-1]
|
37
|
+
end
|
38
|
+
|
39
|
+
alias :prev_state previous_state
|
40
|
+
|
41
|
+
#
|
42
|
+
# Pops through all gamestates until matching a given gamestate
|
43
|
+
#
|
44
|
+
def switch_state(new_state)
|
45
|
+
while (state = @states.pop)
|
46
|
+
break if state == new_state
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Bellow follows a set of auto-called Gosu::Window methods.
|
52
|
+
# We define them game_state_manager so Gosu::Window can call them here.
|
53
|
+
# Then the game_state_manager is responsible to resend them to the active state.
|
54
|
+
# Or in the future many states.
|
55
|
+
#
|
56
|
+
|
57
|
+
#
|
58
|
+
# Called before #update when the user pressed a button while the window had the focus.
|
59
|
+
#
|
60
|
+
def button_down(id)
|
61
|
+
state.button_down(id) if state
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Called when the user released a button.
|
66
|
+
#
|
67
|
+
def button_up(id)
|
68
|
+
state.button_up(id) if state
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Calls #update on the current gamestate, if there is one.
|
73
|
+
#
|
74
|
+
def update
|
75
|
+
state.update if state
|
76
|
+
end
|
77
|
+
#
|
78
|
+
# Calls draw() on the current gamestate, if there is one.
|
79
|
+
#
|
80
|
+
def draw
|
81
|
+
state.draw if state
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Chingu
|
2
|
+
module GameStateHelpers
|
3
|
+
|
4
|
+
#
|
5
|
+
# push_gamestate accepts either a class inherited from GameState or an object-instance from such a class.
|
6
|
+
#
|
7
|
+
# push_gamestate(Intro) is the same as:
|
8
|
+
# push_gamestate(Intro.new)
|
9
|
+
#
|
10
|
+
# The first line ends upp calling "new" to Intro before activating the newlycreated gamestate.
|
11
|
+
#
|
12
|
+
def push_gamestate(state)
|
13
|
+
if state.is_a? Chingu::GameState
|
14
|
+
$window.game_state_manager.push_state(state)
|
15
|
+
elsif state.superclass == Chingu::GameState
|
16
|
+
$window.game_state_manager.push_state(state.new)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def pop_gamestate
|
21
|
+
$window.game_state_manager.pop_state
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_gamestate
|
25
|
+
$window.game_state_manager.state
|
26
|
+
end
|
27
|
+
|
28
|
+
def previous_gamestate
|
29
|
+
$window.game_state_manager.previous_state
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module DrawHelpers
|
34
|
+
def fill(color)
|
35
|
+
$window.draw_quad(0, 0, color, $window.width, 0, color, $window.width, $window.width, color, 0, $window.height, color, 0, :default)
|
36
|
+
end
|
37
|
+
|
38
|
+
def fade(options = {})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/chingu/input.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
module Chingu
|
2
|
+
module Input
|
3
|
+
include Gosu::Button
|
4
|
+
|
5
|
+
#
|
6
|
+
# Ruby symbols describing http://www.libgosu.org/rdoc/classes/Gosu.html
|
7
|
+
#
|
8
|
+
CONSTANT_TO_SYMBOL = {
|
9
|
+
Kb0 => [:zero],
|
10
|
+
Kb1 => [:one],
|
11
|
+
Kb2 => [:two],
|
12
|
+
Kb3 => [:three],
|
13
|
+
Kb4 => [:four],
|
14
|
+
Kb5 => [:five],
|
15
|
+
Kb6 => [:six],
|
16
|
+
Kb7 => [:seven],
|
17
|
+
Kb8 => [:eight],
|
18
|
+
Kb9 => [:nine],
|
19
|
+
|
20
|
+
KbBackspace => [:backspace],
|
21
|
+
KbDelete => [:delete, :del],
|
22
|
+
KbDown => [:down],
|
23
|
+
KbEnd => [:end],
|
24
|
+
KbEnter => [:enter],
|
25
|
+
KbEscape => [:escape, :esc],
|
26
|
+
|
27
|
+
KbHome => [:home],
|
28
|
+
KbInsert => [:insert, :ins],
|
29
|
+
KbLeft => [:left],
|
30
|
+
KbLeftAlt => [:left_alt, :lalt],
|
31
|
+
KbLeftControl => [:left_control, :left_ctrl, :lctrl],
|
32
|
+
KbLeftShift => [:left_shift, :lshift],
|
33
|
+
|
34
|
+
|
35
|
+
KbNumpadAdd => [:"+", :add],
|
36
|
+
KbNumpadDivide => [:"/", :divide],
|
37
|
+
KbNumpadMultiply => [:"*", :multiply],
|
38
|
+
KbNumpadSubtract => [:"-", :subtract],
|
39
|
+
KbPageDown => [:page_down],
|
40
|
+
KbPageUp => [:page_up],
|
41
|
+
# KbPause => [:pause],
|
42
|
+
KbReturn => [:return],
|
43
|
+
KbRight => [:right],
|
44
|
+
KbRightAlt => [:right_alt, :ralt],
|
45
|
+
KbRightControl => [:right_control, :right_ctrl, :rctrl],
|
46
|
+
KbRightShift => [:right_shift, :rshift],
|
47
|
+
KbSpace => [:" ", :space],
|
48
|
+
KbTab => [:tabulator, :tab],
|
49
|
+
KbUp => [:up],
|
50
|
+
|
51
|
+
MsLeft => [:left_mouse_button, :mouse_left],
|
52
|
+
MsMiddle => [:middle_mouse_button, :mouse_middle],
|
53
|
+
MsRight => [:right_mouse_button, :mouse_right],
|
54
|
+
MsWheelDown => [:mouse_wheel_down, :wheel_down],
|
55
|
+
MsWheelUp => [:mouse_wheel_up, :wheel_up],
|
56
|
+
|
57
|
+
GpDown => [:gamepad_down, :gp_down, :pad_down],
|
58
|
+
GpLeft => [:gamepad_left, :gp_left, :pad_left],
|
59
|
+
GpRight => [:gamepad_right, :gp_right, :pad_right],
|
60
|
+
GpUp => [:gamepad_up, :gp_up, :pad_up]
|
61
|
+
}
|
62
|
+
|
63
|
+
# Letters, A-Z
|
64
|
+
("A".."Z").each do |letter|
|
65
|
+
CONSTANT_TO_SYMBOL[eval("Kb#{letter}")] = [letter.downcase.to_sym]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Numbers, 0-9
|
69
|
+
(0..9).each do |number|
|
70
|
+
CONSTANT_TO_SYMBOL[eval("Kb#{number.to_s}")] = [number.to_s.to_sym]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Numpad-numbers, 0-9
|
74
|
+
(0..9).each do |number|
|
75
|
+
CONSTANT_TO_SYMBOL[eval("KbNumpad#{number.to_s}")] = ["numpad_#{number.to_s}".to_sym]
|
76
|
+
end
|
77
|
+
|
78
|
+
#F-keys, F1-F12
|
79
|
+
(1..12).each do |number|
|
80
|
+
CONSTANT_TO_SYMBOL[eval("KbF#{number.to_s}")] = ["f#{number.to_s}".to_sym]
|
81
|
+
end
|
82
|
+
|
83
|
+
# Gamepad-buttons 0-15
|
84
|
+
(0..15).each do |number|
|
85
|
+
CONSTANT_TO_SYMBOL[eval("GpButton#{number.to_s}")] = ["gamepad_button_#{number.to_s}"]
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# Reverse CONSTANT_TO_SYMBOL -> SYMBOL_TO_CONSTNT
|
90
|
+
# like: SYMBOL_TO_CONSTANT = CONSTANT_TO_SYMBOL.invert.dup
|
91
|
+
#
|
92
|
+
SYMBOL_TO_CONSTANT = Hash.new
|
93
|
+
CONSTANT_TO_SYMBOL.each_pair do |constant, symbols|
|
94
|
+
symbols.each do |symbol|
|
95
|
+
SYMBOL_TO_CONSTANT[symbol] = constant
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|