6日目 (DXOpalでUndertaleっぽい画面を作る) の続きです。今回は画像を表示してみましょう。
画像
今回使う画像はこちら。
皆さんご存じの「いらすとや」さんから、"タイピングが速い人のイラスト"をお借りしました。ゲームに使ったという話はあまり聞かないですが、商用かつ21種類以上の画像の使用は有償になるので注意しましょう。
画像を読み込む
DXOpalではImage.register
で使いたい画像を宣言し、Window.load_resources
で読み込みます。描画はWindow.draw
です。
require 'dxopal'
include DXOpal
# 使いたい画像を宣言する
Image.register(:enemy, "images/computer_typing_hayai.png")
# ...
# 画像の読み込みが終わったら、ブロック内が実行される
Window.load_resources do
Window.bgcolor = C_BLACK
Window.loop do
w = 80; h = 100
2.times do |row|
6.times do |col|
x = 80 + col*w
y = 20 + row*h
Window.draw_box(x, y, x+w, y+h, C_GREEN)
end
end
# 画像を表示する
Window.draw(250, 10, Image[:enemy])
# ...
実行結果です。
なんともいえない感じになりました。
動かしてみる
Undertaleの敵キャラはふわふわ浮いてたような気がするので(キャラにもよりますけど)、"タイピングが速い人"も動かしてみましょう。
動かすにはx・y座標を変数にして値を変化させればいいのですけど、下準備として、敵キャラを表すクラスを作ります。基本、動くものはぜんぶクラスにしたほうがいいです。そうしないとx・y座標を表す変数がたくさんできてわけがわからなくなりますからね。
クラスを作る
DXOpalでキャラクタを表すクラスを作るときは、Spriteクラスを親クラスにすると便利です。Spriteクラスの使い方はDXRubyのサイトに説明があります。
今回は敵キャラなのでEnemyというクラス名にしてみます。まずは、前のコードと同じ表示を行うところまでやりましょう。変化した部分にはコメントを入れてあります。
# ...
# 敵キャラのクラスを定義
class Enemy < Sprite
def initialize
x = 250
y = 10
# 親クラスの初期化処理を呼ぶ。x座標、y座標、画像の3つが必要
super(x, y, Image[:enemy])
end
end
Window.load_resources do
Window.bgcolor = C_BLACK
# Enemyクラスのオブジェクトを作る
enemy = Enemy.new
Window.loop do
w = 80; h = 100
2.times do |row|
6.times do |col|
x = 80 + col*w
y = 20 + row*h
Window.draw_box(x, y, x+w, y+h, C_GREEN)
end
end
# 敵を描画する
# (座標はenemy自身が知っているので渡さなくてよい!)
enemy.draw
# ...
敵を描画する部分のコードが、
Window.draw(250, 10, Image[:enemy])
から
enemy.draw
に変わりました。座標や画像はenemyが持っているので、メインループ内ではそれらのことをキにしなくて良くなり、すっきりしましたね。
座標を変化させる
あとは、enemyのxやyを変化させれば敵キャラを動かすことができます。そのためのメソッドを作りましょう。
DXOpalでは、キャラを動かすメソッドはupdate
という名前にしておくと、のちのちキャラが増えたときにSprite.update
でまとめて扱えたりして便利です。
ということで、Enemyクラスにupdate
メソッドを定義します。とりあえず単純にx座標を増やしてみましょう。Spriteのサブクラスでは、self.x
でx座標にアクセスできるので、updateが呼ばれるたびに1ずつ増やします。
class Enemy < Sprite
# ...
# 敵キャラを動かす処理
def update
self.x += 1
end
end
# ...
# 敵キャラを動かす処理を呼ぶ
enemy.update
enemy.draw
こうなりました。
いい感じに動かす
動いたのはいいけど、x座標を増やしすぎて画面外まで出ていってしまいました。これだと何もせずに勝利した感じになるので、いい感じに行ったり来たりしてほしいですね。
いろんなやり方がありますが、今回はMath.cos
を使う方法を紹介します。コードはこちら。
class Enemy < Sprite
def initialize
x = 250
y = 10
super(x, y, Image[:enemy])
# Math.cos用の変数を初期化
@phase = 0
end
def update
@phase += 0.01
self.x = 250 + Math.cos(@phase) * 50
end
end
まず適当なインスタンス変数@phase
を用意して、0に初期化します。これをちょっとずつ増やす(+= 0.01
)と、Math.cos(@phase)
が-1〜+1の範囲でなめらかに変化してくれます。なので、それを50倍して250に足すと、self.x
は200〜300の範囲で変化することになります。
実行結果です。
0.01や50の部分を適当にいじると、ゆっくりになったり爆速になったりします。いろいろ試してみてください。
まとめ
今回は画像の扱い方とSpriteクラスについて紹介しました。実際に動いているところは以下で見られます。
次回があれば自機を出してよりゲームっぽくしたいです。