您的位置:首页 > 编程语言 > Qt开发

QT5-实现小球运动碰撞

2020-02-16 18:32 429 查看

QT实现小球运动碰撞反弹

编程工具为vs2010+qt 5.1.2

思路

由于第一次刚使用qt,所以就写写博客分享一个qt新手从入门到放弃这个过程。

这个小设计使用QT中的QGraphics框架,这个框架适用于2D图像和动画的操作,包括各种变换以及检测等,而在其中的Colliding函数对于碰撞检测这一功能的实现非常简单。

结构

QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget);
QPainterPath shape() const;
void setSpeed(qreal i,qreal j);        //速度
void advance(int phase);

私有成员有X,Y方向上的运动速度。

设置运动速度

这里采用QDialog对话框获取速度,再通过函数setSpeed设置物体的速度。

QString Xspeed = QInputDialog::getText(NULL, " item Xspeed",
"Please input your item XSpeed",
QLineEdit::Normal,
"Xspeed Input",
&isOK);
QString Yspeed = QInputDialog::getText(NULL, " item Yspeed",
"Please input your item YSpeed",
QLineEdit::Normal,
"Yspeed Input",
&isOK);
qreal xspeed = Xspeed.toDouble( );
qreal yspeed = Yspeed.toDouble( );
setSpeed( xspeed , yspeed );

画出小球

painter->drawEllipse(pos().x(),pos().y(),radius*2,radius*2);

BoundingRect和Shape函数

boundingRect函数是返回包含Item的最小矩形,一般用于绘图和碰撞检测。而shape函数与boundingrect函数类似,但是shape更为精确,因为shape返回的是PainterPath而boundingRect返回的是一个矩形。

QRectF MyItem::boundingRect() const
{
qreal penWidth = 1;
return QRectF(pos().x() - penWidth / 2, pos().y() - penWidth / 2,
radius*2 + penWidth, radius*2 + penWidth);
}

QPainterPath MyItem::shape() const
{
QPainterPath path;
path.addEllipse( pos().x() , pos().y() , radius*2 , radius*2 );  //图形项的真实大小
return path;
}

运动和碰撞反弹

运动函数利用advance和计时器就可以实现,反弹就要使用colliding函数和坐标计算判断。

void MyItem::advance( int phase )
{
if(!phase) return;  //如果phase为0,则结束
qreal x=this->pos().x();//更新位置
qreal y=this->pos().y();
if(y<=0||y+radius>=SceneHeight/2)//碰撞Y方向的墙
{
yspeed*=-1;
}
else 	if(x<=0||x+radius>=SceneWidth/2) //碰撞X方向的墙
{
xspeed*=-1;
}

if(!collidingItems().isEmpty()) //碰撞检测
{
xspeed*=-1;
yspeed*=-1;
}
moveBy( xspeed , yspeed  );
}

遗憾没有实现边界和视图窗口的自适应,就是拉大视图,小球的运动边界也改变。
不知道怎么实现这个功能~

2019.11.7:
可以通过重写ResizeEvent事件来实现上述窗口的自适应功能。
ps:
QGraphicsView::ResizeEvent函数已实现,需要继承GraphicsView来重写resizeEvent函数。

void QGraphicsView::resizeEvent(QResizeEvent *event)
{
SceneHeight=this->height();
SceneWidth =this->width();
}

参考文档

  • 点赞
  • 收藏
  • 分享
  • 文章举报
不开心啊不开心 发布了1 篇原创文章 · 获赞 0 · 访问量 103 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: