学习中断了一端时间,再捡起来时候发现生疏了很多。重新复习了一下C语言,写了一个ACLLIB的小游戏《打FJ》,但是存在bug,飞机打不下来,哪位大佬能帮忙看看,找找原因。
各种原型声明
#include "acllib.h" #include <stdio.h> #include <stdbool.h> #include <time.h>
/*声明图片结构体类型,用于加载炮台、炮弹、飞机以及形成炮弹和飞机链表 */ typedef struct _image{ ACL_Image
*pImage; int x; int y; struct _image *next; }Image; /*声明炮台、炮弹、飞机的图片结构,用于加载图片*/
ACL_Image paotai; ACL_Image paodan; ACL_Image lfeiji; ACL_Image rfeiji;
/*声明链表结构体,实现飞机和炮弹的插入和删除*/ typedef struct _linklist{ Image *head; Image *tail;
}List; /*声明炮弹和飞机链表,声明炮台均为全局变量*/ List *PDlist; List *FJlist; Image *PT;
/*声明炮台、炮弹、飞机的初始化函数*/ Image *initPaotai(Image*); Image *initPaodan(Image*);
Image *initFeiji(Image*); /*声明链表的插入、删除、清除等函数*/ List *initList(List*); void
add(List *pList,Image *pNode); void del(List *pList,Image *pNode); void
cle(List *pList); bool isempty(List*); /*声明鼠标、键盘、定时器回调函数;声明画图函数*/ void
MouseEvent(int x,int y,int button,int event); void KeyboardEvent(int key,int
event); void TimerEvent(int id); void paint(void); /*用宏定义窗口大小数据*/ #define LEFT
150 #define UP 100 #define WIDTH 800 #define HEIGH 600
函数入口
/*入口函数:加载图片、初始化炮台、炮弹链表、飞机链表;调用鼠标、键盘和定时器监听函数*/ int Setup(){ char const
*NAME="打飞机"; initWindow(NAME,LEFT,UP,WIDTH,HEIGH); //initConsole();
loadImage("paotai.jpg",&paotai); loadImage("paodan.jpg",&paodan);
loadImage("lfeiji.jpg",&lfeiji); loadImage("rfeiji.jpg",&rfeiji);
PT=initPaotai(PT); PDlist=initList(PDlist); FJlist=initList(FJlist);
registerMouseEvent(MouseEvent); registerKeyboardEvent(KeyboardEvent);
registerTimerEvent(TimerEvent); startTimer(0,20); startTimer(2,1000);
startTimer(3,10); paint(); return 0; }
回调函数
/*鼠标回调函数,点击左键实现炮台就位*/ void MouseEvent(int x,int y,int button,int event){
if(button==LEFT_BUTTON&&event==BUTTON_DOWN&&PT->y!=450){ PT->y=450; paint(); }
} /*键盘回调函数,实现炮台左右移动和发射炮弹*/ void KeyboardEvent(int key,int event){
printf("key=%d,event=%d\nPaotai.x=%d,Paotai.y=%d\n",key,event,PT->x,PT->y);
enum{down,up}; /*用状态变量控制连续发射或者移动的速度,左右键添加按下状态,可以避免按键冲突*/ static int leftstate
=-1; static int rightstate=-1; static int shootstate=-1; static int flag =0;
switch(key){ case 32:{//按下空格,发射状态开启,启动定时器发射炮弹 if(event==KEY_DOWN){
if(shootstate!=down){ Image *pNode=(Image*)malloc(sizeof(Image));
pNode=initPaodan(pNode); add(PDlist,pNode); startTimer(1,150); }
shootstate=down; }else if(event==KEY_UP){ cancelTimer(1); shootstate=up; }
}break; case 37:{// if(event==KEY_DOWN){ leftstate=down; }else
if(event==KEY_UP){ leftstate=up; } }break; case 39:{ if(event==KEY_DOWN){
rightstate=down; }else if(event==KEY_UP){ rightstate=up; } }break;
default:break; } if(leftstate==down&&PT->x>=-100){ PT->x-=10; }else
if(rightstate==down&&PT->x<=WIDTH-140){ PT->x+=10; } paint(); }
/*定时器回调函数,用于实现定时发射炮弹、炮弹和飞机的移动*/ void TimerEvent(int id){ switch(id){ case
0:{//0号定时器 if(PT->y>450){//功能1:炮台缓慢就位 PT->y--; } Image *pdptemp=PDlist->head;
Image *fjptemp=FJlist->head; Image *ptemp=NULL; //功能2:炮弹的自动移动和删除
for(pdptemp=PDlist->head,ptemp=NULL;pdptemp;pdptemp=pdptemp->next){
pdptemp->y-=20; if(ptemp&&ptemp->y>HEIGH){ del(PDlist,ptemp); } ptemp=pdptemp;
} //功能3:飞机的自动移动和删除
for(fjptemp=FJlist->head,ptemp=NULL;fjptemp;fjptemp=fjptemp->next){
if(fjptemp->pImage==&rfeiji){ fjptemp->x+=5; }else
if(fjptemp->pImage==&lfeiji){ fjptemp->x-=5; }
if(ptemp&&(ptemp->x<0||ptemp->x>WIDTH)){ del(FJlist,ptemp); } ptemp=fjptemp; }
}break; case 1:{//1号定时器:发射状态定时装弹 Image *pNode=(Image*)malloc(sizeof(Image));
pNode=initPaodan(pNode); add(PDlist,pNode); }break; case 2:{//2号定时器:定时出动飞机
Image *pNode=(Image*)malloc(sizeof(Image)); pNode=initFeiji(pNode);
add(FJlist,pNode); }break; //3号定时器:定时判定炮弹是否打中飞机,如果打中则删除
//(bug:炮弹和飞机都删除不了,如果换成清除链表,一发炮弹清全屏飞机) case 3:{ Image *pdptemp=PDlist->head;
Image *fjptemp=FJlist->head; Image *ptemp=NULL;
for(pdptemp=PDlist->head;pdptemp;pdptemp=pdptemp->next){
for(fjptemp=FJlist->head;fjptemp;fjptemp=fjptemp->next){
if((pdptemp->y<=fjptemp->y+100&&pdptemp->y>=fjptemp->y)&&
(pdptemp->x>=fjptemp->x&&pdptemp->x<=fjptemp->x+130)){ printf("pdptemp->x=%d
fjptemp->x=%d\n",pdptemp->x,fjptemp->x); del(FJlist,fjptemp); //cle(FJlist);
break; } } if(fjptemp) del(PDlist,pdptemp); } paint(); }break; } paint(); }
画图相关函数
/*实现画图函数,只负责画图*/ void paint(void){ beginPaint(); clearDevice();
putImageTransparent(PT->pImage,PT->x,PT->y,75,165,WHITE); for(Image
*p=PDlist->head;p;p=p->next){
putImageTransparent(p->pImage,p->x,p->y,20,29,WHITE); } for(Image
*p=FJlist->head;p;p=p->next){
putImageTransparent(p->pImage,p->x,p->y,120,90,WHITE); } endPaint(); }
/*实现炮台、炮弹、飞机和链表初始化*/ Image *initPaotai(Image *PT){
PT=(Image*)malloc(sizeof(Image)); PT->pImage=&paotai; PT->x=WIDTH/2-25;
PT->y=HEIGH; PT->next=NULL; return PT; } Image *initPaodan(Image *Paodan){
Paodan->pImage=&paodan; Paodan->x=PT->x+27.5; Paodan->y=PT->y;
Paodan->next=NULL; return Paodan; } Image *initFeiji(Image *Feiji){
srand((unsigned int)time(NULL)); int ret=rand(); if(ret%2){
Feiji->pImage=&rfeiji; Feiji->x=-120; if(ret%3){ Feiji->y=75; }else{
Feiji->y=25; } }else{ Feiji->pImage=&lfeiji; Feiji->x=WIDTH; if(ret%3){
Feiji->y=25; }else{ Feiji->y=75; } } Feiji->next=NULL; return Feiji; }
链表函数
/*实现链表操作函数*/ List *initList(List *pList){ pList=(List*)malloc(sizeof(List));
pList->head=pList->tail=NULL; return pList; } bool isempty(List *pList){ return
pList->head==NULL; } void add(List *pList,Image *pNode){ if(isempty(pList)){
pList->head=pList->tail=pNode; }else{ pList->tail->next=pNode;
pList->tail=pNode; } } void del(List *pList,Image *pNode){ if(isempty(pList)){
Image *pTemp=pList->head; if(pNode==pList->head){ if(pNode==pList->tail){
pList->tail=NULL; } pList->head=pList->head->next; }else{
while(pTemp->next!=pNode){ pTemp=pTemp->next; } if(pNode==pList->tail){
pList->tail=pTemp; } pTemp->next=pNode->next; } free(pNode); } } void cle(List
*pList){ if(!isempty(pList)){ for(Image *p=pList->head;p;p=p->next){
del(pList,p); } pList->head=pList->tail=NULL; } }