【自用14】C++俄罗斯方块-思路复盘3

63 篇文章 1 订阅
34 篇文章 0 订阅

在上篇降落函数中使用到了判断游戏是否结束的功能,因此这篇先从判断游戏是否结束开始

判断游戏是否结束

void failCheck(void){
    if(!moveable(START_X,START_Y,MOVE_DOWN,BLOCK_UP)){
        setcolor(WHITE);
        setfont(45,0,_T("隶体"));
        outtextxy(75,300,_T("GAME OVER!"));
        Sleep(1000);
        system("pause");
        closegraph();
        exit(0);
    }
}

判断游戏是否结束,最主要的判断条件是方块是否可以移动,如果方块刚产生就无法移动,则可以作为游戏结束的判断条件。如果游戏结束,则显示游戏结束的字样。

由于游戏的运行应该不断判断方块能否移动以及游戏是否结束。这里的思路是这样的,在主函数中,不断循环新方块函数,在新方块函数中调用移动函数,在移动函数中判断游戏是否结束。相当于游戏不断调用移动函数并且不断判断游戏是否结束。

如果游戏没有结束,则方块持续降落

在降落过程中要判断用户是否有键盘的输入,由于降落是持续循环的,相当于判断键盘输入也是持续循环的。

判断方块是否可以移动

//如果在指定位置可以在指定方向移动,就返回1,否则就返回0
int moveable(int x0,int y0,move_dir_t moveDir,block_dir_t blockDir){
    //计算当前方块的左上角在30*15的游戏区中的位置(第多少行,第多少列)
    int x=(y0-minY)/UNIT_SIZE;
    int y=(x0-minX)/UNIT_SIZE;
 
    int id=BlockIndex*4+blockDir;
    int ret=1;
 
    if(moveDir==MOVE_DOWN){
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                if(block[id][i][j]==1 && (x+i+1>30 || (x+i>=0 && x+i<30 && y+j>=0 && y+j<15 && visit[x+i+1][y+j]==1))){
                    ret=0;
                }
            }
        }
    }else if(moveDir==MOVE_LEFT){
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                if(block[id][i][j]==1 && (y+j==0 || (x+i>=0 && x+i<30 && y+j-1>=0 && y+j-1<15 && visit[x+i][y+j-1]==1))){
                    ret=0;
                }
            }
        }
    }else if(moveDir==NOVE_RIGHT){
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                if(block[id][i][j]==1 && (y+j+1>=15 || (y+j+1>=15 || (x+i>=0 && x+i<30 && y+i+1>=0 && y+j+1<15 && visit[x+i][y+j+1]==1)))){
                    ret=0;
                }
            }
        }
    }
    return ret;
}

首先找到需要判断的方块的位置,判断这个位置在指定方向上的下一个位置是否越界,如果没有越界,则判断该位置在指定方向的下一个位置是否被占用。

如果位置越界或被占用,则返回不能向指定方向移动的结果。

这里我当初有个疑问:就是如果一个方块的几个格子连在一起,岂不是会判断不能移动。后面发现,假如指定方向是向右,则这个形状方块的最右边的方块是可以移动的,最右边的方块移动之后,次右边的方块也可以移动了,这样依次移动即可。

但是又有一个问题,判断方块是否可以移动的时候是按照顺序判断的,最边上的方块不一定是最先判断的,除非,这个判断的动作不断的循环,否则只判断一轮的话是无法满足移动方块的需求的。那这个判断是否是循环进行的呢?

根据前面的描述,游戏是否结束会循环判断,而是否可以移动函数在判断游戏是否结束函数中被调用,因此判断是否可以移动函数也是会被循环调用的。

这样一来,方块下落的功能就基本上完成了。只需要在移动函数的判断语句之后加上对方块坐标的修改即可。具体代码如下

void move(void){
	int x = START_X;
	int y = START_Y;
	int k = 0;
	block_dir_t  blockDir = BLOCK_UP;
	int curSpeed = speed;

	// 检测游戏是否结束
	failCheck();

	// 持续向下降落
	while (1) {
		if (_kbhit()) {
			int key = _getch();
			if (key == KEY_SPACE) {
				_getch();
			}
		}

		// 清除当前方块
		clearBlock(x, k, blockDir);

		if (_kbhit()) {
			int key = _getch();

			if(key == KEY_UP) {
				
			} else if (key == KEY_DOWN) {
				
			} else if (key == KEY_LEFT) {
				
			} else if (key ==KEY_RIGHT) {
				
			}
		}

		k += 20;

		// 绘制当前方块
		drawBlock(x, y+k, BlockIndex, blockDir);

		wait(curSpeed);
		
		//k += 20;

		// 方块的“固化”处理
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值