|
5鱼币
本帖最后由 猪猪虾 于 2023-5-1 20:19 编辑
这个坎。。。。
我定义的Mainplane.h文件 里面的静态成员static IMAGE imgMyplane;所以在Mainplane.cpp的文件头做了类外的声明
然后在成员函数getImage_Myplane里面返回这个对象,我也尝试了不定义静态的情况,一样的直接崩溃,在主程序
GameMain.cpp文件调用到这个getImage_Myplane的时候 。。。。
Mainplane.h文件
- #pragma once
- #include<graphics.h>
- #include<cstring>
- #include<vector>
- //#include "GameMain.h"
- using namespace std;
- class GameMain;
- class MyPlane
- {
- public:
- MyPlane();
- //static IMAGE getImages(); //私有成员可以在public里面,通过函数来间接访问和修改
- void Move(int dx, int dy);
- static IMAGE getImage_Myplane();
- int My_current_posiX;
- int My_current_posiY;
- int width;
- int height;
- private:
- static IMAGE imgMyplane;
- GameMain *GM;
- };
复制代码
Mainplane.cpp文件
- #pragma once
- #include<graphics.h>
- #include<cstring>
- #include<vector>
- #include "MyPlane.h"
- #include "GameMain.h"
- using namespace std;
- //静态成员,需要在类外进行声明
- IMAGE MyPlane::imgMyplane; // 这一行为 imgMyplane 分配内存空间
- //`MyPlane` 类在头文件 `MyPlane.h` 中声明,而 `imgMyplane` 的定义位于与类实现相关联的源文件
- //`MyPlane.cpp` 中。这样,您就解决了 `LNK2001` 错误。
- //如果您将所有代码放在同一个文件中,那么只需在类定义之后添加 `IMAGE MyPlane::imgMyplane; ` 这一行即可。
- //IMAGE MyPlane::imgMyplane; // 这一行为 imgMyplane 分配内存空间
- MyPlane::MyPlane()
- {
- width = 100;
- height = 125;
- loadimage(&imgMyplane, "E:/2022上/Leecode_April/plane/image/me1.png");
- //初始化飞机的位置在图像的正下方的中心
-
- My_current_posiX = GM->rows / 2 - width / 2;
- My_current_posiY = GM->cols - height;
- }
- IMAGE MyPlane::getImage_Myplane()
- {
- return imgMyplane;
- }
- void MyPlane::Move(int dx, int dy)
- {
-
- My_current_posiX += dx;
- My_current_posiY += dy;
- //判断是否超出了边界,还要考虑飞机本身的宽度
- if (My_current_posiX > (GM->rows - width / 2) || My_current_posiX < width / 2)
- {
- My_current_posiX -= dx;
- }
- if (My_current_posiX > (GM->cols - height / 2) || My_current_posiX < height / 2)
- {
- My_current_posiY -= dy;
- }
- }
复制代码
GameMain.h文件
- #pragma once
- #include<graphics.h>
- #include<cstring>
- #include<vector>
- //#include<MyPlane.h> 如果这里这么用,会发现 当前.h文件和MyPlane.h文件的彼此头文件相互包含,会报错
- class MyPlane; //告诉编译器,需要这个类,其他功能结构都没变
- using namespace std;
- class GameMain
- {
- friend class MyPlane;
- public:
- //构造函数 用于初始化参数,游戏界面设置
- GameMain();
- //游戏界面初始化
- void init();
- void paly(); // 开始游戏
- int* getBgSize();
- int rows;
- int cols;
- private:
- void keyEvent(); //按键控制
- void updateWindow(); //渲染界面
- private:
- bool update;
- // 添加这一行,这样其他地方调用这个类的时候,就不用每次都申明,不同地方申明,还是不同的对象,无法
- //实现同时操作一辆飞机
- MyPlane *MP;
- //背景图像参数
- IMAGE imgBg; //背景图片
- };
复制代码
GameMain.cpp文件
- #include "GameMain.h"
- #include "MyPlane.h"
- #include "Bullet.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:/2022上/res/bg.mp3 repeat", 0, 0, 0);
- //创建游戏窗口
- *initgraph(rows, cols);
- //加载背景图片
- loadimage(&imgBg, "E:/2022上/Leecode_April/plane/image/background.png");
- update = true;
- }
- void GameMain::paly()
- {
- init();
- while (1)
- {
- BeginBatchDraw();
- //接收用户的输入
- keyEvent();
- //更新游戏画面
- updateWindow();
- system("pause");
- EndBatchDraw();
- }
- }
- int* GameMain::getBgSize()
- {
- int num[] = { rows ,cols };
- int* ptr = new int[2];
- for (int i = 0; i < 2; i++) {
- ptr[i] = num[i];
- }
- return ptr;
- }
- 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;
- IMAGE TEMP_my;
- TEMP_my = MP->getImage_Myplane();
- putimage(MP->My_current_posiX, MP->My_current_posiY, &TEMP_my);
- //绘制子弹
- Bullet BT;
- IMAGE TEMP_BT;
- TEMP_BT = BT.getImage_Bullet();
- putimage(MP->My_current_posiX, MP->My_current_posiY, &TEMP_BT);
- EndBatchDraw();
- }
复制代码
根据您提供的代码,我注意到了一个问题。在 GameMain::updateWindow() 函数中,您在绘制子弹时使用了一个临时的 Bullet 对象,而这个对象并没有被正确地初始化。您需要将子弹对象加入到一个容器中(如 vector ),并在游戏主循环中对这些子弹进行更新和绘制。
首先,您需要在 GameMain 类中添加一个 vector 容器来存储子弹对象:
- #include <vector>
- #include "Bullet.h"
- class GameMain {
- // ...
- private:
- // ...
- std::vector<Bullet> bullets; // 添加子弹容器
- };
复制代码
然后,在游戏主循环中,您可以创建子弹并将它们添加到 bullets 容器中。在此之后,您需要在 GameMain::updateWindow() 函数中迭代 bullets 容器,并更新和绘制每个子弹:
- void GameMain::updateWindow() {
- putimage(0, 0, &imgBg);
- BeginBatchDraw();
- // 绘制我方飞机
- IMAGE TEMP_my;
- TEMP_my = MP->getImage_Myplane();
- putimage(MP->My_current_posiX, MP->My_current_posiY, &TEMP_my);
- // 绘制子弹
- for (Bullet& bullet : bullets) {
- bullet.update(); // 更新子弹位置
- IMAGE TEMP_BT;
- TEMP_BT = bullet.getImage_Bullet();
- putimage(bullet.getPosX(), bullet.getPosY(), &TEMP_BT);
- }
- EndBatchDraw();
- }
复制代码
这里需要注意的是,您还需要在 Bullet 类中添加一个更新子弹位置的函数(例如, update() )以及获取子弹位置的函数(例如, getPosX() 和 getPosY() )。
希望这些建议能帮助您解决问题。如果您还有其他问题或疑问,请随时告诉我。
|
最佳答案
查看完整内容
根据您提供的代码,我注意到了一个问题。在 GameMain::updateWindow() 函数中,您在绘制子弹时使用了一个临时的 Bullet 对象,而这个对象并没有被正确地初始化。您需要将子弹对象加入到一个容器中(如 vector ),并在游戏主循环中对这些子弹进行更新和绘制。
首先,您需要在 GameMain 类中添加一个 vector 容器来存储子弹对象:
然后,在游戏主循环中,您可以创建子弹并将它们添加到 bullets 容器中。在此 ...
|