面向对象程序设计我罗斯方块汇报(1)
作业描述 | 详情 |
---|---|
这个作业属于哪个课程 | 2020面向对象程序设计张栋班 |
这个作业的要求 | 作业 |
这个作业的目标 | 汇报小组这个阶段的开发进度 |
项目地址 | 我们的GitHub仓库 |
小组成员 | 031902302 蔡树峰 031902320 李霆政 031902332 周浩东 |
开发进度
1.初步完成地图类Board。
Board::Board{
//初始化块,时间间隔,分数
score_player1=0;
score_player2=0;
block = new Block(this);
time = 200;
height=22;
width=10;
//初始化地图
for(int i=0; i<=height+1; i++)
for(int j=0; j<=width+1; j++)
map[i][j] = '#';//外围多一圈,便于消行时操作执行
}
void Board::confirm(Player player){
//将块更新到map
if(player.num==1){
char (&map_1)[50][50]=map_player1;
char (&map_2)[50][50]=map_player2;
}
else{
char (&map_1)[50][50]=map_player2;
char (&map_2)[50][50]=map_player1;
}//给map取别名
for(int i=0; i<4; i++)
for(int j=0; j<4; j++){
int tx = block->x + i;
int ty = block->y + j;
if(tx<1 || tx > height || ty < 1 || ty > width)
continue;
if(block->BLOCKS[block->type][i][j] != '#')
map_1[tx][ty] = block->BLOCKS[block->type][i][j];
}
//消去完整的行并计算行个数
int cnt = 0;
for(int i=height; i>=1; i--)
{
bool flag = false;
for(int j=1; j<=width; j++)
if(map_1[i][j] == '#')
{
flag = true;
break;
}
if(flag)
continue;
cnt++;
for(int j=i; j>=1; j--)
for(int k=1; k<=width; k++)
map_1[j][k] = map_1[j-1][k];//消行用上一行取代下一行
}
//计分
if(cnt)
player.score += 10*(cnt);
//每下落一个块,时间间隔减2
time -= 2;
if(time < 0)
time = 0;
//更新块
block->toNext();
for(int j=1; j<=height; j++)
for(int k=1; k<=width; k++)
map_2[j][k] = map_2[j+1][k];//此消彼长用下一行取代上一行
}
bool Board::isEnd(){
for(int i=1; i<=width; i++)
if(map[1][i] != '#')
return true;
return false;
}
2.方块类Block的部分成员函数。
bool Block::detect(int flag){
//获得当前操作的目标状态:目标坐标,目标方块类型。
int nextX, nextY, nextType;
// 0,1,2,3对应上下左右
switch(flag)
{
case 0: nextX = x; nextY = y; nextType = NEXT[type]; break;
case 1: nextX = x+1; nextY = y; nextType = type; break;
case 2: nextX = x; nextY = y-1; nextType = type; break;
case 3: nextX = x; nextY = y+1; nextType = type; break;
}
for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
{
//tx,ty表示i,j所对应的地图的实际位置。
int tx = nextX+i;
int ty = nextY+j;
//边界处理
if(tx < 0 || tx > board->height+1 || ty < 0 || ty > board->width+1)
continue;
//如果块与地图墙相重合,则发生碰撞
if(BLOCKS[nextType][i][j] != '#' && (ty == 0 || ty == board->width+1))
return false;
if(BLOCKS[nextType][i][j] != '#' && board->map[tx][ty] != '#')
return false;
}
return true;
}
Block::Block(Board *board){
this->board = board;
x = -3;
y = 4;
//随机数确定第一个块的类型
srand((unsigned) time(NULL));
type = rand()%19;
nextType = rand()%19;
//读入方块类型
freopen("block.bin", "rb", stdin);
for(int i=0; i<19; i++)
{
for(int j=0; j<4; j++)
cin>>BLOCKS[i][j];
}
//next数组模拟指向,用于方块旋转功能
for(int i=0; i<3; i++){
for(int j=0; j<3; j++)
NEXT[i*4+j] = i*4+j+1;
NEXT[i*4+3] = i*4;
}
for(int i=12; i<18; i+=2){
NEXT[i] = i+1;
NEXT[i+1] = i;
}
NEXT[18] = 18;
//设置每种方块对应的颜色
COLOR[1] = Qt::blue;
COLOR[2] = Qt::darkBlue;
COLOR[3] = Qt::yellow;
COLOR[4] = Qt::magenta;
COLOR[5] = Qt::darkMagenta;
COLOR[6] = Qt::cyan;
COLOR[7] = Qt::red;
}
3.完成了游戏主界面的渲染。
采用windows进行渲染,目前已经实现了游戏所需求的基础页面,剩下键盘输入实现接下来的功能,所实现代码以及可执行文件已发送至仓库,实现的界面如图
#include <windows.h>
#include<stdio.h>
void Interface(HDC hdc);
void CreateR(HDC hdc);
void ShowR(HDC hdc);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); // 窗口过程
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd ; // 窗口句柄
MSG msg ; // 消息
WNDCLASS wndclass ; // 窗口类
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground=(HBRUSH)CreateSolidBrush(RGB(103,120,104));
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "HelloWin"; // 窗口类名
if (!RegisterClass (&wndclass)) { // 注册窗口
MessageBox (NULL, "窗口注册失败!", "HelloWin", 0) ;
return 0 ;
}
// 创建窗口
hwnd = CreateWindow ("HelloWin", // 窗口类名
"我的窗口", // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口样式
CW_USEDEFAULT, // 窗口最初的 x 位置
CW_USEDEFAULT, // 窗口最初的 y 位置
915, // 窗口最初的 x 大小
700, // 窗口最初的 y 大小
NULL, // 父窗口句柄
NULL, // 窗口菜单句柄
hInstance, // 应用程序实例句柄
NULL) ; // 创建窗口的参数
ShowWindow (hwnd, nCmdShow) ; // 显示窗口
UpdateWindow (hwnd) ; // 更新窗口,包括窗口的客户区
// 进入消息循环:当从应用程序消息队列中检取的消息是WM_QUIT时,则退出循环
while (GetMessage (&msg, NULL, 0, 0)) {
TranslateMessage (&msg) ; // 转换某些键盘消息
DispatchMessage (&msg) ; // 将消息发送给窗口过程,这里是WndProc
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxChar,cyChar;
HDC hdc;
PAINTSTRUCT ps;
RECT rc;
TEXTMETRIC tm;
HBRUSH hBrush=(HBRUSH)GetStockObject(GRAY_BRUSH);
static HPEN hPen = CreatePen(PS_DASH,1,0);
HRGN hRgn = CreateRectRgn(50,100,100,50);
switch (message) {
case WM_CREATE:
hdc = GetDC(hwnd); // 窗口创建产生的消息
GetTextMetrics(hdc,&tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
ReleaseDC(hwnd,hdc);
return 0 ;
case WM_PAINT:
hdc = BeginPaint( hwnd, &ps );
GetClientRect( hwnd, &rc ); // 获取窗口客户区大小
Interface(hdc);
CreateR(hdc);
ShowR(hdc);
EndPaint( hwnd, &ps );
return 0 ;
case WM_DESTROY: // 当窗口关闭时产生的消息
DeleteObject(hPen);
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ; // 执行默认的消息处理
}
void Interface(HDC hdc)
{
COLORREF crColor=RGB(103,120,104);
SetBkColor(hdc, crColor);
HFONT hFont,hFontOld;
TCHAR szBuffer[40],sz[4];
int a = 0,b = 0;
char c=29;
hFont = CreateFont(40,15,0,0,FW_REGULAR,FALSE,FALSE,FALSE,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_MODERN, "华文新魏");
hFontOld = (HFONT)SelectObject(hdc,hFont);
TextOut(hdc,20,15,"玩家一",6);
TextOut(hdc,70,70,"得分",4);
TextOut(hdc,127,120,szBuffer,wsprintf(szBuffer,TEXT("%d"),a));
TextOut(hdc,750+20,15,"玩家二",6);
TextOut(hdc,750+70,70,"得分",4);
TextOut(hdc,750+120,120,szBuffer,wsprintf(szBuffer,TEXT("%d"),a));
TextOut(hdc,127,480,szBuffer,wsprintf(szBuffer,TEXT("%d"),b));
TextOut(hdc,750+127,480,szBuffer,wsprintf(szBuffer,TEXT("%d"),b));
MoveToEx(hdc,150,0,NULL);
LineTo(hdc,150,700);
MoveToEx(hdc,450,0,NULL);
LineTo(hdc,450,700);
MoveToEx(hdc,750,0,NULL);
LineTo(hdc,750,700);
hFont = CreateFont(22,10,0,0,FW_REGULAR,FALSE,FALSE,FALSE,GB2312_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_MODERN, "华文新魏");
hFontOld = (HFONT)SelectObject(hdc,hFont);
TextOut(hdc,54,180,"下一方块",8);
TextOut(hdc,750+54,180,"下一方块",8);
TextOut(hdc,54,450,"下降速度",8);
TextOut(hdc,750+54,450,"下降速度",8);
TextOut(hdc,10,640,"ESC退出游戏",11);
TextOut(hdc,750+30,510,sz,wsprintf(sz,TEXT("→ ← ↑ ↓")));
TextOut(hdc,750+30,550,"周浩东",6);
TextOut(hdc,750+30,580,"李霆政",6);
TextOut(hdc,750+30,610,"蔡树峰",6);
TextOut(hdc,750+30,640,"联合出品",11);
SelectObject(hdc,hFontOld);
DeleteObject(hFont);
}
void CreateR(HDC hdc)
{
HRGN hRgn,hRgn1;
int x=2,y=202;
for(int i=1;i<5;i++)
{
for(int j=1;j<5;j++)
{
if(x>=150) break;
hRgn = CreateRectRgn(x,y+35,x+35,y);
hRgn1 = CreateRectRgn(x+10,y+25,x+25,y+10);
FrameRgn(hdc,hRgn,(HBRUSH)CreateSolidBrush(RGB(94,108,94)),5,5);
FillRgn(hdc,hRgn1,(HBRUSH)CreateSolidBrush(RGB(94,108,94)));
x=x+37.5;
}
x=2;y=y+37.5;
}
x=2+750;y=202;
for(int i=1;i<5;i++)
{
for(int j=1;j<5;j++)
{
if(x>=900) break;
hRgn = CreateRectRgn(x,y+35,x+35,y);
hRgn1 = CreateRectRgn(x+10,y+25,x+25,y+10);
FrameRgn(hdc,hRgn,(HBRUSH)CreateSolidBrush(RGB(94,108,94)),5,5);
FillRgn(hdc,hRgn1,(HBRUSH)CreateSolidBrush(RGB(94,108,94)));
x=x+37.5;
}
x=2+750;y=y+37.5;
}
}
void ShowR(HDC hdc)
{
HRGN hRgn,hRgn1;
double x,y;
for(y=0;y<700;y=y+30)
{
for(x=151;x<450;x=x+30)
{
hRgn = CreateRectRgn(x,y+28,x+28,y);
hRgn1 = CreateRectRgn(x+10,y+18,x+18,y+10);
FrameRgn(hdc,hRgn,(HBRUSH)CreateSolidBrush(RGB(94,108,94)),5,5);
FillRgn(hdc,hRgn1,(HBRUSH)CreateSolidBrush(RGB(94,108,94)));
}
x=151;
}
for(y=0;y<700;y=y+30)
{
for(x=451;x<750;x=x+30)
{
hRgn = CreateRectRgn(x,y+28,x+28,y);
hRgn1 = CreateRectRgn(x+10,y+18,x+18,y+10);
FrameRgn(hdc,hRgn,(HBRUSH)CreateSolidBrush(RGB(94,108,94)),5,5);
FillRgn(hdc,hRgn1,(HBRUSH)CreateSolidBrush(RGB(94,108,94)));
}
x=451;
}
}
出现的问题
1.各个类的代码未经测试
2.三人分工写代码,各个类之中有矛盾的地方,需要讨论细化