基本思路
在Linux系统下利用Ncurses字符终端处理库,创建游戏的终端页面
通过pthread库函数创建多线程任务,供游戏中食物和蛇的不断更新
Ncurses
Ncurses 提供字符终端处理库,包括面板和菜单
为了能够使用ncurses库,必须在源程序中将<curses.h> 包括进来,而且在编译的需要与它连接起来(
链库-lcurses
)
pthread
在Linux下创建线程的API为pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
函数参数:
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。
PS:
使用这个函数在编译的时候也要
链库-lpthread
代码实现
#include<curses.h>
#include<pthread.h>
#include<stdlib.h>
//定义按键
#define UP 1
#define DOWN -1
#define LEFT 2
#define RIGHT -2
int key;
int dir;
//初始化ncurses字符终端
void initNcurse()
{
initscr();
keypad(stdscr,1);//获取系统功能键(上下左右),1代表允许
noecho();
}
struct snake
{
int hang;
int lie;
struct snake *next;
};
struct snake *head=NULL;
struct snake *tail=NULL;
struct snake food;
//初始化食物
void initFood()
{
int x = rand()%20;//rand产生一个随机数
int y = rand()%20;
food.hang=x;
food.lie=y;
}
//吃到食物
int hasFood(int hang,int lie)
{
if(food.hang==hang && food.lie==lie){
return 1;
}
return 0;
}
//吃到自己
int hasSnakeNode(int hang,int lie)
{
struct snake *p=head;
while(p !=NULL){
if(p->hang==hang && p->lie==lie){
return 1;
}
p=p->next;
}
return 0;
}
void addNode()
{
struct snake *new = (struct snake *)malloc(sizeof(struct snake));
switch(dir){
case UP:
new->hang=tail->hang-1;
new->lie=tail->lie;
break;
case DOWN:
new->hang=tail->hang+1;
new->lie=tail->lie;
break;
case LEFT:
new->hang=tail->hang;
new->lie=tail->lie-1;
break;
case RIGHT:
new->hang=tail->hang;
new->lie=tail->lie+1;
break;
}
new->next=NULL;
tail->next=new;
tail=new;
}
//初始化蛇
void initSnake()
{
dir=RIGHT; //默认初始方向向右
struct snake *p;
while(head != NULL ){
p=head;
head =head->next;
free(p);
}
initFood();
head = (struct snake *)malloc(sizeof(struct snake)) ;
head->hang=1;
head->lie=2;
head->next=NULL;
tail= (struct snake *)malloc(sizeof(struct snake));
tail=head;
addNode();
addNode();
addNode();
}
//构建地图
void gamePic()
{
int hang;
int lie;
move(0,0);
for(hang=0;hang<20;hang++){
if(hang==0){
for(lie=0;lie<20;lie++){
printw("--");
}
printw("\n");
}
if(hang>=0 && hang<=19) {
for(lie=0;lie<=20;lie++){
if(lie==0 || lie==20){
printw("|");
}else if(hasSnakeNode(hang,lie)){
printw("[]");
}
else if(hasFood(hang,lie)){
printw("##");
}else{
printw(" ");
}
}
printw("\n");
}
if(hang==19){
for(lie =0;lie<=20;lie++) {
printw("--");
}
printw("\n");
printw("by g n a hang: %d,lie: %d\n",food.hang,food.lie);
}
}
}
void deleNode(){
struct snake *p = head;
head = head->next;
free(p);
}
void moveSnake(){
addNode();
if(hasFood(tail->hang,tail->lie)){
initFood();
}else{
deleNode();
}
//撞墙嗝屁
if(tail->hang<0 || tail->hang==20 || tail->lie==0 || tail->lie==20){
initSnake();
}
}
//刷新界面
void *refreshJiemian(){
while(1){
moveSnake();
gamePic();
refresh();
usleep(200000);//单位为微秒
}
}
void turn(int direction){
if(abs(dir) != abs(direction)){
dir = direction;
}
}
void *changeDir(){
while(1){
key = getch();
switch(key){
case KEY_UP:
turn(UP);
break;
case KEY_DOWN:
turn(DOWN);
break;
case KEY_LEFT:
turn(LEFT);
break;
case KEY_RIGHT:
turn(RIGHT);
break;
}
}
}
int main(){
pthread_t t1;
pthread_t t2;
initNcurse();//初始化终端
initSnake();//初始化蛇
gamePic();//构建界面地图
pthread_create(&t1,NULL,refreshJiemian,NULL);
pthread_create(&t2,NULL,changeDir,NULL);
while(1);
getch();//getch替换getc或者getchar.
endwin();//释放ncurses使用的所有内存
return 0;
}
游戏运行界面:
PS:游戏能跑起来,但是还存在许多bug
版权声明:本文为m0_53267045原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。