import org.kde.qt.*; public class CannonField extends QWidget { private int ang; private int f; private int timerCount; private QTimer autoShootTimer; private float shoot_ang; private float shoot_f; private final QRect barrelRect = new QRect(33, -4, 15, 8); public CannonField(QWidget parent, String name) { super(parent, name); ang = 45; f = 0; timerCount = 0; autoShootTimer = new QTimer(this, "movement handler"); connect(autoShootTimer, SIGNAL("timeout()"), this, SLOT("moveShot()")); shoot_ang = 0; shoot_f = 0; setPalette(new QPalette(new QColor(250, 250, 200))); } public int angle() { return ang; } public void setAngle(int degrees) { if (degrees < 5) degrees = 5; if (degrees > 70) degrees = 70; if (ang == degrees) return; ang = degrees; repaint(); emit("angleChanged", ang); } public int force() { return f; } public void setForce(int newton) { if (newton < 0) newton = 0; if (f == newton) return; f = newton; emit("forceChanged", f); } public void shoot() { if (autoShootTimer.isActive()) return; timerCount = 0; shoot_ang = ang; shoot_f = f; autoShootTimer.start(50); } public void moveShot() { QRegion r = new QRegion(shotRect()); timerCount++; QRect shotR = shotRect(); if (shotR.x() > width() || shotR.y() > height()) autoShootTimer.stop(); else r = r.unite(new QRegion(shotR)); repaint(r); } public void paintEvent(QPaintEvent e) { QRect updateR = e.rect(); QPainter p = new QPainter(this); if (updateR.intersects(cannonRect())) paintCannon(p); if (autoShootTimer.isActive() && updateR.intersects(shotRect())) paintShot(p); } private void paintShot(QPainter p) { p.setBrush(black()); p.setPen(NoPen); p.drawRect(shotRect()); } private void paintCannon(QPainter p) { QRect cr = cannonRect(); QPixmap pix = new QPixmap(cr.size()); pix.fill(new QColor(250, 250, 200)); QPainter tmp = new QPainter(pix); tmp.setBrush(blue()); tmp.setPen(NoPen); tmp.translate(0, pix.height() - 1); tmp.drawPie(new QRect(-35,-35, 70, 70), 0, 90*16); tmp.rotate(-ang); tmp.drawRect(barrelRect); tmp.end(); p.drawPixmap(cr.topLeft(), pix); } private QRect cannonRect() { QRect r = new QRect(0, 0, 50, 50); r.moveBottomLeft(rect().bottomLeft()); return r; } private QRect shotRect() { final double gravity = 4; double time = timerCount / 4.0; double velocity = shoot_f; double radians = shoot_ang*3.14159265/180; double velx = velocity*Math.cos(radians); double vely = velocity*Math.sin(radians); double x0 = (barrelRect.right() + 5)*Math.cos(radians); double y0 = (barrelRect.right() + 5)*Math.sin(radians); double x = x0 + velx*time; double y = y0 + vely*time - 0.5*gravity*time*time; QRect r = new QRect(0, 0, 6, 6); r.moveCenter(new QPoint((int) x, height() - 1 - (int) y)); return r; } public QSizePolicy sizePolicy() { return new QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding); } }