C语言复习——ACLLIB实现小游戏

学习中断了一端时间,再捡起来时候发现生疏了很多。重新复习了一下C语言,写了一个ACLLIB的小游戏《打FJ》,但是存在bug,飞机打不下来,哪位大佬能帮忙看看,找找原因。

 各种原型声明

#include "acllib.h"
#include 
#include 
#include 
/*声明图片结构体类型,用于加载炮台、炮弹、飞机以及形成炮弹和飞机链表 */
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;
	}
}

C语言复习——ACLLIB实现小游戏_第1张图片

 C语言复习——ACLLIB实现小游戏_第2张图片

 C语言复习——ACLLIB实现小游戏_第3张图片

你可能感兴趣的:(c语言,bug,开发语言)