# デバッグ用情報表示の設定
game.draw_collision_mode false
game.draw_fps_mode false
IS_PRINT_DEBUG = false
IS_VIEW_FPS = true
# 画像のローディング
game.loading do |loader|
loader.add :window, :system => "window"
loader.add :gui_item, :system => "gui_item"
loader.add :bomb, 17
loader.add :bullet, 18
loader.add :player, 21
loader.add :enemy, 20
loader.add :circle, 19
end
# :bomb など:(コロン)で始まるものは
# symbol(シンボル)とよばれるもので
# :以降の文字列と対応する抽象的なデータ
# 内部的には数値でメモリーの容量や処理速度の点で効率がいいが
# 無制限に作るとメモリーがあふれてしまう。
# ゲームの初期化
game.on_init do
set_window_image :window
set_gui_image :gui_item
# オープニングのシーンへ
scene_change :start_scene
end
# ゲーム全体で使うデータ
# 定数に入れておいて、関数で同じインスタンスを返すようにする
LOCAL_DATA_CONSTANT = {}
def local_data
LOCAL_DATA_CONSTANT
end
#当たり判定のグループの名前(シンボル)と値のテーブル
COLLISION_GROUP = {
:player => 1, # プレーヤー
:player_bullet => 2, # プレーヤーの弾
:enemy => 3, # 敵
:enemy_bullet => 4, # 敵の弾
:outside => 5 # 画面の外かどうかの判定用(これに交差したら消す)
}
#
# 画面の幅を取得
# ※豆知識
# 関数の返り値は最後に評価されたものが返ります。
# 関数内に値だけ書けばそれが返り値になります。
def screen_width
game.get_screen_size[0]
end
# 画面の高さを取得
def screen_height
game.get_screen_size[1]
end
# 画面外判定用のスプライトの大きさを取得
def outside_size
4096
end
# ベクトル関係の関数
# ※豆知識
# 関数のかっこは省略可能なため
# vector_len a
# vector_len(a)
# どちらでも書くことができる。
# ただし、関数の引数に関数を書く場合は
# どちらの関数なのか分からなくなるため
# かっこでくくる必要がある場合もある
# ベクトルの長さを求めます。
def vector_len a
Math.sqrt a[0] * a[0] + a[1] * a[1]
end
# ベクトルの足し算
# ここではベクトルを、長さ2の配列で扱っています。
def vector_add a, b
[a[0] + b[0], a[1] + b[1]]
end
# ベクトルの引き算
def vector_sub a, b
[a[0] - b[0], a[1] - b[1]]
end
# ベクトルとスカラーの掛け算
def vector_mul a, b
[a[0] * b, a[1] * b]
end
# ベクトルの正規化、つまりベクトルの長さを1にする。
def vector_normal v
l = vector_len v
if l > 0
vector_mul v, 1.0 / l
else
[0, 1]
end
end
# dからsへまっすぐ移動するとき
# 長さvだけ進むときのベクトルを求める。
# sを通り過ぎてしまう場合は、sのところで止まる量のベクトルを返す。
def vector_dir d, s, v
r = [0, 0]
sb = vector_sub d, s
l = vector_len sb
if l > v
vector_mul sb, (v / l)
else
sb
end
end
# ベクトルの角度を求めます
def vector_angle v
Math.atan2 v[1], v[0]
end
# vの点が画面内(よりちょっと狭い範囲)に収まるようにします
# 操作用ハンドルが画面内に収まる処理に使います。
def clip_screen v
v = v.clone
v[0] = 32 if v[0] < 32
v[0] = screen_width - 32 if v[0] > screen_width - 32
v[1] = 32 + local_data[:circle_pos][1] if v[1] < 32 + local_data[:circle_pos][1]
v[1] = screen_height - 32 if v[1] > screen_height - 32
v
end
#
# デバッグ用の画面表示
# IS_PRINT_DEBUGがtrueのとき画面にこの関数で出力した内容を表示します。
def debug_print str
return unless local_data[:debug_text]
local_data[:debug_text_string] += "#{str}\n"
end
# ※豆知識
# unlessは判定式が偽のときに処理を実行する
# つまりifとは逆の動作
# unless false
# #実行内容
# end
# ※豆知識
# 処理 if 条件
# という書き方は
# if 条件
# 処理
# end
# と同じ
#
# 敵の弾丸生成関数
# pos の位置から弾を生成
# n 個の弾を生成
# th の角度(ラジアン)の範囲に弾を生成
# dir が指定されている場合はその方向に弾を撃つ
# 指定されていない場合はプレーヤーの方向に撃つ
def shoot_dir pos, n, th, velocity, dir = nil
player = local_data[:player]
return unless player
if dir
d = dir
else
pp = player.get_center_position
d = vector_sub pp, pos
d = vector_normal d
end
t = vector_angle d
t -= (th * (n - 1)) / 2
(0...n).each do |i|
s = player.scene.sprite :template => :sprite_template_enemy_bullet,
:center_position => pos
v = [Math.cos(t), Math.sin(t)]
v = vector_mul v, velocity
s.set_data :dir, v
t += th
end
end
# スプライトテンプレートについて
# 同じようなスプライトをたくさん出すのに適した機構
# 次のようにスプライトテンプレートの定義をおこなって、
# sprite_template :sprite_template_name do |sprite_template|
# ...
# end
# 次のような形で、スプライトテンプレートからスプライトを作る。
# scene.sprite :template => :sprite_template_name
# 敵キャラ用のスプライトテンプレートの共通パラメーターの初期化関数
def enemy_init_common sprite_template
sprite_template.texture :enemy # 敵のテクスチャーを設定
sprite_template.rotation Math::PI # 下を向かせる
sprite_template.scale 2.0, 2.0 # 2倍に拡大
sprite_template.collision :rect, :position => [0, 0], :width => [32, 32],
:group_id => COLLISION_GROUP[:enemy] # 矩形の当たり判定を設定
sprite_template.layer_order 30 # 描画順の設定
end
# 敵とプレーヤーの弾があたった時の処理
def enemy_bullet_collision enemy_sprite, damage
# 敵の体力の処理
hp = enemy_sprite.get_data :hp
hp -= damage
enemy_sprite.set_data :hp, hp
if hp <= 0
# 爆発の開始
enemy_sprite.scene.sprite :template => :sprite_template_bomb,
:center_position => enemy_sprite.get_center_position,
:scale => [2.0, 2.0]
# ボスの場合の処理
name = enemy_sprite.get_data :name
if name && name == :boss
enemy_sprite.scene.sprite :template => :sprite_template_boss_end,
:center_position => enemy_sprite.get_center_position,
:scale => [1.0, 1.0], :position => [-10000, -10000]
end
# 敵を消す
enemy_sprite.delete
end
end
# プレーヤーと敵の弾が当たった時の処理
def player_bullet_collision player_sprite
# 爆発
player_sprite.scene.sprite :template => :sprite_template_bomb,
:center_position => player_sprite.get_center_position,
:scale => [4.0, 4.0]
# プレーヤーのスプライトを消す
player_sprite.delete
local_data[:player] = nil
local_data[:player_destroyed] = true
end
# 時間待ちをするスプライトテンプレートを定義する関数
# name という名前のスプライトテンプレートを定義する
# frame 数のフレームだけ待つ
# block の処理を待った後に実行
def define_wait_event name, frame, &block
sprite_template name do |sprite_template|
sprite_template.motion :move do |commands|
commands.loop false # 処理をループするかどうか
commands.wait_frame frame # frame数のあいだ待ちます
commands.proc_call do |s| # この時にこのブロックの処理が呼ばれます
block.call s
s.delete
end
end
sprite_template.event :on_add do |event|
event.target.change_motion :move
end
end
end
# ボスが死んだあとちょっと待ってから、勝利表示用のシーンへ遷移
define_wait_event :sprite_template_boss_end, 180 do |s|
scene_change :win_scene
end
# ※豆知識
# 関数の引数に処理手順を
# do |引数| 処理 end
# {|引数| 処理 }
# などの書き方をして、処理手順そのものを関数に渡すことができる。
# このときの処理手順をblock(ブロック)と呼ぶ
# blockの処理がいつ実行されるかは、blockを渡した関数次第で、
# 関数の処理中に呼ばれることもあれば、
# 関数から抜けてしばらくしてから呼ばれることもある。
# 爆発用のスプライトテンプレート
sprite_template :sprite_template_bomb do |sprite_template|
sprite_template.texture :bomb # テクスチャーの設定
sprite_template.scale 0.25, 0.25 # 拡大量
sprite_template.src_size 96, 96 # アニメーション時のコピー元の矩形の大きさ
sprite_template.dest_size 96, 96 # アニメーション時のコピー先の矩形の設定
sprite_template.copy_rect 0, 0 # src_sizeのグリッドで区切られたテクスチャーの
# どの位置の画像を表示するかの設定
sprite_template.center_offset 48, 48 # スプライトの中心位置の設定
sprite_template.layer_order 40 # 描画順の設定
sprite_template.collision :rect, :position => [0, 0], :width => [0, 0],
:group_id => 0 # 当たり判定はいらないが、デフォルトだとデバッグ時に見づらいため適当な値を設定している
# 爆発のアニメーションの設定(コマンドリスト)
sprite_template.animation :bomb do |commands|
(0...16).each do |i|
# 1行に8パターンならんでいるのでこのような書き方
# 1フレームアニメーションを表示します。
commands.copy_rect :frame => 1, :src => [i % 8, (i / 8).floor]
# アニメーションの待ち
commands.wait_animation
end
# アニメーションが終わったら消します。
commands.proc_call do |s| s.delete end
end
# スプライトが生成された時の処理
sprite_template.event :on_add do |event|
# 起動時のアニメーションを設定します
event.target.change_animation :bomb
end
end
# 敵の弾のスプライトテンプレート
sprite_template :sprite_template_enemy_bullet do |sprite_template|
sprite_template.texture :bullet
sprite_template.src_size 16, 16
sprite_template.dest_size 16, 16
sprite_template.copy_rect 1, 0
sprite_template.center_offset 8, 8
sprite_template.collision :circle, :mode => :center, :position => [0, 0], :radius => 4,
:group_id => COLLISION_GROUP[:enemy_bullet]
sprite_template.layer_order 50
# 弾の移動のモーションの定義(コマンドリスト)
sprite_template.motion :move do |commands|
commands.loop false
#コマンドリストの実行時に処理をおこないたいため、lambdaで処理手順を渡している
commands.velocity(lambda do |s|
s.get_data(:dir)[0]
end,
lambda do |s|
s.get_data(:dir)[1]
end)
commands.wait_frame 320
end
sprite_template.event :on_add do |event|
event.target.set_data :dir, [0, 4]
event.target.change_motion :move
end
# 衝突時の処理
sprite_template.event :on_collision do |event|
source = event.pair[0]
another = event.pair[1]
next unless another # すでにスプライト掛けされている場合がありえて、その場合はnilがはいる
next unless source
type = another.get_data :type
if type && type == :player
player_bullet_collision another
end
# player_bullet_collisionでsourceを削除している可能性があるため
# source.destroyedで壊されているかどうかを判定する
source.delete unless source.destroyed
end
end
# ※豆知識
# 文字列.to_symで文字列をシンボルに変換することができます。
# "test".to_sym == :test
# ジグザグに動く雑魚敵のスプライトテンプレートを定義する関数
# 右から出てくるのと左から出てくるので、共通の部分が多いため関数にまとめている
def sprite_template_enemy_define_zig type
sprite_template ("sprite_template_enemy_zig_" + type.to_s).to_sym do |sprite_template|
enemy_init_common sprite_template
# 動きの記述
sprite_template.motion :move do |commands|
commands.loop false
# 0, 1, 2という値が1に入って繰り返される
(0...2).each do |i|
# 現在位置から [0, 96]の位置に速度4で移動
commands.move_by_v 0, 96, 4
# モーションの終了を待ちます
commands.wait_motion
if i == 0
commands.proc_call do |s|
# 弾を撃つ
shoot_dir s.get_center_position, 2, 0.4, 3
end
end
commands.move_by_v type == 0 ? 125 : -125, 0, 4
commands.wait_motion
commands.move_by_v 0, 96, 4
commands.wait_motion
commands.move_by_v type == 0 ? -125 : 125, 0, 4
commands.wait_motion
end
commands.proc_call do |s|
shoot_dir s.get_center_position, 3, 0.3, 4
end
commands.velocity type == 0 ? 4 : -4, -4
commands.wait_frame 60 * 20
end
sprite_template.event :on_add do |event|
event.target.set_data :type, :enemy
event.target.set_data :hp, 3
event.target.change_motion :move
end
end
end
# ジグザグの動きをする敵を定義する
sprite_template_enemy_define_zig 0
sprite_template_enemy_define_zig 1
# 中ボスの定義、花火のような弾幕を撃つ
sprite_template :sprite_template_enemy_fire_work do |sprite_template|
enemy_init_common sprite_template
sprite_template.motion :move do |commands|
commands.loop false
commands.move_by_v 0, 200, 4
commands.wait_motion
div = 24
(0...12).each do |i|
if i % 2 == 0
commands.proc_call do |s|
shoot_dir s.get_center_position, div, Math::PI * 2 / div, 3, [0, 0]
end
else
commands.proc_call do |s|
shoot_dir s.get_center_position, div, Math::PI * 2 / div, 3,
[Math.cos(Math::PI / div), Math.sin(Math::PI / div)]
end
end
commands.wait_frame 20
end
commands.wait_frame 60
commands.move_by_v 0, -900, 4
commands.wait_motion
end
sprite_template.event :on_add do |event|
event.target.set_data :type, :enemy
event.target.set_data :hp, 30
event.target.change_motion :move
end
end
# ボスキャラのスプライトテンプレート定義
sprite_template :sprite_template_enemy_boss do |sprite_template|
enemy_init_common sprite_template
#sprite_template.scale 4.0, 4.0
sprite_template.motion :start do |commands|
commands.loop false
commands.move_by_v 0, 120, 4
commands.wait_motion
commands.proc_call do |s|
# モーションの変更
s.change_motion :phase1
end
end
sprite_template.motion :phase1 do |commands|
commands.loop true
(0...240).each do |i|
commands.proc_call do |s|
t = i / 5
shoot_dir s.get_center_position, 1, 0.1, 4,
[Math.cos(t), Math.sin(t)]
s.set_rotation 2 * Math::PI / 60 + s.get_rotation
sc = s.get_scale
s.set_scale Math.cos(i * 2 * Math::PI / 40) / 40 + sc[0],
Math.cos(i * 2 * Math::PI / 40) / 40 + sc[1]
if i == 240 - 1
s.set_rotation Math::PI
s.set_scale 2, 2
end
end
commands.wait_frame 1
end
commands.move_by_v 120, 0, 2
commands.wait_motion
(0...24).each do |i|
commands.proc_call do |s|
cp = s.get_center_position
shoot_dir cp, 5, 0.4, 5
p0 = vector_add cp, [20, 0]
shoot_dir p0, 2, 0.4, 5
p1 = vector_add cp, [-20, 0]
shoot_dir p1, 2, 0.4, 5
end
commands.wait_frame 10
end
commands.move_by_v -240, 0, 2
commands.wait_motion
(0...240).each do |i|
commands.proc_call do |s|
t = Math.sin(i / 10) * Math.sin(i / 30) * 3
shoot_dir s.get_center_position, 1, 0.1, 3, [-Math.sin(t), Math.cos(t)]
t = Math.sin((i + 5) / 10) * Math.sin((i + 15) / 30) * 3
shoot_dir s.get_center_position, 1, 0.1, 3, [Math.sin(t), Math.cos(t)]
end
commands.wait_frame 2
end
commands.move_by_v 120, 0, 2
commands.wait_motion
end
sprite_template.event :on_add do |event|
event.target.set_data :type, :enemy
event.target.set_data :name, :boss
event.target.set_data :hp, 300
event.target.change_motion :start
end
end
# 敵の出現パターンを決めるスプライトテンプレート
sprite_template :sprite_template_enemy_generator_0 do |sprite_template|
# :defaltが指定されているコマンドリストは作られた時から実行される
sprite_template.motion :default do |commands|
commands.loop false
# 左からジグザグに動く雑魚
(0...6).each do |i|
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_zig_0, :center_position => [25, 0]
end
commands.wait_frame 30
end
commands.wait_frame 60 * 1
# 右からジグザグに動く雑魚
(0...6).each do |i|
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_zig_1, :center_position => [425, 0]
end
commands.wait_frame 30
end
commands.wait_frame 60 * 1
# 両側からジグザグに動く雑魚
(0...6).each do |i|
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_zig_0, :center_position => [25, 0]
s.scene.sprite :template => :sprite_template_enemy_zig_1, :center_position => [425, 0]
end
commands.wait_frame 30
end
commands.wait_frame 60 * 3
# 中ボス
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_fire_work, :center_position => [225, 0]
end
commands.wait_frame 60 * 5
# 左からジグザグに動く雑魚
(0...6).each do |i|
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_zig_0, :center_position => [25, 0]
end
commands.wait_frame 30
end
commands.wait_frame 60 * 1
# 右からジグザグに動く雑魚
(0...6).each do |i|
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_zig_1, :center_position => [425, 0]
end
commands.wait_frame 30
end
commands.wait_frame 60 * 1
# 両側からジグザグに動く雑魚
(0...6).each do |i|
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_zig_0, :center_position => [25, 0]
s.scene.sprite :template => :sprite_template_enemy_zig_1, :center_position => [425, 0]
end
commands.wait_frame 30
end
commands.wait_frame 60 * 3
# ボス
commands.proc_call do |s|
s.scene.sprite :template => :sprite_template_enemy_boss, :center_position => [225, 0]
end
end
end
# プレーヤーの弾のスプライトテンプレート
sprite_template :sprite_template_player_bullet do |sprite_template|
sprite_template.texture :bullet
sprite_template.src_size 16, 16
sprite_template.dest_size 32, 64
sprite_template.copy_rect 0, 0
sprite_template.center_offset 16, 32
sprite_template.collision :rect, :position => [0, 0], :width => [32, 64],
:group_id => COLLISION_GROUP[:player_bullet]
sprite_template.layer_order 20
sprite_template.motion :move do |commands|
commands.loop true
commands.velocity 0, -32
commands.wait_frame 320
end
sprite_template.event :on_add do |event|
event.target.change_motion :move
end
sprite_template.event :on_collision do |event|
source = event.pair[0]
another = event.pair[1]
next unless another
next unless source
type = another.get_data :type
if type && type == :enemy
enemy_bullet_collision another, 1
event.scene.sprite :template => :sprite_template_bomb,
:center_position => source.get_center_position,
:scale => [0.5, 0.5]
end
source.delete
end
end
# プレーヤーのスプライトテンプレート
sprite_template :sprite_template_player do |sprite_template|
sprite_template.position 230, 600
sprite_template.rotation 0.0
sprite_template.scale 2.0, 2.0
sprite_template.texture :player
sprite_template.src_size 32, 32
sprite_template.dest_size 32, 32
sprite_template.copy_rect 0, 0
sprite_template.center_offset 16, 16
sprite_template.collision :circle, :mode => :center, :position => [0, 0], :radius => 4,
:group_id => COLLISION_GROUP[:player]
sprite_template.layer_order 10
sprite_template.event :on_add do |event|
event.target.set_data :counter, 0
event.target.set_data :type, :player
end
# 描画の間隔ぐらいのタイミングで、この処理が実行される
sprite_template.event :on_step do |event|
ct = event.target.get_data :counter
ct += 1
# プレーヤーのスプライトとハンドルのスプライトの操作
cp = event.target.get_center_position
tp = local_data[:player_move_target]
debug_print "player position #{cp}"
if tp
v = vector_dir tp, cp, 6
np = vector_add cp, v
event.target.set_center_position *np
circle_point = vector_add np, local_data[:circle_pos]
local_data[:circle].set_center_position *circle_point
end
# タッチしているときに撃つ
if ct >= 3 && local_data[:press]
bullet = event.scene.sprite :template => :sprite_template_player_bullet
bullet.set_center_position cp[0], cp[1] - 24
ct = 0
end
#
event.target.set_data :counter, ct
end
end
# 画面の外との当たり判定
sprite_template :sprite_template_outside do |sprite_template|
sprite_template.collision :rect, :position => [0, 0], :width => [outside_size, outside_size],
:group_id => COLLISION_GROUP[:outside]
sprite_template.layer_order 0
sprite_template.event :on_collision do |event|
# 画面の外に出たものを消します。
another = event.pair[1]
next unless another
another.delete
end
sprite_template.event :on_add do |event|
# スプライトのデータを指定します
event.target.set_data :type, :outside
end
end
# 画面入力を扱うスプライトテンプレート
sprite_template :sprite_template_screen do |sprite_template|
sprite_template.layer_order 100
sprite_template.align :fullscreen # 画面全体に広げます
sprite_template.no_image true
# タッチダウン時の処理
sprite_template.event :on_touch_down do |event|
next unless local_data[:player]
pt = clip_screen [event.screen_x, event.screen_y]
local_data[:player_move_target] = vector_sub pt, local_data[:circle_pos]
local_data[:press] = true
end
# タッチムーブ時の処理
sprite_template.event :on_touch_move do |event|
next unless local_data[:player]
pt = clip_screen [event.screen_x, event.screen_y]
local_data[:player_move_target] = vector_sub pt, local_data[:circle_pos]
end
# タッチアップ時の処理
sprite_template.event :on_touch_up do |event|
local_data[:press] = false
end
sprite_template.event :on_step do |event|
# デバッグ文字表示
if local_data[:debug_text]
local_data[:debug_text].set_text local_data[:debug_text_string]
local_data[:debug_text_string] = ""
end
# プレーヤーが死んだあとの処理
if local_data[:player_destroyed]
if local_data[:player_dead_count] > 20
scene_change :loose_scene
end
local_data[:player_dead_count] += 1
end
end
end
#
scene :start_scene do |scene|
scene.loading do |loader|
end
scene.on_init do
speak "タッチあるいはマウスのドラッグで操作します。"
speak "タップ(クリック)でゲーム開始"
scene_change :stage_scene
end
end
def start_stage scene, index
# どの当たり判定グループと、どの当たり判定グループが衝突するかの設定
game.collision_group_pair COLLISION_GROUP[:player_bullet], COLLISION_GROUP[:outside], true
game.collision_group_pair COLLISION_GROUP[:enemy], COLLISION_GROUP[:outside], true
game.collision_group_pair COLLISION_GROUP[:enemy_bullet], COLLISION_GROUP[:outside], true
game.collision_group_pair COLLISION_GROUP[:player_bullet], COLLISION_GROUP[:enemy], true
game.collision_group_pair COLLISION_GROUP[:player], COLLISION_GROUP[:enemy_bullet], true
# ゲームのシーンで使うデータの設定
local_data.clear
local_data[:screen] = scene.collision :template => :sprite_template_screen
local_data[:player] = scene.sprite :template => :sprite_template_player
local_data[:circle] = scene.sprite :texture => :circle, :scale => [2, 2], :layer_order => 90
local_data[:circle_pos] = [0, 128]
local_data[:circle].set_center_position *vector_add(
local_data[:player].get_center_position, local_data[:circle_pos])
local_data[:press] = false
local_data[:player_destroyed] = false
local_data[:player_dead_count] = 0
# デバッグ表示用
if IS_PRINT_DEBUG
text = scene.text :position => [10, 10]
text.set_text_area_size 430, 200
text.set_font_point_size 12
local_data[:debug_text] = text
local_data[:debug_text_string] = ""
text.set_text local_data[:debug_text_string]
end
# 画面外に出た時の判定用
scene.collision :template => :sprite_template_outside, :position =>
[-outside_size - 64, -(outside_size - screen_height) / 2]
scene.collision :template => :sprite_template_outside, :position =>
[-(outside_size - screen_width) / 2, -outside_size - 256]
scene.collision :template => :sprite_template_outside, :position =>
[screen_width + 64, -(outside_size - screen_height) / 2]
scene.collision :template => :sprite_template_outside, :position =>
[-(outside_size - screen_width) / 2, screen_height + 64]
# 敵の出現用
local_data[:enemy_generator] = scene.collision :template =>
("sprite_template_enemy_generator_" + index.to_s).to_sym,
:position => [-5000, -5000]
# ゲーム処理の負荷計測用のfps表示
if IS_VIEW_FPS
fps_sp = scene.text :position => [10, 750]
fps_sp.set_text_area_size 200, 40
fps_sp.set_font_point_size 18
tm = Time.now.to_f
count = 0
fps_sp.event :on_step do
now = Time.now.to_f
count += 1
if now - tm > 1
fps_sp.set_text "fps = #{count}"
count = 0
tm = now
end
end
end
end
# ゲームのステージ用シーン
scene :stage_scene do |scene|
scene.loading do |loader|
end
scene.on_init do
start_stage scene, 0
end
end
# 負けた時のシーン
scene :loose_scene do |scene|
scene.on_init do
speak "負けてしまった。"
text = scene.text :position => [100, 200]
text.set_text_area_size 250, 200
text.set_font_point_size 32
text.set_text "再挑戦"
text.event :on_click do |event|
# もう一度ゲームを始める
scene_change :stage_scene
end
text = scene.text :position => [100, 500]
text.set_text_area_size 250, 200
text.set_font_point_size 32
text.set_text "あきらめる"
text.event :on_click do |event|
# スタートメニューに戻る
game.change_project "start_menu"
end
end
end
# 勝った時のシーン
scene :win_scene do |scene|
scene.on_init do
speak "勝った。"
speak "あなたの偉業は永遠に語り継がれるであろう。"
game.change_project "start_menu"
end
end