■ブロックの回転・落下判定

落ち物ゲームでは、詰まれたブロックをかわして、ブロックの回転や移動を行う必要があるので、シューティングとは、ちがった移動ルーチンが必要です。
ここでは、その方法を説明します。

↑元ネタファイルはこちら

STEP1.基本的な考え方

操作するブロックと背景を配列定義。

左右の移動
実際にブロックを移動させ、背景との重なりがないことを確認。

回転の判定は少しだけ複雑で、
1)今のブロック配列を一時保管
2)実際にブロックを回転させる。このときステージ上のブロックと重なって置けない場合は
  一時保管してあるブロックの配列に戻します。
3)重なっていなければ、そのまま回転。


というわけで、ブロック移動先に重なりがあるかどうかを判定する部分は共通で必要になる為、
この部分は独立して作成することにします。



変数定義
Block[][][] 操作をするブロック
配列は前から
[ブロックの種類][垂直座標][水平座標]
Stage[][] ゲームステージの配列
配列は前から
[垂直座標][水平座標]
OK=1 こんな定義をしておくと後で見やすいコードになります。


STEP2.配列の重なり判定

変数の説明
hp,vp ブロックの移動先座標
hp:水平方向,vp:垂直方向
flag 移動先のステージにブロックがあるかどうかをチェックするフラグ
NUMBER ブロックの種類
StageWidth
StageHeight
ステージの縦横の配列数


移動先ブロックのチェックはこんな感じになります。

  public int BlockCheak(int hp,int vp){
    int flag=1;
    for(int i=0;i<3 && flag ==1;i++){
      for(int j=0;j<3 && flag ==1;j++){
        //ここでステージから飛び出ていないことを確認します。
        if(vp+i>=0 && vp+i<StageHeight && hp+j>=0 && hp+j<StageWidth){
        //移動先が空なことを確認します。
          if(Stage[vp+i][hp+j]>1&&Block[NUMBER][i][j]>1)flag=0;
        }
        if(Block[NUMBER][i][j]>1&&(hp+j<0||hp+j>StageWidth-1||vp+i>StageHeight-1))flag=0;
      }
    }
    return flag;
    //移動できれば1(=OK)出来なければ0を返します。
  }

右への移動はこんな感じになります。(左も同じ)
 
  public void right(){
    if(BlockCheak(HPoint+1,VPoint)==OK){
    HPoint++;
   }
  }


STEP3.回転部分

回転は少し面倒ですが、よく見ればそんなに難しいことはやっていませんので、プログラムを
よく見て理解してください。


変数の説明
HPoint,VPoint ブロックの座標
HPoint:水平方向,VPoint:垂直方向
temp[][] ブロックの配列を保管する配列
work[][] こちらの配列へ回転したブロックの配列を作成
StageWidth
StageHeight
ステージの縦横の配列数


  public void kaiten(){
   int work[][]= new int[3][3];
   int temp[][]= new int[3][3];
   //ブロックをtempに一時保管する
   for (int i=0;i<3;i++)
     for(int j=0;j<3;j++)
     temp[i][j]=Block[NUMBER][i][j];
   //ブロックを回転して作業領域に保管する
   for (int i=0;i<3;i++)
     for(int j=0;j<3;j++)
     work[j][3-i-1]=Block[NUMBER][i][j];
   //作業領域に保管した配列をブロック配列にコピーする
   for (int i=0;i<3;i++)
     for(int j=0;j<3;j++)
     Block[NUMBER][i][j]=work[i][j];
   if(BlockCheak(HPoint,VPoint)==OK){
   }
   //回転して置けない場合は、ブロック配列の内容を元に戻す。
   else {
     for (int i=0;i<3;i++)
      for(int j=0;j<3;j++)
        Block[NUMBER][i][j]=temp[i][j];
     }
  }

といった感じです。かなりはしょって書きましたが、プログラムソースと見比べてみるとわかってくると思います。

Copyright (C) 錬金術師Masa
更新:2005年07月02日
http://www.katch.ne.jp/~mh524-1997/