【プチコン4講座】振り向きとジャンプの仕組みを作ろう

プチコン4

きこりの与作 プチコン4

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

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

きこりゲームの土台を作っていこうの続きの記事になります。

現状、博士を動かしても向きが変わらないですよね。

あまりゲームっぽくないので今回は振り向きとジャンプも実装してみましょう。

この二つを実装すれば一気にゲームぽくなります!

それでは木こりゲーム作り第2回目、始めていきましょう。

  1. 向きを変更する方法
  2. ジャンプを実装してみよう
  3. 画面外に行けないように制御しよう
  4. 衝突判定の準備を使用

向きを変更する方法

前回の時にスプライト変数に「DIRECT」という名前の変数を定義したと思います。

基本的にはこれを使って向きを制御していきます。

左を押したら向きを変更させたいので、スプライトを反転する必要がありますね。

ハカセの顔グラは右向きしかなかったと思うので反転で対応ということになりました。

斧も反転させるのを忘れないでください。

向き変数はハカセのモノを使えば大丈夫です。

あと斧の回転もおかしかったのでついでに直します。

分岐でだいぶコードが変わったので、気を付けてみてください。


' 斧スプライト定義(非表示にしておく)
SPSET 100, 161, 0
SPVAR 100, "ROTATE", 0
' アトリビュートの基準点を変更
SPHOME 100, 8, 16


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

  ' 斧を振っていなかったら
  IF SPVAR(0,"SWING") == #FALSE THEN
    ' 左ボタン処理
    IF (B AND 1 << #B_LLEFT) != 0 THEN
      SPVAR 0, "X", SPVAR(0,"X")-1
      SPVAR 0, "DIRECT", #TRUE
    ENDIF

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

    ' 向き変更
    IF SPVAR(0, "DIRECT") == #TRUE THEN
      SPCHR 0,,,32,32,#A_REVH
      SPCHR 100,,,,,#A_REVH
      ' 向きに合わせて斧の位置を変える
      SPOFS 100, SPVAR(0,"X"), SPVAR(0,"Y")+24
    ELSE
      SPCHR 0,,,32,32,0
      SPCHR 100,,,,,0
      ' 向きに合わせて斧の位置を変える
      SPOFS 100, SPVAR(0,"X")-32, SPVAR(0,"Y")+24
    ENDIF

    ' 移動処理
    SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")

    ' Yボタン処理
    IF (B AND 1 << #B_LRIGHT) != 0 THEN
      ' 振った音を鳴らす
      BEEP 100

      ' ハカセのグラを変更
      IF SPVAR(0, "DIRECT") == #TRUE THEN
        SPCHR 0,1433,,32,32,#A_REVH
      ELSE
        SPCHR 0,1433,,32,32,0
      ENDIF

      ' 斧振りフラグON
      SPVAR 0,"SWING", #TRUE
    ENDIF
  ENDIF
END



' 斧振り関数
'───────────────────────────────
DEF D_SWING_AXE
  IF SPVAR(0,"SWING") == #TRUE THEN
    ' 斧を出現させる
    SPSHOW 100

    ' 向きによって振る方向を変更
    IF SPVAR(0, "DIRECT") == #TRUE THEN

      ' 斧を指定位置まで回転させる
      IF SPVAR(100, "ROTATE") > -90 THEN
        SPVAR 100, "ROTATE", SPVAR(100, "ROTATE")-5
        SPROT 100, SPVAR(100, "ROTATE")
      ELSE
        SPHIDE 100
        SPVAR 100, "ROTATE", 0
        SPROT 100, SPVAR(100, "ROTATE")
        SPVAR 0,"SWING", #FALSE
      ENDIF
    ELSE

      ' 斧を指定位置まで回転させる
      IF SPVAR(100, "ROTATE") < 90 THEN
        SPVAR 100, "ROTATE", SPVAR(100, "ROTATE")+5
        SPROT 100, SPVAR(100, "ROTATE")
      ELSE
        SPHIDE 100
        SPVAR 100, "ROTATE", 0
        SPROT 100, SPVAR(100, "ROTATE")
        SPVAR 0,"SWING", #FALSE
      ENDIF


    ENDIF

  ENDIF
END

コントローラー関数と斧振り関数を結構変更しました。

主に向きによる条件分岐が増えて冗長なコードになっているところは気が向いたら直してもらって大丈夫です。

ハカセの顔グラチェンジと反転、UV座標を指定しなければいけないのがちょっと面倒でしたが、
スマイルツールをみて座標を確認したらなんとかいけました。

グラフィック変更がない場合、UV座標も省略することが出来ます。

斧がそんな感じですね。

こんな感じになればOKです。

ジャンプを実装してみよう

超簡単なジャンプの実装は

ジャンプアクションの作り方:ハンズオン編

で仕組みを説明していますので、今回は省略して実装に踏み込みます。

' 地面と判定するための座標定数
CONST #GND = 160
' ジャンプ配列アクセス用変数
VAR JPPC = 0
' ジャンプ配列
DIM JUMP_PROCESS[] = [-14,-10,-8,-6,-4,-2,2,4,6,8,10,14] 

' スプライト定義
SPVAR 0, "Y", #GND
SPVAR 0, "JUMP" , #FALSE



  ' ジャンプ中か調べる
  IF SPVAR(0,"JUMP") != #TRUE THEN
    ' ジャンプ中じゃなければAボタン処理が効く
    IF (B AND 1 << #B_RRIGHT) != 0 THEN
      ' ジャンプフラグをONにする
      SPVAR 0,"JUMP", #TRUE
      ' 上昇中フラグに切り替える
      SPVAR 0,"UPDOWN", #TRUE
    ENDIF
  ELSE
    ' 現在座標にジャンプ配列の該当する値を取り出して足す
    SPVAR 0, "Y", SPVAR(0,"Y") + JUMP_PROCESS[JPPC]
    ' 次のジャンプ配列にアクセスするためにインクリメント
    INC JPPC
    ' もしアクセス変数と配列の長さが同じになったら
    IF JPPC == LEN(JUMP_PROCESS)-1 THEN 
      ' プレイヤーのY座標補正
      SPVAR 0, "Y", #GND
      ' ジャンプフラグを解除
      SPVAR 0,"JUMP", #FALSE
      ' 次のジャンプのためにアクセス変数を初期化しておく
      JPPC = 0
    ENDIF
  ENDIF

突貫工事ですが、ジャンプを実装しました。

ちょっとコードが必要最低限になっていますので、最後に完成版ソースコードを載せておきますので、
意味不明になったら記事の最後の方を見てください。

ちょっとジャンプが早すぎますね。

ジャンプ中は斧を振れないようにしています。

あえて振らせてもいいかもしれませんが、今はジャンプ中がTRUEだと斧を振る条件から外しています。

詳しくは最後のソースコードまとめでご覧ください。

画面外に行けないように制御しよう

最後に画面外に行けなくしましょう。

単純にはかせの座標を見て画面外に行きそうなら座標を補正するだけです。

移動処理のところに条件式を加えてみましょう。

    ' 移動処理
    IF SPVAR(0,"X") < -16 THEN
      SPVAR 0,"X", -16
    ELSEIF SPVAR(0,"X") > 400-16 THEN
      SPVAR 0,"X", 400-16
    ENDIF
    SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")

半分めり込むぐらいでいいでしょう。

原作もこんな感じでしたし合わせておきます。

右の時はハカセの座標が左上になっているのでちょっと補正が必要になるのを気を付けてください。

衝突判定の準備を使用

次回はジャンプの修正をしつつ衝突判定も行ってみます。

詳しく言うと、ワンパク君に当たったら死亡フラグを立たせて1ミスさせます。

最後にそれぞれのスプライトにSPCOLを設定しておきました。

今回の完成版ソースコードを載せておくので、途中で判らなくなった人は照らし合わせてみてください。

それでは。

ACLS

' 地面と判定するための座標定数
CONST #GND = 160
' ループ用変数
VAR G_I = 0
' ジャンプ配列アクセス用変数
VAR JPPC = 0
' ジャンプ配列
DIM JUMP_PROCESS[] = [-14,-10,-8,-6,-4,-2,2,4,6,8,10,14] 

' スプライト定義
SPSET 0, 1432
SPCOL 0
SPVAR 0, "X", 35
SPVAR 0, "Y", #GND
SPVAR 0, "DIRECT" , #FALSE
SPVAR 0, "SWING" , #FALSE
SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")
SPVAR 0, "JUMP" , #FALSE

' 斧スプライト定義(非表示にしておく)
SPSET 100, 161, 0
SPCOL 100
SPVAR 100, "ROTATE", 0
' アトリビュートの基準点を変更
SPHOME 100, 8, 16



' その他スプライト定義
SPSET 1, 1436
SPSET 2, 1438
SPSET 3, 1442

SPOFS 1, 200,160
SPOFS 2, 100,200
SPOFS 3, 300,50

SPCOL 1
SPCOL 2
SPCOL 3



' 青空ぽい背景描写
FOR G_I=0 TO 240
  GLINE 0,I,400,I,RGB(I/2, 125+ROUND(I/2), 255)
NEXT

' 地面を描写
FOR G_I = 0 TO 24
  TPUT 0, G_I, 14, &HECC2
  TPUT 0, G_I, 14, &HED02
  TPUT 0, G_I, 14, &HED02
NEXT

LOOP
  D_CONTROLLER
ENDLOOP


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

  ' 斧を振っていなかったら
  IF SPVAR(0,"SWING") == #FALSE THEN
    ' 左ボタン処理
    IF (B AND 1 << #B_LLEFT) != 0 THEN
      SPVAR 0, "X", SPVAR(0,"X")-1
      SPVAR 0, "DIRECT", #TRUE
    ENDIF

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

    ' 向き変更
    IF SPVAR(0, "DIRECT") == #TRUE THEN
      SPCHR 0,,,32,32,#A_REVH
      SPCHR 100,,,,,#A_REVH
      ' 向きに合わせて斧の位置を変える
      SPOFS 100, SPVAR(0,"X"), SPVAR(0,"Y")+24
    ELSE
      SPCHR 0,,,32,32,0
      SPCHR 100,,,,,0
      ' 向きに合わせて斧の位置を変える
      SPOFS 100, SPVAR(0,"X")-32, SPVAR(0,"Y")+24
    ENDIF

    ' 移動処理
    IF SPVAR(0,"X") < -16 THEN
      SPVAR 0,"X", -16
    ELSEIF SPVAR(0,"X") > 400-16 THEN
      SPVAR 0,"X", 400-16
    ENDIF
    SPOFS 0, SPVAR(0,"X"), SPVAR(0,"Y")

    ' Yボタン処理
    IF (B AND 1 << #B_LRIGHT) != 0 THEN
      ' 振った音を鳴らす
      BEEP 100

      ' ハカセのグラを変更
      IF SPVAR(0, "DIRECT") == #TRUE && SPVAR(0,"JUMP") != #TRUE THEN
        SPCHR 0,1433,,32,32,#A_REVH
      ELSE
        SPCHR 0,1433,,32,32,0
      ENDIF

      ' 斧振りフラグON
      SPVAR 0,"SWING", #TRUE
    ENDIF


    ' ジャンプ中か調べる
    IF SPVAR(0,"JUMP") != #TRUE THEN
      ' ジャンプ中じゃなければAボタン処理が効く
      IF (B AND 1 << #B_RRIGHT) != 0 THEN
        ' ジャンプフラグをONにする
        SPVAR 0,"JUMP", #TRUE
        ' 上昇中フラグに切り替える
        SPVAR 0,"UPDOWN", #TRUE
      ENDIF
    ELSE
      ' 現在座標にジャンプ配列の該当する値を取り出して足す
      SPVAR 0, "Y", SPVAR(0,"Y") + JUMP_PROCESS[JPPC]
      ' 次のジャンプ配列にアクセスするためにインクリメント
      INC JPPC
      ' もしアクセス変数と配列の長さが同じになったら
      IF JPPC == LEN(JUMP_PROCESS)-1 THEN 
        ' プレイヤーのY座標補正
        SPVAR 0, "Y", #GND
        ' ジャンプフラグを解除
        SPVAR 0,"JUMP", #FALSE
        ' 次のジャンプのためにアクセス変数を初期化しておく
        JPPC = 0
      ENDIF
    ENDIF


  ENDIF
END



' 斧振り関数
'───────────────────────────────
DEF D_SWING_AXE
  IF SPVAR(0,"SWING") == #TRUE THEN
    ' 斧を出現させる
    SPSHOW 100

    ' 向きによって振る方向を変更
    IF SPVAR(0, "DIRECT") == #TRUE THEN

      ' 斧を指定位置まで回転させる
      IF SPVAR(100, "ROTATE") > -90 THEN
        SPVAR 100, "ROTATE", SPVAR(100, "ROTATE")-5
        SPROT 100, SPVAR(100, "ROTATE")
      ELSE
        SPHIDE 100
        SPVAR 100, "ROTATE", 0
        SPROT 100, SPVAR(100, "ROTATE")
        SPVAR 0,"SWING", #FALSE
      ENDIF
    ELSE

      ' 斧を指定位置まで回転させる
      IF SPVAR(100, "ROTATE") < 90 THEN
        SPVAR 100, "ROTATE", SPVAR(100, "ROTATE")+5
        SPROT 100, SPVAR(100, "ROTATE")
      ELSE
        SPHIDE 100
        SPVAR 100, "ROTATE", 0
        SPROT 100, SPVAR(100, "ROTATE")
        SPVAR 0,"SWING", #FALSE
      ENDIF


    ENDIF

  ENDIF
END