vol.2_3 ぷよが動くようにする

はじめに

今回はぷよが動けるようにします。前回作ったkbhit関数が役に立ちます。
まずは自由落下や高速落下ではなく、ぷよの座標に応じて適切にぷよが移動するようにします。

ぷよの座標の操作

試作としてa,d,sキーを押すことでぷよが左右・下に動くように実装します。
ぷよが移動する際にもとあった場所の色は黒(CELL_TYPE_EMPTY)で塗るようにします。
そうすれば毎回フィールド全体を更新する必要はありません。
___puyo.c____

#include "game.h"

int main(void)
{
    system("clear"); //画面のクリア
    
    //フィールドの描画
    for(int y = 1; y <= FIELD_HEIGHT; y++){
        for(int x = 1; x <= FIELD_WIDTH; x++){
            if((y != 1) && (x == 1 || x == FIELD_WIDTH || y == FIELD_HEIGHT))
                putColor(y, x, CELL_TYPE_WALL); //壁・床の描画
        }
        printf("\n");
    }
    
    //組みぷよの生成
    twinPuyoes_t tsumo = {
        INIT_ROLL_PUYO_X, INIT_ROLL_PUYO_Y,
        INIT_AXIS_PUYO_X, INIT_AXIS_PUYO_Y,
        CELL_TYPE_GREEN,
        CELL_TYPE_RED
    };
    
    //初期位置に設置
    putColor(tsumo.ry, tsumo.rx, tsumo.rollPuyoColor);
    putColor(tsumo.ay, tsumo.ax, tsumo.axisPuyoColor);
    
    //ゲーム部分
    while(1){
        if(kbhit()){
            //キーが入力されたかどうかのフラグ
            int keyFlag = FALSE_BOOL;
            //位置を変更するとき、もとの位置のぷよはクリアしたい
            //もとのぷよの情報をここに保持しておく
            twinPuyoes_t old;
            
            switch(getchar()){
                case 'a':
                    old = tsumo;
                    old.rollPuyoColor = CELL_TYPE_EMPTY;
                    old.axisPuyoColor = CELL_TYPE_EMPTY;
                    
                    tsumo.rx -= 2;
                    tsumo.ax -= 2;
                    keyFlag = TRUE_BOOL;
                    break;
                
                case 'd':
                    old = tsumo;
                    old.rollPuyoColor = CELL_TYPE_EMPTY;
                    old.axisPuyoColor = CELL_TYPE_EMPTY;
                    
                    tsumo.rx += 2;
                    tsumo.ax += 2;
                    keyFlag = TRUE_BOOL;
                    break;
                
                case 's':
                    old = tsumo;
                    old.rollPuyoColor = CELL_TYPE_EMPTY;
                    old.axisPuyoColor = CELL_TYPE_EMPTY;
                    
                    tsumo.ry++;
                    tsumo.ay++;
                    keyFlag = TRUE_BOOL;
                    break;
                    
                default: break;
            }
            
            if(keyFlag == TRUE_BOOL){
                //oldの消去
                putColor(old.ry, old.rx, old.rollPuyoColor);
                putColor(old.ay, old.ax, old.axisPuyoColor);
                //ぷよの描画
                putColor(tsumo.ry, tsumo.rx, tsumo.rollPuyoColor);
                putColor(tsumo.ay, tsumo.ax, tsumo.axisPuyoColor);
            }
        }
    }
    
    return 0;
}

※実行結果は最後にまとめて表示します

壁・床判定

今のままだとぷよはどこまでも突き進みます。これでは困ってしまうので当たり判定をつけます。
判定自体は簡単で、組みぷよのうちどちらかのぷよの座標が移動先で壁・床にめり込んでしまうなら、座標の変更はしないようにすればOKです。
左側の壁の判定をするために、

#define FIELD_START_X 1

としておきます。
____game.h____

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

#define TRUE_BOOL 1
#define FALSE_BOOL 0
#define FIELD_HEIGHT 14
#define FIELD_WIDTH 15
#define FIELD_START_X 1

#define INIT_ROLL_PUYO_X 7
#define INIT_ROLL_PUYO_Y 2
#define INIT_AXIS_PUYO_X 7
#define INIT_AXIS_PUYO_Y 3

#define CELL_TYPE_EMPTY 0
#define CELL_TYPE_WALL 1
#define CELL_TYPE_RED 2
#define CELL_TYPE_BLUE 3
#define CELL_TYPE_GREEN 4
#define CELL_TYPE_YELLOW 5
#define CELL_TYPE_PURPLE 6
#define CELL_TYPE_OJAMA 7

typedef struct {
    int rx, ry; //軸でないぷよ(生成時は上側のぷよ)の座標
    int ax, ay; //軸となるぷよ(生成時は下側のぷよ)の座標
    int rollPuyoColor; //軸でないぷよの色情報
    int axisPuyoColor; //軸となるぷよの色情報
} twinPuyoes_t;

int kbhit(void);
void putColor(int, int, int);

____puyo.c____

#include "game.h"

int main(void)
{
    system("clear"); //画面のクリア
    
    //フィールドの描画
    for(int y = 1; y <= FIELD_HEIGHT; y++){
        for(int x = 1; x <= FIELD_WIDTH; x++){
            if((y != 1) && (x == 1 || x == FIELD_WIDTH || y == FIELD_HEIGHT))
                putColor(y, x, CELL_TYPE_WALL); //壁・床の描画
        }
        printf("\n");
    }
    
    //組みぷよの生成
    twinPuyoes_t tsumo = {
        INIT_ROLL_PUYO_X, INIT_ROLL_PUYO_Y,
        INIT_AXIS_PUYO_X, INIT_AXIS_PUYO_Y,
        CELL_TYPE_GREEN,
        CELL_TYPE_RED
    };
    
    //初期位置に設置
    putColor(tsumo.ry, tsumo.rx, tsumo.rollPuyoColor);
    putColor(tsumo.ay, tsumo.ax, tsumo.axisPuyoColor);
    
    //ゲーム部分
    while(1){
        if(kbhit()){
            //キーが入力されたかどうかのフラグ
            int keyFlag = FALSE_BOOL;
            //位置を変更するとき、もとの位置のぷよはクリアしたい
            //もとのぷよの情報をここに保持しておく
            twinPuyoes_t old;
            
            switch(getchar()){
                case 'a':
                    //移動先が適切でなければ終了
                    if(tsumo.rx - 2 == FIELD_START_X || tsumo.ax - 2 == FIELD_START_X)
                        break;
                        
                    old = tsumo;
                    old.rollPuyoColor = CELL_TYPE_EMPTY;
                    old.axisPuyoColor = CELL_TYPE_EMPTY;
                    
                    tsumo.rx -= 2;
                    tsumo.ax -= 2;
                    keyFlag = TRUE_BOOL;
                    break;
                
                case 'd':
                    //移動先が適切でなければ終了
                    if(tsumo.rx + 2 == FIELD_WIDTH || tsumo.ax + 2 == FIELD_WIDTH)
                        break;
                        
                    old = tsumo;
                    old.rollPuyoColor = CELL_TYPE_EMPTY;
                    old.axisPuyoColor = CELL_TYPE_EMPTY;
                    
                    tsumo.rx += 2;
                    tsumo.ax += 2;
                    keyFlag = TRUE_BOOL;
                    break;
                
                case 's':
                    //移動先が適切でなければ終了
                    if(tsumo.ry + 1 == FIELD_HEIGHT || tsumo.ay + 1 == FIELD_HEIGHT)
                        break;
                        
                    old = tsumo;
                    old.rollPuyoColor = CELL_TYPE_EMPTY;
                    old.axisPuyoColor = CELL_TYPE_EMPTY;
                    
                    tsumo.ry++;
                    tsumo.ay++;
                    keyFlag = TRUE_BOOL;
                    break;
                    
                default: break;
            }
            
            if(keyFlag == TRUE_BOOL){
                //oldの消去
                putColor(old.ry, old.rx, old.rollPuyoColor);
                putColor(old.ay, old.ax, old.axisPuyoColor);
                //ぷよの描画
                putColor(tsumo.ry, tsumo.rx, tsumo.rollPuyoColor);
                putColor(tsumo.ay, tsumo.ax, tsumo.axisPuyoColor);
            }
        }
    }
    
    return 0;
}

実行結果:
f:id:sion2000114:20191216234815g:plain

おわりに

今回でいよいよぷよが動き始めました。
次回はぷよの自由落下→組みぷよの再生成を実装していきます。
では、お疲れ様でした。.