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>
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 enum OPR opr;
enum GS blockGameStatus = __idle;
@ -15,7 +16,7 @@ enum GS blockGameStatus = __idle;
void blockInit()
{
score = 0;
srand((unsigned)TL0);
srand((unsigned)TL0);
blockGameStatus = start;
}
@ -65,7 +66,7 @@ void genPiece()
//若存在尚未下落完成的方块则打断
for(i = 0; i < MAX_X; i++)
for(j = 0; j < MAX_Y; j++)
if(base[i][j] == 2)
if(base[i][j] >= 2)
return;
//当两个方块的情况
@ -77,12 +78,12 @@ void genPiece()
//当两个方块的情况
if(random >= 7 && random <= 15)
{
base[4][9] = 2; //
base[4][9] = 3; //
base[4][10] = 2; //
}
else if(random >= 16 && random <= 22)
{
base[3][9] = 2; ////
base[3][9] = 3; ////
base[4][9] = 2;
}
@ -91,37 +92,37 @@ void genPiece()
{
base[4][11] = 2;
base[4][10] = 2;
base[4][10] = 3;
base[4][9] = 2;
}
else if(random >= 32 && random <= 38)
{
base[3][9] = 2;
base[4][9] = 2;
base[4][9] = 3;
base[5][9] = 2;
}
else if(random >= 39 && random <= 47)
{
base[3][10] = 2;
base[3][9] = 2;
base[3][9] = 3;
base[4][9] = 2;
}
else if (random >= 48 && random <= 55)
{
base[4][10] = 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[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][10] = 2;
base[3][10] = 3;
base[4][10] = 2;
}
@ -133,31 +134,31 @@ void genPiece()
base[3][9] = 2;
base[4][9] = 2;
}
else if(random >= 80 && random <= 84)
else if(random >= 80 && random <= 84)
{
base[3][10] = 2;
base[4][10] = 2;
base[4][10] = 3;
base[3][9] = 2;
base[4][11] = 2;
}
else if(random >= 85 && random <= 89)
else if(random >= 85 && random <= 89)
{
base[3][10] = 2;
base[4][10] = 2;
base[4][10] = 3;
base[3][11] = 2;
base[4][9] = 2;
}
else if(random >= 90 && random <= 94)
else if(random >= 90 && random <= 94)
{
base[3][10] = 2;
base[4][10] = 2;
base[4][10] = 3;
base[4][9] = 2;
base[5][9] = 2;
}
else if(random >= 95 && random <= 99)
else if(random >= 95 && random <= 99)
{
base[3][10] = 2;
base[4][10] = 2;
base[4][10] = 3;
base[3][9] = 2;
base[4][9] = 2;
}
@ -196,7 +197,7 @@ void dropPiece()
{
if(flag == 1)
break;
if(base[i][j] == 2)
if(base[i][j] >= 2)
{
//若触底,做标记
if(flag == 0 && (base[i][j - 1] == 1 || j == 0))
@ -215,12 +216,12 @@ void dropPiece()
{
for(j = 0; j < MAX_Y; j++)
{
if(base[i][j] == 2)
if(base[i][j] >= 2)
{
//无标记则下落
if(flag == 0 && isIegal(i, j - 1))
{
base[i][j - 1] = 2;
base[i][j - 1] = base[i][j];
base[i][j] = 0;
}
//有标记则转换
@ -250,14 +251,13 @@ void moveLeftPiece()
}
for(i = 0; i < MAX_X; i++)
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;
}
}
void moveRightPiece()
{
char i, j;
if(blockGameStatus == over)
@ -270,9 +270,9 @@ void moveRightPiece()
}
for(i = MAX_X - 1; i >= 0; i--)
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;
}
}
@ -337,6 +337,7 @@ void blockGameOver()
}
}
//判定最高分
unsigned int addBest(unsigned int s)
{
int i, j;
@ -351,3 +352,83 @@ unsigned int addBest(unsigned int s)
}
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 readBest();
unsigned int addBest(unsigned int s);
unsigned int rotateBlock(enum OPR opr);
#endif

View file

@ -92,6 +92,10 @@ code unsigned char SUPER_NUM1[]={
code unsigned char IMG_BLOCK[]={
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[]={
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)
{
delayms(15);
delayms(9);
if(PIN_4 == 0)
{
opr = confirm;

View file

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