flonkerton 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,135 @@
1
+ require '../../lib/flonkerton'
2
+ require '../../examples/extras/random_color'
3
+ include Flonkerton
4
+ include Gosu
5
+
6
+ module GosuTutorial
7
+ module ZOrder
8
+ Background, Stars, Player, UI = *0..3
9
+ end
10
+
11
+ class Player
12
+ attr_reader :score
13
+
14
+ def initialize
15
+ @image = Images[:starfighter]
16
+ @beep = Samples[:beep]
17
+ @x = @y = @vel_x = @vel_y = @angle = 0.0
18
+ @score = 0
19
+ end
20
+
21
+ def warp(x, y)
22
+ @x, @y = x, y
23
+ end
24
+
25
+ def turn_left
26
+ @angle -= 4.5
27
+ end
28
+
29
+ def turn_right
30
+ @angle += 4.5
31
+ end
32
+
33
+ def accelerate
34
+ @vel_x += Gosu::offset_x(@angle, 0.5)
35
+ @vel_y += Gosu::offset_y(@angle, 0.5)
36
+ end
37
+
38
+ def move
39
+ @x += @vel_x
40
+ @y += @vel_y
41
+ @x %= CONFIG[:width]
42
+ @y %= CONFIG[:height]
43
+
44
+ @vel_x *= 0.95
45
+ @vel_y *= 0.95
46
+ end
47
+
48
+ def draw
49
+ @image.draw_rot(@x, @y, ZOrder::Player, @angle)
50
+ end
51
+
52
+ def collect_stars(stars)
53
+ stars.reject! do |star|
54
+ if Gosu::distance(@x, @y, star.x, star.y) < 35 then
55
+ @score += 10
56
+ @beep.play
57
+ true
58
+ else
59
+ false
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ class Star
66
+ attr_reader :x, :y
67
+
68
+ def initialize
69
+ @animation = Tiles[:star]
70
+ @offset = @animation.first.width / 2.0
71
+ @color = Color.random((40..254), (40..254), (40..254))
72
+ @x = rand * CONFIG[:width]
73
+ @y = rand * CONFIG[:height]
74
+ end
75
+
76
+ def draw
77
+ current_frame.draw :x => @x - @offset,
78
+ :y => @y - @offset,
79
+ :z => ZOrder::Stars,
80
+ :color => @color,
81
+ :mode => :additive
82
+ end
83
+
84
+ protected
85
+
86
+ def current_frame
87
+ @animation[Gosu::milliseconds / 100 % @animation.size]
88
+ end
89
+ end
90
+
91
+ class GameScreen < Screen
92
+ def setup
93
+ @background = Images[:space]
94
+ @player = Player.new
95
+ @player.warp(320, 240)
96
+ @stars = Array.new
97
+ @font = Fonts[:default]
98
+ @input = { :up => [KbUp, GpButton0],
99
+ :left => [KbLeft, GpLeft],
100
+ :right => [KbRight, GpRight] }
101
+ end
102
+
103
+ def update
104
+ @player.turn_left if pressed?(:left)
105
+ @player.turn_right if pressed?(:right)
106
+ @player.accelerate if pressed?(:up)
107
+ @player.move
108
+ @player.collect_stars(@stars)
109
+
110
+ if rand(100) < 4 and @stars.size < 25 then
111
+ @stars << Star.new
112
+ end
113
+ end
114
+
115
+ def draw
116
+ @background.draw
117
+ @player.draw
118
+ @stars.each { |star| star.draw }
119
+ @font.draw :text => "Score: #{@player.score}",
120
+ :x => 10,
121
+ :y => 10,
122
+ :z => ZOrder::UI,
123
+ :color => Color::YELLOW
124
+ end
125
+
126
+ protected
127
+
128
+ # Taken from control example.
129
+ def pressed?(key)
130
+ @input[key].detect { |k| @game.button_down?(k) }
131
+ end
132
+ end
133
+ end
134
+
135
+ Game.start
@@ -0,0 +1,241 @@
1
+ require 'gosu'
2
+ require 'yaml'
3
+
4
+ class File
5
+ def self.label(file)
6
+ self.basename(file)[/^\w+/].scan(/[A-Z]*[a-z0-9]+/).join('_').downcase.intern
7
+ end
8
+ end
9
+
10
+ module Flonkerton
11
+ VERSION = '0.0.1'
12
+ LIB_PATH = File.dirname(File.expand_path(__FILE__))
13
+ CURRENT_PATH = File.dirname(File.expand_path($0))
14
+
15
+ if File.exist?(CURRENT_PATH + '/config/defaults.yml')
16
+ CONFIG = YAML.load_file(CURRENT_PATH + '/config/defaults.yml')
17
+ else
18
+ CONFIG = YAML.load_file(LIB_PATH + '/../config/defaults.yml')
19
+ end
20
+
21
+ module Drawable
22
+ def draw(options = {})
23
+ super(*draw_args(defaults.merge(options)))
24
+ end
25
+
26
+ protected
27
+
28
+ def draw_args(options)
29
+ defaults[:order].map { |arg| options[arg] } # 1.8.6 Patch - defaults.keys.map in 1.9
30
+ end
31
+
32
+ def name
33
+ self.class.to_s[/\w+$/].downcase
34
+ end
35
+
36
+ def defaults
37
+ CONFIG[name.intern]
38
+ end
39
+ end
40
+
41
+ class Font < Gosu::Font
42
+ include Drawable
43
+
44
+ def initialize(game, name, height = CONFIG[:font_size])
45
+ super(game, name, height)
46
+ end
47
+ end
48
+
49
+ class Image < Gosu::Image
50
+ include Drawable
51
+
52
+ def self.load_tiles(game, file, width, height, border = true)
53
+ super(game, file, width, height, border).each do |image|
54
+ image.extend(Drawable)
55
+ end
56
+ end
57
+ end
58
+
59
+ class Sample < Gosu::Sample; end
60
+
61
+ class Song < Gosu::Song
62
+ def loop
63
+ play(true)
64
+ end
65
+ end
66
+
67
+ # This class shouldn't be used directly, it provides behavior for subclasses.
68
+ #
69
+ class Resource
70
+ def self.load(game)
71
+ Dir[path].each do |file|
72
+ all[File.label(file)] = klass.new(game, file)
73
+ end
74
+ end
75
+
76
+ def self.all
77
+ @hash ||= Hash.new
78
+ end
79
+
80
+ def self.[](key)
81
+ all[key]
82
+ end
83
+
84
+ protected
85
+
86
+ def self.name
87
+ self.to_s[/\w+$/]
88
+ end
89
+
90
+ def self.klass
91
+ Module.class_eval(name.chop)
92
+ end
93
+
94
+ def self.path
95
+ File.join(CONFIG[:media_path], extension)
96
+ end
97
+
98
+ def self.extension
99
+ CONFIG["#{name.downcase}_ext".intern]
100
+ end
101
+ end
102
+
103
+ class Songs < Resource; end
104
+ class Images < Resource; end
105
+ class Samples < Resource; end
106
+
107
+ class Fonts < Resource
108
+ def self.load(game)
109
+ super(game)
110
+ all[:default] = Font.new(game, Gosu::default_font_name)
111
+ end
112
+ end
113
+
114
+ class Tiles < Resource
115
+ def self.load(game)
116
+ Dir[path].each do |file|
117
+ if File.basename(file) =~ /(\w+)_(\d+)x(\d+)/
118
+ all[$1.intern] = Image.load_tiles(game, file, $2.to_i, $3.to_i, true)
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ class Game
125
+ def self.start screen = nil
126
+ @window = Window.new(screen)
127
+ @window.show
128
+ end
129
+ end
130
+
131
+ class Window < Gosu::Window
132
+ attr_reader :screen
133
+ attr_accessor :next_screen
134
+
135
+ def initialize initial_screen = nil
136
+ super(CONFIG[:width], CONFIG[:height], CONFIG[:fullscreen])
137
+ self.caption = CONFIG[:caption]
138
+ load_resources
139
+ create(initial_screen || default_screen)
140
+ end
141
+
142
+ def update
143
+ @screen.update
144
+ create(@next_screen) if @next_screen
145
+ end
146
+
147
+ def draw
148
+ @screen.draw
149
+ end
150
+
151
+ def button_down(id)
152
+ @screen.button_down(id)
153
+ end
154
+
155
+ def button_up(id)
156
+ @screen.button_up(id)
157
+ end
158
+
159
+ def params
160
+ @params ||= Hash.new
161
+ end
162
+
163
+ protected
164
+
165
+ def load_resources
166
+ [Fonts, Songs, Images, Samples, Tiles].each do |resource|
167
+ resource.load(self)
168
+ end
169
+ end
170
+
171
+ def default_screen
172
+ Module.module_eval(CONFIG[:initial_screen])
173
+ end
174
+
175
+ def create(klass)
176
+ @screen = klass.new(self)
177
+ @next_screen = nil
178
+ end
179
+ end
180
+
181
+ # This class shouldn't be instantiated, it provides behavior for subclasses.
182
+ #
183
+ class Screen
184
+ def initialize game
185
+ @game = game
186
+ setup
187
+ end
188
+
189
+ def setup; end
190
+ def button_up(id); end
191
+
192
+ def button_down(id)
193
+ close if id == Gosu::KbEscape # Don't Panic!
194
+ end
195
+
196
+ def update; end
197
+ def draw; end
198
+
199
+ def width
200
+ @game.width
201
+ end
202
+
203
+ def height
204
+ @game.height
205
+ end
206
+
207
+ def mouse_x
208
+ @game.mouse_x
209
+ end
210
+
211
+ def mouse_y
212
+ @game.mouse_y
213
+ end
214
+
215
+ def button_down?(id)
216
+ @game.button_down?(id)
217
+ end
218
+
219
+ def close
220
+ @game.close
221
+ end
222
+
223
+ def go_to(screen)
224
+ @game.next_screen = screen
225
+ end
226
+
227
+ def params
228
+ @game.params
229
+ end
230
+
231
+ def clip_to(x, y, w, h, &block)
232
+ @game.clip_to(x, y, w, h, &block)
233
+ end
234
+ end
235
+
236
+ class WelcomeScreen < Screen
237
+ def draw
238
+ Fonts[:default].draw :text => 'Welcome'
239
+ end
240
+ end
241
+ end
Binary file
@@ -0,0 +1,4 @@
1
+ ArcadeClassic.ttf - Jacob Fisher - http://www.pizzadude.dk
2
+ background.png - http://blog.medianotions.de/de/artikel/2009/wallpaper-tangled-green
3
+ catch_me_song.ogg - ...
4
+ tiles_32x32.png - http://www.molotov.nu/
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,115 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ Protest.context('A Game example') do
4
+ module Example
5
+ class TextLogo
6
+
7
+ SPEED_X = 16
8
+ SPEED_Y = 10
9
+
10
+ def initialize text, limit
11
+ @text = text
12
+ @limit = limit
13
+ @font = Flonkerton::Fonts[:default]
14
+ @x = 0
15
+ @y = 0
16
+ end
17
+
18
+ def update
19
+ @x += SPEED_X
20
+ @y += SPEED_Y
21
+ end
22
+
23
+ def draw
24
+ @font.draw :text => @text,
25
+ :x => @x,
26
+ :y => @y,
27
+ :factor_x => 4,
28
+ :factor_y => 4
29
+ end
30
+
31
+ def on_screen?
32
+ @y < @limit
33
+ end
34
+ end
35
+
36
+ class LogoScreen < Flonkerton::Screen
37
+ LOGO_TIME = 1000
38
+
39
+ def setup
40
+ @time = Gosu.milliseconds
41
+ @font = Flonkerton::Fonts[:default]
42
+ @image = Flonkerton::Images[:gosu_logo]
43
+ @sample = Flonkerton::Samples[:select]
44
+ @x = (width - @image.width) / 2
45
+ @y = (height - @image.height) / 2
46
+ @song = Flonkerton::Songs[:catch_me_song]
47
+ @song.volume = 0.1
48
+ @song.loop
49
+ end
50
+
51
+ def update
52
+ if time_elapsed? or button_down?(Gosu::KbReturn)
53
+ @song.play
54
+ @sample.play
55
+ params[:health] = 75
56
+ go_to(GameScreen)
57
+ end
58
+ end
59
+
60
+ def draw
61
+ fill
62
+ @image.draw :x => @x, :y => @y
63
+
64
+ @font.draw :x => 10,
65
+ :y => height - @font.height,
66
+ :text => 'Press Enter to continue...',
67
+ :color => Gosu::Color::BLACK
68
+
69
+ @font.draw :text => time_left,
70
+ :color => Gosu::Color::BLACK
71
+ end
72
+
73
+ def fill(color = 0xffffffff)
74
+ @game.draw_quad(0, 0, color, width, 0, color, 0, height, color, width, height, color)
75
+ end
76
+
77
+ def time_left
78
+ Gosu.milliseconds - @time
79
+ end
80
+
81
+ def time_elapsed?
82
+ time_left >= LOGO_TIME
83
+ end
84
+ end
85
+
86
+ class GameScreen < Flonkerton::Screen
87
+ def setup
88
+ @logo = TextLogo.new('LOGO', height)
89
+ @mouse = Flonkerton::Images[:cursor]
90
+ @tiles = Flonkerton::Tiles[:tiles]
91
+ @background = Flonkerton::Images[:background]
92
+ end
93
+
94
+ def draw
95
+ @tiles.first.draw
96
+ clip_to(40, 40, 640, 480) do
97
+ @background.draw
98
+ end
99
+ @logo.draw
100
+ @mouse.draw :x => mouse_x, :y => mouse_y
101
+ end
102
+
103
+ def update
104
+ @logo.update
105
+ close unless @logo.on_screen?
106
+ end
107
+ end
108
+ end
109
+
110
+ it "should work." do
111
+ assert_nothing_raised do
112
+ Flonkerton::Game.start(Example::LogoScreen)
113
+ end
114
+ end
115
+ end