|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 猪猪虾 于 2023-4-27 21:57 编辑
这个图是将下面这段程序放在void GameMain::updateWindow()函数里面的效果
//初始化飞机的位置在图像的正下方的中心
MyPlane mp;
int* temp = mp.getMyPlaneSize();
int MyPlaneWidth = temp[0];
int MyPlaneHeight = temp[1];
int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
int My_current_posiY = cols - MyPlaneHeight;
下面这个图是将下面这段程序放在GameMain::GameMain()构造函数里面的效果
//初始化飞机的位置在图像的正下方的中心
MyPlane mp;
int* temp = mp.getMyPlaneSize();
int MyPlaneWidth = temp[0];
int MyPlaneHeight = temp[1];
int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
int My_current_posiY = cols - MyPlaneHeight;
也就是说*****************************
那段设置起始位置的程序除了放在void GameMain::updateWindow()里面有效,放在其他函数里面都无效,我尝试过,但是我不想把这段程序放在updateWindow()里面,因为飞机的位置要实时改变,只能指定初始位置,如果放在updateWindow()里面,每次刷新都
回到初始位置,bug无疑了
- #include "GameMain.h"
- #include "MyPlane.h"
- #include<stdlib.h>
- #include <time.h>
- #include<graphics.h>
- #include <conio.h>
- #include"iostream"
- #include"string"
- #include "fstream"
- //音效
- #include<mmsystem.h>
- #pragma comment(lib,"winmm.lib")
- #pragma comment(lib,"WINMM.LIB")
- using namespace std;
- GameMain::GameMain()
- {
- //将游戏界面的宽度指定成背景图片的显示宽度
- rows = 438;
- cols = 675;
- //初始化飞机的位置在图像的正下方的中心
- //MyPlane mp;
- //int* temp = mp.getMyPlaneSize();
- //int MyPlaneWidth = temp[0];
- //int MyPlaneHeight = temp[1];
- //int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
- //int My_current_posiY = cols - MyPlaneHeight;
- }
- void GameMain::init()
- {
- //播放背景音乐
- mciSendString("play E:/res/bg.mp3 repeat", 0, 0, 0);
- //创建游戏窗口
- *initgraph(rows, cols);
- //加载背景图片
- loadimage(&imgBg, "E:/Leecode_April/plane/image/background.png");
- loadimage(&imgMyplane, "E:/Leecode_April/plane/image/me1.png");
- loadimage(&imgBullet, "E:/Leecode_April/plane/image/bullet1.png");
- update = true;
- }
- void GameMain::paly()
- {
- init();
- while (1)
- {
- BeginBatchDraw();
- //接收用户的输入
- keyEvent();
- //更新游戏画面
- updateWindow();
- system("pause");
- EndBatchDraw();
- }
- }
- IMAGE GameMain::getImage_Myplane()
- {
- return imgMyplane;
- }
- IMAGE GameMain::getImage_Bullet()
- {
- return imgBullet;
- }
- void GameMain::keyEvent()
- {
- unsigned char ch;
- int dx = 0;
- int dy = 0;
- //判断当前有没有按键输入,如果他没有按键输入,程序正常执行
- if (_kbhit()) {
- ch = _getch();
- //按下字母,返回的就是字母,按下的是方向键
- //上,先后返回: 224 72 下:224 80 左:75 224,75 右:224 77
- if (ch == 224) {
- ch = _getch();
- switch (ch) {
- case 72:
- dy = 1;
- break;
- case 80:
- dy = -1;
- break;
- case 75:
- dx = -1;
- break;
- case 77:
- dx = 1;
- break;
- default:
- break;
- }
- }
- }
- if (dx != 0 || dy != 0) //左右移动
- {
- MyPlane mp;
- mp.Move(dx,dy);
- update = true;
- }
- }
- void GameMain::updateWindow()
- {
- putimage(0, 0, &imgBg);
- BeginBatchDraw();
- //初始化飞机的位置在图像的正下方的中心
- MyPlane mp;
- int* temp = mp.getMyPlaneSize();
- int MyPlaneWidth = temp[0];
- int MyPlaneHeight = temp[1];
- int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
- int My_current_posiY = cols - MyPlaneHeight;
- putimage(My_current_posiX, My_current_posiY, &imgMyplane);
- putimage(My_current_posiX+50, My_current_posiY-50, &imgBullet);
- EndBatchDraw();
- }
复制代码
[b]从你的代码来看,问题在于你在`GameMain`构造函数以及`updateWindow`函数中分别创建了不同的`MyPlane`对象。这些对象是独立的,每个对象的位置信息都是单独的。当你在`keyEvent`函数中移动飞机时,你也是在操作一个独立的`MyPlane`对象。由于`updateWindow`函数中的`MyPlane`对象没有被移动,因此每次更新画面时飞机的位置没有改变。
为了解决这个问题,你需要将飞机对象的创建放在`GameMain`类的成员变量中。这样,在整个`GameMain`类中,只有一个`MyPlane`对象,其位置信息将在各个函数间共享。
修改方法如下:
1. 在`GameMain.h`中添加一个成员变量`MyPlane mp;`,例如:
- class GameMain
- {
- public:
- GameMain();
- void init();
- void paly();
- IMAGE getImage_Myplane();
- IMAGE getImage_Bullet();
- void keyEvent();
- void updateWindow();
- private:
- int rows;
- int cols;
- MyPlane mp; // 添加这一行
- IMAGE imgBg;
- IMAGE imgMyplane;
- IMAGE imgBullet;
- bool update;
- };
复制代码
2. 将你想放入`GameMain`构造函数的初始化代码移到`GameMain::init()`函数中。这样,在构造函数中不再创建新的`MyPlane`对象,而是使用`init()`函数中的成员变量`mp`:
- void GameMain::init()
- {
- // 其他初始化代码...
- // 初始化飞机的位置在图像的正下方的中心
- int* temp = mp.getMyPlaneSize();
- int MyPlaneWidth = temp[0];
- int MyPlaneHeight = temp[1];
- int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
- int My_current_posiY = cols - MyPlaneHeight;
- // 其他初始化代码...
- }
复制代码
3. 在`keyEvent`函数和`updateWindow`函数中,去掉局部的`MyPlane`对象创建,直接使用`GameMain`类的成员变量`mp`,例如:
- void GameMain::keyEvent()
- {
- // 其他代码...
- if (dx != 0 || dy != 0) //左右移动
- {
- mp.Move(dx,dy); // 修改这一行
- update = true;
- }
- }
- void GameMain::updateWindow()
- {
- putimage(0, 0, &imgBg);
- BeginBatchDraw();
- int* temp = mp.getMyPlaneSize();
- int MyPlaneWidth = temp[0];
- int MyPlaneHeight = temp[1];
- int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
- int My_current_posiY = cols - MyPlaneHeight;
- putimage(My_current_posiX, My_current_posiY, &imgMyplane);
- putimage(My_current_posiX+50, My_current_posiY-50, &imgBullet);
- EndBatchDraw();
- }
复制代码
这样修改后,你的飞机对象`mp`将在`GameMain` 类中各个函数之间共享,你可以在`GameMain::init()`函数中设置飞机的初始位置,并在`keyEvent`函数中实现飞机的移动。`updateWindow`函数将正确显示飞机的当前位置,而不会每次刷新都回到初始位置。
这里是修改后的完整`GameMain`类的实现:
- #include "GameMain.h"
- #include "MyPlane.h"
- #include<stdlib.h>
- #include <time.h>
- #include<graphics.h>
- #include <conio.h>
- #include"iostream"
- #include"string"
- #include "fstream"
- //音效
- #include<mmsystem.h>
- #pragma comment(lib,"winmm.lib")
- #pragma comment(lib,"WINMM.LIB")
- using namespace std;
- GameMain::GameMain()
- {
- //将游戏界面的宽度指定成背景图片的显示宽度
- rows = 438;
- cols = 675;
- }
- void GameMain::init()
- {
- //播放背景音乐
- mciSendString("play E:/res/bg.mp3 repeat", 0, 0, 0);
- //创建游戏窗口
- *initgraph(rows, cols);
- //加载背景图片
- loadimage(&imgBg, "E:/Leecode_April/plane/image/background.png");
- loadimage(&imgMyplane, "E:/Leecode_April/plane/image/me1.png");
- loadimage(&imgBullet, "E:/Leecode_April/plane/image/bullet1.png");
- // 初始化飞机的位置在图像的正下方的中心
- int* temp = mp.getMyPlaneSize();
- int MyPlaneWidth = temp[0];
- int MyPlaneHeight = temp[1];
- int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
- int My_current_posiY = cols - MyPlaneHeight;
- update = true;
- }
- void GameMain::paly()
- {
- init();
- while (1)
- {
- BeginBatchDraw();
- //接收用户的输入
- keyEvent();
- //更新游戏画面
- updateWindow();
- system("pause");
- EndBatchDraw();
- }
- }
- IMAGE GameMain::getImage_Myplane()
- {
- return imgMyplane;
- }
- IMAGE GameMain::getImage_Bullet()
- {
- return imgBullet;
- }
- void GameMain::keyEvent()
- {
- unsigned char ch;
- int dx = 0;
- int dy = 0;
- //判断当前有没有按键输入,如果他没有按键输入,程序正常执行
- if (_kbhit()) {
- ch = _getch();
- //按下字母,返回的就是字母,按下的是方向键
- //上,先后返回: 224 72 下:224 80 左:75 224,75 右:224 77
- if (ch == 224) {
- ch = _getch();
- switch (ch) {
- case 72:
- dy = 1;
- break;
- case 80:
- dy = -1;
- break;
- case 75:
- dx = -1;
- break;
- case 77:
- dx = 1;
- break;
- default:
- break;
- }
- }
- }
- if (dx != 0 || dy != 0) // 左右移动
- {
- mp.Move(dx,dy); // 使用成员变量mp
- update = true;
- }
- }
- void GameMain::updateWindow()
- {
- putimage(0, 0, &imgBg);
- BeginBatchDraw();
- int* temp = mp.getMyPlaneSize(); // 使用成员变量mp
- int MyPlaneWidth = temp[0];
- int MyPlaneHeight = temp[1];
- int My_current_posiX = rows / 2 - MyPlaneWidth / 2;
- int My_current_posiY = cols - MyPlaneHeight;
- putimage(My_current_posiX, My_current_posiY, &imgMyplane);
- putimage(My_current_posiX+50, My_current_posiY-50, &imgBullet);
- EndBatchDraw();
- }
复制代码
现在,你的代码应该可以正常工作。飞机的初始位置将在`GameMain::init()`函数中设置,而且当飞机移动时,`GameMain::keyEvent()`函数将更新飞机的位置。`GameMain::updateWindow()`函数将正确显示飞机的当前位置,而不会每次刷新都回到初始位置。这样,你可以实现飞机在游戏中的实时移动。[/b]
|
|