#include "cannonwidget.h"
#include <QPalette> //调色板 设置背景颜色
#include <QMouseEvent>
#include <QTimer>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
#include <math.h>
#include <QDateTime>
#include <stdlib.h>
cannonWidget::cannonWidget(QWidget *parent) :
QWidget(parent)
{
setFixedSize(500,395);
setAutoFillBackground(true);
skinChanged("spring.png");
angle=45;
force=10;
gravity=9.8;
shotTimerCount=0;
setMouseTracking(true);//开启鼠标追踪,否则只有在按下鼠标的时候 才能追踪
timerForce=new QTimer(this);
QObject::connect(timerForce,SIGNAL(timeout()),this,SLOT(addForce()));
autoShotTimer=new QTimer(this);
QObject::connect(autoShotTimer,SIGNAL(timeout()),this,SLOT(moveShot()));
QTime midNight(0,0,0);
srand(midNight.secsTo(QTime::currentTime()));//种下随机时间种子
targetPoint=QPoint(50+rand()%400,10+rand()%350);
QObject::connect(this,SIGNAL(hit()),this,SLOT(newTarget()));
}
//public slot 改变背景颜色
void cannonWidget::skinChanged(QString picName)
{
QPalette palette;
palette.setBrush(QPalette::Background,QBrush(QPixmap(":/img/big_"+picName)));
setPalette(palette);
}
//private slot 移动子弹
void cannonWidget::moveShot()
{
QRegion r(shotRect());
shotTimerCount++;
QRect rect=shotRect();
if(rect.intersects(targetRect()))
{
autoShotTimer->stop();
emit hit();
force=10;
emit forceChanged(force);
}
else if(rect.y()<=0 ||rect.y()>height() || rect.x()>width())
{
autoShotTimer->stop();
force=10;
emit forceChanged(force);
emit missed();
}
else
{
r=r.united(rect);
}
repaint(r);
}
void cannonWidget::mouseMoveEvent(QMouseEvent *event)
{
if(autoShotTimer->isActive())
return;
double anglePiece=75*1.0/rect().width(); //5-80 总共85个角度 算出每个x坐标对应的角度
double angleTemp=anglePiece*event->x();
double ang=80-(int)angleTemp;
if(ang<5)
ang=5;
if(ang>80)
ang=80;
if(angle!=ang)//防止当按下鼠标并一直拖动后,angle已被限制,却仍然发送信号
{
angle=ang;
emit angleChanged(angle);
repaint(cannonRect());
}
}
void cannonWidget::mousePressEvent(QMouseEvent *event)
{
if(autoShotTimer->isActive())
return;
if(event->button()&Qt::LeftButton)
{
timerForce->start(20);
}
}
void cannonWidget::mouseReleaseEvent(QMouseEvent *)
{
if(timerForce->isActive())
{
timerForce->stop();
shotTimerCount=0;
//发射子弹
autoShotTimer->start(20);
}
}
void cannonWidget::paintEvent(QPaintEvent *event)
{
QRect updateRect=event->rect();
QPainter p(this);
if(updateRect.intersects(cannonRect()))
paintCannon(&p);
if(autoShotTimer->isActive() && updateRect.intersects(shotRect()))
paintShot(&p);
if(updateRect.intersects(targetRect()))
paintTarget(&p);
}
//public slot
void cannonWidget::newTarget()
{
QRegion r(targetRect());
targetPoint=QPoint(50+rand()%400,10+rand()%350);
repaint(r.united(targetRect()));
}
//private slot
void cannonWidget::addForce()
{
force++;
if(force>99)
force=10;
emit forceChanged(force);
}
//rect 加农炮
QRect cannonWidget::cannonRect() const
{
QRect cannon(0,0,50,50);
cannon.moveBottomLeft(rect().bottomLeft());
return cannon;
}
//QRect 子弹
QRect cannonWidget::shotRect() const
{
double time=shotTimerCount*50.0/1000;//把时间转化为秒
double radians=angle*3.1415926/180;
double velX=force*cos(radians);//水平速度
double velY=force*sin(radians);//垂直速度
double x0=(35+13)*cos(radians);//炮筒口的x坐标
double y0=(35+13)*sin(radians);//炮筒口的y坐标
double x=x0+velX*time;
double y=y0+velY*time-0.5*gravity*time*time;
QRect shotR(0,0,6,6);
shotR.moveCenter(QPoint(qRound(x),height()-qRound(y)-1));
return shotR;
}
//QRect 目标
QRect cannonWidget::targetRect() const
{
QRect rect(0,0,20,10);
rect.moveCenter(targetPoint);
return rect;
}
void cannonWidget::paintCannon(QPainter *p)
{
QRect cannon=cannonRect();
QPixmap pixmap(cannon.size());
pixmap.fill(this,cannon.topLeft());
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing,true);//抗锯齿
painter.setBrush(QBrush(QColor(178,34,34)));
painter.setPen(Qt::NoPen);
painter.translate(0,pixmap.height());//移动坐标系顶点
painter.drawPie(QRect(-35,-35,70,70),0*16,90*16);
painter.rotate(-angle);
painter.drawRect(QRect(33,-4,15,8));
painter.end();
p->drawPixmap(cannon.topLeft(),pixmap);
}
void cannonWidget::paintShot(QPainter *p)
{
p->setRenderHint(QPainter::Antialiasing,true);
p->setBrush(QBrush(QColor(255,0,0)));
p->setPen(Qt::NoPen);
p->drawEllipse(shotRect());
}
void cannonWidget::paintTarget(QPainter *p)
{
p->setBrush(Qt::green);
p->setPen(Qt::NoPen);
p->setRenderHint(QPainter::Antialiasing,true);
p->drawRect(targetRect());
}
- 1
- 2
- 3
前往页