学习中断了一端时间,再捡起来时候发现生疏了很多。重新复习了一下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;
}
}