首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >2 QGraphicsPixmapItems之间的QT碰撞检测

2 QGraphicsPixmapItems之间的QT碰撞检测
EN

Stack Overflow用户
提问于 2018-05-02 15:21:32
回答 1查看 562关注 0票数 1

链接到项目有趣的部分应该在gameengine.cpp. and的"launchSplash“-function和splashanimation.cpp中

游戏中随机创造的泡泡是可以接受的。这位球员的工作是用水滴射出气泡。水滴是从游戏屏幕的中间底部发射的。网格只用于调试,稍后将消失,但它使可视化区域变得更容易。

气泡会被水滴击中而被摧毁,但是当水滴击中一个气泡或游戏的上界时,水滴就会消失。水滴朝鼠标点击的方向飞去。

我试图创建一个基本的气泡射击游戏的碰撞检测,但我不知道我如何能够以一种整洁的方式检测碰撞。

游戏板看起来像这个棋盘,水滴是从屏幕的中间底部到光标的方向拍摄的。

最后,我会让水滴从墙壁上弹跳,但现在我蔑视弄清楚如何从一开始就检测碰撞。

棋盘是500x600单位(宽度x高度),所以点的水滴是在是(250,600)。

当水滴被射中时,我用

代码语言:javascript
复制
void GameEngine::launchSplash(int clickX, int clickY){
// <my long method of calculating the coordinates for the water drop's path>

    graphicalGameBoard_.animateSplash(graphicalGameBoard_.width()/2, graphicalGameBoard_.height(), xDestination, yDestination);
}

xDestinationyDestionation所在的地方,如果水滴不受阻碍地流动,水滴就会最终消失。水滴将在x=0 / x=500和/或y=0/y=600处结束,但我认为这与此无关。

将气泡添加到游戏板上。

代码语言:javascript
复制
board_.clear();

for(int y = 0; y < HEIGHT; ++y)
{
    std::vector< std::shared_ptr<Bubble> > row;
    for(int x = 0; x < WIDTH; ++x)
    {
        std::shared_ptr<Bubble> newBubble = nullptr;

        // There will be bubbles only in the top 3/4 of the board only in the middle
        // (i.e. not in the first two and last two columns).
        if (y < HEIGHT*3/4 && x > 1 && x < WIDTH-2)
        {
            // Generate random numbers using the enumearation type defined in
            // file bubble.hh. The value COLOR_COUNT is used to represent no bubble.
            std::uniform_int_distribution<int> distribution(RED,COLOR_COUNT);

            // If you want no empty squares, change the initialization to:
            // std::uniform_int_distribution<int> distribution(RED,BLUE);

            Color color = static_cast<Color>(distribution(randomEngine_));
            if(color != COLOR_COUNT) {
                newBubble = std::make_shared<Bubble>(x, y, color);
            }
        }
        row.push_back(newBubble);
    }
    board_.push_back(row);
}

在画板的gameengine.cpp中,水滴被射向气泡。

水滴是用

代码语言:javascript
复制
SplashAnimation::SplashAnimation(GameBoard* scene, QPointF startPoint, QPointF endPoint):
    QVariantAnimation(0),
    scene_(scene),
    item_()
{
    scene_->addItem(&item_);

    // The animation runs for the given duration and moves the splash
    // smoothly from startpoint to endpoint.
    setDuration(2000);
    setKeyValueAt(0, QPointF(startPoint));
    setKeyValueAt(1, QPointF(endPoint));
}

我认为有两种方法可以做到这一点:要么是内置的QT碰撞检测,要么是单独的计算。我无法处理QT碰撞,手动检测冲突的尝试也没有很好地完成。

我已经有了检测特定单元格中的气泡对象的功能,但是它位于列/行中,而不是原始坐标(500x600)中。

代码语言:javascript
复制
std::shared_ptr<Bubble> GameEngine::bubbleAt(int x, int y) const
{
    if (0 <= x and x < WIDTH and 0 <= y and y < HEIGHT){
        return board_.at(y).at(x);
    }
    else{
        return nullptr;
    }
}

编辑:目前我正试着做这样的事情,但我担心这对游戏来说会有点沉重,因为它迭代了那么多次(或者不是?):

代码语言:javascript
复制
for (int i = 0; i<600;++i)
{
     xfract = (xDestination+250.0)/600.0;
     yfract = (600.0-yDestination)/600.0;
     xStep = xfract*i;
     yStep = yfract*i;
     if (xStep >= 50){
        thisX = xStep/50-5;
     }else{
         thisX=5;
     }
     if (yStep >= 50){
         thisY = 11-yStep/50 + 1;
     }else{
         thisY = 11;
     }
     thisX = abs(thisX);
    if (bubbleAt(thisX, thisY)!=nullptr){
        endX = xfract*i;
        endY = yfract*i;
        i = 600;
       std::cout << "collision at x: "<<thisX<< " y: "<<thisY<<std::endl;
       std::cout << "collision at x: "<<xStep<< " y: "<<yStep<<std::endl;
       std::cout << graphicalGameBoard_.width() << " " << graphicalGameBoard_.height()<<std::endl;
       removeBubble(thisX, thisY);
       graphicalGameBoard_.removeBubble(thisX, thisY);
       endY = 600-endY;
    }
}


graphicalGameBoard_.animateSplash(graphicalGameBoard_.width()/2, graphicalGameBoard_.height(), endX, endY);

我试图把这些步骤分成几个小部分,并检查当前的步骤中是否有一个气泡,直到水滴到达终点或找到一个气泡。

--这是我唯一的一边计算的,但是动画没有标记,而右侧(x>250)碰撞检测由于某些原因而根本无法工作(它在右侧不可能的位置上碰到看似随机的气泡)。

编辑^2:为了处理QT的实际碰撞检测,我尝试了以下几点:

在splashanimation.cpp中,其中的水滴是使用

代码语言:javascript
复制
SplashAnimation::SplashAnimation(GameBoard* scene, QPointF startPoint, QPointF endPoint):
    QVariantAnimation(0),
    scene_(scene),
    item_()
{
    scene_->addItem(&item_);


    // The animation runs for the given duration and moves the splash
    // smoothly from startpoint to endpoint.
    setDuration(2000);
    setKeyValueAt(0, QPointF(startPoint));
    setKeyValueAt(1, QPointF(endPoint));   
}

SplashAnimation::~SplashAnimation()
{
    scene_->removeItem(&item_);
}

void SplashAnimation::updateCurrentValue(QVariant const& value)
{
    item_.setPos(value.toPointF());
}

其中场景是QGraphicsScene,而this的父场景包含气泡。

我已经在gameboard.cpp (它是气泡和动画的父版)和splash.cpp (水滴的动画)上尝试过这一点,但是两者都给了我相同的编译错误。

代码语言:javascript
复制
    QGraphicsItem::QGraphicsItem();

给出

错误:不能调用构造函数?QGraphicsItem::QGraphicsItem?直接-fpermissive QGraphicsItem::QGraphicsItem();^

代码语言:javascript
复制
QList<QGraphicsItem *> list = collidingItems() ;

给出error: ?collidingItems? was not declared in this scope QList<QGraphicsItem *> list = collidingItems() ; ^

代码语言:javascript
复制
    QList<QGraphicsItem *> list = QGraphicsItem::collidingItems() ;

给出error: cannot call member function ?QList<QGraphicsItem*> QGraphicsItem::collidingItems(Qt::ItemSelectionMode) const? without object QList<QGraphicsItem *> list = QGraphicsItem::collidingItems() ; ^

我也尝试增加论点,但我没有任何想法去尝试更好的工作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-03 06:40:48

在这个答案中,我将为您提供一些用于实现该解决方案的建议:

  • 避免使用下面的指令,使用Qt中最强大的元素之一的信号,以及事件循环所做的工作。 时间(animations_.state() == Q文摘动画::Running){==}
  • QGraphicsScene与支持浮点的坐标一起工作,因此场景的坐标由QPointF处理。
  • 使用上述方法,如果要发送点信息,请在信号中使用QPointF而不是int, int
  • 使用Qt提供的方法,例如: if (0 <= clickPosition.x()和clickPosition.x() <= GRID_SIDE*WIDTH和0 <= clickPosition.y()和clickPosition.y() <= GRID_SIDE*HEIGHT)

它可以减少到以下几个方面:

代码语言:javascript
复制
if(sceneRect().contains(event->scenePos()))

该实现的优点是它更易读。

我不明白你为什么不能实现collidingItems,也许是你的.pro的配置,

使用以下方法添加gui模块、核心和小部件

代码语言:javascript
复制
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

另外,要实现动画,请使用我以前的回答

完整的功能代码可以在下面的链接中找到。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50138172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档