150809227

飞机游戏

#define MAXOBJ  物体最大数量

#define MAXX    屏幕宽度

#define MAXY    屏幕高

struct TOBJ{

int mode;

int x, y;

int index;

int type;

}Objs[MAXOBJ];

int AllocObj()

{

int i=0;

while(i<MAXOBJ&&Objs[i].mode) i++;

if(i>=MAXOBJ) return MAXOBJ - 1;

return i;

}

int CheckHit(int x1, int y1, int x2, int y2, int r)

{

if(abs(x1-x2)<=r&&abs(y1-y2)<=r) return 1;

return 0;

}

void drivers()

{

if(!random(20)){

int i=AllocObj();

Objs[i].x=random(MAXX);

Objs[i].y=-random(60);

Objs[i].mode=1;

Objs[i].type=Objs[i].index=0;

if(!random(120)) Objs[i].type=2;

//直接出现的敌机的速度就很快

}

}

int fly_x=MAXX/2, fly_y=MAXY*4/5, fire_flag=0,

fly_flag=1;

int GameOver=1;

char GameOver()

{

while(GameOver){

clear();

control();

dirvers();

show();

if(key[ESC]) GameOver = 0;

}

return 1;

}

void control()

{

int i, j;

int x, y;

for(i=0; i<MAXOBJ; i++){

x=Objs[i].x; y=Objs[i].y;

switch(Objs[i].mode){

case 1:

if(!Objs[i].index){

switch(Objs[i].type){

case 0:

if(!random(3))  Objs[i].type = 1;

break;

case 1:

if(x<fly_x) x++; if(x>fly_x) x--;

if(!random(40)) Objs[i].type = 2;

break;

case 2:

default:

if(!random(3)) y+=3;

}//end switch(Objs[i].type);

if(Check(x, y, fly_x, fly_y, 15) fly_flag=0;//  画出敌机;

if(!random(10)){

j=AllocObj();

if(!random(3)) Objs[j].mode=3;

else{

Objs[j].mode = 4;

Objs[j].k = (fly_y - y)* 1.0 / (fly_x-x);

}

Objs[j].x=x; Objs[j].y=y;

}

}//end if(!Objs[i].index)

else{

if((Objs[i].index&3)==0)  画出敌机;

if(++Objs[i].index>50) Objs[i].mode=0;

}end if(!Objs[i].index))

y++;

if(y>MAXY) Objs[i].mode=0;

break;

case 2:

y-=3;

画出我方子弹;

for(j=0; j<MAXOBJ; j++)

if((Objs[j].mode==1)&&(!Objs[j].index)&&CheckHit(x, y,Objs[j].x, Objs[j].y, 15)){

Objs[j].index = 1;

Objs[i].mode = 0;

}

break;

case 3:

y+=3;

x+=random(20)-10;

if(y>MAXY) Objs[i].mode=0;

画出子弹;

if(Check(x, y, fly_x, fly_y, 15)) fly_flag=0;

break;

case 4:

x += -Objs[i].k;

abs(Objs[i].k)<=1?(y += 4):(y+=2) ;

画出子弹;

if(CheckHit(x,y,fly_x,fly_y,8))   fly_flag=0;

break;

}//end switch(Objs[i].mode);

}//end for

if(key[UP])    if(fly_y--<0)     fly_y=0;

if(key[DOWN])  if(fly_y++>MAXY)  fly_y=MAXY;

if(key[LEFT])  if(fly_x--<0)     fly_x=0;

if(key[RIGHT]) if(fly_x++>MAXX)  fly_x=MAXX;

if(key[CTRL]){

i=AllocObj();

Objs[i].x=fly_x,

Objs[i].y=fly_y-10;

Objs[i].mode=2;

}

if(!fly_flag) GameOver=0;

}

对飞机游戏编码的理解

int GameStart()

{

while(GameOver){

clear();

control();

dirver();

show();

if(key[ESC]) GameOver = 0;

}

return 1;

}

  这个函数在此用while语句,是用来控制游戏退出的。clear()这个语句是清屏。control()这个函数是游戏的核心,控制整个游戏的,比如说控制飞机,子弹如何飞。dirver()这个函数是控制着敌人的出现。show()函数是显示图形

所以整个游戏的思路很简单,清屏——游戏控制——敌机出现——显示:

1.clear();

清屏函数直接把MemBuf全部赋值成0。

2.control();

 首先定义物体结构。

 struct TOBJ{

  int mode; //类型,0:空闲,1:敌机;2,自己发射的子弹,3,敌人子弹类型1;

  int x, y;

  int type;

  int index;

 } Objs[MAXOBJ];

 要控制整个游戏的进程,必须每个飞机,子弹都在动,所以用

for(i=0; i<MAXOBJ; i++) 这个循环对每个物体进行控制。

对单个物体来说,首先要确定每个物体的类型,类型不一样,执行的操作也就不一样

switch(Obj[i].mode){

case 1:  //如果是敌机,执行敌机的操作;

......;

break;

case 2:  //如果是自己发射的子弹,执行自己的子弹的操作;

......;

break;

case 3:  //如果是敌人子弹类型1,执行子弹类型1的操作;

......;

break;

case 4:  //执行敌人子弹类型2的操作

......;

break;

......   //执行子弹类型N的操作;

}

1.1敌机操作:

首先判断敌机是不是已经死亡,如果死亡,则显示死亡的效果,比如说爆炸,这是最常见的飞机游戏中,敌机死亡的效果,还比如说敌机出现闪烁的效果,这种方式倒是也有,不过效果自然没有爆炸的效果华丽,在此我用闪烁的效果。如果敌机没有死亡,则要往我机上撞,以期消灭我机——显然不能任何时候都跟着咱们跑,所以要有一定的几率性,这样,不会时时刻刻跟着咱们。

switch (Objs[i].type) {

case 0:

if(!random(20)) Objs[i].type=1;

break;

case 1:

if(Objs[i].x<fly_x) Objs[i].x++;

if(Objs[i].x>fly_x) Objs[i].x--;

if(!random(40)) Objs[i].type=2;

break;

case 2:

default:

if(!random(3)) y+=3;

break;

}

这段程序是执行敌机的飞行擦作的。Objs[i].type==0是,1/20的几率让敌机跟着自己飞,此时执行case

1。然后1/40的几率使敌机加速,此时执行case 2:default:;

敌机的飞行任务完成,还必须能发射子弹,一样,用随机函数,比方说:

if (!random(30){ // 1/30的几率发射子弹

j=AllocObj();// 从Objs中选择一个,也就是空闲的

if(!random(5)) Objs[j].mode=2; // 1/5的几率,是子弹类型2;

else Objs[j].mode=3;

Objs[j].x=Objs[i].x;

Objs[j].y=Objs[i].y;

}

最后这两句很容易理解,子弹发射的坐标,自然要从发射它的敌机那里发射,所以坐标一样。然后是判断敌机和我机相撞没有if(CheckHit(x,y,fly_x,fly_y,15)) fly_flag=0;CheckHit是碰撞函数,和上面的AllocObj()函数一起在后面给出实现过程。这只是敌机未死亡所执行的操作如果敌机死亡,则要出现死亡效果

if(Objs[i].index){

if ((Objs[i].index&3)==0) 画敌机图片

if(++Objs[i].index>50) Objs[i].mode=0;

}

这段程序很容易理解也就是过段时间,显示次敌机的图片。如果是不显示的话,在前面的主循环中,已经被clear()函数给清屏了。敌机的操作还有最后一步if(Objs[i].y>MAXY) Objs[i].mode=0;如果敌机飞到屏幕下方,则释放函数AllocObj()的实现

int AllocObj()

{

int i = 0;

while(i<MAXOBJ&&Objs[i].mode) i++;

if(i>=MAXOBJ) i = MAXOBJ - 1;

return i;

} 函数CheckHit()的实现这个函数通过矩形判断

int CheckHit(int x1,int y1,int x2,int y2,int r)

{

if(abs(x1-x2)<=r&&abs(y1-y2)<=r) return 1;

return 0;

}

1.2我方子弹

先让子弹往上飞Objs[i].y-=3;然后判断是否射中敌人。

for (j=0;j<MAX_OBJ;j++) // 检查与敌机相碰

if(Objs[j].mode==1&&CheckHit(x,y,Objs[j].x,Objs[j].y,15)&&!Objs[j].index){

Objs[j].index=1;

Objs[i].mode=0;

}

显然,要判断是否射中敌人,要首先扫描所有的敌人,看看是否射中,

Objs[i].mode = 0 回收此子弹

Objs[j].index = 0; 代表敌机存活

Objs[j].index!=0;代表敌机死亡,之所以不用Objs[j].mode=0代表敌人死亡,是因为还要出现死亡后的效果,也可以用Objs[j].mode=0代表敌机死亡,不过这样子就没有死亡后效果了,射中敌人,敌人就消失。)

1.3敌方:子弹

Objs[i].y+=3;

Objs[i].x+=random(10)-5;

if(CheckHit(x,y,fly_x,fly_y,10))

//敌机子弹射中我机

fly_flag=0;

这段程序x+=random(10)-5;这个语句,它在原横坐标的位置,往左右5幅度的概率相等,随机,因此造成这个子弹很阴险

1.4 我机的操作

if(key[KEY_UP]) if (--fly_y<0) fly_y=0;

if(key[KEY_DOWN]) if (++fly_y>MAXM-16) fly_y=MAXM-16;

if(key[KEY_LEFT]) if (--fly_x<0) fly_x=0;

if(key[KEY_RIGHT]) if (++fly_x>MAXX-16) fly_x=MAXX-16;

if(key[KEY_CONTROL]){

i=AllocObj();

Objs[i].x=fly_x,

Objs[i].y=fly_y-10;

Objs[i].mode=2;

}

画出我机的图片if(!fly_flag) GameOver = 1;在此,整个程序的思路很清晰了

2.0下面设计dirver()函数

void drivers()

{

if(!random(20)){

int i=AllocObj();

Objs[i].x=random(MAXX);

Objs[i].y=-random(60);

Objs[i].mode=1;

Objs[i].type=Objs[i].index=0;

if(!random(120)) Objs[i].type=2;

//直接出现的敌机的速度就很快

}

}

时间: 2024-08-26 07:35:53

150809227的相关文章

指针与链表结构理解

指针与链表结构理解#include<stdio.h>int main(void){ int a=3,*p; p=&a; printf("a=%d,*p=%d\n",a,*p); *p=10; printf("a=%d,*p=%d\n",a,*p); printf("Enter a:"); scanf("%d",&a); printf("a=%d,*p=%d\n",a,*p); r