素材链接:
https://share.weiyun.com/6NlDMrJU
代码如下:
//游戏名:【星球大战】。//游戏玩法:玩家操控火箭攻击boss,期间通过走位躲避boss的炮弹和小怪,(小怪可以被玩家的炮弹打碎),// 通过攻击boss获得能量来积攒大招,或者通过捡取道具来获得高额炮弹。//键位:w s a d 上下左右移动, Shift 加速, J 射击,K 大炮,Z 技能;//该游戏自带四种BGM(来源于网络)分别为背景音乐,获胜音乐,失败音乐,boss更换形态音乐#include<stdio.h>#include <stdlib.h>#include <graphics.h>#include<conio.h>#include<time.h>#include<mmsystem.h>#pragma comment(lib,"Winmm.lib")#include<easyX.h>//申请图片内存,定义图片变量IMAGE bk;//背景图片IMAGE Player[2];//角色图片IMAGE ENEMY[2];//小飞船图片IMAGE BOSS[4];//boss图片IMAGE beginbk;//开始界面图片IMAGE winbk;//获胜界面图片IMAGE losebk;//失败界面图片IMAGE playerHP[2];//玩家血条IMAGE bossHP;//boss生命条IMAGE PP;//能量条IMAGE boomnumber[2];//炸弹数目显示图IMAGE update[2];//升级图IMAGE JINKELA[2];//道具IMAGE paodan[2];//炮弹void picture()//加载图片{ loadimage(&bk,_T("./背景.jpg")); loadimage(&playerHP[0],_T("./玩家血条掩码.png"),20,20); loadimage(&playerHP[1],_T("./玩家血条.jpg"),20,20); loadimage(&bossHP,_T("./boss血条.png"),4,20); loadimage(&ENEMY[0],_T("敌人1掩码.png"),100,100); loadimage(&ENEMY[1],_T("敌人1.png"),100,100); loadimage(&PP,_T("./能量条.png"),4,20); loadimage(&update[0],_T("./升级.png"),40,40); loadimage(&update[1],_T("./升级掩码.png"),40,40); loadimage(&Player[0],_T("./火箭掩码.png"),100,70); loadimage(&Player[1],_T("./火箭.png"),100,70); loadimage(&BOSS[0],_T("./boss掩码1.png"),600,600); loadimage(&BOSS[1],_T("./boss.png"),600,600); loadimage(&beginbk,_T("./beginbk.jpeg"),1200,700); loadimage(&winbk,_T("./牛.jpeg"),1200,800); loadimage(&losebk,_T("./哭.jpeg"),1200,800); loadimage(&JINKELA[0],_T("./大炮道具掩码.png"),70,70); loadimage(&JINKELA[1],_T("./大炮道具.png"),70,70); loadimage(&paodan[0],_T("./炮弹掩码.png"),80,80); loadimage(&paodan[1],_T("./炮弹.png"),80,80); loadimage(&boomnumber[0],_T("./炮弹数目显示掩码.png"),30,30); loadimage(&boomnumber[1],_T("./炮弹数目显示.png"),30,30);}bool timer(unsigned int ms)//计时器{ static DWORD t1,t2; if(t2-t1>ms) { t1=t2; return true; } t2=clock(); return false;}bool timer2(int ms)//计时器{ static DWORD t3,t4; if(t4-t3>ms) { t3=t4; return true; } t4=clock(); return false;}bool timer3(int ms)//计时器{ static DWORD t5,t6; if(t6-t5>ms) { t5=t6; return true; } t6=clock(); return false;}void begingame()//开始界面 { initgraph(1200,800); putimage(0,0,&beginbk);//加载背景图片1 PlaySound(TEXT("./begin.wav"),NULL,SND_FILENAME | SND_ASYNC|SND_LOOP);//游戏背景BGM char beginstring[]="开始游戏"; char closestring[]="退出游戏"; char instructstring[]="wsad上下左右移动Shift加速J射击K大炮"; setfillcolor(LIGHTBLUE); solidrectangle(500,500,700,550); solidrectangle(500,600,700,650); solidrectangle(300,700,900,750); settextcolor(RED);//文字颜色 setbkmode(TRANSPARENT);//背景透明 settextstyle(30,0,"楷体"); outtextxy(500+40,500+10,beginstring); outtextxy(500+40,600+10,closestring); outtextxy(300+20,700+10,instructstring); ExMessage m; while(1) { m = getmessage(EM_MOUSE); if(m.x>=500&&m.x<=700&&m.y>=500&&m.y<=550) { setlinecolor(RED); rectangle(500-5,500-5,700+5,550+5); if(m.message==WM_LBUTTONDOWN) break; } else if(m.x>=500&&m.x<=700&&m.y>=600&&m.y<=650) { setlinecolor(RED); rectangle(500-5,600-5,700+5,650+5); if(m.message==WM_LBUTTONDOWN) exit(0); } else { setlinecolor(BLACK); rectangle(500-5,500-5,700+5,550+5); rectangle(500-5,600-5,700+5,650+5); } }}struct role//角色属性结构体:{ float x;//x坐标 float y;//y坐标 bool live;//状态 int hp;//生命值 int ATK;//攻击力 int type;//类型}player,bullet[5],enemy[3],boss,bulletBOSS[8],bulletplus,jinkela;//结构体变量:玩家,玩家子弹,敌人,boss,boss子弹,boss子弹类型void gameinit()//初始化游戏:玩家初始坐标,初始HP,子弹初始坐标,boss初始坐标,bossHP,boss子弹初始坐标{ player.x=400; player.y=600; player.live=true; player.hp=4; player.ATK=1; player.type=1; boss.x=600; boss.y=300; boss.live=true; boss.hp=400; int p=0; for(p=0;p<3;p++) enemy[p].live=false; for(p=0;p<5;p++) bullet[p].x=0; bullet[p].y=0; bullet[p].live=false; int i=0; for(i=0;i<8;i++) bulletBOSS[i].live=false; bulletplus.x=0; bulletplus.y=0; bulletplus.hp=0; bulletplus.live=false; jinkela.live=false;}void gamedraw()//运行游戏:{ //构件界面,加载图片 putimage(0,0,&bk); putimage(boss.x,boss.y,&BOSS[0],NOTSRCERASE); putimage(boss.x,boss.y,&BOSS[1],SRCINVERT); putimage(player.x,player.y,&Player[0],NOTSRCERASE ); putimage(player.x,player.y,&Player[1],SRCINVERT ); putimage(20,60,&update[1],NOTSRCERASE); putimage(20,60,&update[0],SRCINVERT); int temp,p=0; for(temp=0;temp<player.hp;temp++)//玩家血量的实时显示 { putimage(50+temp*20,50,&playerHP[0],NOTSRCERASE); putimage(50+temp*20,50,&playerHP[1],SRCINVERT); } for(temp=0;temp<int(boss.hp/2);temp++)//boss血量实时显示 putimage(350+temp*4,50,&bossHP); for(temp=0;temp<bulletplus.hp;temp++)//玩家炸弹的实时显示 { putimage(50+temp*30,100,&boomnumber[0],NOTSRCERASE); putimage(50+temp*30,100,&boomnumber[1],SRCINVERT); } for(p=0;p<3;p++) { if(enemy[p].live==true) { putimage(enemy[p].x,enemy[p].y,&ENEMY[0],NOTSRCERASE ); putimage(enemy[p].x,enemy[p].y,&ENEMY[1],SRCINVERT ); } if(enemy[p].hp==0||enemy[p].x<=-100) enemy[p].live=false; } for(p=0;p<5;p++) { if(bullet[p].live==true) { fillcircle(bullet[p].x,bullet[p].y,5);//普通子弹设定 setfillcolor(YELLOW); } } if(bulletplus.live==true) { putimage(bulletplus.x,bulletplus.y,&paodan[0],NOTSRCERASE ); putimage(bulletplus.x,bulletplus.y,&paodan[1],SRCINVERT );//高额炮弹设置 }}void playermove(float speed)//角色移动{ if(GetAsyncKeyState(VK_UP)||GetAsyncKeyState('W')) { if(player.y>0) player.y-=speed; } if(GetAsyncKeyState(VK_DOWN)||GetAsyncKeyState('S')) { if(player.y<730) player.y+=speed; }if(GetAsyncKeyState(VK_LEFT)||GetAsyncKeyState('A')){ if(player.x>0) player.x-=speed;}if(GetAsyncKeyState(VK_RIGHT)||GetAsyncKeyState('D')){ if(player.x<400) player.x+=speed;}if(GetAsyncKeyState('J'))//发射子弹{ int p=0; if(player.type==1||player.type==2) {for(p=0;p<5;p++) { if(!bullet[p].live&&timer3(300)) { bullet[p].x=player.x+100; bullet[p].y=player.y+35; bullet[p].live=true; } } } if(player.type==3&&bullet[0].live==false&&bullet[1].live==false&&bullet[2].live==false&&bullet[3].live==false&&bullet[4].live==false) { int k=0; for(p=0;p<5;p++) { bullet[p].live=true; bullet[p].x=player.x+100; bullet[p].y=player.y+k; k+=10; } }} if(GetAsyncKeyState('K')&&bulletplus.hp>0)//发射高额炮弹 { if(!bulletplus.live) { bulletplus.hp--; bulletplus.x=player.x+100; bulletplus.y=player.y+35; bulletplus.live=true; } }}void speedup()//手动加速{ if(GetAsyncKeyState(VK_SHIFT))playermove(0.4); }void UPDATE()//升级{ static int temp,P; for(temp=0;temp<P;temp++)//玩家能量条实时显示 putimage(50+temp*5,70,&PP); //积攒能量条的条件设定:普通子弹命中boss int p=0; for(p=0;p<5;p++) { if(bullet[p].x>boss.x+20&&bullet[p].x<boss.x+580&&bullet[p].y>boss.y+200&&bullet[p].y<boss.y+400) if(P<30) P++; } if(P==30) { bulletplus.hp++; player.ATK+=0.5; for(temp=0;temp<(1200-player.x)/10;temp++) P=0; } }void bulletmove()//子弹移动{ int p=0; if(player.type==1) {for(p=0;p<5;p++) {if(bullet[p].live==true) bullet[p].x+=1.5; if(bullet[p].x>1200) bullet[p].live=false; } } if(player.type==2) { for(p=0;p<5;p++) { if(bullet[p].live==true) { if(bullet[p].x<boss.x+300) bullet[p].x+=1.2; if(bullet[p].x>boss.x+300) bullet[p].x-=1.2; if(bullet[p].y<boss.y+300) bullet[p].y+=1.2; if(bullet[p].y>boss.y+300) bullet[p].y-=1.2; } } } if(player.type==3) { bullet[0].x+=2.5; bullet[0].y-=1.2; bullet[1].x+=2.8; bullet[1].y-=1; bullet[2].x+=3; bullet[3].x+=2.8; bullet[3].y+=1; bullet[4].x+=2.5; bullet[4].y+=1.2; for(p=0;p<5;p++) if(bullet[p].x>1200||bullet[p].y<-4||bullet[p].y>1204) bullet[p].live=false; } if(bulletplus.live==true) bulletplus.x+=1.0; if(bulletplus.x>1200) bulletplus.live=false;}void bossmove(float speed)//boss移动{ static int i=0; if(boss.live==true&&i%2==0) boss.y-=speed; if(boss.y<=-200||boss.y>=400) i++; if(boss.live==true&&i%2!=0) boss.y+=speed;}void playerbulletInteraction()//子弹交互(子弹打到boss,boss的变换){ int p=0; for(p=0;p<5;p++) {if(bullet[p].x>boss.x+20&&bullet[p].x<boss.x+580&&bullet[p].y>boss.y+200&&bullet[p].y<boss.y+400)//子弹与boss的坐标发生碰撞 { boss.hp-=player.ATK;//掉血 bullet[p].live=false;//子弹消失 //子弹坐标回归初始 bullet[p].x=0; bullet[p].y=0; } } if(bulletplus.x+40>boss.x+20&&bulletplus.x+40<boss.x+600&&bulletplus.y+40>boss.y+200&&bulletplus.y+40<boss.y+400) { boss.hp-=20; bulletplus.live=false; bulletplus.x=0; bulletplus.y=0; } //玩家子弹与小怪的交互 int j=0; for(j=0;j<5;j++) { for(p=0;p<3;p++) { if(bullet[j].x>enemy[p].x&&bullet[j].x<enemy[p].x+100&&bullet[j].y>enemy[p].y&&bullet[j].y<enemy[p].y+100) { enemy[p].hp-=player.ATK; bullet[j].live=false; bullet[j].x=0; bullet[j].y=0; } if(bulletplus.x+40>enemy[p].x&&bulletplus.x+40<enemy[p].x+100&&bulletplus.y+40>enemy[p].y&&bulletplus.y+40<enemy[p].y+100) enemy[p].live=false; } }}void enemybulletInteraction()//boss子弹交互{ int i=0; for(i=0;i<8;i++) { if(bulletBOSS[i].x<player.x+100&&bulletBOSS[i].x>player.x+90&&bulletBOSS[i].y<player.y+70&&bulletBOSS[i].y>player.y) { player.hp--; bulletBOSS[i].live=false; bulletBOSS[i].x=0; bulletBOSS[i].y=0; } } int p=0; for(p=0;p<3;p++) { //玩家碰到小怪掉血 if(enemy[p].x+50<player.x+100&&enemy[p].x+50>player.x&&enemy[p].y+50<player.y+70&&enemy[p].y+50>player.y) {player.hp--; enemy[p].live=false; enemy[p].x=0; enemy[p].y=0; }}}void createnemy()//创建小怪{ int p=0; for(p=0;p<3;p++) { if(!enemy[p].live) { enemy[p].live=true; enemy[p].hp=4; enemy[p].x=900; enemy[p].y=boss.y+200; } }}void enemymove()//小怪的移动方式{ if(enemy[0].live) { static int m=0; if(m%2==0) { enemy[0].x-=0.15; enemy[0].y+=0.5; } if(enemy[0].y>=700) m++; if(enemy[0].y<=0) m++; if(m%2!=0) { enemy[0].x-=0.15; enemy[0].y-=0.5; } } if(enemy[1].live) { static int n=0; if(n%2==0) { enemy[1].x-=0.3; enemy[1].y-=0.3; } if(enemy[1].y>=700) n++; if(enemy[1].y<=0) n++; if(n%2!=0) { enemy[1].x-=0.3; enemy[1].y+=0.3; } } if(enemy[2].live) { static int h=0; if(h%2==0) { enemy[2].x-=0.25; enemy[2].y-=0.4; } if(enemy[2].y>=700) h++; if(enemy[2].y<=0) h++; if(h%2!=0) { enemy[2].x-=0.25; enemy[2].y+=0.4; } }}void bossattack()//boss攻击方式{ static int j=0; static int k=-1,k2=0;//k2为boss进入第二状态时更换BGM所用的变量 if(boss.y<=-199) j++; if(boss.y>=399) j++; static int i=-500; if(j>k) { srand((unsigned int)time(NULL)); i=rand()%600-200; k++; } if(boss.y>=i&&boss.y<=i+1&&boss.hp>250)//boss召唤小兵 createnemy(); enemymove(); if(boss.hp<=250) { k2++; if(k2==1)//k2==1时boss为第四形态,更换BGM; PlaySound(TEXT("./BGM2.wav"),NULL,SND_FILENAME | SND_ASYNC|SND_LOOP); if(k2>10000)//为防止k2超上限,令k2在boss形态进入第二形态后一直循环于2-10000; k2=2; if(timer(300)) { int i=0; for(i=0;i<8;i++) { if(!bulletBOSS[i].live) { bulletBOSS[i].live=true; bulletBOSS[i].x=rand()%400+1200; bulletBOSS[i].y=rand()%800; } } } for(i=0;i<8;i++)//boss发射的炮弹 { fillcircle(bulletBOSS[i].x,bulletBOSS[i].y,8); if(bulletBOSS[i].live) { bulletBOSS[i].x-=1.3; if(bulletBOSS[i].x<-8) bulletBOSS[i].live=false; } } }}void createJINKELA()//局内道具{ if(timer2(10000)) { jinkela.live=true; static int q,r; srand((unsigned int)time(NULL)); q=rand()%400; r=rand()%730; jinkela.x=q; jinkela.y=r; } if(jinkela.live==true) { putimage(jinkela.x,jinkela.y,&JINKELA[0],NOTSRCERASE); putimage(jinkela.x,jinkela.y,&JINKELA[1],SRCINVERT ); } if(jinkela.x+35<player.x+100&&jinkela.x+35>player.x&&jinkela.y+35<player.y+70&&jinkela.y+35>player.y)//判定玩家吃到道具 { int i=1; srand((unsigned int)time(NULL)); i=rand()%100; jinkela.live=false; jinkela.x=-500; if(i%2==0) player.hp++; if(i%2!=0) bulletplus.hp++; if(player.type<3) player.type++; else player.type=1; }}void gameendwin()//游戏获胜界面{ initgraph(1200,800); putimage(0,0,&winbk); PlaySound(TEXT("./THEWIN.wav"),NULL,SND_FILENAME | SND_ASYNC|SND_LOOP); char endString[]="你赢啦!"; char closestring[]="退出游戏"; settextstyle(30,0,"楷体"); settextcolor(RED); setbkmode(TRANSPARENT); outtextxy(560,100,endString); setfillcolor(LIGHTBLUE); solidrectangle(500,500,700,550); outtextxy(500+40,500+10,closestring); ExMessage m; while(1) { m = getmessage(EM_MOUSE); if(m.x>=500&&m.x<=700&&m.y>=500&&m.y<=550) { setlinecolor(RED); rectangle(500-5,500-5,700+5,550+5); if(m.message==WM_LBUTTONDOWN) exit(0); } else { setlinecolor(BLACK); rectangle(500-5,500-5,700+5,550+5); } }}int gameendlose()//游戏失败界面{ initgraph(1200,800); putimage(0,0,&losebk); PlaySound(TEXT("./GAMEOVER.wav"),NULL,SND_FILENAME | SND_ASYNC|SND_LOOP);//游戏 char endString[]="你输啦!"; char closestring[]="退出游戏"; char againstring[]="返回主界面"; settextstyle(30,0,"楷体"); settextcolor(RED); setbkmode(TRANSPARENT); outtextxy(560,100,endString); setfillcolor(LIGHTBLUE); solidrectangle(500,500,700,550); outtextxy(500+40,500+10,againstring); solidrectangle(500,560,700,610); outtextxy(500+40,560+10,closestring); ExMessage m; while(1) { m = getmessage(EM_MOUSE); if(m.x>=500&&m.x<=700&&m.y>=560&&m.y<=610) { setlinecolor(RED); rectangle(500-5,560-5,700+5,610+5); if(m.message==WM_LBUTTONDOWN) exit(0); } else { setlinecolor(BLACK); rectangle(500-5,560-5,700+5,610+5); } if(m.x>=500&&m.x<=700&&m.y>=500&&m.y<=550) { setlinecolor(RED); rectangle(500-5,500-5,700+5,550+5); if(m.message==WM_LBUTTONDOWN) { begingame(); PlaySound(TEXT("./enemy.wav"),NULL,SND_FILENAME | SND_ASYNC|SND_LOOP);//游戏背景BGM gameinit(); BeginBatchDraw(); int i=0;//胜利失败判断 while(1) { FlushBatchDraw(); gamedraw(); playermove(0.35); bulletmove(); speedup(); UPDATE(); bossmove(0.4); bossattack(); playerbulletInteraction(); enemybulletInteraction(); createJINKELA(); if(boss.hp<=0) { i=1; break; } if(player.hp<=0) { i=2; break; } } EndBatchDraw(); if(i==1) gameendwin(); if(i==2) gameendlose(); return 0;} } else { setlinecolor(BLACK); rectangle(500-5,500-5,700+5,550+5); } }}int main(){ initgraph(1200,800); picture(); begingame(); PlaySound(TEXT("./enemy.wav"),NULL,SND_FILENAME | SND_ASYNC|SND_LOOP);//游戏背景BGM gameinit(); BeginBatchDraw(); int i=0;//胜利失败判断 while(1) { FlushBatchDraw(); gamedraw(); playermove(0.35); bulletmove(); speedup(); UPDATE(); bossmove(0.4); bossattack(); playerbulletInteraction(); enemybulletInteraction(); createJINKELA(); if(boss.hp<=0) { i=1; break; } if(player.hp<=0) { i=2; break; } } EndBatchDraw(); if(i==1) gameendwin(); if(i==2) gameendlose(); return 0;}