1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Opal (Ruby-to-JavaScript compiler)Advent Calendar 2018

Day 8

DXOpalでUndertaleっぽい画面を作る(続)

Last updated at Posted at 2018-12-11

6日目 (DXOpalでUndertaleっぽい画面を作る) の続きです。今回は画像を表示してみましょう。

画像

今回使う画像はこちら。

computer_typing_hayai.png

皆さんご存じの「いらすとや」さんから、"タイピングが速い人のイラスト"をお借りしました。ゲームに使ったという話はあまり聞かないですが、商用かつ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])
# ...

実行結果です。

スクリーンショット 2018-12-10 0.25.13.png

なんともいえない感じになりました。

動かしてみる

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の範囲で変化することになります。

実行結果です。

output.gif

0.01や50の部分を適当にいじると、ゆっくりになったり爆速になったりします。いろいろ試してみてください。

まとめ

今回は画像の扱い方とSpriteクラスについて紹介しました。実際に動いているところは以下で見られます。

次回があれば自機を出してよりゲームっぽくしたいです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?