[Androidアプリ開発]衝突判定

Android

Androidアプリ開発の6回目です。
前回はキャラの落下を実装したので、今回は横方向の衝突を追加します。

  • 使用言語 java
  • 開発ツール AndroidStudio
変更点

  • MainCharクラスのgetCharPointメソッドに横方向の衝突判定処理を追加
  • ついでにキャラのジャンプ用の処理を追加

import android.graphics.Color;
import android.graphics.Paint;

public class MainChar {

    private float x;            //キャラ横位置
    private float y;            //キャラ縦位置
    private float sizeX;        //キャラ横サイズ
    private float sizeY;        //キャラ縦サイズ
    private Paint paint;        //キャラの色

    private int fallVel = 1;      //落下速度
    Map map;

    //コンストラクタ
    public MainChar(Map map){
        x = map.getViewX() / 2;     //キャラ初期位置設定
        y = map.getViewY() / 2;     //キャラ初期位置設定
        sizeX = map.getDotX() ;      //キャラ初期サイズ設定
        sizeY = map.getDotY() * 2;      //キャラ初期サイズ設定
        paint = new Paint();
        paint.setColor(Color.RED);  //キャラの色設定
        this.map = map;
    }


    //キャラの位置を更新して衝突判定後に現在位置を戻す
    float[] getCharPoint(int xx){
        //現在位置からmap配列の要素番号の割り出し
        int indexX = (int)(x / map.getDotX());
        int indexY = (int)((y + sizeY) / map.getDotY());
        if(map.getMap()[indexY][indexX + xx] == 0 ){
            fallVel++;
            y = y + fallVel;
        }else if(fallVel != 0){
            fallVel = 0;
            y = (indexY - 2) * map.getDotY();  //描画位置調整用の-2
        }
        if(map.getXxPlus() == 1 && map.getMap()[indexX + map.getXx()][indexY] != 0){
            map.setXxPlus(0);
        }else if(map.getXxPlus() == -1 && map.getMap()[indexX - 1 + map.getXx()][indexY] != 0){
            map.setXxPlus(0);
        }
        float[] point = {x,y};

        return point;
    }

    void charJump(){
        y += -400;
    }
    //以下getter setter
    public float getX() {
        return x;
    }

    public void setX(float x) {
        this.x = x;
    }

    public float getY() {
        return y;
    }

    public void setY(float y) {
        this.y = y;
    }

    public float getSizeX() {
        return sizeX;
    }

    public void setSizeX(float sizeX) {
        this.sizeX = sizeX;
    }

    public float getSizeY() {
        return sizeY;
    }

    public void setSizeY(float sizeY) {
        this.sizeY = sizeY;
    }

    public Paint getPaint() {
        return paint;
    }

    public void setPaint(Paint paint) {
        this.paint = paint;
    }
}

これでキャラが移動する方向に障害物がある場合は停止するようになりました。
あとはジャンプイベントを実装するためにMapとStageにも処理を加えます。


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Stage extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    Map map;    //Mapクラスの参照保持変数
    SurfaceHolder holder;  //ディスプレイ編集・監視用インターフェース

    //画面変更時の処理
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}

    //画面破棄時の処理
    @Override
    public void surfaceDestroyed(SurfaceHolder holder){}

    //画面作成時の処理
    @Override
    public void surfaceCreated(SurfaceHolder holder){
        //Mapクラスのインスタンス生成 
        //画面幅,画面高さを取得 コンストラクタの処理の後なら取得可能
        map = new Map(super.getWidth(), super.getHeight(),this);
        Thread thread = new Thread(this);
        thread.start();
    }

    //画面にタッチすると動くメソッド
    @Override
    public boolean onTouchEvent(MotionEvent event){
        float touchX = event.getX(); //タッチ位置取得

        //画面に指を置いたタイミングで条件分岐処理
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN :
                //タッチ位置が画面の右側ならxxをインクリメント
                if(touchX > super.getWidth() / 2 + 300){
                    map.xxPlus = 1;
                }else if(touchX < super.getWidth() / 2 - 300){ //それ以外はデクリメント
                    map.xxPlus = -1;
                }else{
                    map.callJump();
                }
                break;
            case MotionEvent.ACTION_UP :
                map.xxPlus = 0;
                break;
        }
        return true;
    }

    //コンストラクタ
    public Stage(Context context){
        super(context);
        //この処理でsurfaceCreatedメソッドが動きます
        holder = super.getHolder();
        holder.addCallback(this);
    }

    @Override
    public void run(){
        map.draw();
    }

}

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

public class Map {

    private final int ROWCOUNT = 20; //縦表示ドット数
    private final int COLUMNCOUNT = 10; //横表示ドット数
    private float viewX;        //画面の横サイズ
    private float viewY;        //画面の縦サイズ
    private float dotX;  //1ドットの横幅
    private float dotY;  //1ドットの縦幅
    private Stage stage; //描画用にstageクラスの参照保持
    private Paint paint; //色保持用
    private MainChar mainChar;  //キャラ描画用データ参照用

    int xx;             //横位置保持用
    int xxPlus;         //変数xx加算用

    //表示マップの2次元配列
    private int[][] map = {
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
            {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    };

    //コンストラクタ
    //画面サイズを引数で受け取り、ドットサイズを設定
    public Map(float viewX, float viewY,Stage stage){
        this.stage = stage;
        this.viewX = viewX;
        this.viewY = viewY;
        dotX = viewX / COLUMNCOUNT;
        dotY = viewY / ROWCOUNT;
        paint = new Paint();
        paint.setColor(Color.GREEN);
        //MainCharクラスのインスタンス生成(初期設定値)
        mainChar = new MainChar(this);
    }

    public void draw(){
        while(true) {
            float[] charPoint = mainChar.getCharPoint(xx);    //キャラの位置取得

            if(xx + xxPlus <= map[0].length - COLUMNCOUNT && xx + xxPlus >= 0) { //加算後の値がマップの範囲を超えなければ
                xx += xxPlus;  //横移動
            }
            Canvas canvas = stage.holder.lockCanvas(); //画面をロックして
            canvas.drawColor(Color.WHITE); //画面をクリア
            //描画ドット数分繰り返す
            for (int y = 0; y < ROWCOUNT; y++) {
                for (int x = 0; x < COLUMNCOUNT; x++) {
                    switch (map[y][x + xx]) {  //xxが描画開始インデックスを調整
                        case 1:     //配列の値が1の場合は
                            float drawX = x * dotX;  //描画開始位置のX座標を設定
                            float drawY = y * dotY;  //描画開始位置の座標を設定
                            canvas.drawRect(drawX, drawY, drawX + dotX, drawY + dotY, paint);
                            break;
                    }
                }
            }
            canvas.drawRect(charPoint[0],charPoint[1],charPoint[0] + mainChar.getSizeX(), charPoint[1] + mainChar.getSizeY(), mainChar.getPaint()); //キャラ描画
            stage.holder.unlockCanvasAndPost(canvas); //画面に変更反映
        }

    }

    void callJump(){
        mainChar.charJump();
    }

    //以下はゲッター

    public int getROWCOUNT() {
        return ROWCOUNT;
    }

    public int getCOLUMNCOUNT() {
        return COLUMNCOUNT;
    }

    public float getViewX() {
        return viewX;
    }

    public void setViewX(float viewX) {
        this.viewX = viewX;
    }

    public float getViewY() {
        return viewY;
    }

    public void setViewY(float viewY) {
        this.viewY = viewY;
    }

    public float getDotX() {
        return dotX;
    }

    public void setDotX(float dotX) {
        this.dotX = dotX;
    }

    public float getDotY() {
        return dotY;
    }

    public void setDotY(float dotY) {
        this.dotY = dotY;
    }

    public Stage getStage() {
        return stage;
    }

    public void setStage(Stage stage) {
        this.stage = stage;
    }

    public Paint getPaint() {
        return paint;
    }

    public void setPaint(Paint paint) {
        this.paint = paint;
    }

    public MainChar getMainChar() {
        return mainChar;
    }

    public void setMainChar(MainChar mainChar) {
        this.mainChar = mainChar;
    }

    public int getXx() {
        return xx;
    }

    public void setXx(int xx) {
        this.xx = xx;
    }

    public int getXxPlus() {
        return xxPlus;
    }

    public void setXxPlus(int xxPlus) {
        this.xxPlus = xxPlus;
    }

    public int[][] getMap() {
        return map;
    }

    public void setMap(int[][] map) {
        this.map = map;
    }
}

今回はこのくらいで。
今後はデザインの改良とゲームシステムの方向性を定めます。

コメント

タイトルとURLをコピーしました