用到不少物理知识
#include <QPaintEvent>
#include <QPainter>
#include <QTimer>
#include <math.h>
#include "cannonfield.h"
CannonField::CannonField(QWidget *parent)
: QWidget(parent)
{
currentAngle = 45;
currentForce = 0;
timerCount = 0;
autoShootTimer = new QTimer(this);
connect(autoShootTimer, SIGNAL(timeout()), this, SLOT(moveShot()));
shootAngle = 0;
shootForce = 0;
setPalette(QPalette(QColor(250, 250, 200)));
setAutoFillBackground(true);
}
void CannonField::setAngle(int angle)
{
if (angle < 5)
angle = 5;
if (angle > 70)
angle = 70;
if (currentAngle == angle)
return;
currentAngle = angle;
update(cannonRect());
emit angleChanged(currentAngle);
}
void CannonField::setForce(int force)
{
if (force < 0)
force = 0;
if (currentForce == force)
return;
currentForce = force;
emit forceChanged(currentForce);
}
void CannonField::shoot()
{
if (autoShootTimer->isActive())
return;
timerCount = 0;
shootAngle = currentAngle;
shootForce = currentForce;
autoShootTimer->start(5);
}
void CannonField::moveShot()
{
QRegion region = shotRect();
++timerCount;
QRect shotR = shotRect();
if (shotR.x() > width() || shotR.y() > height()) {
autoShootTimer->stop();
} else {
region = region.unite(shotR); // 两个区域的或
}
update(region);
}
void CannonField::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this);
paintCannon(painter);
if (autoShootTimer->isActive())
paintShot(painter);
}
void CannonField::paintShot(QPainter &painter)
{
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::black);
painter.drawRect(shotRect());
}
const QRect barrelRect(30, -5, 20, 10); // 炮管区域
void CannonField::paintCannon(QPainter &painter)
{
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::blue);
painter.save();
painter.translate(0, height());
painter.drawPie(QRect(-35, -35, 70, 70), 0, 90 * 16);
painter.rotate(-currentAngle);
painter.drawRect(barrelRect);
painter.restore();
}
QRect CannonField::cannonRect() const
{
QRect result(0, 0, 50, 50);
result.moveBottomLeft(rect().bottomLeft());
return result;
}
QRect CannonField::shotRect() const
{
const double gravity = 4; // 重力加速度
double time = timerCount / 20.0;
double velocity = shootForce; // 速度
double radians = shootAngle * 3.14159265 / 180; // 弧度
double velx = velocity * cos(radians); // x 方向速度
double vely = velocity * sin(radians); // y 方向速度
double x0 = (barrelRect.right() + 5) * cos(radians); // 炮弹初始位置 x
double y0 = (barrelRect.right() + 5) * sin(radians); // 炮弹初始位置 y
double x = x0 + velx * time; // velx * time 为 time 时间内炮弹在x方向上行进的距离
double y = y0 + vely * time - 0.5 * gravity * time * time; // 公式 s = vt - 0.5* g * t * t
QRect result(0, 0, 6, 6); // 炮弹的大小
result.moveCenter( QPoint( qRound(x), height() - 1 - qRound(y) ) );
return result;
}
posted on 2007-07-23 01:40
七星重剑 阅读(507)
评论(0) 编辑 收藏 引用 所属分类:
PL--c/c++ 、
C++ lib -- Qt