【プチコン4講座】キャラを中心に置いて背景をスクロールする方法

プチコン4

プチコン4 背景スクロール

こんにちは。なおキーヌです。

ブログ毎日更新は269日目になります。

多重スクロールに入る前に、キャラクターとスクロールの関係を学んでおきましょう。

スクロールを使いこなせることによって、作られるゲームのバリエーションはかなり増えます。

シューティングゲームの場合は1画面から自動スクロールで進んでいくタイプのゲームに仕上げられますし、
RPGや横スクロールアクションゲームにおいてはスクロールは必須ですよね。

Unityなんかは元々3Dのゲームを作るツールなので2Dゲームを作っても
カメラという概念があるのでそれを操作するだけなのですが、普通のよくある2Dゲームは画面は固定されたままですね。

なので背景やキャラクターを動かしてスクロールしてるように見せなければいけません。

今回は横スクロールアクションゲームによくあるタイプのスクロールを学んでみます。

  1. キャラクターが中央に居るままスクロールさせる方法
  2. 画面端に行ったらキャラクターだけを動かす方法
  3. まずはキャラクターを表示して動かせるようにしよう
  4. マップエディタなしで簡単な横長の背景を作ってみよう

キャラクターが中央に居るままスクロールさせる方法

スクロールがあるタイプのゲームは、基本的にプレイヤーを中心に動きます。

プレイヤーキャラが常に画面中央にきているか、
右に進むタイプのアクションゲームの場合、先を見やすくするために中央から少し左に位置することが多いです。

今回はプレイヤーキャラクターを中央に固定する方法を学んでみましょう。

デフォルトの解像度は400×240なので、16×16のスプライトを横軸中央に設置する場合
200-8でX座標192になりますね。(8は16の半分ズラして中央におくためです。)

画面中央に固定したいため、何が動こうがプレイヤーのX座標は192固定ということになります。

Y座標はジャンプなど上下したり地面によって変動するので基本固定はしません。

これでプレイヤーの横軸を固定しながらスクロールする準備はできました。

シューティングゲームの場合は背景が動きつつ、自機も動かせるので中央に固定する必要はありません。

画面端に行ったらキャラクターだけを動かす方法

プレイヤーキャラのX座標を固定したので、あとは背景を動かすだけです。

しかしX座標を固定してしまってはスクロールが止まってしまったら端っこのゴールにたどり着けませんね。

なのでスクロールが終了(画面の橋が見えたら)プレイヤーキャラクターのX座標固定を外してしまえばOKです。

具体的なやり方は、テキストスクリーンの座標を監視しておくことです。

TOFSで座標をズラして端っこが見えたらその時のテキストスクリーンの座標が一定の数値になるので
その数値を元にIFで条件分岐を作って端っこまで行ったらスクロールを止めてプレイヤーのX座標固定を解除する。

といった感じで作れば、基本は画面中央で端っこに行ったらプレイヤーだけが動かすことができます。

まずはキャラクターを表示して動かせるようにしよう

予備知識はここまでです。

実際にキャラクターを設置して操作できるようにしてスクロールを実装してみましょう。

すでに過去のミニゲーム講座をやってきた人なら楽勝ですね!

一応ここから講座を始める方のためにプレイヤー操作ができるようにコードを載せておきます。

もし、コードがよくわからん!

ってなった人はそっくりそのままコードを書き写してください。


' プレイヤーの定義
SPSET 0, 876
SPVAR 0, "X", 200-8
SPVAR 0, "Y", 240-32
' アニメーションループ設定
SPANIM 0, "I", 20,876, 20,877, 20,878, 20,879, 0 

' ループ開始
LOOP
  D_CONTROLLER
ENDLOOP


' コントローラー関数
'───────────────────────────────
DEF D_CONTROLLER
  ' 0番目のコントローラー(つまり1コン)の押されているボタンを取得
  VAR B = BUTTON(0)

  ' 左ボタン処理
  IF (B AND 1 << #B_LLEFT) != 0 THEN
    SPVAR 0, "X", SPVAR(0,"X")-1
  ENDIF

  ' 右ボタン処理
  IF (B AND 1 << #B_LRIGHT) != 0 THEN
    SPVAR 0, "X", SPVAR(0,"X")+1
  ENDIF

  ' プレイヤーを移動
  SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")
END

これで犬が画面下の方の中央に来ているはずです。

プチコン4 テキストスクリーン1

とりあえず上下は固定で左右だけ動けるようにしました。

アニメーションループ設定に関しては今回は説明割愛します。

止まっているのも寂しいし不自然と思いとりあえずこうしておけば、
犬が足踏みしてくれるので左右に動かすと歩いているように見えます。

マップエディタなしで簡単な横長の背景を作ってみよう

スクロールするにはマップが必要になりますね。

多重スクロールのマップを作るのは難しい(私がまだ作られていない)ので、
とりあえず普通のアクションゲームっぽいマップを作ってみましょう。

マップエディタを使うと楽なのですが、単純なマップなのでエディタ無しで作ってみましょう。

配列を全部手打ちしてもいいのですが、すさまじく面倒くさいのでループでマップデータを作ります。

VAR G_I = 0 , G_J = 0

' 空のマップデータ配列用意
DIM MAPADTA[]

FOR G_J = 0 TO 14
  FOR G_I = 0 TO 63
    IF G_J != 14 THEN
      PUSH MAPDATA, 0
    ELSE
      PUSH MAPDATA, 1
    ENDIF
  NEXT
NEXT

0~63までカウントしたら次の行に行くという感じで2次元のマップデータを作ります。

そしてこのマップを描写するためにもう一度ループするのですが、
そのまま描写しちゃうとエラーが起ってしまいます。

というのも、デフォルトで画面サイズ分しかテキストスクリーンは描写出来ないようになっています。

なのでTSCREENを使って描写する幅を広げてあげる必要があります。

マップ描写の前に以下のコードを挿入してください。

TSCREEN 3,16,16,64,15

これの意味は テキストスクリーン3番に対して

  • フォントの種類を16
  • 文字サイズを16
  • 横幅を64
  • 縦幅を15

にしています。

フォントの種類というのが正直な所いまいちよく分かってないのですが、
16にしておかないと描写すごいことになってしまいます。

恐らくマップチップ16なので16にしておかない取得するための計算がおかしくなるっぽいです。

もうちょっと勉強しなきゃいけませんね。

正直初心者の方がヘルプを見てもわかり辛いかなと思っています。

プログラミングある程度できる私でもよくわからない表記があったりします。

しかし使い方さえ分かっておけば理解してなくても使えるので安心してください。

それではマップを描写してみましょう。

ACLS

' テキストスクリーンのサイズを64x15に設定(解像度的には1024x240)
TSCREEN 3,16,16,64,15

' ループ用変数
VAR G_I = 0 , G_J = 0

' 空のマップデータ配列用意
DIM MAPADTA[]

' プレイヤーの定義
SPSET 0, 876
SPVAR 0, "X", 200-8
SPVAR 0, "Y", 240-32
' アニメーションループ設定
SPANIM 0, "I", 20,876, 20,877, 20,878, 20,879, 0 

' テキストスクリーン3の変数設定
TVAR 3, "X", 0
TVAR 3, "Y", 0

' マップ配列生成
FOR G_J = 0 TO 14
  FOR G_I = 0 TO 63
    IF G_J != 14 THEN
      PUSH MAPDATA, 0
    ELSE
      PUSH MAPDATA, 1
    ENDIF
  NEXT
NEXT

' マップ配列で描写
FOR G_J = 0 TO 14
  FOR G_I = 0 TO 63
    CASE MAPDATA[G_I + (G_J+64)]
      WHEN 0
        ' 配列の数字が0の場合空を表示
        TPUT 3, G_I, G_J, &HEC9F
      WHEN 1
        ' 配列の数字が1の場合地面を表示
        TPUT 3, G_I, G_J, &HECC2
    ENDCASE
  NEXT
NEXT


' ループ開始
LOOP
  D_CONTROLLER
ENDLOOP



' コントローラー関数
'───────────────────────────────
DEF D_CONTROLLER
  ' 0番目のコントローラー(つまり1コン)の押されているボタンを取得
  VAR B = BUTTON(0)

  ' 左ボタン処理
  IF (B AND 1 << #B_LLEFT) != 0 THEN
    ' SPVAR 0, "X", SPVAR(0,"X")-1
    TPVAR 3, "X", TVAR(3,"X")-1
  ENDIF

  ' 右ボタン処理
  IF (B AND 1 << #B_LRIGHT) != 0 THEN
    ' SPVAR 0, "X", SPVAR(0,"X")+1
    TPVAR 3, "X", TVAR(3,"X")+1
  ENDIF
END

  ' プレイヤーを移動
  SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")
  ' マップを移動
  TOFS 0, TVAR(3,"X"), TVAR(3,"Y")

移動関数にテキストスクリーンの移動も付け加えているのに気を付けてください。

プレイヤーはその場固定にしたいので座標加減算を一旦コメントアウトしています。

これで実際に動かしてみましょう。

プチコン4 テキストスクリーン2

……どうでしょうか?

視覚的にはボタンの方向と逆に動いていると思います。

なのでTOFSは押したボタンと逆の方向に動かさないと背景スクロールが逆になってしまうんです。

SCROLL命令の時は最初から逆になっていましたが、TOFSは座標に移動するという命令なのでSPOFSと同じ挙動になります。

しかも空の区切り目が出ていて不自然ですね。

これは後日直します。

今回はここまでにしておきましょう。

スクロールの概念についてだいぶ理解してきたと思います。

残るは多重スクロールなのですが、それぞれのスクリーンに速度を設定して、
それをTOFSで加算してやればそれらしくみえます。

ですが、マップを用意するのがすごく大変なので少し時間をください。

なので多重スクロールに関しては少し記事の更新が遅れてしまうことをお許しください。

それでは。