100个免费货源网站,音乐网站如何建设,网站建设应该注意什么,顺德网站建设公司有哪些1.优化边界问题
之前视频中当使用drawAlpha函数时#xff0c;是为了去除飞机后面变透明#xff0c;当时当飞机到达边界的时候#xff0c;会出现异常退出#xff0c;这是因为drawAlpha函数不稳定#xff0c;昨天试过制作掩码图#xff0c;下载了一个ps,改的话#xff0c…1.优化边界问题
之前视频中当使用drawAlpha函数时是为了去除飞机后面变透明当时当飞机到达边界的时候会出现异常退出这是因为drawAlpha函数不稳定昨天试过制作掩码图下载了一个ps,改的话图片大小又变了最后采用的方式是当飞机在窗口内的时候使用drawAlpha函数贴图当飞机要出边缘的时候使用putimage贴图防止出现闪退优化后飞机到边界的时候会出现黑框. 边界优化 对应的代码实现
void draw()
{putimage(0, 0, img_bk);if (plane.x -1 plane.x WIDTH plane.y-1 plane.y 48 HEIGHT){drawAlpha(img_plane, plane.x, plane.y);}else{putimage(plane.x, plane.y, img_plane);}if (a.x -1 a.x WIDTH a.y0 a.y 98 HEIGHT){drawAlpha(img_a, a.x, a.y);}else{putimage(a.x, a.y, img_a);}if (b.x -1 b.x WIDTH b.y-1 b.y 120 HEIGHT){drawAlpha(img_b, b.x, b.y);}else{putimage(b.x, b.y, img_b);}if (c.x -1 c.x WIDTH c.y-1 c.y 120 HEIGHT){drawAlpha(img_c, c.x, c.y);}else{putimage(c.x, c.y, img_c);}}2.我方战机发射子弹
如果我们用数组存储子弹的信息的话在不断发射子弹的过程中不断的创建数组元素会导致栈溢出所以我们使用链表存储每个子弹的信息当打出一个子弹时会创建一个新的结点并且尾插到头结点上去当子弹出屏幕或者隔一段时间删除出屏幕的子弹用到单链表节点的删除.
1.首先创建一个子弹的结构体并创建我方飞机子弹的头节点
typedef struct bullet
{float x, y;float vx, vy;int isexist;struct bullet* next;}list;
list* planebullet NULL;
2.创建新结点
list* BuyplanebulletNode(float vx, float vy)
{list* newnode (list*)malloc(sizeof(list));//空间申请assert(newnode);//断言新结点是否申请到了newnode-vx vx;//数据赋值newnode-vy vy;//数据赋值newnode-x plane.x plane.width / 217;newnode-y plane.y;//让子弹的出生坐标在飞机中间newnode-isexist 1;newnode-next NULL;//指向的地址赋值return newnode;//将申请好的空间首地址返回回去}3 尾插新结点.
void pushback1(list** pphead,float vx,float vy)//尾插
{list* newnode BuyplanebulletNode(vx, vy);if (*pphead NULL)//链表无结点{*pphead newnode;// 将创建好的头节点的地址给给*pphead作为新头节点的地址}else{list* tail *pphead;//定义一个指针先指向头结点的地址while (tail-next ! NULL)//循环遍历找尾结点{tail tail-next;//指针指向下一个结点}tail-next newnode;//找到尾结点将尾结点的next存放新接结点的地址}}4.结点的删除
void removebullet(list** pplist)
{if (*pplist NULL)return;list* cur *pplist;list* prev NULL;while (cur ! NULL){if (cur-isexist 0){if (*pplist cur){*pplist cur-next;free(cur);cur *pplist;}else{prev-next cur-next;free(cur);cur prev;}}else{prev cur;cur cur-next;}}}5.子弹位置改变参数设置
void listchangexy(list** pplist)
{if (*pplist NULL)return;list* cur *pplist;while (cur ! NULL){cur-x cur-vx;cur-y cur-vy;if ((cur-y0 )|| (cur-yHEIGHT) || (cur-x 0) || (cur-x WIDTH))cur-isexist 0;cur cur-next;}}遍历子弹链表使得每个子弹的位置属性发生变化当子弹出屏幕时将当前cur指向的子弹的exist0,表示子弹消失cur指向下一个子弹改变子弹的位置坐标属性. 上面创建的链表存下了每个子弹的属性然后我们遍历子弹链表贴子弹上去。
6.贴子弹上去
void showbullet()
{static int count1 0;listchangexy(planebullet);for (list* cur planebullet; cur! NULL; cur cur -next){putimage(cur-x,cur-y, img_planebullet);}if (count1 100){removebullet(planebullet);}if (count1 99999){count1 0;}}}这里定时清理一下出屏幕的子弹要不然太占内存了.如果直接使用removebullet会出现错误 当然在player_move函数里面加 if (GetAsyncKeyState(VK_SPACE))// Timer(300, 1)){pushback1(planebullet, 0, -20);}我们可以使用空格开火当空格按下一次就尾插子弹信息到对应子弹的结点上去 总结 子弹发射 7.解决子弹太密集问题
使用定时器函数隔一段时间才能发射子弹
bool Timer(int ms, int id)
{static DWORD t[10];if (clock() - t[id] ms){t[id] clock();return true;}return false;
}这个先记住就行不用理解参数第一个是定时时间单位是ms,第二个我也不太清楚传个1就行. if ((GetAsyncKeyState(VK_SPACE)) Timer(300, 1)){pushback1(planebullet, 0, -20);//pushback1(planebullet, -10, -17.32);//pushback1(planebullet, 10, -17.32);}8.子弹升级 子弹升级 if ((GetAsyncKeyState(VK_SPACE)) Timer(300, 1)){pushback1(planebullet, 0, -20);pushback1(planebullet, -10, -17.32);pushback1(planebullet, 10, -17.32);}3.敌方的子弹发射
当我们会处理我方的子弹发射之后敌方子弹的发射也是同样的道理 敌机a子弹的发射 敌机a子弹发射步骤和我方战机相同
list* abullet NULL;
void pushback2(list** pphead, float vx, float vy);
list* BuyabulletNode(float vx, float vy)
{list* newnode (list*)malloc(sizeof(list));//空间申请assert(newnode);//断言新结点是否申请到了newnode-vx vx;//数据赋值newnode-vy vy;//数据赋值newnode-x a.x a.width / 2-10;newnode-y a.y80;newnode-isexist 1;newnode-next NULL;//指向的地址赋值return newnode;//将申请好的空间首地址返回回去}
void pushback2(list** pphead, float vx, float vy)//尾插
{list* newnode BuyabulletNode(vx, vy);if (*pphead NULL)//链表无结点{*pphead newnode;// 将创建好的头节点的地址给给*pphead作为新头节点的地址}else{list* tail *pphead;//定义一个指针先指向头结点的地址while (tail-next ! NULL)//循环遍历找尾结点{tail tail-next;//指针指向下一个结点}tail-next newnode;//找到尾结点将尾结点的next存放新接结点的地址}}
void removebullet(list** pplist)
{if (*pplist NULL)return;list* cur *pplist;list* prev NULL;while (cur ! NULL){if (cur-isexist 0){if (*pplist cur){*pplist cur-next;free(cur);cur *pplist;}else{prev-next cur-next;free(cur);cur prev;}}else{prev cur;cur cur-next;}}}
void listchangexy(list** pplist)
{if (*pplist NULL)return;list* cur *pplist;while (cur ! NULL){cur-x cur-vx;cur-y cur-vy;if ((cur-y0 )|| (cur-yHEIGHT) || (cur-x 0) || (cur-x WIDTH))cur-isexist 0;cur cur-next;}}void showbullet()
{static int count1 0;listchangexy(planebullet);if (count1 100){removebullet(planebullet);removebullet(abullet);removebullet(bbullet);}if (count1 99999){count1 0;}for (list* cur planebullet; cur! NULL; cur cur -next){putimage(cur-x,cur-y, img_planebullet);}listchangexy(abullet);for (list* cur abullet; cur ! NULL; cur cur-next){//putimage(cur-x - 10, cur-y - 10, img_planebullet);putimage(cur-x , cur-y, img_abullet);}//listchangexy(bbullet);////for (list* cur bbullet; cur ! NULL; cur cur-next)//{// //putimage(cur-x - 10, cur-y - 10, img_planebullet);// putimage(cur-x, cur-y, img_bbullet);//}}
因为敌机a在移动中发射子弹所以将puchback2放在ufoamove函数里面
void ufoamove()
{static int dir1 1;static int cnt 0;if (a.bornflag 1){a.bornflag 0;a.x rand() % (WIDTH - a.width);a.y -50;}if (a.y 200){dir1 0;}else if (a.y -150){dir1 1;a.bornflag 1;}if (1 dir1){a.y a.speed;}else{a.y - a.speed;}if (cnt % 50 0){pushback2(abullet, 0, 10);}if (cnt 99999){cnt 0;}}设置一个静态变量cnt,当cnt%50取余0时发射子弹这样也解决了子弹太密集50可以修改就相当于间隔cnt为int可能会溢出所以99999,将cnt0;
敌机b子弹的发射
同理 包含头文件#includemath.h
4.程序源码
#includestdio.h
#include graphics.h
#include assert.h
#include stdlib.h
#includeconio.h//_getch();
#include time.h
#include math.h
#define PI 3.1415926
#define HEIGHT 503
#define WIDTH 700IMAGE img_bk, img_plane, img_a, img_b, img_c, img_abullet, img_bbullet, img_cbullet, img_planebullet,img_tmp;
typedef struct bullet
{float x, y;float vx, vy;int isexist;struct bullet* next;}list;
list* planebullet NULL;
list* abullet NULL;
list* bbullet NULL;
void pushback2(list** pphead, float vx, float vy);
void pushback3(list** pphead, float vx, float vy);
void pushback(list** pphead, list* newnode);//尾插;
struct aircraft
{int x, y;int width;int height;int speed;int bornflag;};
aircraft plane, a, b, c;
void datainit()
{plane { 150,150 };//a { 0,0 };/*b { 300,0 };*//*c { 450,0 };*/a.speed 1;a.bornflag 1;b.bornflag 1;c.bornflag 1;a.width 100;a.height 100;b.speed 1;b.width 80;b.height 100;c.height 70;c.width 70;c.speed 3;}
list* BuyabulletNode(float vx, float vy)
{list* newnode (list*)malloc(sizeof(list));//空间申请assert(newnode);//断言新结点是否申请到了newnode-vx vx;//数据赋值newnode-vy vy;//数据赋值newnode-x a.x a.width / 2-10;newnode-y a.y80;newnode-isexist 1;newnode-next NULL;//指向的地址赋值return newnode;//将申请好的空间首地址返回回去}
list* BuybbulletNode(float vx, float vy)
{list* newnode (list*)malloc(sizeof(list));//空间申请assert(newnode);//断言新结点是否申请到了newnode-vx vx;//数据赋值newnode-vy vy;//数据赋值newnode-x b.x b.width / 2 - 10;newnode-y b.y 80;newnode-isexist 1;newnode-next NULL;//指向的地址赋值return newnode;//将申请好的空间首地址返回回去}
list* BuyplanebulletNode(float vx, float vy)
{list* newnode (list*)malloc(sizeof(list));//空间申请assert(newnode);//断言新结点是否申请到了newnode-vx vx;//数据赋值newnode-vy vy;//数据赋值newnode-x plane.x plane.width / 217;newnode-y plane.y;newnode-isexist 1;newnode-next NULL;//指向的地址赋值return newnode;//将申请好的空间首地址返回回去}
void drawAlpha(IMAGE* picture, int picture_x, int picture_y) //x为载入图片的X坐标y为Y坐标
{// 变量初始化DWORD* dst GetImageBuffer(); // GetImageBuffer()函数用于获取绘图设备的显存指针EASYX自带DWORD* draw GetImageBuffer();DWORD* src GetImageBuffer(picture); //获取picture的显存指针int picture_width picture-getwidth(); //获取picture的宽度EASYX自带int picture_height picture-getheight(); //获取picture的高度EASYX自带int graphWidth getwidth(); //获取绘图区的宽度EASYX自带int graphHeight getheight(); //获取绘图区的高度EASYX自带int dstX 0; //在显存里像素的角标// 实现透明贴图 公式 Cpαp*FP(1-αp)*BP 贝叶斯定理来进行点颜色的概率计算for (int iy 0; iy picture_height; iy){for (int ix 0; ix picture_width; ix){int srcX ix iy * picture_width; //在显存里像素的角标int sa ((src[srcX] 0xff000000) 24); //0xAArrggbb;AA是透明度int sr ((src[srcX] 0xff0000) 16); //获取RGB里的Rint sg ((src[srcX] 0xff00) 8); //Gint sb src[srcX] 0xff; //Bif (ix 0 ix graphWidth iy 0 iy graphHeight dstX graphWidth * graphHeight){if ((ix picture_x) 0 (ix picture_x) graphWidth) //防止出边界后循环显示{dstX (ix picture_x) (iy picture_y) * graphWidth; //在显存里像素的角标int dr ((dst[dstX] 0xff0000) 16);int dg ((dst[dstX] 0xff00) 8);int db dst[dstX] 0xff;draw[dstX] ((sr * sa / 255 dr * (255 - sa) / 255) 16) //公式 Cpαp*FP(1-αp)*BP αpsa/255 , FPsr , BPdr| ((sg * sa / 255 dg * (255 - sa) / 255) 8) //αpsa/255 , FPsg , BPdg| (sb * sa / 255 db * (255 - sa) / 255); //αpsa/255 , FPsb , BPdb}}}}
}void load()
{loadimage(img_bk, ./back.png);loadimage(img_plane, ./1.png);loadimage(img_a, ./2.png);loadimage(img_b, ./3.png);loadimage(img_c, ./4.png);loadimage(img_abullet, ./5.png);loadimage(img_bbullet, ./6.png);loadimage(img_cbullet, ./7.png);loadimage(img_planebullet, ./8.png);}
void draw()
{putimage(0, 0, img_bk);if (plane.x -1 plane.x WIDTH plane.y-1 plane.y 48 HEIGHT){drawAlpha(img_plane, plane.x, plane.y);}else{putimage(plane.x, plane.y, img_plane);}if (a.x -1 a.x WIDTH a.y0 a.y 98 HEIGHT){drawAlpha(img_a, a.x, a.y);}else{putimage(a.x, a.y, img_a);}if (b.x -1 b.x WIDTH b.y-1 b.y 120 HEIGHT){drawAlpha(img_b, b.x, b.y);}else{putimage(b.x, b.y, img_b);}if (c.x -1 c.x WIDTH c.y-1 c.y 120 HEIGHT){drawAlpha(img_c, c.x, c.y);}else{putimage(c.x, c.y, img_c);}/*drawAlpha(img_a, a.x, a.y);drawAlpha(img_b, b.x, b.y);drawAlpha(img_c, c.x, c.y);drawAlpha(img_abullet, 400, 0);drawAlpha(img_bbullet, 400, 50);drawAlpha(img_cbullet, 400, 100);drawAlpha(img_planebullet, 400, 150);*//* putimage(plane.x, plane.y, img_plane); putimage(a.x, a.y ,img_a);putimage(b.x, b.y ,img_b );putimage(c.x, c.y, img_c );putimage(400, 50 ,img_bbullet);putimage(400, 100 ,img_cbullet );*/}void ufoamove()
{static int dir1 1;static int cnt 0;if (a.bornflag 1){a.bornflag 0;a.x rand() % (WIDTH - a.width);a.y -50;}if (a.y 200){dir1 0;}else if (a.y -150){dir1 1;a.bornflag 1;}if (1 dir1){a.y a.speed;}else{a.y - a.speed;}if (cnt % 50 0){pushback2(abullet, 0, 10);}if (cnt 99999){cnt 0;}}
void ufobmove()
{static int num 0;static int step b.speed;if (b.bornflag 1){b.bornflag 0;b.x rand() % (WIDTH - b.width);b.y -b.height;}if (b.x 0 || b.x b.width WIDTH){step -step;}b.x step;b.y;if (b.y HEIGHT){b.bornflag 1;}if (num % 200 0){for (int i 0; i 10; i){float angle i * 2 * PI / 10;float vx 1* sin(angle);float vy 1 * cos(angle);pushback3(bbullet, vx, vy);}}if (num 99999){num 0;}}void pushback1(list** pphead,float vx,float vy)//尾插
{list* newnode BuyplanebulletNode(vx, vy);if (*pphead NULL)//链表无结点{*pphead newnode;// 将创建好的头节点的地址给给*pphead作为新头节点的地址}else{list* tail *pphead;//定义一个指针先指向头结点的地址while (tail-next ! NULL)//循环遍历找尾结点{tail tail-next;//指针指向下一个结点}tail-next newnode;//找到尾结点将尾结点的next存放新接结点的地址}}
void pushback2(list** pphead, float vx, float vy)//尾插
{list* newnode BuyabulletNode(vx, vy);if (*pphead NULL)//链表无结点{*pphead newnode;// 将创建好的头节点的地址给给*pphead作为新头节点的地址}else{list* tail *pphead;//定义一个指针先指向头结点的地址while (tail-next ! NULL)//循环遍历找尾结点{tail tail-next;//指针指向下一个结点}tail-next newnode;//找到尾结点将尾结点的next存放新接结点的地址}}
void pushback3(list** pphead, float vx, float vy)//尾插
{list* newnode BuybbulletNode(vx, vy);if (*pphead NULL)//链表无结点{*pphead newnode;// 将创建好的头节点的地址给给*pphead作为新头节点的地址}else{list* tail *pphead;//定义一个指针先指向头结点的地址while (tail-next ! NULL)//循环遍历找尾结点{tail tail-next;//指针指向下一个结点}tail-next newnode;//找到尾结点将尾结点的next存放新接结点的地址}}
void removebullet(list** pplist)
{if (*pplist NULL)return;list* cur *pplist;list* prev NULL;while (cur ! NULL){if (cur-isexist 0){if (*pplist cur){*pplist cur-next;free(cur);cur *pplist;}else{prev-next cur-next;free(cur);cur prev;}}else{prev cur;cur cur-next;}}}
void listchangexy(list** pplist)
{if (*pplist NULL)return;list* cur *pplist;while (cur ! NULL){cur-x cur-vx;cur-y cur-vy;if ((cur-y0 )|| (cur-yHEIGHT) || (cur-x 0) || (cur-x WIDTH))cur-isexist 0;cur cur-next;}}
void showbullet()
{static int count1 0;listchangexy(planebullet);if (count1 100){removebullet(planebullet);removebullet(abullet);removebullet(bbullet);}if (count1 99999){count1 0;}for (list* cur planebullet; cur! NULL; cur cur -next){putimage(cur-x,cur-y, img_planebullet);}listchangexy(abullet);for (list* cur abullet; cur ! NULL; cur cur-next){//putimage(cur-x - 10, cur-y - 10, img_planebullet);putimage(cur-x , cur-y, img_abullet);}listchangexy(bbullet);for (list* cur bbullet; cur ! NULL; cur cur-next){//putimage(cur-x - 10, cur-y - 10, img_planebullet);putimage(cur-x, cur-y, img_bbullet);}}void ufocmove()
{static float disx 0, disy 0;static float tmpx 0, tmpy 0;static float vx 0, vy 0;float step 1000 / c.speed;if (1 c.bornflag){c.bornflag 0;tmpx rand() % (WIDTH - c.width);tmpy -c.height;disx plane.x - tmpx;disy plane.y - tmpy;vx disx / step;vy disy / step;}tmpx vx;tmpy vy;c.x (int)(tmpx 0.5);c.y (int)(tmpy 0.5);if (c.x -c.width){c.bornflag 1;}else if (c.x WIDTH){c.bornflag 1;}if (c.y HEIGHT){c.bornflag 1;}}
bool Timer(int ms, int id)
{static DWORD t[10];if (clock() - t[id] ms){t[id] clock();return true;}return false;
}
void player_move(int speed) //处理飞机移动
{int reload_time 100;static int fire_start 0;int tmp clock();if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState(W)){if (plane.y 0)plane.y - speed;}if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState(S)){if (plane.y 51 HEIGHT)plane.y speed;}if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState(A)){if (plane.x 0)plane.x - speed;}if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState(D)){if (plane.x 51 WIDTH)plane.x speed;}if ((GetAsyncKeyState(VK_SPACE)) Timer(300, 1)){pushback1(planebullet, 0, -20);pushback1(planebullet, -10, -17.32);pushback1(planebullet, 10, -17.32);}}int main(){initgraph(WIDTH, HEIGHT,CONSOLE_FULLSCREEN);BeginBatchDraw();datainit();while (1){load();draw();ufoamove();ufobmove();ufocmove();player_move(5);showbullet();FlushBatchDraw();}EndBatchDraw();getchar();}5.剩下的发在下篇
6.效果演示 效果演示