我罗斯方块汇报(1)

这个作业属于哪个课程 <2020面向对象程序设计>
这个作业要求在哪里 <我罗斯方块>
这个作业的目标 进行第一次汇报,报告进展及遇到的问题
成员 魏兴晟031903124
陈天武031903105
邓泽纪031903109

目前进度及目标

目前已将方块类和玩家类写得比较详细,其中比较重大的困难如砖块的碰撞判定及消行和涨行都经过了测试
接下来的目的是在游戏类中进行操作的输入控制方块,以及加入计时器功能使方块能够随时间下落
在渲染类中要能够即时地将场地和砖块显示在屏幕上
当前代码还需要让每次运行时随机到的方块不同

方块类

方块类遇到的困难是要返回四个格子的坐标来进行碰撞判断,这里最好使用穷举法

这是id=1,state=0的方块,转轴坐标为(x,y),左上角为坐标原点,因为数组特性的原因y要写在前面,四个格子的坐标分别为
(y,x)(y,x-1)(y,x+1)(y-1,x-1)

玩家类

在玩家类中有方块对象now和next,分别是当前操控的方块和接下来会出现的方块
二维数组wall[26][16]用来存储场地中所有砖的位置
变量refuse用来存储将要上涨的垃圾行数,在放置下一个方块的瞬间上涨
采用这种设计的原因是考虑到砖块离地面1格时若突然涨4格垃圾行会很难处理,而事实上现代方块也确实是采用存储垃圾行的方式
玩家类中有操控方块的方法,碰撞的判定是通过方块对象test进行测试,判断左右移动是否会导致方块和场地重合,如未重合则操作合法
若旋转导致了重合将会测试旋转后方块右侧1格和左侧2格的位置能否移动,因此靠墙的竖直方块能够旋转成横向

对玩家类一些方法的测试

砖块的碰撞判定及踢墙


int main() {
	Player p;
	int i;
	for (i = 0; i < 10; i++) p.Rmove(); //进行10次右移操作,Z砖未出墙
	for (i = 0; i < 20; i++)p.drop();//进行20次下落,Z砖落地,J砖产生,初始形状为 ∟
	p.rotate();//J砖顺时针旋转,形状为 「
	for (i = 0; i < 10; i++)p.Lmove();//J砖左移,竖直面贴墙
	p.rotate();//此旋转会导致J砖和墙重合,因此J砖测试了右侧1格的位置,形状为┐
	for (i = 0; i < 120; i++)p.drop();//J砖及其他各砖块正常产生及落地
	p.display();
}

垃圾行上涨

int main() {
	Player p;
	p.add_refuse(10);//refuse+=10
	p.rise();//上涨
	p.display();
}

目前方块类和玩家类的代码

#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Block {
private:
	int x, y;//转轴坐标
	int id;//0=I青,1=J蓝,2=L橙,3=O黄,4=S绿,5=T紫,6=Z红
	int state;//旋转状态
public:
	Block(Block&b) {
		x = b.x;
		y = b.y;
		id = b.id;
		state = b.state;
	}
	Block(int y1,int x1,int id1,int state1=0):y(y1),x(x1),id(id1),state(state1){}
	int** coordinate() {
		int** i=new int*[4];
		for (int j = 0; j < 4; j++)i[j] = new int[2];
		i[0][0] = y;
		i[0][1] = x;
		if (id == 0) {
			if (state == 0 || state == 2) {
				i[1][0] = y;
				i[1][1] = x - 1;
				i[2][0] = y;
				i[2][1] = x + 1;
				i[3][0] = y;
				i[3][1] = x + 2;
			}
			else if (state == 1 || state == 3) {
				i[1][0] = y + 1;
				i[1][1] = x;
				i[2][0] = y - 1;
				i[2][1] = x;
				i[3][0] = y - 2;
				i[3][1] = x;
			}
		}
		else if (id == 1) {
			if (state == 0) {
				i[1][0] = y;
				i[1][1] = x - 1;
				i[2][0] = y - 1;
				i[2][1] = x - 1;
				i[3][0] = y;
				i[3][1] = x + 1;
			}
			else if (state == 1) {
				i[1][0] = y - 1;
				i[1][1] = x;
				i[2][0] = y - 1;
				i[2][1] = x + 1;
				i[3][0] = y + 1;
				i[3][1] = x;
			}
			if (state == 2) {
				i[1][0] = y;
				i[1][1] = x - 1;
				i[2][0] = y + 1;
				i[2][1] = x + 1;
				i[3][0] = y;
				i[3][1] = x + 1;
			}
			else if (state == 3) {
				i[1][0] = y - 1;
				i[1][1] = x;
				i[2][0] = y + 1;
				i[2][1] = x - 1;
				i[3][0] = y + 1;
				i[3][1] = x;
			}
		}
		else if (id == 2) {
			if (state == 0) {
				i[1][0] = y;
				i[1][1] = x - 1;
				i[2][0] = y - 1;
				i[2][1] = x + 1;
				i[3][0] = y;
				i[3][1] = x + 1;
			}
			else if (state == 1) {
				i[1][0] = y - 1;
				i[1][1] = x;
				i[2][0] = y + 1;
				i[2][1] = x + 1;
				i[3][0] = y + 1;
				i[3][1] = x;
			}
			if (state == 2) {
				i[1][0] = y;
				i[1][1] = x - 1;
				i[2][0] = y + 1;
				i[2][1] = x - 1;
				i[3][0] = y;
				i[3][1] = x + 1;
			}
			else if (state == 3) {
				i[1][0] = y - 1;
				i[1][1] = x;
				i[2][0] = y - 1;
				i[2][1] = x - 1;
				i[3][0] = y + 1;
				i[3][1] = x;
			}
		}
		else if (id == 3) {
			i[1][0] = y - 1;
			i[1][1] = x;
			i[2][0] = y - 1;
			i[2][1] = x + 1;
			i[3][0] = y;
			i[3][1] = x + 1;
		}
		else if (id == 4) {
			if (state == 0||state==2) {
				i[1][0] = y - 1;
				i[1][1] = x;
				i[2][0] = y;
				i[2][1] = x - 1;
				i[3][0] = y - 1;
				i[3][1] = x + 1;
			}
			else if (state == 1||state==3) {
				i[1][0] = y-1;
				i[1][1] = x;
				i[2][0] = y;
				i[2][1] = x+1;
				i[3][0] = y+1;
				i[3][1] = x + 1;
			}
		}
		else if (id == 5) {
			if (state == 0) {
				i[1][0] = y;
				i[1][1] = x - 1;
				i[2][0] = y - 1;
				i[2][1] = x;
				i[3][0] = y;
				i[3][1] = x + 1;
			}
			else if (state == 1) {
				i[1][0] = y - 1;
				i[1][1] = x;
				i[2][0] = y;
				i[2][1] = x + 1;
				i[3][0] = y + 1;
				i[3][1] = x;
			}
			if (state == 2) {
				i[1][0] = y;
				i[1][1] = x - 1;
				i[2][0] = y + 1;
				i[2][1] = x;
				i[3][0] = y;
				i[3][1] = x + 1;
			}
			else if (state == 3) {
				i[1][0] = y - 1;
				i[1][1] = x;
				i[2][0] = y;
				i[2][1] = x - 1;
				i[3][0] = y + 1;
				i[3][1] = x;
			}
		}
		else if (id == 6) {
		    if (state == 0 || state == 2) {
			    i[1][0] = y - 1;
		    	i[1][1] = x;
			    i[2][0] = y - 1;
			    i[2][1] = x - 1;
			    i[3][0] = y;
	    		i[3][1] = x + 1;
	    	}
        		else if (state == 1 || state == 3) {
	    		i[1][0] = y - 1;
	    		i[1][1] = x + 1;
	    		i[2][0] = y;
	    		i[2][1] = x + 1;
	    		i[3][0] = y + 1;
    			i[3][1] = x;
    		}
		}
		return i;
	}//根据私有变量返回方块四个格子的坐标
	void rotate() {
		if (state < 3)state++;
		else state = 0;
	}
	void Lmove() { x--; }
	void Rmove() { x++; }
	void drop() { y++; }
};


class Player {
private:
	int refuse;//积攒垃圾行数,放置下一个方块的瞬间上涨
	int wall[26][16];//边界及所有屏幕内存在方块的位置
	Block now, next;//目前方块及下一方块


public:
	Player():refuse(0),now(*(new Block(2,7,rand()%7))),next(*(new Block(2,7, rand() % 7))){
		for (int i = 0; i < 26; i++)
			for (int j = 0; j < 16; j++)
				wall[i][j] = 0;
		for (int i = 0; i < 23; i++)
			wall[i][2] = wall[i][13] = 1;
		for (int j = 3; j <=12; j++)
			wall[22][j] = 1;
	}


	void produce() {
		now = next;
		next =Block(2, 7, rand() % 7);
	}//产生新方块,设置now和next对象


	int clear() {
		int sum = 0,t;
		int i, j,k;
		for (i = 2; i < 22; i++) {
			t = 0;
			for (j = 3; j <= 12; j++) {
				if (wall[i][j] == 0) {
					t++;
				}
			}
			if (t == 0) {
				sum++;
				for (j = i; j >= 2; j--) {
					for (k = 3; k <= 12; k++) {
						wall[j][k] = wall[j - 1][k];
					}
				}
			}
		}
		return sum;
	}//消行,返回消除行数


	void add_refuse(int x) {refuse += x;}


	void rise() {
		int i, j;
		if (height() + refuse <= 20&&refuse!=0) {
			for (i = 2; i < 22 - refuse;i++ ) {
				for (j = 3; j <= 12; j++) {
					wall[i][j] = wall[i + 1][j];
				}
			}
			for (i =22-refuse; i <22; i++) {
				for (j = 3; j <= 12; j++) {
					wall[i][j] = 1;
				}
			}
			for (i = 22 - refuse; i < 22; i++) {
				wall[i][rand() % 10 + 3] = 0;
			}
			refuse = 0;
		}
	}//根据refuse数值上涨垃圾行,refuse归零


	int height() {
		for (int i = 2; i < 22; i++) {
			for (int j = 3; j <= 12; j++) {
				if (wall[i][j] == 1)
					return 22 - i;
			}
		}
		return 0;
	}//返回屏幕内方块高度


	bool judge_fail() {
		for (int i = 0; i <= 1; i++)
			for (int j = 3; j <= 12; j++)
				if (wall[i][j] == 1)
					return true;
		if (height() + refuse > 20)
			return true;
		return false;
	}//3<=x<=12,0<=y<=1内有方块或height+refuse>20时判定失败


	bool judge_coincide(Block test) {
		int** i = test.coordinate();
		for(int j=0;j<4;j++)
			if (wall[i[j][0]][i[j][1]] == 1)return true;
		return false;
	}//判断测试砖块与墙是否重合


	void rotate() {
		Block test = now;
		test.rotate();
		if (judge_coincide(test) == false)
			now.rotate();
		else {
			test.Rmove();
			if (judge_coincide(test) == false) {
				now.rotate();
				now.Rmove();
			}
			else {
				test.Lmove();
				test.Lmove();
				if (judge_coincide(test) == false) {
					now.rotate();
					now.Lmove();
				}
				else {
					test.Lmove();
					if (judge_coincide(test) == false) {
						now.rotate();
						now.Lmove();
						now.Lmove();
					}
				}
			}
		}
	}//旋转并判断合法性以及踢墙


	void Lmove() {
		Block test = now;
		test.Lmove();
		if (judge_coincide(test) == false)
			now.Lmove();
	}//左移


	void Rmove() {
		Block test = now;
		test.Rmove();
		if (judge_coincide(test) == false)
			now.Rmove();
	}//右移


	void drop() {
		Block test = now;
		test.drop();
		if (judge_coincide(test) == false)
			now.drop();
		else {
			set();
		}
	}//下降


	void set() {
		int** i = now.coordinate();
		for (int j = 0; j < 4; j++)
			wall[i[j][0]][i[j][1]] = 1;
		produce();
	}//放置方块


	void display() {
		for (int i = 0; i < 26; i++) {
			for (int j = 0; j < 16; j++) {
				if (wall[i][j] == 0)cout << "  ";
				else cout << "■";
			}
			cout << endl;
		}
	}
};

猜你喜欢

转载自www.cnblogs.com/q1317264/p/12934296.html
今日推荐