|
本帖最后由 捞屎人 于 2014-12-3 20:27 编辑
NXT小游戏之贪吃蛇
把nxt当成编译器了,做几个小游戏纯当软件练手
算法网上找的,由于robotc不是纯C,数组操作容易越界溢出,所以部分代码需要加工,键盘操作采用多任务完成,也是我第一次在robotc上尝试使用使用多任务,才坏了一个NXT很心疼呢,就不损耗我仅剩的NXT了,凑合着看看PC虚拟的效果图吧……
下面是robot代码,屏幕还有部分剩余是用来显示积分及关卡等信息,太晚了没劲做了
/********游戏结束有2种可能********/
/*************一碰墙*************/
/******二自杀即蛇头碰到蛇身******/
#define H 7 //地图的高
#define L 10 //地图的长
#define T 1000 //延迟半秒(1000为1s),即每半秒刷新一次地图
char GameMap[H+2][L+2]; //游戏地图
int key; //按键保存
int sum = 1, over = 0; //蛇的长度, 游戏结束(自吃或碰墙)
int dx[4] = {0, 0, -1, 1}; //左、右、上、下的方向
int dy[4] = {-1, 1, 0, 0};
int Snake[H*L][3];
const char Shead = '@'; //蛇头
const char Sbody = '#'; //蛇身
const char Sfood = '*'; //食物
const char Snode = '-'; //'-'在地图上标示为空
void Initial(); //地图的初始化
void Create_Food(); //在地图上随机产生食物
void Show(); //刷新显示地图
void Button(); //取出按键,并判断方向
void Move(); //蛇的移动
void Check_Border(); //检查蛇头是否越界
void Check_Head(int x, int y); //检查蛇头移动后的位置情况
//===================================================================
task ButtonTask() //按键控制
{
nSchedulePriority = kHighPriority; //把任务设置为高优先级
key=nNxtButtonPressed;//将按键从控制台中取出并保存到key中
PlaySoundFile("! Click.rso");
return;
}
//===================================================================
task main()
{
nNxtButtonTask = ButtonTask;// 设定按钮状态为用户程序接管的模式.
nNxtExitClicks = 3; //使用三连击退出按钮的接管模式
Initial();
//wait10Msec(1000);
Show();
}
//===================================================================
void Initial() //地图的初始化
{
int i, j;
int hx, hy;
memset(GameMap,Snode,sizeof(GameMap)); //初始化地图全部为空'-'
eraseDisplay(); //刷新地图
hx=abs(rand())%H+1; //产生蛇头
hy=abs(rand())%L+1;
GameMap[hx][hy] = Shead;
Snake[0][0]= hx; Snake[0][1]= hy;
Snake[0][2]=-1;
Create_Food(); //随机产生食物
for(i =1; i <=H; i++) //地图显示
for(j =1; j<=L; j++)
nxtDisplayStringAt (7*j-6,9*i-1,"%c", GameMap[j]);
while(nNxtButtonPressed!=3){} //按下黄键开始
Button(); //取出按键,并判断方向
}
//===================================================================
void Create_Food() //在地图上随机产生食物
{
int fx, fy;
while(1)
{
fx =abs(rand())%H+1;
fy =abs(rand())%L+1;
if(GameMap[fx][fy] ==Snode) //不能出现在蛇所占有的位置
{
GameMap[fx][fy] = Sfood;
break;
}
}
}
//===================================================================
void Show() //刷新显示地图
{
int i, j;
while(1)
{
wait1Msec(T); //设置延时
Button(); //先判断按键在移动
Move();
if(over) //自吃或碰墙即游戏结束
{
eraseDisplay();
nxtDisplayBigStringAt (30, 50, "Over!");
while(nNxtButtonPressed!=3){} //按下黄键结束
break;
}
eraseDisplay(); //清空地图再显示刷新后的地图
for(i = 1; i <=H; i++)
for(j = 1; j <=L; j++)
nxtDisplayStringAt (7*j-6,9*i-1,"%c", GameMap[j]);
}
}
//===================================================================
void Button() //取出按键,并判断方向
{
switch(key)
{
case 2: Snake[0][2]=0;break; //左3
case 1: Snake[0][2]=1;break; //右0
case 0: Snake[0][2]=2; break; //上1
case 3: Snake[0][2]=3; break; //下2
}
}
//===================================================================
void Move() //蛇的移动
{
int i, x, y;
int t = sum; //保存当前蛇的长度
//记录当前蛇头的位置,并设置为空,蛇头先移动
x=Snake[0][0];
y=Snake[0][1];
GameMap[x][y]=Snode;
Snake[0][0]=Snake[0][0]+dx[Snake[0][2]];
Snake[0][1]=Snake[0][1]+dy[Snake[0][2]];
Check_Border();//蛇头是否越界
Check_Head(x,y);//蛇头移动后的位置情况,参数为:蛇头的开始位置
if(sum==t)//未吃到食物即蛇身移动
for(i=1;i<sum;i++)//要从蛇尾节点向前移动,前一个节点作为参照
{
if(i==1)//尾节点设置为空再移动
GameMap[Snake[0]][Snake[1]]=Snode;
if(i==sum-1)//为蛇头后面的蛇身节点,特殊处理
{
Snake[0]=x;
Snake[1]=y;
Snake[2]=Snake[0][2];
}
else//其他蛇身即走到前一个蛇身位置
{
Snake[0]=Snake[i+1][0];
Snake[1]=Snake[i+1][1];
Snake[2]=Snake[i+1][2];
}
GameMap[Snake[0]][Snake[1]]=Sbody;//移动后要置为'#'蛇身
}
}
//===================================================================
void Check_Border() //检查蛇头是否越界
{
if(Snake[0][0]<1||Snake[0][0]>H||Snake[0][1]<1||Snake[0][1]>L)
over=1;
}
//===================================================================
void Check_Head(int x, int y) //检查蛇头移动后的位置情况
{
if(GameMap[Snake[0][0]][ Snake[0][1] ] == Snode) //为空
GameMap[ Snake[0][0] ][ Snake[0][1] ] = Shead;
else
if(GameMap[ Snake[0][0] ][ Snake[0][1] ] ==Sfood) //为食物
{
GameMap[ Snake[0][0] ][ Snake[0][1] ] = Shead;
Snake[sum][0] = x; //新增加的蛇身为蛇头后面的那个
Snake[sum][1] = y;
Snake[sum][2] = Snake[0][2];
GameMap[ Snake[sum][0]][ Snake[sum][1] ] = Sbody;
sum++;
Create_Food(); //食物吃完了马上再产生一个食物
}
else
over = 1;
}
|
|