源代码的开发(以新浪SAE为例),小游戏编写规则
原创要编写一个小游戏,需要先将该游戏的规则写得清楚明白,要找到游戏进行的流程、奖励等。以一个小游戏——贪吃蛇为例。
规则
这个游戏很简单,通过玩家的操作来控制蛇移动的方向,使贪吃蛇迟到果实,并且不让蛇的身体碰到墙壁。
程序启动后,载入游戏并初始化,同时定时器启动。按下 4 个方向键中的任意一个后,蛇身开始运动,界面内随机出现果实。根据键盘控制蛇的移动。判断是否吃到果实,如果没吃到果实,就继续随键盘控制而移动;如果吃到一个果实,蛇身增加一节,随机生成下一个果实,并继续随键盘控制而移动。判断蛇头坐标和自身或者墙坐标是否重合,如果不重合,就继续随键盘控制而移动;如果重合,游戏结束。
编写游戏中需要注意的是:
(1)要实现贪吃蛇自动向前移动,根据时间间隔,每一次将贪吃蛇的每节身体分别向前移动一格。移动方向为贪吃蛇当前行走方向。
(2)要使玩家能够通过键盘的上下左右 4 个方向控制贪吃蛇当前行走方向,吃掉屏幕上出现的果实。
(3)在游戏中,果实的出现,采用随机方式。当前一个果实被吃掉时,屏幕上随机出现另一个果实,且果实不与蛇身重合。
编写代码
撰写游戏的相关规则后,就可以着手游戏代码了。“贪吃蛇”的构成可大致分为“蛇”“食物”“墙壁”3 个部分,因此首先就要将这 3 个要素编写出来。蛇身初始化编码,如下所示。
void init() {
initscr(); //屏幕控制初始化,如果成功,返回一个只想 stdscr 结构的指针
raw(); //关闭特殊字符的处理
noecho();//关闭输入字符的回显功能
keypad(stdscr,TRUE);
curs_set(0);
nodelay(stdscr,TRUE);
}
蛇身的初始化编码
“蛇”与“食物”,它们用结构体表示出来,如下所示。
struct Snack {
int x[100];
int y[100];
int node;
int life;
int direction;
} snack;
struct Food {
int X,Y;
int set;
} food;
结构体
接着打印出蛇身和食物,如下所示。这里的“打印”就是 C 语言中的 printf()函数,是一种最常用的格式化输出函数,其原型为: int printf(char * format,...) ;printf()会根据参数 format 字符串来转换并格式化数据,然后将结果输出到标准输出设备(显示器),直到出现字符串结束('\0')为止。
void draw() {
snack.x[0]=6;
snack.y[0]=3;
snack.x[1]=5;
snack.y[1]=3;
snack.x[2]=4;
snack.y[2]=3;
snack.life= 0;
snack.node= 3;
snack.direction= 4;
food.set=0;
color();
d_e();
for(i=0; i < snack.node; i ++)
mvprintw(snack.y [i],snack.x[i],"*");
refresh();
timer=time(NULL);
}
打印出蛇身和食物
mvprintw() 函数为 int myprintw(int y,int x,char * format,...)
然后在指定的位置打印(x,y)字符串 format。随机生成食物,如下所示。
if(food.set== 0){
food.X=rand() % 50;
while(food.X== 0 || food.X==49)
food.X=rand() % 50;
food.Y=rand() % 20;
while(food.Y== 0 || food.Y==19)
food.Y=rand() % 20;
food.set=1;
}
食物生成
打印四面墙的模板如下所示。其中 start_color()函数对 curses 的颜色例程进行初始化;init_pair()函数对准备使用的颜色组合进行初始化;attron()函数在不影响其他属性的前提下启用制定的属性。
void color() {
start_color();
init_pair(1,COLOR_ GREEN,COLOR _RED);
attron(COLOR _PAIR(1));
for(i=0; i < 50; i++)
mvaddch(0,i,'*');
for(i=0; i < 20; i++)
mvaddch(i, 0,'*');
for(i=49; i >=0; i--)
mvaddch(19,i,'*');
for(i=19; i >=0; i--)
mvaddch(i, 49,'*'); // box(stdscr,' *','*');
attroff(COLOR _PAIR(1));
}
打印四面墙
在贪吃蛇游戏中,蛇身的移动也是游戏的重要组成部分。只有蛇身能够移动转向,才能将游戏推动下去。在游戏中玩家能够控制蛇身的移动方向,所以编程中需要能够判断前进方向,这一项编码如下所示。
void judge() {
if(snack.direction== 1)//up
snack.y[0]--;
else if(snack.direction== 2)//down
snack.y[0]++;
else if(snack.direction== 3)//left
snack.x[0]--;
else //right
snack.x[0]++;
}
ch=getch();
switch(ch) {
case(KEY_UP):
if(snack.direction== 3 || snack.direction== 4){
判断前进方向
snack.y[0]--;
snack.direction= 1;
} else if(snack.direction== 1)
snack.y[0]--;
else
snack.y[0]++;
break;
case(KEY_DOWN):
if(snack.direction== 3 || snack.direction== 4){
snack.y[0]++;
snack.direction= 2;
} else if(snack.direction== 1)
snack.y[0]--;
else
snack.y[0]++;
break;
case(KEY_LEFT):
if(snack.direction== 1 || snack.direction== 2){
snack.x[0]--;
snack.direction= 3;
} else if(snack.direction== 3)
snack.x[0]--;
else
snack.x[0]++;
break;
case(KEY_RIGHT):
if(snack.direction== 1 || snack.direction== 2){
snack.x[0]++;
snack.direction= 4;
} else if(snack.direction== 3)
snack.x[0]--;
else
snack.x[0]++;
break;
判断前进方向(续)
当贪吃蛇吃到食物后,需要进行加分奖励,因此在编程中也需要注意判断蛇是否吃到食物,吃到食物的个数以及奖励分数等,如下所示。
if(snack.x [0] ==food.X && snack.y [0]==food.Y){
food.set=0;
snack.node ++;
score +=10;
for(i=snack.node - 1; i > 0; i--){
snack.x[i]=snack.x[i - 1];
snack.y[i]=snack.y[i - 1];
}
judge();
}
蛇吃到食物
游戏开始之后,蛇身碰到墙壁即游戏失败,因此也需要在代码中编写判断游戏结束的程序,如下所示。
if((snack.x [0]==snack.x[i] && snack.y [0]==snack.y[i])
|| snack.x[0]==0 || snack.y[0]==0 || snack.x[0]==49
|| snack.y[0]==19){
for(i=1; i < snack.node; i ++){
snack.x[i - 1]=snack.x[i];
snack.y[i - 1]=snack.y[i];
}
snack.y[ snack.node - 1]=tem[0];
snack.x[ snack.node - 1]=tem[1];
for(i=0; i < snack.node; i ++)
mvprintw(snack.y [i],snack.x[i],"*");
mvaddch(food.Y,food.X,' *');
start_attr();
mvprintw(10,10 ,"You lose!");
mvprintw(11,10 ,"Do you want again?(y /n)");
output();
snack.life= 1;
//sleep(1);
break;
}
游戏结束
贪吃蛇的完整程序如下所示。
#include<curses.h>
#include<stdlib.h>
#include<unistd.h>
#include<time.h>
struct Snack {
int x[100],y[100];
int node;
int life;
int direction;
} snack;
struct Food {
int X,Y;
int set;
} food;
struct timespec delay;
struct timespec dummy;
time_t timer;
int TIME=0;
long Time,Time 1=0,Time2=0;
int ptime[100];
int score= 0;
int i,tem[2],k=0;
void color();
void init();
void draw();
void start _attr();
void output();
void play();
void judge();
int pause_ time(int,int *);
void d_e();
int main(int argc,char **argv){
init();
draw();
完整程序
play();
return 0;
}
void d_e(){
int location= 18;
int ch2=KEY_ LEFT,which= 0;
char str[2][5]={ "Easy","Hard" };
while(ch2 !='\n')
switch(ch2){
case(KEY_LEFT):
if(location != 18){
location -= 10;
which=0;
}
break;
case(KEY_RIGHT):
if(location== 18){
location +=10;
which=1;
}
break;
}
mvprintw(8,10 ,"Please choose the difficulty!");
mvprintw(10,23,"^_^");
mvprintw(12,18,"Easy");
mvprintw(12,28,"Hard");
attron(A_REVERSE);
mvprintw(12 ,location," %s",str[which]);
attroff(A_REVERSE);
refresh();
ch2=getch();
}
/*Time2 =time(NULL);
ptime[k]=Time2-Time1;
k++; */
if(location== 28)
完整程序(续)
delay.tv_nsec=100000000;
else
delay.tv_nsec=200000000;
}
int pause_ time(int k,int *PTIME){
int j;
int sum=0;
for(j=0; j < k; j++)
sum=sum + ptime[j];
return sum;
}
void judge() {
if(snack.direction== 1)
snack.y[0]--;
else if(snack.direction== 2)
snack.y[0]++;
else if(snack.direction== 3)
snack.x[0]--;
else
snack.x[0]++;
}
void color() {
start_color();
init_pair(1,COLOR_ GREEN,COLOR _RED);
attron(COLOR _PAIR(1));
for(i=0; i < 50; i++)
mvaddch(0,i,'*');
for(i=0; i < 20; i++)
mvaddch(i, 0,'*');
for(i=49; i >=0; i--)
mvaddch(19,i,'*');
for(i=19; i >=0; i--)
mvaddch(i, 49,'*'); // box(stdscr,' *','*');
attroff(COLOR _PAIR(1));
}
完整程序(续)
void init() {
initscr();
raw();
noecho();
keypad(stdscr,TRUE);
curs_set(0);
nodelay(stdscr,TRUE);
}
void draw() {
snack.x[0]=6;
snack.y[0]=3;
snack.x[1]=5;
snack.y[1]=3;
snack.x[2]=4;
snack.y[2]=3;
snack.life= 0;
snack.node= 3;
snack.direction= 4;
food.set=0;
color();
d_e();
for(i=0; i < snack.node; i ++)
mvprintw(snack.y [i],snack.x[i],"*");
refresh();
timer=time(NULL);
}
void output() {
color();
mvprintw(20,0,"Score=% d",score);
mvprintw(20,43,"Node=% d",snack.node);
mvprintw(21,0,"Time=% ds",TIME);
attroff(A_REVERSE);
refresh();
}
void start _attr(){
attron(A_REVERSE);
}
完整程序(续)
void play() {
while(1){
Time=time(NULL);
TIME=Time - timer - pause _ time(k,ptime);
clear();
if(food.set== 0){
food.X=rand() % 50;
while(food.X== 0 || food.X==49)
food.X=rand() % 50;
food.Y=rand() % 20;
while(food.Y== 0 || food.Y==19)
food.Y=rand() % 20;
food.set=1;
}
tem[0]=snack.y[ snack.node - 1];
tem[1]=snack.x[ snack.node - 1];
for(i=snack.node - 1; i > 0; i--){
snack.x[i]=snack.x[i - 1];
snack.y[i]=snack.y[i - 1];
}
int ch=0;
ch=getch();
switch(ch) {
case(KEY_UP):
if(snack.direction== 3 || snack.direction== 4){
snack.y[0]--;
snack.direction= 1;
} else if(snack.direction== 1)
snack.y[0]--;
else
snack.y[0]++;
break;
case(KEY_DOWN):
if(snack.direction== 3 || snack.direction== 4){
snack.y[0]++;
snack.direction= 2;
} else if(snack.direction== 1)
完整程序(续)
snack.y[0]--;
else
snack.y[0]++;
break;
case(KEY_LEFT):
if(snack.direction== 1 || snack.direction== 2){
snack.x[0]--;
snack.direction= 3;
} else if(snack.direction== 3)
snack.x[0]--;
else
snack.x[0]++;
break;
case(KEY_RIGHT):
if(snack.direction== 1 || snack.direction== 2){
snack.x[0]++;
snack.direction= 4;
} else if(snack.direction== 3)
snack.x[0]--;
else
snack.x[0]++;
break;
case 'p':
case 'P':
Time1 =time(NULL);
judge();
for(i=0; i < snack.node; i ++)
mvprintw(snack.y [i],snack.x[i],"*");
mvaddch(food.Y,food.X,' *');
start_attr();
mvprintw(9,10 ,"Pause!Press 'p' to continue!");
output();
while(getch()!='p')
;
Time2 =time(NULL);
ptime[k]=Time2 - Time1;
k++;
完整程序(续)
break;
case 'q':
case 'Q':
Time1 =time(NULL);
judge();
for(i=0; i < snack.node; i ++)
mvprintw(snack.y [i],snack.x[i],"*");
mvaddch(food.Y,food.X,' *');
start_attr();
mvprintw(10,22 ,"Quit!");
output();
int location= 18;
int ch2=KEY_ LEFT,which= 0;
char str[2][5]={ "No","Yes" };
while(ch2 !=‘\n’){
switch(ch2){
case(KEY_LEFT):
if(location != 18){
location -= 10;
which=0;
}
break;
case(KEY_RIGHT):
if(location== 18){
location +=10;
which=1;
}
break;
}
mvprintw(12,18,"No");
mvprintw(12,28,"Yes");
attron(A_REVERSE);
mvprintw(12 ,location," %s",str[which]);
attroff(A_REVERSE);
refresh();
ch2=getch();
完整程序(续)
}
Time2 =time(NULL);
ptime[k]=Time2 - Time1;k++;
if(location== 18)
break;
else {
clear();
endwin();
exit(1);
}
default:
judge();
break;
}
for(i=1; i < snack.node; i ++)
if((snack.x [0]==snack.x[i] && snack.y [0]==snack.y[i])
|| snack.x[0]==0 || snack.y[0]==0 || snack.x[0]==49
|| snack.y[0]==19){
for(i=1; i < snack.node; i ++){
snack.x[i - 1]=snack.x[i];
snack.y[i - 1]=snack.y[i];
}
snack.y[ snack.node - 1]=tem[0];
snack.x[ snack.node - 1]=tem[1];
for(i=0; i < snack.node; i ++)
mvprintw(snack.y [i],snack.x[i],"*");
mvaddch(food.Y,food.X,' *');
start_attr();
mvprintw(10,10 ,"You lose!");
mvprintw(11,10 ,"Do you want again?(y /n)");
output();
snack.life= 1;
//sleep(1);
break;
}
if(snack.x [0] ==food.X && snack.y [0]==food.Y){
food.set=0;
完整程序(续)
snack.node ++;
score +=10;
for(i=snack.node - 1; i > 0; i--){
snack.x[i]=snack.x[i - 1];
snack.y[i]=snack.y[i - 1];
}
judge();
}
if(snack.life== 0){
;
for(i=0; i < snack.node; i ++)
mvprintw(snack.y [i],snack.x[i],"*");
//attron(A_INVIS);
mvaddch(food.Y,food.X,' *');
//sleep(1);
//attroff(A_INVIS);
start_attr();
output();
nanosleep(&delay,&dummy); //sleep(2);
}
else {
char ch1;
while(ch1=getch())
if(ch1=='y' || ch1=='Y'){
clear();
for(i=0; i < snack.node; i ++)
snack.x[i]=snack.y[i]=-1;
TIME=Time1=Time2=k=0;
score=0;
draw();
snack.life= 0;
break;
} else if(ch 1=='n' || ch1=='N'){
完整程序(续)
endwin();
exit(1);
} else
continue;
}
}
}
完整程序(续)
版权保护: 本文由 李斯特 原创,转载请保留链接: https://www.wechatadd.com/artdet/8399
- 上一篇:源代码的开发(以新浪SAE为例),位置与天气编写
- 下一篇:微信与微信公众号
阅读推荐
更多...- 以小博大公众号大号投放广告攻略 2023-05-31
- 公众号发文章编辑排版全指南?(公众号怎样排版) 2021-05-21
- 公众号的设计、开通与使用技巧,“推广”区功能使用详解 2023-05-30
- 快速引流、聚集粉丝的9大技巧,视频引流法 2023-05-30
- 注册微信公众号,资料的准备 2023-05-31
- 寻找潜在客户与吸引粉丝,微信圈吸引粉丝的秘诀 2023-05-29
- 让粉丝忍不住去点击的公众号大标题,共鸣话题:天津上班族那些事,赶紧对号入座 2023-05-29
- 普通人可以运营公众号吗?怎样把公众号做大做强? 2021-10-19
- 「公众号运营秘籍」萌萌风格:萌萌哒、亲哦等网络新词 2023-05-28
- 微信公众号配色应该注意些什么问题? 2023-05-27
- 「大V」也在用的微信公众号小秘诀,如何让上传的PNG透明底图片不显示为白底 2023-05-27
- 公众号内容 2023-05-30
- 让公众号名字与众不同 2023-05-31
- 微信公众平台申请与策划,微信公众账号的认证 2023-05-29
- 电视台微信公众号的运维策略 2023-05-31
- 各行各业的微信公众号营销实战案例,餐饮业 2023-05-31
- 「公众号运营」如何通过软文植入盈利,后大哥靠一篇软文年入500万案例解析 2023-05-29
- 九个方面,打造公众号精美版式 2022-07-06