feat(MCU课设): 增加方块旋转逻辑

This commit is contained in:
iridiumR 2022-06-09 12:52:41 +08:00
parent 6e2b3a7e90
commit 438dfeea08
7 changed files with 150 additions and 39 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

View file

@ -7,7 +7,8 @@
#include <stdlib.h> #include <stdlib.h>
extern unsigned int bestScore[]; extern unsigned int bestScore[];
char base[MAX_X][MAX_Y] = {0}; //x*y //0为空 1为下落完成 2为正在下落 char base[MAX_X][MAX_Y] = {0}; //x*y //0为空 1为下落完成 2为正在下落 3为旋转中心点
char mask[MAX_X][MAX_Y] = {0}; //旋转缓存层
extern unsigned int score; extern unsigned int score;
extern enum OPR opr; extern enum OPR opr;
enum GS blockGameStatus = __idle; enum GS blockGameStatus = __idle;
@ -15,7 +16,7 @@ enum GS blockGameStatus = __idle;
void blockInit() void blockInit()
{ {
score = 0; score = 0;
srand((unsigned)TL0); srand((unsigned)TL0);
blockGameStatus = start; blockGameStatus = start;
} }
@ -65,7 +66,7 @@ void genPiece()
//若存在尚未下落完成的方块则打断 //若存在尚未下落完成的方块则打断
for(i = 0; i < MAX_X; i++) for(i = 0; i < MAX_X; i++)
for(j = 0; j < MAX_Y; j++) for(j = 0; j < MAX_Y; j++)
if(base[i][j] == 2) if(base[i][j] >= 2)
return; return;
//当两个方块的情况 //当两个方块的情况
@ -77,12 +78,12 @@ void genPiece()
//当两个方块的情况 //当两个方块的情况
if(random >= 7 && random <= 15) if(random >= 7 && random <= 15)
{ {
base[4][9] = 2; // base[4][9] = 3; //
base[4][10] = 2; // base[4][10] = 2; //
} }
else if(random >= 16 && random <= 22) else if(random >= 16 && random <= 22)
{ {
base[3][9] = 2; //// base[3][9] = 3; ////
base[4][9] = 2; base[4][9] = 2;
} }
@ -91,37 +92,37 @@ void genPiece()
{ {
base[4][11] = 2; base[4][11] = 2;
base[4][10] = 2; base[4][10] = 3;
base[4][9] = 2; base[4][9] = 2;
} }
else if(random >= 32 && random <= 38) else if(random >= 32 && random <= 38)
{ {
base[3][9] = 2; base[3][9] = 2;
base[4][9] = 2; base[4][9] = 3;
base[5][9] = 2; base[5][9] = 2;
} }
else if(random >= 39 && random <= 47) else if(random >= 39 && random <= 47)
{ {
base[3][10] = 2; base[3][10] = 2;
base[3][9] = 2; base[3][9] = 3;
base[4][9] = 2; base[4][9] = 2;
} }
else if (random >= 48 && random <= 55) else if (random >= 48 && random <= 55)
{ {
base[4][10] = 2; base[4][10] = 2;
base[3][9] = 2; base[3][9] = 2;
base[4][9] = 2; base[4][9] = 3;
} }
else if (random >= 56 && random <= 63) else if (random >= 56 && random <= 63)
{ {
base[4][9] = 2; base[4][9] = 2;
base[3][10] = 2; base[3][10] = 2;
base[4][10] = 2; base[4][10] = 3;
} }
else if (random >= 64 && random <= 69) else if (random >= 64 && random <= 69)
{ {
base[3][9] = 2; base[3][9] = 2;
base[3][10] = 2; base[3][10] = 3;
base[4][10] = 2; base[4][10] = 2;
} }
@ -133,31 +134,31 @@ void genPiece()
base[3][9] = 2; base[3][9] = 2;
base[4][9] = 2; base[4][9] = 2;
} }
else if(random >= 80 && random <= 84) else if(random >= 80 && random <= 84)
{ {
base[3][10] = 2; base[3][10] = 2;
base[4][10] = 2; base[4][10] = 3;
base[3][9] = 2; base[3][9] = 2;
base[4][11] = 2; base[4][11] = 2;
} }
else if(random >= 85 && random <= 89) else if(random >= 85 && random <= 89)
{ {
base[3][10] = 2; base[3][10] = 2;
base[4][10] = 2; base[4][10] = 3;
base[3][11] = 2; base[3][11] = 2;
base[4][9] = 2; base[4][9] = 2;
} }
else if(random >= 90 && random <= 94) else if(random >= 90 && random <= 94)
{ {
base[3][10] = 2; base[3][10] = 2;
base[4][10] = 2; base[4][10] = 3;
base[4][9] = 2; base[4][9] = 2;
base[5][9] = 2; base[5][9] = 2;
} }
else if(random >= 95 && random <= 99) else if(random >= 95 && random <= 99)
{ {
base[3][10] = 2; base[3][10] = 2;
base[4][10] = 2; base[4][10] = 3;
base[3][9] = 2; base[3][9] = 2;
base[4][9] = 2; base[4][9] = 2;
} }
@ -196,7 +197,7 @@ void dropPiece()
{ {
if(flag == 1) if(flag == 1)
break; break;
if(base[i][j] == 2) if(base[i][j] >= 2)
{ {
//若触底,做标记 //若触底,做标记
if(flag == 0 && (base[i][j - 1] == 1 || j == 0)) if(flag == 0 && (base[i][j - 1] == 1 || j == 0))
@ -215,12 +216,12 @@ void dropPiece()
{ {
for(j = 0; j < MAX_Y; j++) for(j = 0; j < MAX_Y; j++)
{ {
if(base[i][j] == 2) if(base[i][j] >= 2)
{ {
//无标记则下落 //无标记则下落
if(flag == 0 && isIegal(i, j - 1)) if(flag == 0 && isIegal(i, j - 1))
{ {
base[i][j - 1] = 2; base[i][j - 1] = base[i][j];
base[i][j] = 0; base[i][j] = 0;
} }
//有标记则转换 //有标记则转换
@ -250,14 +251,13 @@ void moveLeftPiece()
} }
for(i = 0; i < MAX_X; i++) for(i = 0; i < MAX_X; i++)
for(j = 0; j < MAX_Y; j++) for(j = 0; j < MAX_Y; j++)
if(base[i][j] == 2) if(base[i][j] >= 2)
{ {
base[i - 1][j] = 2; base[i - 1][j] = base[i][j];
base[i][j] = 0; base[i][j] = 0;
} }
} }
void moveRightPiece() void moveRightPiece()
{ {
char i, j; char i, j;
if(blockGameStatus == over) if(blockGameStatus == over)
@ -270,9 +270,9 @@ void moveRightPiece()
} }
for(i = MAX_X - 1; i >= 0; i--) for(i = MAX_X - 1; i >= 0; i--)
for(j = MAX_Y - 1; j >= 0; j--) for(j = MAX_Y - 1; j >= 0; j--)
if(base[i][j] == 2 ) if(base[i][j] >= 2 )
{ {
base[i + 1][j] = 2; base[i + 1][j] = base[i][j];
base[i][j] = 0; base[i][j] = 0;
} }
} }
@ -337,6 +337,7 @@ void blockGameOver()
} }
} }
//判定最高分
unsigned int addBest(unsigned int s) unsigned int addBest(unsigned int s)
{ {
int i, j; int i, j;
@ -351,3 +352,83 @@ unsigned int addBest(unsigned int s)
} }
return 0; return 0;
} }
unsigned int rotateBlock(enum OPR opr)
{
char i, j, cy, cx, flag = 0;
//寻找旋转中心点
for(i = 0; i < MAX_X; i++)
for(j = 0; j < MAX_Y; j++)
{
if(base[i][j] == 3)
{
flag = 1;
cx = i;
cy = j;
break;
}
}
if(!flag)
return 0; //没找到就直接返回
if(opr == right)
{
//判定是否合法 不合法不旋转
for(i = - 1; i <= 1; i++)
for(j = - 1; j <= 1; j++)
if(base[cx + i][cy + j] == 2)
if(isIegal(j + cx, -i + cy))
{
//生成缓存层
mask[j + cx][-i + cy] = base[cx + i][cy + j];
}
else
{
memset(mask, 0, sizeof(mask));
return 0;
}
//清除现有层
for(i = 0; i < MAX_X; i++)
for(j = 0; j < MAX_Y; j++)
if(base[i][j] == 2)
base[i][j] = 0;
//缓存层覆盖
for(i = -1; i <= 1; i++)
for(j = -1; j <= 1; j++)
if(mask[cx + i][cy + j] == 2)
base[cx + i][cy + j] = mask[cx + i][cy + j];
}
if(opr == left)
{
//判定是否合法 不合法不旋转
for(i = - 1; i <= 1; i++)
for(j = - 1; j <= 1; j++)
if(base[cx + i][cy + j] == 2)
if(isIegal(-j + cx, i + cy))
{
//生成缓存层
mask[-j + cx][i + cy] = base[cx + i][cy + j];
}
else
{
memset(mask, 0, sizeof(mask));
return 0;
}
//清除现有层
for(i = 0; i < MAX_X; i++)
for(j = 0; j < MAX_Y; j++)
if(base[i][j] == 2)
base[i][j] = 0;
//缓存层覆盖
for(i = -1; i <= 1; i++)
for(j = -1; j <= 1; j++)
if(mask[cx + i][cy + j] == 2)
base[cx + i][cy + j] = mask[cx + i][cy + j];
}
memset(mask, 0, sizeof(mask));
return 1;
}

View file

@ -23,4 +23,5 @@ void blockGameOver();
void saveBest(); void saveBest();
void readBest(); void readBest();
unsigned int addBest(unsigned int s); unsigned int addBest(unsigned int s);
unsigned int rotateBlock(enum OPR opr);
#endif #endif

View file

@ -92,6 +92,10 @@ code unsigned char SUPER_NUM1[]={
code unsigned char IMG_BLOCK[]={ code unsigned char IMG_BLOCK[]={
0x81,0x7E,0x7E,0x7E,0x7A,0x72,0x7E,0x81, 0x81,0x7E,0x7E,0x7E,0x7A,0x72,0x7E,0x81,
}; };
//Ðýת¼ýÍ·
code unsigned char IMG_ROTATE[]={
0x7F,0x1F,0x07,0x0B,0x13,0x21,0x41,0x80,
};
//µÃ·Ö //µÃ·Ö
code unsigned char FONT_SCORE0[]={ code unsigned char FONT_SCORE0[]={
0x00,0x10,0x88,0xC4,0x33,0x00,0xBE,0xAA,0xAA,0xAA,0xAA,0xAA,0xBE,0x80,0x00,0x00, 0x00,0x10,0x88,0xC4,0x33,0x00,0xBE,0xAA,0xAA,0xAA,0xAA,0xAA,0xBE,0x80,0x00,0x00,

View file

@ -40,7 +40,7 @@ void time() interrupt 1 //
if(PIN_4 == 0) if(PIN_4 == 0)
{ {
delayms(15); delayms(9);
if(PIN_4 == 0) if(PIN_4 == 0)
{ {
opr = confirm; opr = confirm;

View file

@ -27,7 +27,7 @@ Menu* LAST = NULL; //
code unsigned int ver _at_ 0x7ffe; code unsigned int ver _at_ 0x7ffe;
enum OPR opr = idle; enum OPR opr = idle;
static unsigned int local[5] = {0}; static unsigned int local[5] = {0}; //主菜单使用0,1其余公用
unsigned int score; unsigned int score;
unsigned int bestScore[10]; unsigned int bestScore[10];
unsigned int mBestScore[10]; unsigned int mBestScore[10];
@ -106,30 +106,47 @@ void m_block(struct _menu* this)
if(LAST != &M_BLOCK) if(LAST != &M_BLOCK)
{ {
LAST = &M_BLOCK; LAST = &M_BLOCK;
drawVerticalDottedLine(64);
drawBLOCKSCORE();
blockInit(); blockInit();
local[2] = 0; //目前状态 0平移 1旋转
} }
//返回 //返回
if(opr == confirm) if(opr == confirm)
{ {
opr = idle; opr = idle;
clear(); if(blockGameStatus == over)
blockDestroy(); {
NOW = &M_MAINMENU; clear();
local[2] = 0;
blockDestroy();
NOW = &M_MAINMENU;
return;
}
local[2] = ~local[2];
return; return;
} }
if(opr == left) if(opr == left)
{ {
if(local[2])
{
rotateBlock(opr);
local[2] = 0;
}
else
moveLeftPiece();
opr = idle; opr = idle;
moveLeftPiece();
drawBlock(); drawBlock();
return; return;
} }
if(opr == right) if(opr == right)
{ {
if(local[2])
{
rotateBlock(opr);
local[2] = 0;
}
else
moveRightPiece();
opr = idle; opr = idle;
moveRightPiece();
drawBlock(); drawBlock();
return; return;
} }
@ -147,17 +164,25 @@ void m_block(struct _menu* this)
drawVOID8(70, 4, 40); drawVOID8(70, 4, 40);
drawVOID8(70, 6, 32); drawVOID8(70, 6, 32);
} }
drawVerticalDottedLine(64);
drawBLOCKSCORE();
drawSUPNUM(70, 2, score / 10000); //绘制分数 drawSUPNUM(70, 2, score / 10000); //绘制分数
drawSUPNUM(79, 2, (score % 10000) / 1000); drawSUPNUM(79, 2, (score % 10000) / 1000);
drawSUPNUM(88, 2, (score % 1000) / 100); drawSUPNUM(88, 2, (score % 1000) / 100);
drawSUPNUM(97, 2, (score % 100) / 10); drawSUPNUM(97, 2, (score % 100) / 10);
drawSUPNUM(106, 2, score % 10); drawSUPNUM(106, 2, score % 10);
// if(local[2])
// placeIMG_ROTATE(115, 6);
// else
// placeRIMG_BLOCK(115, 6);
blockGameOver(); //检查是否游戏结束 blockGameOver(); //检查是否游戏结束
genPiece(); //若有需要,生成新块 genPiece(); //若有需要,生成新块
dropPiece(); //若有需要,块下落 dropPiece(); //若有需要,块下落
judgeBlock(); //若有需要,清除一行 judgeBlock(); //若有需要,清除一行
drawBlock(); //绘制界面 drawBlock(); //绘制界面
delayms(400); delayms(1500);
} }