当前位置: 技术问答>linux和unix
我写的贪吃蛇,请大家多多支持
来源: 互联网 发布时间:2017-04-15
本文导语: //mysnake1.0.c //编译命令:cc mysnake1.0.c -lcurses -o mysnake1.0 //用方向键控制蛇的方向 #include #include #include #include #include #define NUM 60 struct direct //用来表示方向的 { int cx; int cy; }; typedef struct node //链表的结点 { int ...
//mysnake1.0.c
//编译命令:cc mysnake1.0.c -lcurses -o mysnake1.0
//用方向键控制蛇的方向
#include
#include
#include
#include
#include
#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; /* set reload */
new_timeset.it_interval.tv_usec = n_usecs; /* new ticker value */
n_msecs = 1;
n_sec = n_msecs / 1000 ;
n_usecs = ( n_msecs % 1000 ) * 1000L ;
new_timeset.it_value.tv_sec = n_sec ; /* store this */
new_timeset.it_value.tv_usec = n_usecs ; /* and this */
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;inext->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;jcx = 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);
}
学LINUX差不多一个月了,就写一个curses版的贪吃蛇来练习一下吧,同时谢谢CSDN上的朋友对我的帮助
这个程序不难,但也算是我的一个作品吧,呵呵
如果你觉得这个程序写得好,就支持一下,如果觉得不好,就提点改进意见吧。
我也是初学者,大家共同学习,共同进步,呵呵
说一下这个程序的不足之吧(自我感觉)
1:数据封装做得不好,大量使用全局变量,存在安全隐患。(以前用C++用得多了,用回C语言反而不习惯了)
2:这个游戏没有存档功能。(因为我不知该怎样实现)
3:蛇上下行走与左右行走的速度不同。
4:没有使用多线程,多线程技术我现在用得还不是很熟练,如果有机会做2.0版本的话,我会加上多线程机制的。
如果大家发现了这个程序的BUG的话,请和我说一声,我会尽力改正的,
也欢迎大家多提意见,还是那句话,大家共同学习,共同进步。
最后,祝大家国庆节快乐!!
|
撞墙之后 随便按个键 会出现一个段错误
|
支持,加精,支持开源的程序。
|
不错不错,虽然我看不懂C
|
不错不错,虽然我看不懂C
|
|
我改变终端大小,莫名挂了
写得不错
写得不错
|
恩 不错 感谢分享
|
恩 不错 感谢分享
|
顶了...不错不错哈
|
呵呵,不错,还可以短一点
|
楼主是我的榜样啊。
我接触Linux都两年多了,除了工作上的事外,还真没写过像样的程序。
向楼主致敬,向楼主学习!
我接触Linux都两年多了,除了工作上的事外,还真没写过像样的程序。
向楼主致敬,向楼主学习!
|
有个提议,将每次的行位移设置为2,就能保证上下/左右的移动速度一致了~~不过为保证游戏不出错还得改点参数:
首先,void getOrder()里的
if(KEY_LEFT == ch)
{
dir.cx = -1;
dir.cy = 0;
}
else if(KEY_RIGHE == ch)
{
dir.cx = 1;
dir.cy = 0;
}
改为:
if(KEY_LEFT == ch)
{
dir.cx = -2;
dir.cy = 0;
}
else if(KEY_RIGHE == ch)
{
dir.cx = 2;
dir.cy = 0;
}
然后,void intiGame()里
dir.cx = 1;
改为
dir.cx = 2;
food.cx = rand() % COLS;
改为:
food.cx = (rand() % COLS)/2*2;
void showSnake()里也有上面这一句,也要改;
void creatLink()里面的
temp->cx = 5;
改为:
temp->cx = 6;(偶数就行)
这样改完看起来上下左右速度就一样拉~~
一点个人想法,仅供参考~呵呵
首先,void getOrder()里的
if(KEY_LEFT == ch)
{
dir.cx = -1;
dir.cy = 0;
}
else if(KEY_RIGHE == ch)
{
dir.cx = 1;
dir.cy = 0;
}
改为:
if(KEY_LEFT == ch)
{
dir.cx = -2;
dir.cy = 0;
}
else if(KEY_RIGHE == ch)
{
dir.cx = 2;
dir.cy = 0;
}
然后,void intiGame()里
dir.cx = 1;
改为
dir.cx = 2;
food.cx = rand() % COLS;
改为:
food.cx = (rand() % COLS)/2*2;
void showSnake()里也有上面这一句,也要改;
void creatLink()里面的
temp->cx = 5;
改为:
temp->cx = 6;(偶数就行)
这样改完看起来上下左右速度就一样拉~~
一点个人想法,仅供参考~呵呵
|
在linux下用终端 sudo apt-get install libncurses5-dev
然后sudo aptitude install libqt3-headers libqt3-mt-dev libqt3-compat-headers libqt3-mt
通过 gcc mysnake1.0.c -lcurses -o mysnake1.0 编译就能运行拉~
|
嗨!我是刚进(CSDN)的一个新人。我也说一两句好了:去掉传统的形状,把蛇的形状和食物的形状做饿好看点,开头的是蛇头,第二就是蛇尾然后的都是蛇中间的蛇身。要真能这样就好了,既好玩又看。
我收传咯!学习学习。
我收传咯!学习学习。
|
呵呵~~不知楼主有没有写过内核代码,呵呵~~~学习,像贪吃蛇这样的程序,在windows下编过,感觉没味道,不够刺激,只是在应用层面上开发,不过也已经很了不起了。如果能看懂、会编写内核代码的话,建议楼主将改进后的贪吃蛇嵌入内核中,呵呵~~有趣有趣。。。。。
|
Unix环境高级编程在书店看到过的确很好 不过没用过Linux之类所以不知道和一般的编有什么区别
还有一本Unix环境网络编程也不错 不过这种书都是讲理论 就像看语言书一样 看完了也不一定编的出来
如果能编出来 可以说是有天赋 不知道比尔盖茨是怎么个学法 难道看些垃圾桶里的资料就会了? 天才就是不一样啊
还有一本Unix环境网络编程也不错 不过这种书都是讲理论 就像看语言书一样 看完了也不一定编的出来
如果能编出来 可以说是有天赋 不知道比尔盖茨是怎么个学法 难道看些垃圾桶里的资料就会了? 天才就是不一样啊
|
选中你的程序,按工具栏上面的 插入源代码->C/C++ 就行了
[/Quote]
哦 我试试
char *p=malloc(sizeof(char));
free(p);
free(p);
|
呵呵,贪吃蛇这个游戏我也写了一个。
自己感觉写的不是很好,看了你的和我的比较了一下,你的写的还是不错的啊!
有很多是值得我借鉴的,顶了 啊
自己感觉写的不是很好,看了你的和我的比较了一下,你的写的还是不错的啊!
有很多是值得我借鉴的,顶了 啊
|
开发游戏我略有经验,最好不要用多线程来开发游戏,效率是很低的。
再有,作为LINUX,我是新手,请问。
LINUX下绘图是用哪个库实现的呀
再有,作为LINUX,我是新手,请问。
LINUX下绘图是用哪个库实现的呀
|
呵呵,不错啊,努力!
我到现在还没单纯用C编写过
游戏呢,一般用MFC、Direcx比较多一点!
我到现在还没单纯用C编写过
游戏呢,一般用MFC、Direcx比较多一点!
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。