第一版本:多画面显示
//#include <tchar.h> //在程序中使用 #include <tchar.h> 添加对 TCHAR 的支持。
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //清屏命令在这里。
#include <windows.h> //延时10毫秒-sleep,gotoxy函数
#include <iostream>
#include <conio.h> //getch()----不用按回车,就可以输入字符。
#include <graphics.h> //EasyX库,所使用的!
#include <math.h> //三角函数
#include <algorithm> //max(),min(),和abs(),sort函数排序方法,https://blog.csdn.net/BIGKALA/article/details/81624691,这是方法适用的地址
#include <time.h>
using namespace std;
//引用 windows multimedia api
#pragma comment(lib,"Winmm.lib " )
#define High 870
#define Width 591 //游戏画面尺寸
IMAGE img_bk; //背景图片
float position_x, position_y; //飞机的位置
float bullet_x, bullet_y; //子弹的位置
float enemy_x, enemy_y; //敌机的位置
IMAGE img_planeNormal1, img_planeNormal2; //正常飞机图片
IMAGE img_planeExplode1, img_planeExplode2; //爆炸飞机图片
IMAGE img_bullet1, img_bullet2; //子弹图片
IMAGE img_enemyPlane1, img_enemyPlane2; //敌机图片
int isExpolde = 0; //飞机是否爆炸
int score = 0; //得分
int gameStatus = 0; //游戏状态,0为初始菜单界面,1为正常游戏,2为结束游戏状态,3位游戏暂停
void startMenu(); //初始菜单界面
void pauseMenu(); //游戏暂停后的菜单界面,一般按下esc键后启动该界面
void startup(); //数据的初始化
void show(); //显示画面
void updateWithoutInput(); //与用户输入无关的更新
void updateWithInpute(); //与用户输入有关的更新
void gameover(); //游戏结束,进入后续处理
void startMenu() //初始菜单界面
{
putimage(0, 0, &img_bk); //显示背景
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.3, _T("1,进入游戏 "));
outtextxy(Width*0.3, High*0.4, _T("2,退出 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
gameStatus = 2;
exit(0);
}
}
}
void pauseMenu()
{
putimage(0, 0, &img_bk);
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.3, _T("1,继续游戏 "));
outtextxy(Width*0.3, High*0.4, _T("2,退出 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
gameStatus = 2;
exit(0);
}
}
}
void startup()
{
mciSendString(_T("open .\\game_music.mp3 alias bkmusic"), NULL, 0, NULL); //打开背景音乐
mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL); //循环播放
initgraph(Width, High);
//获取窗口句柄
HWND hwnd = GetHWnd();
//设置窗口标题文字
SetWindowText(hwnd, _T("飞机大战V1.0 "));
loadimage(&img_bk, _T(".\\background.jpg"));
/*loadimage(&img_planeNormal1, _T(".\\planeNormal1.jpg"));
loadimage(&img_planeNormal2, _T(".\\planeNormal2.jpg"));
loadimage(&img_bullet1, _T(".\\bullet1.jpg"));
loadimage(&img_bullet2, _T(".\\bullet2.jpg"));
loadimage(&img_enemyPlane1, _T(".\\enemyPlane1.jpg"));
loadimage(&img_enemyPlane2, _T(".\\enemyPlane2.jpg"));
loadimage(&img_planeExplode1, _T(".\\planeExplode1.jpg"));
loadimage(&img_planeExplode2, _T(".\\planeExplode2.jpg"));
*/
position_x = Width*0.5;
position_y = High*0.7;
bullet_x = position_x;
bullet_y = -85;
enemy_x = Width*0.5;
enemy_y = 10;
BeginBatchDraw();
while (gameStatus == 1)
{
startMenu(); //初始菜单界面
}
}
void show()
{
while (gameStatus == 3)
{
pauseMenu(); //游戏暂停后的菜单界面,一般按ESC键后启动该界面
}
putimage(0, 0, &img_bk); //显示背景
if (isExpolde == 0)
{
putimage(position_x - 50, position_y - 60, &img_planeNormal1, NOTSRCERASE); //显示正常飞机
putimage(position_x - 50, position_y - 60, &img_planeNormal2, SRCINVERT);
putimage(bullet_x - 7, bullet_y, &img_bullet1, NOTSRCERASE); //显示子弹
putimage(bullet_x - 7, bullet_y, &img_bullet2, SRCINVERT);
putimage(enemy_x, enemy_y, &img_enemyPlane1, NOTSRCERASE); //显示敌机
putimage(enemy_x, enemy_y, &img_enemyPlane2, SRCINVERT);
}
else
{
putimage(position_x - 50, position_y - 60, &img_planeExplode1, NOTSRCERASE); //显示爆炸飞机
putimage(position_x - 50, position_y - 60, &img_planeExplode2, SRCINVERT);
}
settextcolor(RED);
settextstyle(20, 0, _T("黑体"));
outtextxy(Width*0.48, High*0.95, _T("得分: "));
//TCHAR s[5]; //这里竟然出现了一个bug,字符串宽度问题 把char 改成TCHAR即可 https://www.cnblogs.com/zhougeng/p/11827675.html
TCHAR s[5];
scanf("%d", &s);
outtextxy(Width*0.55, High*0.95, s);
FlushBatchDraw();
Sleep(2);
}
void updateWithoutInput()
{
if (isExpolde == 0)
{
if (bullet_y>-25 )
{
bullet_y = bullet_y - 2;
}
if (enemy_y<High-25 )
{
enemy_y = enemy_y + 0.5;
}
else
{
enemy_y = 10;
}
if (abs(bullet_x-enemy_x )+abs(bullet_y-enemy_y )<80 )
{
enemy_x = rand() % Width;
enemy_y = -40;
bullet_y = -85;
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\gotEnemy.mp3 alias gemusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play gemusic"), NULL, 0, NULL); //仅仅播放一次
score++;
}
if (score>0 && score%5==0 &&score%2!=0 )
{
mciSendString(_T("stop 5music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 5music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\5.mp3 alias 5music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 5music"), NULL, 0, NULL); //仅仅播放一次
}
if (score%10==0)
{
mciSendString(_T("stop 10music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 10music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\10.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 10music"), NULL, 0, NULL); //仅仅播放一次
}
}
if (abs(position_x-enemy_x )+abs(position_y-enemy_y )<150 ) //敌机击中我机
{
isExpolde = 1;
mciSendString(_T("stop exmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close exmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\explode.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play exmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
void updateWithInpute()
{
MOUSEMSG m;
while (MouseHit())
{
m = GetMouseMsg(); //定义鼠标消息
if (m.uMsg==WM_MOUSEMOVE ) //这个函数用于检测当前是否有鼠标消息
{
//飞机的位置等于鼠标所在的位置
position_x = m.x;
position_y = m.y;
}
else if (m.uMsg==WM_LBUTTONDOWN )
{
//按下鼠标左键发射子弹
bullet_x = position_x;
bullet_y = position_y - 85;
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\f_gun.mp3 alias fgmusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play fgmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
char input;
if (kbhit())
{
input = getch();
if (input == 27)
{
gameStatus = 3;
}
}
}
void gameover()
{
EndBatchDraw();
getch();
closegraph();
}
int main()
{
startup(); //数据的初始化
while (1) //游戏循环执行
{
show(); //显示画面
updateWithoutInput();
updateWithInpute();
}
gameover(); //游戏结束,进行后续处理
return 0;
}
我去调试,结果提示我这个错误
image.png
1>源.obj : error LNK2019: 无法解析的外部符号 "void __cdecl updateWithInpute(void)" (?updateWithInpute@@YAXXZ),该符号在函数 _main 中被引用
1>G:\360data\重要数据\我的文档\Visual Studio 2013\Projects\C++文件01\Debug\C++文件01.exe : fatal error LNK1120: 1 个无法解析的外部命令
解决办法很简单,有一个updatewithinput函数,我忘记写了。完善之后就搞定了
但是我遇到了新的问题!
加载图片,失败,加载不进去。
=========
找了很多方法,都不行!
https://tieba.baidu.com/p/5138402911
https://tieba.baidu.com/p/5053729526
最后还是解决了,原来是代码游戏状态 gamestatus的问题
//#include <tchar.h> //在程序中使用 #include <tchar.h> 添加对 TCHAR 的支持。
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //清屏命令在这里。
#include <windows.h> //延时10毫秒-sleep,gotoxy函数
#include <iostream>
#include <conio.h> //getch()----不用按回车,就可以输入字符。
#include <graphics.h> //EasyX库,所使用的!
#include <math.h> //三角函数
#include <algorithm> //max(),min(),和abs(),sort函数排序方法,https://blog.csdn.net/BIGKALA/article/details/81624691,这是方法适用的地址
#include <time.h>
using namespace std;
//引用 windows multimedia api
#pragma comment(lib,"Winmm.lib " )
#define High 870
#define Width 591 //游戏画面尺寸
IMAGE img_bk; //背景图片
float position_x, position_y; //飞机的位置
float bullet_x, bullet_y; //子弹的位置
float enemy_x, enemy_y; //敌机的位置
IMAGE img_planeNormal1, img_planeNormal2; //正常飞机图片
IMAGE img_planeExplode1, img_planeExplode2; //爆炸飞机图片
IMAGE img_bullet1, img_bullet2; //子弹图片
IMAGE img_enemyPlane1, img_enemyPlane2; //敌机图片
int isExpolde = 0; //飞机是否爆炸
int score = 0; //得分
int gameStatus = 0; //游戏状态,0为初始菜单界面,1为正常游戏,2为结束游戏状态,3位游戏暂停
void startMenu(); //初始菜单界面
void pauseMenu(); //游戏暂停后的菜单界面,一般按下esc键后启动该界面
void startup(); //数据的初始化
void show(); //显示画面
void updateWithoutInput(); //与用户输入无关的更新
void updateWithInpute(); //与用户输入有关的更新
void gameover(); //游戏结束,进入后续处理
void startMenu() //初始菜单界面
{
putimage(0, 0, &img_bk); //显示背景
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.3, _T("1,进入游戏 "));
outtextxy(Width*0.3, High*0.4, _T("2,退出 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
gameStatus = 2;
exit(0);
}
}
}
void pauseMenu()
{
putimage(0, 0, &img_bk);
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.3, _T("1,继续游戏 "));
outtextxy(Width*0.3, High*0.4, _T("2,退出 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
gameStatus = 2;
exit(0);
}
}
}
void startup()
{
mciSendString(_T("open .\\game_music.mp3 alias bkmusic"), NULL, 0, NULL); //打开背景音乐
mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL); //循环播放
initgraph(Width, High);
//获取窗口句柄
HWND hwnd = GetHWnd();
//设置窗口标题文字
SetWindowText(hwnd, _T("飞机大战V1.0 "));
//loadimage,就是将这些图片载入到内存中。
loadimage(&img_bk, _T(".\\background.jpg"));
loadimage(&img_planeNormal1, _T(".\\planeNormal1.jpg"));
loadimage(&img_planeNormal2, _T(".\\planeNormal2.jpg"));
loadimage(&img_bullet1, _T(".\\bullet1.jpg"));
loadimage(&img_bullet2, _T(".\\bullet2.jpg"));
loadimage(&img_enemyPlane1, _T(".\\enemyPlane1.jpg"));
loadimage(&img_enemyPlane2, _T(".\\enemyPlane2.jpg"));
loadimage(&img_planeExplode1, _T(".\\planeExplode1.jpg"));
loadimage(&img_planeExplode2, _T(".\\planeExplode2.jpg"));
position_x = Width*0.5;
position_y = High*0.7;
bullet_x = position_x;
bullet_y = -85;
enemy_x = Width*0.5;
enemy_y = 10;
BeginBatchDraw();
while (gameStatus == 0) //游戏状态为0,初始菜单界面
{
startMenu(); //初始菜单界面
}
cout << "跳出了初始化。。。。。" << endl;
}
void show()
{
while (gameStatus == 3)
{
pauseMenu(); //游戏暂停后的菜单界面,一般按ESC键后启动该界面
}
putimage(0, 0, &img_bk); //显示背景
if (isExpolde == 0) //0代表没有爆炸
{
putimage(position_x - 50, position_y - 60, &img_planeNormal1, NOTSRCERASE); //显示正常飞机
putimage(position_x - 50, position_y - 60, &img_planeNormal2, SRCINVERT);
putimage(bullet_x - 7, bullet_y, &img_bullet1, NOTSRCERASE); //显示子弹
putimage(bullet_x - 7, bullet_y, &img_bullet2, SRCINVERT);
putimage(enemy_x, enemy_y, &img_enemyPlane1, NOTSRCERASE); //显示敌机
putimage(enemy_x, enemy_y, &img_enemyPlane2, SRCINVERT);
}
else
{
putimage(position_x - 50, position_y - 60, &img_planeExplode1, NOTSRCERASE); //显示爆炸飞机
putimage(position_x - 50, position_y - 60, &img_planeExplode2, SRCINVERT);
}
settextcolor(RED);
settextstyle(20, 0, _T("黑体"));
outtextxy(Width*0.48, High*0.95, _T("得分: "));
//TCHAR s[5]; //这里竟然出现了一个bug,字符串宽度问题 把char 改成TCHAR即可 https://www.cnblogs.com/zhougeng/p/11827675.html
TCHAR s[5];
scanf("%d", &s);
outtextxy(Width*0.55, High*0.95, s);
FlushBatchDraw();
Sleep(2);
}
void updateWithoutInput()
{
if (isExpolde == 0)
{
if (bullet_y>-25 )
{
bullet_y = bullet_y - 2;
}
if (enemy_y<High-25 )
{
enemy_y = enemy_y + 0.5;
}
else
{
enemy_y = 10;
}
if (abs(bullet_x-enemy_x )+abs(bullet_y-enemy_y )<80 )
{
enemy_x = rand() % Width;
enemy_y = -40;
bullet_y = -85;
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\gotEnemy.mp3 alias gemusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play gemusic"), NULL, 0, NULL); //仅仅播放一次
score++;
}
if (score>0 && score%5==0 &&score%2!=0 )
{
mciSendString(_T("stop 5music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 5music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\5.mp3 alias 5music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 5music"), NULL, 0, NULL); //仅仅播放一次
}
if (score%10==0)
{
mciSendString(_T("stop 10music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 10music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\10.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 10music"), NULL, 0, NULL); //仅仅播放一次
}
}
if (abs(position_x-enemy_x )+abs(position_y-enemy_y )<150 ) //敌机击中我机
{
isExpolde = 1;
mciSendString(_T("stop exmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close exmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\explode.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play exmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
void updateWithInpute()
{
MOUSEMSG m;
while (MouseHit())
{
m = GetMouseMsg(); //定义鼠标消息
if (m.uMsg==WM_MOUSEMOVE ) //这个函数用于检测当前是否有鼠标消息
{
//飞机的位置等于鼠标所在的位置
position_x = m.x;
position_y = m.y;
}
else if (m.uMsg==WM_LBUTTONDOWN )
{
//按下鼠标左键发射子弹
bullet_x = position_x;
bullet_y = position_y - 85;
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\f_gun.mp3 alias fgmusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play fgmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
char input;
if (kbhit())
{
input = getch();
if (input == 27)
{
gameStatus = 3;
}
}
}
void gameover()
{
EndBatchDraw();
getch();
closegraph();
}
int main()
{
startup(); //数据的初始化
while (true)
{
show(); //显示画面,背景图片之类的,都在这里显示。。
updateWithoutInput();
updateWithInpute();
} //游戏循环执行
gameover(); //游戏结束,进行后续处理
return 0;
}
但是遇到了新的问题,按键数字1或者2,都不好使
image.png
也解决了。
下面是我测试成功之后,可以正常运行的版本
//#include <tchar.h> //在程序中使用 #include <tchar.h> 添加对 TCHAR 的支持。
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //清屏命令在这里。
#include <windows.h> //延时10毫秒-sleep,gotoxy函数
#include <iostream>
#include <conio.h> //getch()----不用按回车,就可以输入字符。
#include <graphics.h> //EasyX库,所使用的!
#include <math.h> //三角函数
#include <algorithm> //max(),min(),和abs(),sort函数排序方法,https://blog.csdn.net/BIGKALA/article/details/81624691,这是方法适用的地址
#include <time.h>
using namespace std;
//引用 windows multimedia api
#pragma comment(lib,"Winmm.lib " )
#define High 870
#define Width 591 //游戏画面尺寸
IMAGE img_bk; //背景图片
float position_x, position_y; //飞机的位置
float bullet_x, bullet_y; //子弹的位置
float enemy_x, enemy_y; //敌机的位置
IMAGE img_planeNormal1, img_planeNormal2; //正常飞机图片
IMAGE img_planeExplode1, img_planeExplode2; //爆炸飞机图片
IMAGE img_bullet1, img_bullet2; //子弹图片
IMAGE img_enemyPlane1, img_enemyPlane2; //敌机图片
int isExpolde = 0; //飞机是否爆炸
int score = 0; //得分
int gameStatus = 0; //游戏状态,0为初始菜单界面,1为正常游戏,2为结束游戏状态,3位游戏暂停
void startMenu(); //初始菜单界面
void pauseMenu(); //游戏暂停后的菜单界面,一般按下esc键后启动该界面
void startup(); //数据的初始化
void show(); //显示画面
void updateWithoutInput(); //与用户输入无关的更新
void updateWithInpute(); //与用户输入有关的更新
void gameover(); //游戏结束,进入后续处理
void startMenu() //初始菜单界面
{
putimage(0, 0, &img_bk); //显示背景
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.3, _T("1,进入游戏 "));
outtextxy(Width*0.3, High*0.4, _T("2,退出 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
gameStatus = 2;
exit(0);
}
}
else
{
cout << "没有案件消息" << endl;
}
cout << "startmenu结束了" << endl;
}
void pauseMenu()
{
putimage(0, 0, &img_bk);
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.3, _T("1,继续游戏 "));
outtextxy(Width*0.3, High*0.4, _T("2,退出 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
gameStatus = 2;
exit(0);
}
}
}
void startup()
{
mciSendString(_T("open .\\game_music.mp3 alias bkmusic"), NULL, 0, NULL); //打开背景音乐
mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL); //循环播放
initgraph(Width, High);
//获取窗口句柄
HWND hwnd = GetHWnd();
//设置窗口标题文字
SetWindowText(hwnd, _T("飞机大战V1.0 "));
//loadimage,就是将这些图片载入到内存中。
loadimage(&img_bk, _T(".\\background.jpg"));
loadimage(&img_planeNormal1, _T(".\\planeNormal_1.jpg"));
loadimage(&img_planeNormal2, _T(".\\planeNormal_2.jpg"));
loadimage(&img_bullet1, _T(".\\bullet1.jpg"));
loadimage(&img_bullet2, _T(".\\bullet2.jpg"));
loadimage(&img_enemyPlane1, _T(".\\enemyPlane1.jpg"));
loadimage(&img_enemyPlane2, _T(".\\enemyPlane2.jpg"));
loadimage(&img_planeExplode1, _T(".\\planeExplode_1.jpg"));
loadimage(&img_planeExplode2, _T(".\\planeExplode_2.jpg"));
position_x = Width*0.5;
position_y = High*0.7;
bullet_x = position_x;
bullet_y = -85;
enemy_x = Width*0.5;
enemy_y = 10;
BeginBatchDraw();
while (gameStatus == 0) //游戏状态为0,初始菜单界面
{
startMenu(); //初始菜单界面,等待用户按键1-进入游戏,还是按键2---退出程序
}
cout << "跳出了初始化。。。。。" << endl;
}
void show()
{
while (gameStatus == 3) //按下ESC的时候,游戏状态为3
{
pauseMenu(); //游戏暂停后的菜单界面,一般按ESC键后启动该界面
}
putimage(0, 0, &img_bk); //显示背景
if (isExpolde == 0) //0代表没有爆炸.然后就显示了正常飞机,子弹,敌机的图片都显示出来
{
putimage(position_x - 50, position_y - 60, &img_planeNormal1, NOTSRCERASE); //显示正常飞机
putimage(position_x - 50, position_y - 60, &img_planeNormal2, SRCINVERT);
putimage(bullet_x - 7, bullet_y, &img_bullet1, NOTSRCERASE); //显示子弹
putimage(bullet_x - 7, bullet_y, &img_bullet2, SRCINVERT);
putimage(enemy_x, enemy_y, &img_enemyPlane1, NOTSRCERASE); //显示敌机
putimage(enemy_x, enemy_y, &img_enemyPlane2, SRCINVERT);
}
else
{
putimage(position_x - 50, position_y - 60, &img_planeExplode1, NOTSRCERASE); //显示爆炸飞机
putimage(position_x - 50, position_y - 60, &img_planeExplode2, SRCINVERT);
}
settextcolor(RED);
settextstyle(20, 0, _T("黑体"));
outtextxy(Width*0.48, High*0.95, _T("得分: "));
//TCHAR s[5]; //这里竟然出现了一个bug,字符串宽度问题 把char 改成TCHAR即可 https://www.cnblogs.com/zhougeng/p/11827675.html
//char s[5];
////scanf("%d", &s);
//sprintf_s(s, "%d", score);
outtextxy(Width*0.6, High*0.95, score); //这个得分显示,有一些问题,显示的不够完整,以后再说。
FlushBatchDraw();
Sleep(2);
}
void updateWithoutInput()
{
if (isExpolde == 0) //0--没有爆炸的时候,
{
if (bullet_y>-25 ) //当子弹速度大于 -25的时候
{
bullet_y = bullet_y - 2; //子弹持续往上走
}
if (enemy_y<High-25 ) //当飞机没有落到最底下的时候,
{
enemy_y = enemy_y + 0.5; //飞机Y坐标缓慢的往下飞!
}
else
{
enemy_y = 10; //否则,当飞机落到最底下的时候,从上面重新往下落
}
if (abs(bullet_x-enemy_x )+abs(bullet_y-enemy_y )<80 ) //当子弹距离敌机足够近,也就是击中敌机的时候
{
enemy_x = rand() % Width; //敌机x坐标,重新生成
enemy_y = -40; //敌机Y坐标,从上往下走
bullet_y = -85; //子弹也在最上面,屏幕外面
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\gotEnemy.mp3 alias gemusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play gemusic"), NULL, 0, NULL); //仅仅播放一次
score++; //得分加1
}
if (score>0 && score%5==0 &&score%2!=0 ) //当得分是1,3,7,9等数字的时候,播放很嚣张的音乐,谁能阻止我?
{
//谁能阻止我
mciSendString(_T("stop 5music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 5music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\5.mp3 alias 5music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 5music"), NULL, 0, NULL); //仅仅播放一次
}
if (score%10==0) //每得10分,就播放,还要继续吗?如此嚣张的言论
{
mciSendString(_T("stop 10music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 10music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\10.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 10music"), NULL, 0, NULL); //仅仅播放一次
}
}
if (abs(position_x-enemy_x )+abs(position_y-enemy_y )<150 ) //敌机击中我机
{
isExpolde = 1;
mciSendString(_T("stop exmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close exmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\explode.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play exmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
void updateWithInpute()
{
MOUSEMSG m; //实例化一个对象 //定义鼠标消息
while (MouseHit()) //这个函数用于检测当前是否有鼠标消息
{
m = GetMouseMsg();
if (m.uMsg==WM_MOUSEMOVE ) //当鼠标移动的时候,飞机坐标就等同于鼠标坐标
{
//飞机的位置等于鼠标所在的位置
position_x = m.x;
position_y = m.y;
}
else if (m.uMsg==WM_LBUTTONDOWN ) //按下鼠标左键发射子弹
{
bullet_x = position_x;
bullet_y = position_y - 85;
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\f_gun.mp3 alias fgmusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play fgmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
char input;
if (kbhit())
{
input = getch();
if (input == 27)
{
gameStatus = 3;
}
}
}
void gameover()
{
EndBatchDraw();
getch();
closegraph();
}
int main()
{
startup(); //数据的初始化,游戏状态为0时,会一直在初始化界面。当用户按键1时候,会进入到下个页面
while (true)
{
show(); //显示画面,背景图片之类的,都在这里显示。。
updateWithoutInput();
updateWithInpute();
} //游戏循环执行
gameover(); //游戏结束,进行后续处理
return 0;
}
========================
接下来的版本,要加上游戏的读档和存档
//新的延时函数
void delay(DWORD ms) //新的延时函数
{
static DWORD oldtime = GetTickCount();
while (GetTickCount()-oldtime<ms )
{
Sleep(1);
}
oldtime = GetTickCount();
} //用delay(5)代替sleep(5)进行调用,
============
//#include <tchar.h> //在程序中使用 #include <tchar.h> 添加对 TCHAR 的支持。
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //清屏命令在这里。
#include <windows.h> //延时10毫秒-sleep,gotoxy函数
#include <iostream>
#include <conio.h> //getch()----不用按回车,就可以输入字符。
#include <graphics.h> //EasyX库,所使用的!
#include <math.h> //三角函数
#include <algorithm> //max(),min(),和abs(),sort函数排序方法,https://blog.csdn.net/BIGKALA/article/details/81624691,这是方法适用的地址
#include <time.h>
using namespace std;
//引用 windows multimedia api
#pragma comment(lib,"Winmm.lib " )
#define High 870
#define Width 591 //游戏画面尺寸
IMAGE img_bk; //背景图片
float position_x, position_y; //飞机的位置
float bullet_x, bullet_y; //子弹的位置
float enemy_x, enemy_y; //敌机的位置
IMAGE img_planeNormal1, img_planeNormal2; //正常飞机图片
IMAGE img_planeExplode1, img_planeExplode2; //爆炸飞机图片
IMAGE img_bullet1, img_bullet2; //子弹图片
IMAGE img_enemyPlane1, img_enemyPlane2; //敌机图片
int isExpolde = 0; //飞机是否爆炸
int score = 0; //得分
int gameStatus = 0; //游戏状态,0为初始菜单界面,1为正常游戏,2为结束游戏状态,3位游戏暂停
void startMenu(); //初始菜单界面
void pauseMenu(); //游戏暂停后的菜单界面,一般按下esc键后启动该界面
void startup(); //数据的初始化
void show(); //显示画面
void updateWithoutInput(); //与用户输入无关的更新
void updateWithInpute(); //与用户输入有关的更新
void gameover(); //游戏结束,进入后续处理
void readRecordFile(); //读取游戏存档
void writeRecordFile(); //存储游戏存档
void delay(DWORD ms) //新的延时函数
{
static DWORD oldtime = GetTickCount();
while (GetTickCount()-oldtime<ms )
{
Sleep(1);
}
oldtime = GetTickCount();
} //用delay(5)代替sleep(5)进行调用,
void startMenu() //初始菜单界面
{
putimage(0, 0, &img_bk); //显示背景
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.2, _T("1,进入游戏 "));
outtextxy(Width*0.3, High*0.3, _T("2,读取游戏存档 "));
outtextxy(Width*0.3, High*0.4, _T("3,退出 "));
settextcolor(BLUE);
settextstyle(30, 0, _T("黑体"));
outtextxy(Width*0.25, High*0.6, _T("鼠标移动控制飞机移动 "));
outtextxy(Width*0.25, High*0.65, _T("鼠标左键发射子弹 "));
outtextxy(Width*0.25, High*0.7, _T("ESC键暂停游戏 "));
outtextxy(Width*0.25, High*0.75, _T("撞击后按任意键重新开始 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
gameStatus = 1;
}
else if (input == '3')
{
gameStatus = 2;
exit(0);
}
}
}
void pauseMenu()
{
putimage(0, 0, &img_bk);
setbkmode(TRANSPARENT);
settextcolor(BLACK);
settextstyle(50, 0, _T("黑体"));
outtextxy(Width*0.3, High*0.2, _T("1,继续游戏 "));
outtextxy(Width*0.3, High*0.3, _T("2,保存档案 "));
outtextxy(Width*0.3, High*0.4, _T("3,退出 "));
settextcolor(BLUE);
settextstyle(30, 0, _T("黑体"));
outtextxy(Width*0.25, High*0.6, _T("鼠标移动控制飞机移动 "));
outtextxy(Width*0.25, High*0.65, _T("鼠标左键发射子弹 "));
outtextxy(Width*0.25, High*0.7, _T("ESC键暂停游戏 "));
outtextxy(Width*0.25, High*0.75, _T("撞击后按任意键重新开始 "));
FlushBatchDraw();
Sleep(2);
char input;
if (kbhit()) //判断用户是否有输入?
{
input = getch(); //根据用户的不同输入来移动,不必输入回车
if (input == '1')
{
gameStatus = 1;
}
else if (input == '2')
{
writeRecordFile();
gameStatus = 1;
}
else if (input == '3')
{
gameStatus = 2;
exit(0);
}
}
}
void readRecordFile()
{
FILE *fp;
fp = fopen(".\\gameRecord.dat ", "r");
fscanf(fp, "%f %f %f %f %f %f %d %d ", &position_x, &position_y, &bullet_x, &bullet_y, &enemy_x, &enemy_y, &isExpolde, &score);
fclose(fp);
}
void writeRecordFile()
{
FILE *fp;
fp = fopen(".\\gameRecord.dat ", "w");
fprintf(fp, "%f %f %f %f %f %f %d %d ", position_x, position_y, bullet_x, bullet_y, enemy_x, enemy_y, isExpolde, score);
fclose(fp);
}
void startup()
{
mciSendString(_T("open .\\game_music.mp3 alias bkmusic"), NULL, 0, NULL); //打开背景音乐
mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL); //循环播放
initgraph(Width, High);
//获取窗口句柄
HWND hwnd = GetHWnd();
//设置窗口标题文字
SetWindowText(hwnd, _T("飞机大战V1.0 "));
//loadimage,就是将这些图片载入到内存中。
loadimage(&img_bk, _T(".\\background.jpg"));
loadimage(&img_planeNormal1, _T(".\\planeNormal_1.jpg"));
loadimage(&img_planeNormal2, _T(".\\planeNormal_2.jpg"));
loadimage(&img_bullet1, _T(".\\bullet1.jpg"));
loadimage(&img_bullet2, _T(".\\bullet2.jpg"));
loadimage(&img_enemyPlane1, _T(".\\enemyPlane1.jpg"));
loadimage(&img_enemyPlane2, _T(".\\enemyPlane2.jpg"));
loadimage(&img_planeExplode1, _T(".\\planeExplode_1.jpg"));
loadimage(&img_planeExplode2, _T(".\\planeExplode_2.jpg"));
position_x = Width*0.5;
position_y = High*0.7;
bullet_x = position_x;
bullet_y = -85;
enemy_x = Width*0.5;
enemy_y = 10;
BeginBatchDraw();
while (gameStatus == 0) //游戏状态为0,初始菜单界面
{
startMenu(); //初始菜单界面,等待用户按键1-进入游戏,还是按键2---退出程序
}
}
void show()
{
while (gameStatus == 3) //按下ESC的时候,游戏状态为3
{
pauseMenu(); //游戏暂停后的菜单界面,一般按ESC键后启动该界面
}
putimage(0, 0, &img_bk); //显示背景
if (isExpolde == 0) //0代表没有爆炸.然后就显示了正常飞机,子弹,敌机的图片都显示出来
{
putimage(position_x - 50, position_y - 60, &img_planeNormal1, NOTSRCERASE); //显示正常飞机
putimage(position_x - 50, position_y - 60, &img_planeNormal2, SRCINVERT);
putimage(bullet_x - 7, bullet_y, &img_bullet1, NOTSRCERASE); //显示子弹
putimage(bullet_x - 7, bullet_y, &img_bullet2, SRCINVERT);
putimage(enemy_x, enemy_y, &img_enemyPlane1, NOTSRCERASE); //显示敌机
putimage(enemy_x, enemy_y, &img_enemyPlane2, SRCINVERT);
}
else
{
putimage(position_x - 50, position_y - 60, &img_planeExplode1, NOTSRCERASE); //显示爆炸飞机
putimage(position_x - 50, position_y - 60, &img_planeExplode2, SRCINVERT);
}
settextcolor(RED);
settextstyle(20, 0, _T("黑体"));
outtextxy(Width*0.48, High*0.95, _T("得分: "));
//TCHAR s[5]; //这里竟然出现了一个bug,字符串宽度问题 把char 改成TCHAR即可 https://www.cnblogs.com/zhougeng/p/11827675.html
//char s[5];
////scanf("%d", &s);
//sprintf_s(s, "%d", score);
outtextxy(Width*0.6, High*0.95, score); //这个得分显示,有一些问题,显示的不够完整,以后再说。
FlushBatchDraw();
Sleep(2);
}
void updateWithoutInput()
{
if (isExpolde == 0) //0--没有爆炸的时候,
{
if (bullet_y>-25 ) //当子弹速度大于 -25的时候
{
bullet_y = bullet_y - 2; //子弹持续往上走
}
if (enemy_y<High-25 ) //当飞机没有落到最底下的时候,
{
enemy_y = enemy_y + 0.5; //飞机Y坐标缓慢的往下飞!
}
else
{
enemy_y = 10; //否则,当飞机落到最底下的时候,从上面重新往下落
}
if (abs(bullet_x-enemy_x )+abs(bullet_y-enemy_y )<80 ) //当子弹距离敌机足够近,也就是击中敌机的时候
{
enemy_x = rand() % Width; //敌机x坐标,重新生成
enemy_y = -40; //敌机Y坐标,从上往下走
bullet_y = -85; //子弹也在最上面,屏幕外面
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\gotEnemy.mp3 alias gemusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play gemusic"), NULL, 0, NULL); //仅仅播放一次
score++; //得分加1
}
if (score>0 && score%5==0 &&score%2!=0 ) //当得分是1,3,7,9等数字的时候,播放很嚣张的音乐,谁能阻止我?
{
//谁能阻止我
mciSendString(_T("stop 5music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 5music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\5.mp3 alias 5music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 5music"), NULL, 0, NULL); //仅仅播放一次
}
if (score%10==0) //每得10分,就播放,还要继续吗?如此嚣张的言论
{
mciSendString(_T("stop 10music"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close 10music"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\10.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play 10music"), NULL, 0, NULL); //仅仅播放一次
}
}
if (abs(position_x-enemy_x )+abs(position_y-enemy_y )<150 ) //敌机击中我机
{
isExpolde = 1;
mciSendString(_T("stop exmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close exmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\explode.mp3 alias 10music"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play exmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
void updateWithInpute()
{
MOUSEMSG m; //实例化一个对象 //定义鼠标消息
while (MouseHit()) //这个函数用于检测当前是否有鼠标消息
{
m = GetMouseMsg();
if (m.uMsg==WM_MOUSEMOVE ) //当鼠标移动的时候,飞机坐标就等同于鼠标坐标
{
//飞机的位置等于鼠标所在的位置
position_x = m.x;
position_y = m.y;
}
else if (m.uMsg==WM_LBUTTONDOWN ) //按下鼠标左键发射子弹
{
bullet_x = position_x;
bullet_y = position_y - 85;
mciSendString(_T("stop fgmusic"), NULL, 0, NULL); //先把前面一次的音乐停止
mciSendString(_T("close fgmusic"), NULL, 0, NULL); //先把前面一次的音乐关闭
mciSendString(_T("open .\\f_gun.mp3 alias fgmusic"), NULL, 0, NULL); //打开跳动音乐
mciSendString(_T("play fgmusic"), NULL, 0, NULL); //仅仅播放一次
}
}
char input;
if (kbhit())
{
input = getch();
if (input == 27)
{
gameStatus = 3;
}
}
}
void gameover()
{
EndBatchDraw();
getch();
closegraph();
}
int main()
{
startup(); //数据的初始化,游戏状态为0时,会一直在初始化界面。当用户按键1时候,会进入到下个页面
while (true)
{
show(); //显示画面,背景图片之类的,都在这里显示。。
updateWithoutInput();
updateWithInpute();
} //游戏循环执行
gameover(); //游戏结束,进行后续处理
return 0;
}
网友评论