C語言實現(xiàn)俄羅斯方塊小游戲
更新時間:2020年04月01日 14:04:37 作者:半片瓜
這篇文章主要為大家詳細介紹了Linux下C語言實現(xiàn)俄羅斯方塊小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
C語言實現(xiàn)俄羅斯方塊小游戲的制作代碼,具體內(nèi)容如下
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define TTY_PATH "/dev/tty"
#define STTY_ON "stty raw -echo -F"
#define STTY_OFF "stty -raw echo -F"
int map[21][14];
char direct;
int node[7][4][16]={
{{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},//長方形
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},
{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}},
{{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},//正方形
{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
{1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0}},
{{0,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0},//3邊加一中點
{0,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0},
{0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0},
{0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}},
{{0,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0},//右鋤頭型
{0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,0},
{0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0},
{1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}},
{{1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0},//左鋤頭型
{0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0},
{0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0}},
{{0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0},//右曲折型
{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0},
{0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0}},
{{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},//左曲折型
{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0},
{0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0},
{1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}}
};
typedef struct block
{
int x;
int y;
int blockType;
int blockDirect;
}Block;
Block bl;
void init_map()//初始化邊框
{
int i,j;
for(i=0; i<21; i++)
for(j=0; j<14; j++)
{
if(j==0 || j==13)
map[i][j] = 200;
else if(i==20)
map[i][j] = 201;
else
map[i][j] = 0;
}
}
void new_block()//生成隨機的俄羅斯方塊
{
int blockType = rand()%7;
int blockDirect = rand()%4;
int x = 1;
int y = 5;
bl.x = x;
bl.y = y;
bl.blockType = blockType;
bl.blockDirect = blockDirect;
}
void input()//將移動后的俄羅斯方塊,導(dǎo)入地圖中作標記
{
int i, j;
for(i=0; i<4; i++)
for(j=0; j<4; j++)
if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
{
map[bl.x+i][bl.y+j] = 1;
}
}
void output()//移動時,將之前俄羅斯方塊在地圖信息清空。
{
int i, j;
for(i=0; i<4; i++)
for(j=0; j<4; j++)
if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
{
map[bl.x+i][bl.y+j] = 0;
}
}
void change()//俄羅斯方格在碰撞后融入,固定
{
int i, j;
for(i=0; i<4; i++)
for(j=0; j<4; j++)
if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
{
map[bl.x+i][bl.y+j] = 10;
}
for(j=1; j<13; j++)
if(map[5][j] == 10)
{
system("clear");
printf("game over !!!!!!!!!\n");
exit(1);
}
}
void print_map()//打印地圖,顯示信息
{
int i,j;
for(i=5; i<21; i++)
{
for(j=0; j<14; j++)
{
if(map[i][j]==200)//左右邊界
printf("#");
else if(map[i][j]==201)//下邊界
printf(" # ");
else if(map[i][j]==0)//空白地
printf(" ");
else if(map[i][j]==1)//移動的俄羅斯方塊
printf(" * ");
else if(map[i][j]==10)//固定的俄羅斯方塊
printf(" @ ");
}
printf("\n");
}
}
void delLine(int n)//消行
{
int i,j;
for(j = 1; j<13; j++)
map[n][j] = 0;
for(i = n; i>5 ; i--)
for(j = 1; j<13; j++)
if(map[i-1][j] != 1)
map[i][j] = map[i-1][j];
}
void isFillLine()//是否滿足消行條件
{
int i,j;
int fals;
for(i=19; i>5; i--)
{
fals = 1;
for(j=1; j<13; j++)
{
if(map[i][j] != 10)
{
fals = 0;
continue;
}
}
if(fals)
{
delLine(i);
}
}
}
void down()//下移
{
int i, j;
int fale = 1;
for(i=3; i>=0; i--)
for(j=0; j<4; j++)
if(node[bl.blockType][bl.blockDirect][i*4+j] == 1)
if(map[bl.x+i+1][bl.y+j] == 10 || map[bl.x+i+1][bl.y+j] == 201)
{
change();
fale = 0;
new_block();
isFillLine();
return;
}
if(fale)
{
output();
bl.x += 1;
input();
}
}
void right()//右移
{
int i, j;
int fale = 1;
for(i=3; i>=0; i--)
for(j=0; j<4; j++)
if(node[bl.blockType][bl.blockDirect][i*4+j] == 1)
if(map[bl.x+i][bl.y+j+1] == 10 || map[bl.x+i][bl.y+j+1] == 200)
{
fale = 0;
return;
}
if(fale)
{
output();
bl.y += 1;
input();
}
}
void left()//左移
{
int i, j;
int fale = 1;
for(i=3; i>=0; i--)
for(j=0; j<4; j++)
if(node[bl.blockType][bl.blockDirect][i*4+j] == 1)
if(map[bl.x+i][bl.y+j-1] == 10 || map[bl.x+i][bl.y+j-1] == 200)
{
fale = 0;
return;
}
if(fale)
{
output();
bl.y -= 1;
input();
}
}
void change_block()//俄羅斯方塊變形
{
int i,j;
output();
int fals = 1;
bl.blockDirect += 1;
bl.blockDirect %= 4;
for(i=0; i<4; i++)
for(j=0; j<4; j++)
if(node[bl.blockType][bl.blockDirect][i*4+j]==1)
if(map[bl.x+i][bl.y+j] != 0 )
{
fals = 0;
break;
}
if(fals)
{
input();
}else
{
bl.blockDirect -= 1;
input();
}
}
char in_direct()//非堵塞輸入
{
fd_set fd;
struct timeval tv;
char ch;
FD_ZERO(&fd);
FD_SET(0, &fd);
tv.tv_sec = 0;
tv.tv_usec = 10;
if(select(1, &fd ,NULL, NULL, &tv) > 0)
{
ch = getchar();
}
return ch;
}
int main()//q 退出游戲,a,d 左右移動,空格變形
{
srand(time(NULL));
init_map();
new_block();
input();
char ch;
int num = 0;
while(1)
{
usleep(500000);
system(STTY_ON TTY_PATH);
ch = in_direct();
system(STTY_OFF TTY_PATH);
system("clear");
if(ch == 'a' && num <= 1)
{
left();
print_map();
num++;
continue;
}else if(ch == 'd' && num <= 1)
{
right();
print_map();
num++;
continue;
}else if(ch == ' ' && num <= 1 )
{
change_block();
print_map();
num++;
continue;
}else if(ch == 'q')
{
system("clear");
printf("gave over!!!!!\n");
exit(0);
}
down();
print_map();
num = 0;
}
return 0;
}
更多俄羅斯方塊精彩文章請點擊專題:俄羅斯方塊游戲集合 進行學(xué)習(xí)。
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
計時器的time_t和clock_t 的兩種實現(xiàn)方法(推薦)
下面小編就為大家?guī)硪黄嫊r器的time_t和clock_t 的兩種實現(xiàn)方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10
GCC 編譯使用動態(tài)鏈接庫和靜態(tài)鏈接庫的方法
根據(jù)鏈接時期的不同,庫又有靜態(tài)庫和動態(tài)庫之分,有別于靜態(tài)庫,動態(tài)庫的鏈接是在程序執(zhí)行的時候被鏈接的2013-03-03
C++結(jié)構(gòu)體字節(jié)對齊和共用體大小
這篇文章主要介紹了C++結(jié)構(gòu)體字節(jié)對齊和共用體大小,結(jié)構(gòu)體內(nèi)存對齊在筆試和面試中經(jīng)常被問到,所以這篇文章做個總結(jié),首先通過代碼驗證不同結(jié)構(gòu)體的內(nèi)存大小,需要的朋友可以參考下2021-11-11
C語言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10
在matlab中實現(xiàn)for循環(huán)的方法
for循環(huán)用來循環(huán)處理數(shù)據(jù),break用于終止離它最近的一層for循環(huán),continue用于跳過離它最近的一層for循環(huán),接著執(zhí)行下一次循環(huán),本文重點給大家介紹在matlab中實現(xiàn)for循環(huán)的方法,感興趣的朋友一起看看吧2021-11-11

