c++putimage函数使用,为啥在构造函数里初始化飞机位置无效
本帖最后由 猪猪虾 于 2023-4-27 21:57 编辑这个图是将下面这段程序放在void GameMain::updateWindow()函数里面的效果
//初始化飞机的位置在图像的正下方的中心
MyPlane mp;
int* temp = mp.getMyPlaneSize();
int MyPlaneWidth = temp;
int MyPlaneHeight = temp;
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;
int MyPlaneHeight = temp;
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;
//int MyPlaneHeight = temp;
//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;
int MyPlaneHeight = temp;
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();
}
构造函数 是初始化,只执行一次
updateWindow() 是实时执行,刷新窗体是时时咳咳都在进行的。 从你的代码来看,问题在于你在`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;
int MyPlaneHeight = temp;
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;
int MyPlaneHeight = temp;
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;
int MyPlaneHeight = temp;
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;
int MyPlaneHeight = temp;
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()`函数将正确显示飞机的当前位置,而不会每次刷新都回到初始位置。这样,你可以实现飞机在游戏中的实时移动。 isdkz 发表于 2023-4-28 00:47
从你的代码来看,问题在于你在`GameMain`构造函数以及`updateWindow`函数中分别创建了不同的`MyPlane`对象 ...
谢谢大哥 猪猪虾 发表于 2023-4-28 13:59
谢谢大哥
是xie xie gpt
页:
[1]