リファクタリング歓迎!
フルカラー (αチャンネル付き) は扱えないライブラリもあるため今回は使用しません。
αチャンネル付きが扱えないライブラリ:
スプライトの座標と速度を管理するクラスです。 update メソッドで更新します。
class Sprite
MAX_X = 640 - 32
MAX_Y = 480 - 32
attr_reader :x
attr_reader :y
def initialize
@x = rand(MAX_X)
@y = rand(MAX_Y)
@vx = rand(2) * 2 - 1
@vy = rand(2) * 2 - 1
end
def update
@x += @vx
@y += @vy
if @x < 0
@x = -@x
@vx = 1
end
if @y < 0
@y = -@y
@vy = 1
end
if MAX_X <= @x
@x = -(@x - MAX_X) + MAX_X
@vx = -1
end
if MAX_Y <= @y
@y = -(@y - MAX_Y) + MAX_Y
@vy = -1
end
end
end
Version 1.5.0a
require "Miyako/miyako"
require "Miyako/idaten_miyako"
require "sprite"
# Sprite の配列を生成する。
sprites = Array.new(200){ Sprite.new }
# Miyako::Sprite の配列を生成する。 sprites のスプライトと一対一対応する。
msprites = Array.new(sprites.size) do
# Miyako::Sprite オブジェクトを生成する。
# デフォルトでは非表示なので show メソッドを呼ぶ。
# show メソッドは self を返す。
Miyako::Sprite.new(:filename => "ruby.png").show
end
# ウィンドウのキャプションを設定する。
Miyako.setTitle("Sprites")
# FPS を設定する。
Miyako::Screen.fps = 30
# メインループ
Miyako.main_loop do
# ウィンドウが閉じられるか ESC キーが押されていたら終了する。
break if Miyako::Input.quit_or_escape?
# [[Sprite オブジェクト, Miyako::Sprite オブジェクト],
# [Sprite オブジェクト, Miyako::Sprite オブジェクト], ...]
# という配列を生成し、一つ一つに対して処理を行う。
sprites.zip(msprites).each do |sprite, msprite|
# Sprite オブジェクトを更新する。
sprite.update
# Miyako::Sprite オブジェクトの座標を設定する。
msprite.move_to(sprite.x, sprite.y)
end
end
sample.rbをインクルードしてないことに注目!
require "Miyako/miyako"
require "Miyako/idaten_miyako"
# 移動量 の配列を生成する。
vs = Array.new(200){ [rand(2)*2-1,rand(2)*2-1] }
# Miyako::Sprite の配列を生成する。 sprites のスプライトと一対一対応する。
msprites = Array.new(vs.size) do
# Miyako::Sprite オブジェクトを生成する。
# 位置をランダムに設定する
# roundメソッドは相対位置の移動メソッドだが、初期の位置は(0,0)なので問題は無い
# デフォルトでは非表示なので show メソッドを呼ぶ。
# show メソッドは self を返す。
spr = Miyako::Sprite.new(:filename => "ruby.png")
spr.round(rand(640), rand(480))
spr.show
end
# ウィンドウのキャプションを設定する。
Miyako.setTitle("Sprites")
# FPS を設定する。
Miyako::Screen.fps = 30
# メインループ
Miyako.main_loop do
# ウィンドウが閉じられるか ESC キーが押されていたら終了する。
break if Miyako::Input.quit_or_escape?
# [[Array オブジェクト, Miyako::Sprite オブジェクト],
# [Array オブジェクト, Miyako::Sprite オブジェクト], ...]
# という配列を生成し、一つ一つに対して処理を行う。
vs = vs.zip(msprites).map do |v, msprite|
# Miyako::Sprite オブジェクトの座標を更新する
# (更新された移動量がround_rev2メソッドの返却値となり、更新されたvs配列の新しい要素となる)。
msprite.round_rev2(*v)
end
end
Miyakoでは、ゲームやシナリオの構成をシーン単位(Sceneモジュールをmixinしたクラス)で管理できる。 また、これらのシーン全体をストーリー(Storyクラス)で管理(実行管理)する。
require "Miyako/miyako"
require "Miyako/idaten_miyako"
# ウィンドウのキャプションを設定する。
Miyako.setTitle("Sprites")
# FPS を設定する。
Miyako::Screen.fps = 30
class Hikaku
# Sceneモジュールをmixinして、このクラスはシーンクラスだとStoryクラスのインスタンスに認識させる
include Miyako::Story::Scene
def init # 初期化メソッド
# 移動量 の配列を生成する。
@vs = Array.new(200){ [rand(2)*2-1,rand(2)*2-1] }
# Miyako::Sprite の配列を生成する。 sprites のスプライトと一対一対応する。
@msprites = Array.new(@vs.size) do
# Miyako::Sprite オブジェクトを生成する。
# 位置をランダムに設定する
# roundメソッドは相対位置の移動メソッドだが、初期の位置は(0,0)なので問題は無い
spr = Miyako::Sprite.new(:filename => "ruby.png")
spr.round(rand(640), rand(480))
end
end
def setup # シーン開始時処理メソッド
# スプライトを表示させる(デフォルトでは非表示なので show メソッドを呼ぶ)
@msprites.each{|spr| spr.show }
end
def update # シーン更新メソッド
# Input.updateとScreen.updateはupdateメソッドの前後で呼ばれているので
# 明示的に呼び出す必要がない
# ウィンドウが閉じられるか ESC キーが押されていたら終了する。
# updateの戻り値をnilにすると、ストーリーが終了する
return nil if Miyako::Input.quit_or_escape?
# [[Array オブジェクト, Miyako::Sprite オブジェクト],
# [Array オブジェクト, Miyako::Sprite オブジェクト], ...]
# という配列を生成し、一つ一つに対して処理を行う。
@vs = @vs.zip(@msprites).map do |v, msprite|
# Miyako::Sprite オブジェクトの座標を更新する
# (更新された移動量がround_rev2メソッドの返却値となり、更新された@vs配列の新しい要素となる)。
msprite.round_rev2(*v)
end
return @now # @now(=現在実行しているシーンクラス名)を返すと、シーンの更新を繰り返す
# シーン移動を行うときは、移動先シーンクラス名を戻り値として指定する
end
def final # シーン終了時処理メソッド
# スプライトの表示をやめる(このサンプルでは必要無いが、習慣的に付けておく)
@msprites.each{|spr| spr.hide }
end
end
# シーンのObserver、Storyクラスのインスタンス(ストーリー)を作成
hikaku_sample = Miyako::Story.new
# シーンHikakuからストーリーの実行を開始する
hikaku_sample.run(Hikaku)
Version 0.9.1
require "mygame/boot"
require "sprite"
# Sprite オブジェクトの配列を生成する。
sprites = Array.new(200){ Sprite.new }
# 画像 TransparentImage オブジェクトを生成する。
# 今回左上点がたまたま透明色だったので、 Image オブジェクトでなく
# TransparentImage オブジェクトがそのまま使える。
image = TransparentImage.new("ruby.png")
# メインループ。引数は FPS を表す。
# ウィンドウが閉じられた場合は自動的に終了する。
# 画面は毎フレームリセットされる。
main_loop(30) do
# ESC キーが押された場合終了する。
exit if key_pressed?(Key::ESCAPE)
# Sprite オブジェクトそれぞれについて処理する。
sprites.each do |sprite|
# Sprite オブジェクトを更新する。
sprite.update
# 画像の座標を設定する。
image.x, image.y = sprite.x, sprite.y
# 画像を画面に対して描画する。
image.render
end
end
Version 2.0.1
require "sdl"
require "sprite"
# Sprite オブジェクトの配列を生成する。
sprites = Array.new(200){ Sprite.new }
# SDL の初期化処理を行う。
SDL.init(SDL::INIT_VIDEO)
# ウィンドウのキャプションを設定する。
SDL::WM.set_caption("Sprites", "")
# 画面を初期化する。
flags = SDL::SWSURFACE | SDL::SRCALPHA | SDL::DOUBLEBUF
screen = SDL.set_video_mode(640, 480, 32, flags)
# スプライト画像を生成する。
# display_format メソッドで、画像のフォーマットを画面のそれに合わせる。
image = SDL::Surface.load("ruby.png").display_format
# 1 フレームあたりにかかる秒数
interval = 1 / 30.0
# メインループ
loop do
# 現在の時間を取得し、秒単位に直す。
loop_start = SDL.get_ticks / 1000.0
# キューにたまっているイベントを処理する。
while event = SDL::Event2.poll
# event が SDL::Event2::Quit オブジェクトならば終了する。
# このイベントはウィンドウを閉じようとしたときに発生する。
exit if SDL::Event2::Quit === event
end
# 入力状態を更新する。
SDL::Key.scan
# ESC キーが押されていたら終了する。
exit if SDL::Key.press?(SDL::Key::ESCAPE)
# 画面を黒色に塗りつぶす。
screen.fill_rect(0, 0, 640, 480, [0, 0, 0])
# 各 Sprite オブジェクトに対して処理を行う。
sprites.each do |sprite|
# Sprite オブジェクトを更新する。
sprite.update
# 画面 (screen) にスプライト画像 (image) を描画する。
SDL.blit_surface(image, 0, 0, 0, 0, screen, sprite.x, sprite.y)
end
# 画面のバッファを交換する。
screen.flip
# 現在の時刻を取得し、秒単位に直す。
loop_end = SDL.get_ticks / 1000.0
# 1 フレームにかかる予定の時間 (1/30 秒) から、実際にかかった時間 (loop_end - loop_start) を差し引いた分だけスリープする。
# 予定の時間よりも時間がかかりすぎた場合は何もしない。
if 0 < (d = interval - (loop_end - loop_start))
sleep(d)
end
end
Version 0.3.0
require "starruby"
require "sprite"
# Sprite オブジェクトの配列を初期化する。
sprites = Array.new(200){ Sprite.new }
# スプライトに用いる画像を初期化する。
texture = StarRuby::Texture.load("ruby.png")
# メインループ。ウィンドウのキャプション、 FPS も指定する。
# ウィンドウが閉じられたら自動的に終了する。
StarRuby::Game.run(640, 480, :title => "Sprites", :fps => 30) do |game|
# ESC キーが押されていたら終了する。
break if StarRuby::Input.keys(:keyboard).include?(:escape)
# 画面を初期化する。
game.screen.clear
# 各 Sprite オブジェクトに対して処理を行う。
sprites.each do |sprite|
# Sprite オブジェクトを更新する。
sprite.update
# 画面 (game.screen) に対してスプライト画像 (texture) を描画する。
game.screen.render_texture(texture, sprite.x, sprite.y)
end
end
Version 1.0.0
require "dxruby"
require "sprite"
# Sprite オブジェクトの配列を生成する。
sprites = Array.new(200){ Sprite.new }
# Imageオブジェクトを作成
image = Image.load("ruby.png")
# ウィンドウのキャプションを設定する。
Window.caption = "Sprites"
# fpsを設定する。
Window.fps = 30
# メインループ。
# ウィンドウが閉じられた場合は自動的に終了する。
# 画面は毎フレームリセットされる。
Window.loop do
# ESC キーが押されたら終了する。
exit if Input.keyPush?(K_ESCAPE)
# Sprite オブジェクトそれぞれについて処理する。
sprites.each do |sprite|
# Sprite オブジェクトを更新する。
sprite.update
# 画面に対してスプライト画像(image)を描画する。
Window.draw(sprite.x, sprite.y, image)
end
end