用qt的图形视图框架实现的圆,三角形,矩形运动及碰撞.

用qt的图形视图框架实现的圆,三角形,矩形运动及碰撞.

效果如图:



/*main.cpp*/
#include "project.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	Project w;
	w.show();
	return a.exec();
}



/*project.h*/
#ifndef PROJECT_H
#define PROJECT_H

#include <QtWidgets/QWidget>
#include "ui_project.h"
#include <QGraphicsEllipseItem>
#include <QGraphicsRectItem>
#include <QGraphicsPolygonItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QPolygonF>
class Project : public QWidget
{
	Q_OBJECT

public:
	Project(QWidget *parent = 0);


protected slots:
		void buttonStartClicked();
		void buttonPauseClicked();
		void buttonStopClicked();
		void buttonAddClicked();
		void buttonMinusClicked();


protected:
	void timerEvent(QTimerEvent *);


private:
	Ui::ProjectClass ui;
	QGraphicsEllipseItem *ballItem;
	QGraphicsRectItem *rectItem;
	QGraphicsPolygonItem *triAngleItem;
	QGraphicsScene *scene0;
	QGraphicsScene *scene1;
	QGraphicsScene *scene2;
	qreal x0, y0, intervalX0,intervalY0;
	qreal x1, y1, intervalX1,intervalY1;
	qreal x2, y2, intervalX2,intervalY2;
	QTimer *timer;
	int id0, id1, id2;
	QPolygonF polygon;
};

#endif // PROJECT_H

/*project.cpp*/
#include "project.h"
#include <QTimer>
#include <QTimerEvent>

Project::Project(QWidget *parent)
	: QWidget(parent)
{
		ui.setupUi(this);
		/*设置第一个场景*/
		scene0 = new QGraphicsScene;
		scene0->setSceneRect(-300, -300, 600, 600);//场景大小
		ballItem = new QGraphicsEllipseItem();
		ballItem->setPen(Qt::NoPen);
		/*设置球的颜色, 渐变*/
		QRadialGradient gradient(QPointF(x0+25, y0+25), 25, QPointF((x0+25)/2,(y0+25)/2));
		gradient.setColorAt(0, QColor(255, 255, 255, 255));
		gradient.setColorAt(0.25, QColor(0, 255, 255, 180));
		gradient.setColorAt(1, QColor(0, 0, 255, 100));
		ballItem->setBrush(gradient);
		scene0->addItem(ballItem);
		ballItem->setRect(QRectF(-25, -25, 50, 50));

		ui.viewBall->setRenderHint(QPainter::Antialiasing);
		ui.viewBall->setBackgroundBrush(QColor(0x9F, 0x79, 0xEE));
		ui.viewBall->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
		ui.viewBall->setScene(scene0);
		ui.viewBall->show();

		/*设置第二个场景*/
		scene1 = new QGraphicsScene;
		scene1->setSceneRect(-300, -300, 600, 600);
		rectItem = new QGraphicsRectItem();
		rectItem->setPen(Qt::NoPen);
		rectItem->setBrush(Qt::darkRed);
		scene1->addItem(rectItem);
		rectItem->setRect(QRectF(-25, -25, 50, 50));

		ui.viewRect->setRenderHint(QPainter::Antialiasing);
		ui.viewRect->setBackgroundBrush(QColor(0x9F, 0x79, 0xEE));
		ui.viewRect->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
		ui.viewRect->setScene(scene1);
		ui.viewRect->show();

		/*设置第三个场景*/
		scene2 = new QGraphicsScene;
		scene2->setSceneRect(-300, -300, 600, 600);
		triAngleItem = new QGraphicsPolygonItem();
		triAngleItem->setPen(Qt::NoPen);
		triAngleItem->setBrush(Qt::green);
		scene2->addItem(triAngleItem);
		polygon<<QPointF(-25, -25)<<QPointF(25, -25)<<QPointF(0, 25);
		triAngleItem->setPolygon(polygon);

		ui.viewTriAngle->setRenderHint(QPainter::Antialiasing);
		ui.viewTriAngle->setBackgroundBrush(QColor(0x9F, 0x79, 0xEE));
		ui.viewTriAngle->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
		ui.viewTriAngle->setScene(scene2);
		ui.viewTriAngle->show();

		x0 = -25; 
		y0 = -25;
		intervalX0 = 0.5;  /*x步长*/
		intervalY0 = 0.8; /*y步长*/
		x1 = -25; 
		y1 = -25;
		intervalX1 = 0.5;
		intervalY1 = 0.8;
		x2 = -25; 
		y2 = -25;
		intervalX2 = 0.5;
		intervalY2 = 0.8;
	
	connect(ui.buttonStart, SIGNAL(clicked()), this, SLOT(buttonStartClicked()));
	connect(ui.buttonPause, SIGNAL(clicked()), this, SLOT(buttonPauseClicked()));
	connect(ui.buttonStop, SIGNAL(clicked()), this, SLOT(buttonStopClicked()));
	connect(ui.buttonAdd, SIGNAL(clicked()), this, SLOT(buttonAddClicked()));
	connect(ui.buttonMinus, SIGNAL(clicked()), this, SLOT(buttonMinusClicked()));


}



void Project::timerEvent( QTimerEvent *event )
{
	if(ui.tab_4->currentIndex() == 0)//第二个场景
	{
		QRadialGradient gradient(QPointF(x0+25, y0+25), 25, QPointF((x0+25)/2,(y0+25)/2));
		gradient.setColorAt(0, QColor(255, 255, 255, 255));
		gradient.setColorAt(0.25, QColor(0, 255, 255, 180));
		gradient.setColorAt(1, QColor(0, 0, 255, 100));
		ballItem->setBrush(gradient);

		if(event->timerId() == id0)/*第一个定时器*/
		{
			ballItem->setRect(QRectF(x0, y0, 50, 50));
			x0 +=intervalX0;//运动
			y0 +=intervalY0;
			
			/*判断反弹*/
			if(x0+50 > 292)
			{
				x0 = 292 - (x0+50-292)-50;
				intervalX0 = -intervalX0;
			}
			if(y0+50 >284)
			{
				y0 = 284-(y0+50-284)-50;
				intervalY0 = -intervalY0;
			}
			if(x0 <-290)
			{
				x0= -290-x0-290;
				intervalX0 = -intervalX0;
			}
			if(y0 <-290)
			{
				y0 = -290-y0-290;
				intervalY0 = -intervalY0;
			}
			update();
		}
	}
	if(ui.tab_4->currentIndex() == 1)//第二个场景
	{

		if(event->timerId() == id1)/*第二个定时器*/
		{
			rectItem->setRect(QRectF(x1, y1, 50, 50));
			x1 +=intervalX1;
			y1 +=intervalY1;
			if(x1+50 > 292)
			{
				x1 = 292 - (x1+50-292)-50;
				intervalX1 = -intervalX1;
			}
			if(y1+50 >284)
			{
				y1 = 284-(y1+50-284)-50;
				intervalY1 = -intervalY1;
			}
			if(x1 <-290)
			{
				x1 = -290-x1-290;
				intervalX1 = -intervalX1;
			}
			if(y1 <-290)
			{
				y1 = -290-y1-290;
				intervalY1 = -intervalY1;
			}

			update();
		}
	}

	if(ui.tab_4->currentIndex() == 2)<span style="font-family: Arial, Helvetica, sans-serif;">//第三个场景</span>
	{
		if(event->timerId() == id2)//第三个定时器
		{
			update();
			
			x2 +=intervalX2;
			y2 +=intervalY2;
			if(x2+50 > 292)
			{
				x2 = 292 - (x2+50-292)-50;
				intervalX2 = -intervalX2;
			}
			if(y2+50 >284)
			{
				y2 = 284-(y2+50-284)-50;
				intervalY2 = -intervalY2;
			}
			if(x2 <-290)
			{
				x2 = -290-x2-290;
				intervalX2 = -intervalX2;
			}
			if(y2 <-290)
			{
				y2 = -290-y2-290;
				intervalY2 = -intervalY2;
			}
			polygon.clear();
			polygon<<QPointF(x2, y2)<<QPointF(x2+50, y2)<<QPointF(x2+25, y2+50);
			triAngleItem->setPolygon(polygon);

		}
	}
}

void Project::buttonStartClicked()//开始按钮,启动对应定时器
{
	if(ui.tab_4->currentIndex() == 0)
		id0 = startTimer(10);
	if(ui.tab_4->currentIndex() == 1)
		id1 = startTimer(10);
	if(ui.tab_4->currentIndex() == 2)
		id2 = startTimer(10);

}

void Project::buttonPauseClicked()//暂停按钮
{
	if(ui.tab_4->currentIndex() == 0)
	 killTimer(id0);
	if(ui.tab_4->currentIndex() == 1)
		killTimer(id1);
	if(ui.tab_4->currentIndex() == 2)
		killTimer(id2);
}

void Project::buttonStopClicked()//停止按钮, 恢复初始化状态
{
	if(ui.tab_4->currentIndex() == 0)
	{
		killTimer(id0);
		scene0->removeItem(ballItem);
		x0 = -25;
		y0 = -25;
		intervalX0 = 0.5;
		intervalY0 = 0.8;
		ballItem = new QGraphicsEllipseItem();
		ballItem->setPen(Qt::NoPen);
		ballItem->setBrush(Qt::darkRed);
		scene0->addItem(ballItem);
		ballItem->setRect(QRectF(x0, y0, 50, 50));
	}

	if(ui.tab_4->currentIndex() == 1)
	{
		killTimer(id1);
		scene1->removeItem(rectItem);
		x1 = -25;
		y1 = -25;
		intervalX1 = 0.5;
		intervalY1 = 0.8;
		rectItem = new QGraphicsRectItem();
		rectItem->setPen(Qt::NoPen);
		rectItem->setBrush(Qt::darkRed);
		scene1->addItem(rectItem);
		rectItem->setRect(QRectF(x1, y1, 50, 50));
	}

	if(ui.tab_4->currentIndex() == 2)
	{
		killTimer(id2);
		scene0->removeItem(triAngleItem);
		x2 = -25;
		y2 = -25;
		intervalX2 = 0.5;
		intervalY2 = 0.8;
		triAngleItem = new QGraphicsPolygonItem();
		triAngleItem->setPen(Qt::NoPen);
		triAngleItem->setBrush(Qt::darkRed);
		scene2->addItem(triAngleItem);
		polygon<<QPointF(x2, y2)<<QPointF(x2+50, y2)<<QPointF(x2+25, y2+50);
		triAngleItem->setPolygon(polygon);
	}
}

void Project::buttonAddClicked()//加速,增加步长
{
	if(ui.tab_4->currentIndex() == 0)
	{
		intervalX0 *= 1.5;
		intervalY0 *= 1.5;
	}
	if(ui.tab_4->currentIndex() == 1)
	{
		intervalX1 *= 1.5;
		intervalY1 *= 1.5;
	}
	if(ui.tab_4->currentIndex() == 2)
	{
		intervalX2 *= 1.5;
		intervalY2 *= 1.5;
	}
}

void Project::buttonMinusClicked()//减速, 减小步长
{
	if(ui.tab_4->currentIndex() == 0)
	{
		intervalX0 *= 1/1.5;
		intervalY0 *= 1/1.5;
	}
	if(ui.tab_4->currentIndex() == 1)
	{
		intervalX1 *= 1/1.5;
		intervalY1 *= 1/1.5;
	}
	if(ui.tab_4->currentIndex() == 2)
	{
		intervalX2 *= 1/1.5;
		intervalY2 *= 1/1.5;
	}
}




posted on 2015-07-30 18:43  小二杰  阅读(1766)  评论(0编辑  收藏  举报

导航