Lee_Serena 2024-06-18 14:01 采纳率: 14.3%
浏览 7

为什么我的敌机出场有一个敌机一直定在坐标(0,0),其他的飞机飞到半路就失踪了


#include "enemyplane.h"
#include"config.h"

EnemyPlane::EnemyPlane()
{
    //初始化敌机图片
    m_enemyPlane.load(ENEMY_PATH);

    //初始化敌机位置
    m_X=0;
    m_Y=0;

    //初始化敌机速度
    m_speed=ENEMY_SPEED;

    //初始化敌机状态
    isFree=true;

    //初始化矩形框
    m_rect.setWidth(m_enemyPlane.width());
    m_rect.setHeight(m_enemyPlane.height());
    m_rect.moveTo(m_X,m_Y);
}

void EnemyPlane::updatePosition()
{
    //如果敌机空闲,则不用计算敌机坐标
    if(isFree==true)
    {
        return;
    }

    //敌机不空闲,计算敌机坐标
    m_Y+=m_speed;

    //更新敌机矩形框位置
    m_rect.moveTo(m_X,m_Y);
    //超出屏幕,重置空闲状态
    if(m_Y>GAME_HEIGHT+m_rect.height())
        isFree=true;


}

```c++
#ifndef ENEMYPLANE_H
#define ENEMYPLANE_H
#include"qpixmap.h"
#include"qrect.h"


class EnemyPlane
{
public:
    EnemyPlane();

    //敌机的图片
 QPixmap m_enemyPlane;
    //敌机的位置
 int m_X;
 int m_Y;
 //敌机的速度
 int m_speed;
    //敌机的空闲状态
 bool isFree;
    //更新敌机的位置
 void updatePosition();
    //给敌机加矩形框,用于碰撞检测
 QRect m_rect;
};

#endif // ENEMYPLANE_H


#ifndef MAINSCENE_H
#define MAINSCENE_H

#include <QWidget>
#include"qtimer.h"
#include"qpainter.h"
#include"map.h"
#include"heroplane.h"
#include"QMouseEvent"
#include"bullet.h"
#include"enemyplane.h"

namespace Ui {
class MainScene;
}

class MainScene : public QWidget
{
    Q_OBJECT

public:
    explicit MainScene(QWidget *parent = 0);
    ~MainScene();
    //初始化
    void initScene();
    //启动游戏
    void playGame();
    //设置定时器
    QTimer m_timer;
    //加入地图对象作为背景
    Map m_map;
    //地图中元素位置更新
    void updatePosition();
    //把地图对象绘制到地图中
    void paintEvent(QPaintEvent *event);

    //加入飞机对象
    HeroPlane m_plane;

    //重写鼠标事件,实现对飞机的拖拽移动
    void mouseMoveEvent(QMouseEvent *event);

    //加入敌机对象
    EnemyPlane m_enemyPlane[ENEMY_NUM];

    //记录敌机出现间隔时间变量
    int m_record=0;
//敌机出现
    void enemyToScene();


private:
    Ui::MainScene *ui;
};

#endif // MAINSCENE_H

```c++

#include "mainscene.h"
#include "ui_mainscene.h"
#include"config.h"
#include"qicon.h"


MainScene::MainScene(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainScene)
{
    ui->setupUi(this);
    initScene();
    //启动游戏
    playGame();
    //不用一直按着飞机才会动了
    setMouseTracking(true);
}

MainScene::~MainScene()
{
    delete ui;
}

//初始化游戏场景
void MainScene::initScene()
{
    //设置窗口大小
    setFixedSize(GAME_WIDTH,GAME_HEIGHT);
    //设置窗口标题
    setWindowTitle(GAME_TITLE);
    //设置窗口图标
    setWindowIcon(QIcon(":/res/app.ico"));
    //设置刷新间隔
    m_timer.setInterval(GAME_RATE);
}

void MainScene::playGame()
{

    //启动定时器
    m_timer.start(10);

    //监听信号实现更新地图位置
    connect(&m_timer,&QTimer::timeout,[=](){
        //敌机出现
        enemyToScene();

        //每隔一段时间更新游戏中元素的位置
        updatePosition();
        //每隔一段时间调用painterevent实现绘制
        update();
    });
}

void MainScene::updatePosition()
{
    //更新地图元素的坐标
    m_map.mapUpdate();

    //发射子弹
    m_plane.shoot();

    //更新所有非空闲子弹的坐标
    for(int i=0;i<BULLET_NUM;i++)
    {
        if(m_plane.m_bullet[i].isFree==false)
            m_plane.m_bullet[i].updatePosition();
    }

    //更新所有敌机的位置
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemyPlane[i].isFree==false)
            m_enemyPlane[i].updatePosition();
    }

}

void MainScene::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    //画背景图
    //直接画不了map这个对象,只能分别画map里的成员pixmap1、2
    painter.drawPixmap(0,m_map.m_map1_posY,m_map.m_pix1);
    painter.drawPixmap(0,m_map.m_map2_posY,m_map.m_pix2);
    
    //画飞机
    painter.drawPixmap(m_plane.m_X,m_plane.m_Y,m_plane.m_plane);

    //画子弹
    for(int i=0;i<BULLET_NUM;i++)
    {
        painter.drawPixmap(m_plane.m_bullet[i].m_X,m_plane.m_bullet[i].m_Y,m_plane.m_bullet[i].m_bullet);

    }

    //画敌机
    for(int i=0;i<ENEMY_NUM;i++)
    {
        painter.drawPixmap(m_enemyPlane[i].m_X,m_enemyPlane[i].m_Y,m_enemyPlane[i].m_enemyPlane);
    }


}
void MainScene::mouseMoveEvent(QMouseEvent *event)
{
    //鼠标拖拽实现飞机移动
    //偏移量实现鼠标拖拽飞机中心移动(不懂为什么是减去)
    int x=event->x()-m_plane.m_plane.width()*0.5;
    int y=event->y()-m_plane.m_plane.height()*0.5;


    //飞机位置不可超出窗口  边界检测
    if(x<=0)
        x=0;
    if(x>=GAME_WIDTH-m_plane.m_plane.width())
        x=GAME_WIDTH-m_plane.m_plane.width();
    if(y<=0)
        y=0;
    if(y>=GAME_HEIGHT-m_plane.m_plane.height())
        y=GAME_HEIGHT-m_plane.m_plane.height();
//拖动飞机
    m_plane.setPosition(x,y);
}

void MainScene::enemyToScene()
{
    //启动记录
    m_record++;
    //未达到间隔时间,敌机不出现
    if(m_record<ENEMY_INTERVAL)
        return;
    //达到时间,下一辆敌机可以出现
    m_record=0;
    //还要再找空闲的敌机
    for(int i=0;i<ENEMY_NUM;i++)
    {
        if(m_enemyPlane[i].isFree==true)
            //如果空闲,发出敌机
            m_enemyPlane[i].isFree=false;
        //坐标
        m_enemyPlane[i].m_X=rand()%(GAME_WIDTH-m_enemyPlane[i].m_rect.width());
        m_enemyPlane[i].m_Y=-m_enemyPlane[i].m_rect.height();
        //找到一个就退出循环
        break;
    }

}


  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2024-06-18 14:05
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    根据你提供的代码和描述,我们可以逐一检查你提到的几个关键点来定位问题:

    1. EnemyPlane构造函数中的初始化设置

      • 从你的代码来看,EnemyPlane构造函数中的初始化设置看起来是正确的。敌机图片被加载,位置和速度被设置,矩形框也被正确初始化。
    2. updatePosition函数中敌机位置更新的逻辑

      • updatePosition函数中,你使用了if(isFree==true)来检查敌机是否空闲,这里应该使用==来比较,而不是赋值操作符=。正确的写法应该是if(isFree == true)
      • 另外,当敌机超出屏幕后,你将isFree设置为true,这是一个正确的逻辑,但是要确保敌机在重置为空闲状态后,其位置和速度等属性也被正确重置。
    3. enemyToScene函数中敌机生成和初始化的逻辑

      • enemyToScene函数中,你正确地检查了时间间隔,并寻找空闲的敌机来生成。但是,你使用了rand()%(GAME_WIDTH-m_enemyPlane[i].m_rect.width())来设置敌机的X坐标,这可能会导致敌机生成在屏幕边缘。你可能需要调整这个逻辑,确保敌机不会生成在屏幕边缘。
    4. 代码中逻辑错误导致敌机状态未正确更新

      • 检查isFree变量的使用是否恰当,确保在敌机被激活和重置为空闲状态时,isFree被正确地设置。
    5. 内存泄漏或其他资源管理问题

      • 从提供的代码片段来看,没有明显的内存泄漏问题。但是,如果m_enemyPlane数组中的每个EnemyPlane对象都正确地管理其资源(如图片加载和释放),那么内存泄漏的可能性较小。

    此外,还有一些其他可能的问题点:

    • 确保GAME_HEIGHT的值是正确的,并且敌机的移动逻辑没有导致它们在屏幕外的Y坐标上出现负值。
    • 检查paintEvent函数中绘制敌机的部分,确保使用了正确的变量来获取敌机的图片。

    这里是一个修改后的updatePosition函数示例,修复了比较操作符的问题:

    void EnemyPlane::updatePosition()
    {
        // 如果敌机空闲,则不用计算敌机坐标
        if(isFree == true)  // 修复比较操作符
        {
            return;
        }
    
        // 敌机不空闲,计算敌机坐标
        m_Y += m_speed;
    
        // 更新敌机矩形框位置
        m_rect.moveTo(m_X, m_Y);
        // 超出屏幕,重置空闲状态
        if(m_Y > GAME_HEIGHT + m_rect.height())
        {
            isFree = true;  // 确保重置为空闲状态
            m_Y = 0;        // 重置Y坐标
        }
    }
    

    最后,如果问题仍然存在,建议使用调试工具逐步跟踪敌机的状态和位置,以确定问题发生的具体位置。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月18日