^_^一个小游戏,贪吃蛇,C语言实现 嘎嘎 在linux 环境下 编译通过

标签:
杂谈 |
http://s13/middle/4c3b26e1t9fc8c396c14c&690嘎嘎 在linux 环境下 编译通过" TITLE="^_^一个小游戏,贪吃蛇,C语言实现 嘎嘎 在linux 环境下 编译通过" />
//mysnake1.0.c
//编译命令:cc mysnake1.0.c -lcurses -o mysnake1.0
//用方向键控制蛇的方向
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <signal.h>
#include <sys/time.h>
#define NUM 60
struct direct
//用来表示方向的
{
int cx;
int cy;
};
typedef struct node
//链表的结点
{
int cx;
int cy;
struct node *back;
struct node *next;
}node;
void initGame();
//初始化游戏
int setTicker(int);
//设置计时器
void show();
//显示整个画面
void showInformation();
//显示游戏信息(前两行)
void showSnake();
//显示蛇的身体
void getOrder();
//从键盘中获取命令
void over(int i);
//完成游戏结束后的提示信息
void creatLink();
//(带头尾结点)双向链表以及它的操作
void insertNode(int x, int y);
void deleteNode();
void deleteLink();
int ch;
//输入的命令
int hour, minute, second;
//时分秒
int length, tTime, level;
//(蛇的)长度,计时器,(游戏)等级
struct direct dir, food;
//蛇的前进方向,食物的位置
node *head, *tail;
//链表的头尾结点
int main()
{
initscr();
initGame();
signal(SIGALRM, show);
getOrder();
endwin();
return 0;
}
void initGame()
{
cbreak();
//把终端的CBREAK模式打开
noecho();
//关闭回显
curs_set( 0);
//把光标置为不可见
keypad(stdscr, true);
//使用用户终端的键盘上的小键盘
srand(time( 0));
//设置随机数种子
//初始化各项数据
hour = minute = second = tTime
= 0;
length = 1;
dir.cx = 1;
dir.cy = 0;
ch
= 'A';
food.cx = rand() % COLS;
food.cy = rand() % (LINES-2)
+ 2;
creatLink();
setTicker( 20);
}
//设置计时器(这个函数是书本上的例子,有改动)
int setTicker(int n_msecs)
{
struct itimerval new_timeset;
long
n_sec, n_usecs;
n_sec
= n_msecs / 1000
;
n_usecs = ( n_msecs % 1000
) * 1000L
;
new_timeset.it_interval.tv_sec
= n_sec;
new_timeset.it_interval.tv_usec = n_usecs;
n_msecs = 1;
n_sec
= n_msecs / 1000
;
n_usecs = ( n_msecs % 1000
) * 1000L
;
new_timeset.it_value.tv_sec
= n_sec
;
new_timeset.it_value.tv_usec
= n_usecs
;
return setitimer(ITIMER_REAL, &new_timeset, NULL);
}
void showInformation()
{
tTime ++;
if(tTime >= 1000000)
//
tTime = 0;
if(1
!= tTime %
50)
return;
move( 0, 3);
//显示时间
printw( "time: %d:%d:%d %c", hour,
minute, second);
second ++;
if(second > NUM)
{
second = 0;
minute ++;
}
if(minute > NUM)
{
minute = 0;
hour ++;
}
//显示长度,等级
move( 1, 0);
int i;
for(i=0;i<COLS;i++)
addstr( "-");
move( 0, COLS/2-5);
printw( "length: %d",
length);
move( 0, COLS-10);
level
= length / 3
+ 1;
printw( "level: %d",
level);
}
//蛇的表示是用一个带头尾结点的双向链表来表示的,
//蛇的每一次前进,都是在链表的头部增加一个节点,在尾部删除一个节点
//如果蛇吃了一个食物,那就不用删除节点了
void showSnake()
{
if(1
!= tTime %
(30-level))
return;
//判断蛇的长度有没有改变
bool lenChange = false;
//显示食物
move(food.cy, food.cx);
printw( "@");
//如果蛇碰到墙,则游戏结束
if((COLS-1==head->next->cx &&
1==dir.cx)
|| (0==head->next->cx &&
-1==dir.cx)
|| (LINES-1==head->next->cy &&
1==dir.cy)
|| (2==head->next->cy &&
-1==dir.cy))
{
over( 1);
return;
}
//如果蛇头砬到自己的身体,则游戏结束
if('*'
== mvinch(head->next->cy+dir.cy,
head->next->cx+dir.cx)
)
{
over( 2);
return;
}
insertNode(head ->next->cx+dir.cx,
head->next->cy+dir.cy);
//蛇吃了一个“食物”
if(head->next->cx==food.cx &&
head->next->cy==food.cy)
{
lenChange = true;
length ++;
//恭喜你,通关了
if(length >= 50)
{
over( 3);
return;
}
//重新设置食物的位置
food.cx = rand() % COLS;
food.cy = rand() % (LINES-2)
+ 2;
}
if(!lenChange)
{
move(tail ->back->cy, tail->back->cx);
printw( " ");
deleteNode();
}
move(head ->next->cy, head->next->cx);
printw( "*");
}
void show()
{
signal(SIGALRM,
show);
//设置中断信号
showInformation();
showSnake();
refresh();
//刷新真实屏幕
}
void getOrder()
{
//建立一个死循环,来读取来自键盘的命令
while(1)
{
ch = getch();
if(KEY_LEFT == ch)
{
dir.cx = -1;
dir.cy = 0;
}
else if(KEY_UP == ch)
{
dir.cx = 0;
dir.cy = -1;
}
else if(KEY_RIGHT == ch)
{
dir.cx = 1;
dir.cy = 0;
}
else if(KEY_DOWN == ch)
{
dir.cx = 0;
dir.cy = 1;
}
setTicker( 20);
}
}
void over(int i)
{
//显示结束原因
move( 0, 0);
int j;
for(j=0;j<COLS;j++)
addstr( " ");
move( 0, 2);
if(1
== i)
addstr( "Crash the wall. Game over");
else if(2
== i)
addstr( "Crash itself. Game over");
else if(3
== i)
addstr( "Mission Complete");
setTicker( 0);
//关闭计时器
deleteLink();
//释放链表的空间
}
//创建一个双向链表
void creatLink()
{
node
*temp =
(node *)malloc( sizeof(node)
);
head
= (node *)malloc( sizeof(node)
);
tail
= (node *)malloc( sizeof(node)
);
temp ->cx =
5;
temp ->cy =
10;
head ->back =
tail->next =
NULL;
head ->next =
temp;
temp ->next =
tail;
tail ->back =
temp;
temp ->back =
head;
}
//在链表的头部(非头结点)插入一个结点
void insertNode(int x, int y)
{
node
*temp =
(node *)malloc( sizeof(node)
);
temp ->cx =
x;
temp ->cy =
y;
temp ->next =
head->next;
head ->next =
temp;
temp ->back =
head;
temp ->next->back =
temp;
}
//删除链表的(非尾结点的)最后一个结点
void deleteNode()
{
node
*temp =
tail->back;
node
*bTemp =
temp->back;
bTemp ->next =
tail;
tail ->back =
bTemp;
temp ->next =
temp->back =
NULL;
free(temp);
temp
= NULL;
}
//删除整个链表
void deleteLink()
{
while(head->next !=
tail)
deleteNode();
head ->next =
tail->back =
NULL;
free(head);
free(tail);
}
//mysnake1.0.c
//编译命令:cc mysnake1.0.c -lcurses -o mysnake1.0
//用方向键控制蛇的方向
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <signal.h>
#include <sys/time.h>
#define NUM 60
struct direct
{
};
typedef struct node
{
}node;
void initGame();
int setTicker(int);
void show();
void showInformation();
void showSnake();
void getOrder();
void over(int i);
void creatLink();
void insertNode(int x, int y);
void deleteLink();
int ch;
int hour, minute, second;
int length, tTime, level;
struct direct dir, food;
node *head, *tail;
int main()
{
}
void initGame()
{
}
//设置计时器(这个函数是书本上的例子,有改动)
int setTicker(int n_msecs)
{
}
void showInformation()
{
}
//蛇的表示是用一个带头尾结点的双向链表来表示的,
//蛇的每一次前进,都是在链表的头部增加一个节点,在尾部删除一个节点
//如果蛇吃了一个食物,那就不用删除节点了
void showSnake()
{
}
void show()
{
}
void getOrder()
{
}
{
}
//创建一个双向链表
void creatLink()
{
}
//在链表的头部(非头结点)插入一个结点
void insertNode(int x, int y)
{
}
//删除链表的(非尾结点的)最后一个结点
void deleteNode()
{
}
//删除整个链表
void deleteLink()
{
}