欢迎光临
我们一直在努力

0基础学习linux——俄罗斯方块小游戏

1.项目形式:提交项目代码以及运行结果

2.项目流程:

1.分析需求文档

2.概要设计文档

3.流程图

4.代码

5.调试

6.测评

3.项目需求

1.基于C语言在Linux系统终端下能够实现俄罗斯方块游戏

2.运行程序后,界面分为三个区域:

        1.区域1:游戏区

        2.区域2:下一个出现的俄罗斯方块

        3.区域3:游戏说明和计分系统

3.间隔1秒,俄罗斯方块下落,一行放满后实现消行处理。

4.允许用户通过左移(a键),右移(d键),变形(w键),完成对俄罗斯方块的操作。

5.功能可自行增加

4.涉及技术

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>
#include<termios.h>
#define HANG20
#define LIE60
#define SUB_LINE 40

unsigned char next_els[4][8];
unsigned char bg[HANG][LIE];
unsigned char els[4][8];
int cury = 2;
int curx = (LIE-SUB_LINE)/2;
int score = 0;
struct termios old_termios;
typedef enum{
SHAPE_O = 0,//正方形
SHAPE_I = 1,//长条
SHAPE_L = 2,//L型
SHAPE_J = 3, // 反L型
SHAPE_Z = 4, // Z型
SHAPE_S = 5, // 反Z型
SHAPE_T = 6, // T型
} ShapeType;
void CleanNextBox()
{
int i = 0, j = 0;
int next_y = 3;
int next_x = 36;

// 清空固定的4×8显示区域
for (j = 0; j < 4; j++)
{
for (i = 0; i < 8; i++)
{
bg[next_y + j][next_x + i] = ' ';
}
}
return ;
}
void GameInfo(void)
{
//int ret = 0;
//ret = ClearFullLine();
printf("\\033[6;35H%s","The next figure\\n");
printf("\\033[14;35H%s","Score:\\n");
//printf("\\033[16;35H%d",ret);
printf("\\033[14;35HScore: %d\\n", score);
printf("\\033[18;36H%s", "Instructions for game\\n");
printf("\\033[19;36H%s","a -> move to thr left\\n");
printf("\\033[20;36H%s","d -> move to thr right\\n");
printf("\\033[21;36H%s","w -> shape to another\\n");
}
void DrawNextBox()
{
int i = 0;
int j = 0;
int next_y =3;
int next_x = 36;
CleanNextBox();
for(j = 0;j<4;j++)
{
for (i = 0;i<8;i++)
{
if ('[' == next_els[j][i] || ']' == next_els[j][i])
{
bg[next_y + j][next_x + i] = next_els[j][i];
}
}
}

}
void MoveBox(int y, int x)
{
int i = 0;
int j = 0;

for (j = 0; j < 4; j++)
{
for (i = 0; i < 8; i++)
{
if ('[' == els[j][i] || ']' == els[j][i])
{
if(x+i >= 2 && x+i <= SUB_LINE-2)
{

bg[y+j][x+i] = els[j][i];
}
}
}
}
return ;
}
int CheckMove(int y, int x) {
int i = 0, j = 0;
for (j = 0; j < 4; j++) {
for (i = 0; i < 8; i++) {
if ('[' == els[j][i] || ']' == els[j][i]) {
if (x+i < 2 || x+i >=(LIE- SUB_LINE) || y+j >= HANG-1||y+j<1)

{
return 0;
}

if (bg[y+j][x+i] == '[' || bg[y+j][x+i] == ']')
{

return 0;
}
}
}
}
return 1; // 1表示可以移动/绘制
}

void cleanbox(int y,int x)
{
int i = 0;
int j = 0;

for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{
if('[' == els[j][i] || ']' == els[j][i])
{
bg[y+j][x+i] = ' ';
}
}
}
return;
}
void CreateNextBox()
{
int i = 0, j = 0;
memset(next_els,' ',sizeof(next_els));

switch (rand()%7)
{
case 0://方块
next_els[0][0] = '['; next_els[0][1] = ']';
next_els[0][2] = '['; next_els[0][3] = ']';
next_els[1][0] = '['; next_els[1][1] = ']';
next_els[1][2] = '['; next_els[1][3] = ']';
break;
case 1://I
next_els[0][0] = '['; next_els[0][1] = ']';
next_els[1][0] = '['; next_els[1][1] = ']';
next_els[2][0] = '['; next_els[2][1] = ']';
next_els[3][0] = '['; next_els[3][1] = ']';
break;
case 2://L
next_els[0][0] = '['; next_els[0][1] = ']';
next_els[1][0] = '['; next_els[1][1] = ']';
next_els[2][0] = '['; next_els[2][1] = ']';
next_els[2][2] = '['; next_els[2][3] = ']';
break;
case 3://反L型
next_els[0][2] = '['; next_els[0][3] = ']';
next_els[1][2] = '['; next_els[1][3] = ']';
next_els[2][0] = '['; next_els[2][1] = ']';
next_els[2][2] = '['; next_els[2][3] = ']';
break;
case 4://Z型
next_els[0][0] = '['; next_els[0][1] = ']';
next_els[0][2] = '['; next_els[0][3] = ']';
next_els[1][2] = '['; next_els[1][3] = ']';
next_els[1][4] = '['; next_els[1][5] = ']';
break;
case 5://反Z型
next_els[0][2] = '['; next_els[0][3] = ']';
next_els[0][4] = '['; next_els[0][5] = ']';
next_els[1][0] = '['; next_els[1][1] = ']';
next_els[1][2] = '['; next_els[1][3] = ']';
break;
case 6://T型
next_els[0][0] = '['; next_els[0][1] = ']';
next_els[1][0] = '['; next_els[1][1] = ']';
next_els[1][2] = '['; next_els[1][3] = ']';
next_els[2][0] = '['; next_els[2][1] = ']';
break;
}
}

void CreateElsBox(void)
{
int i = 0, j = 0;
memset(els,' ',sizeof(els));
//memset(els,' ',sizeof(els));
memcpy(els, next_els, sizeof(els));
CreateNextBox(); // 生成新的下一个方块
DrawNextBox(); // 绘制新的下一个方块
return;
}

void fanzhuanbox()
{
unsigned char temp[4][8];
memset(temp, ' ', sizeof(temp));

// 1. 简单的 90 度旋转矩阵变换
// 对于 4×4 的块状逻辑(8列是因为[ ]占两个位置)
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
// 每一个块由 els[j][i*2] 和 els[j][i*2+1] 组成
temp[i][(3 – j) * 2] = els[j][i * 2];
temp[i][(3 – j) * 2 + 1] = els[j][i * 2 + 1];
}
}

// 2. 检查旋转后是否合法
// 先暂存原形状
unsigned char backup[4][8];
memcpy(backup, els, sizeof(els));

// 尝试应用新形状
memcpy(els, temp, sizeof(els));

if (!CheckMove(cury, curx)) {
memcpy(els, backup, sizeof(els));{
}
}
return;
}
int ClearFullLine()
{
int i = 0;
int j = 0;
int k = 0;
for(j = HANG-2;j>0;j–)
{
int is_full = 1;
for(i = 2;i<=(LIE-SUB_LINE)-2;i++)
{
//if('[' != bg[j][i] && ']' != bg[j][i])
if(bg[j][i] == ' ')
{
is_full = 0;
break;
}

}
if(is_full)
{
score += 100;
printf("score = %d",score);
for(k = j; k>=1 ;k–)
{
for(i = 2;i<(LIE-SUB_LINE)-2;i++)
{
memset(bg[1],' ',LIE);
bg[k][i]=bg[k-1][i];
}
}
//memset(bg[1],' ',LIE);
bg[1][0] = '*'; bg[1][1] = '*';
bg[1][LIE-2] = '*'; bg[1][LIE-1] = '*';
bg[1][LIE-SUB_LINE] = '*'; bg[1][LIE-SUB_LINE+1] = '*';
j++;
}
}
return score;
}

void FrameInit(void)
{
int i = 0;
int j = 0;

memset(bg, ' ', sizeof(bg));

for (j = 0; j < HANG; j++)
{
bg[j][0] = '*';
bg[j][1] = '*';
bg[j][LIE-2] = '*';
bg[j][LIE-1] = '*';
bg[j][LIE-SUB_LINE] = '*'; //第LIE-30列有一道分割线
bg[j][LIE-SUB_LINE+1] = '*';
}

for (i = 0; i < LIE; i++)
{
bg[0][i] = bg[HANG-1][i] = '*';
for(j = LIE-SUB_LINE;j < LIE;j++)
{
bg[7][j] = bg[12][j] = '*'; //第10行有一道,第20行有一道
}
}
return;
}
void MenuShow(void)
{
int j = 0;
int i = 0;

printf("\\033[2J");
printf("\\033[5;0H");
for (j = 0; j < HANG; j++)
{
for (i = 0; i < LIE; i++)
{
if ('*' == bg[j][i])
{
printf("\\033[37m\\033[47m%c\\033[0m", bg[j][i]);
}
else if('[' == bg[j][i] || ']' == bg[j][i])
{
printf("\\033[36m\\033[46m%c\\033[0m",bg[j][i]);
}
else
{
printf("%c", bg[j][i]);
}
}
printf("\\n");
}
GameInfo();

return;
}
void handler(int signo)
{
cleanbox(cury,curx);
if (CheckMove(cury+1,curx))
{
cury++;
MoveBox(cury, curx);
}
else
{
MoveBox(cury, curx);
ClearFullLine();
CreateElsBox();
cury = 1;
curx = (LIE-SUB_LINE)/2;
if (!CheckMove(cury, curx))
{
//printf("\\033[0;0H");
//printf("\\033[37m\\033[44m===游戏结束===\\033[0m\\n");
//sleep(5);
printf("\\033[%d;%dH游戏结束!",HANG/2,LIE/3-5);
printf("\\033[%d;%dH最终分数:%d\\033[0m\\n",HANG/2+1,LIE/3-5,score);
printf("\\033[32;0H");
printf("\\n");
fflush(stdout);
sleep(3);
exit(0);
}
/* for(int i = 2;i <= SUB_LINE-2;i++)
{
if(bg[2][i] == '[' || bg[2][i] == ']')
{
printf("\\033[%d;%dH游戏结束!\\n",HANG/2,LIE/3-3);
}
}*/
}
MenuShow();

//ualarm(100000,100000);
alarm(1);
return;
}

int main(void)
{

//注册SIGALRM对应的处理事件为handler函数
signal(SIGALRM, handler);

//ualarm(100000,100000);
alarm(1);
FrameInit();
CreateNextBox();
CreateElsBox();

MenuShow();

//MoveBox(3,40);
//MenuShow();

while (1)
{
char c = getchar();
if(c == 'a')
{
cleanbox(cury,curx);
if(CheckMove(cury,curx – 2))
{
cleanbox(cury,curx);
curx -= 2;
MoveBox(cury,curx);
MenuShow();
}
}
else if(c == 'd')
{
cleanbox(cury,curx);
if(CheckMove(cury,curx + 2))
{
MoveBox(cury,curx+2);
curx += 2;
MenuShow();
}
else
{
MoveBox(cury,curx);
}
}
else if(c == 'w')
{
cleanbox(cury,curx);
fanzhuanbox();
MoveBox(cury,curx);
MenuShow();
}
}
return 0;
}

赞(0)
未经允许不得转载:171主机测评 » 0基础学习linux——俄罗斯方块小游戏
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址