import org.trinitydesktop.qt.*; public class CannonField extends TQWidget { private int ang; private int f; private int timerCount; private TQTimer autoShootTimer; private float shoot_ang; private float shoot_f; private TQPoint target; private boolean gameEnded; private boolean barrelPressed; private final TQRect barrelRect = new TQRect(33, -4, 15, 8); public CannonField(TQWidget parent, String name) { super(parent, name); ang = 45; f = 0; timerCount = 0; autoShootTimer = new TQTimer(this, "movement handler"); connect(autoShootTimer, SIGNAL("timeout()"), this, SLOT("moveShot()")); shoot_ang = 0; shoot_f = 0; target = new TQPoint(0, 0); gameEnded = false; barrelPressed = false; setPalette(new TQPalette(new TQColor(250, 250, 200))); newTarget(); } 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); emit("canShoot", false); } public void newTarget() { TQRegion r = new TQRegion(targetRect()); target = new TQPoint((int) (200 + Math.random()*190), (int) (10 + Math.random()*255)); repaint(r.unite(new TQRegion(targetRect()))); } public void setGameOver() { if (gameEnded) return; if (isShooting()) autoShootTimer.stop(); gameEnded = true; repaint(); } public boolean gameOver() { return gameEnded; } public void restartGame() { if (isShooting()) autoShootTimer.stop(); gameEnded = false; repaint(); emit("canShoot", true); } public void moveShot() { TQRegion r = new TQRegion(shotRect()); timerCount++; TQRect shotR = shotRect(); if (shotR.intersects(targetRect())) { autoShootTimer.stop(); emit("hit"); emit("canShoot", true); } else if (shotR.x() > width() || shotR.y() > height() || shotR.intersects(barrierRect())) { autoShootTimer.stop(); emit("missed"); emit("canShoot", true); } else { r = r.unite(new TQRegion(shotR)); } repaint(r); } protected void mousePressEvent(TQMouseEvent e) { if (e.button() != LeftButton) return; if (barrelHit(e.pos())) barrelPressed = true; } protected void mouseMoveEvent(TQMouseEvent e) { if (!barrelPressed) return; TQPoint pnt = e.pos(); if (pnt.x() <= 0) pnt.setX(1); if (pnt.y() >= height()) pnt.setY(height() - 1); double rad = Math.atan(((double)rect().bottom()-pnt.y())/pnt.x()); setAngle((int) (rad*180/3.14159265)); } protected void mouseReleaseEvent(TQMouseEvent e) { if (e.button() == LeftButton) barrelPressed = true; } protected void paintEvent(TQPaintEvent e) { TQRect updateR = e.rect(); TQPainter p = new TQPainter(this); if (gameEnded) { p.setPen(black()); p.setFont(new TQFont("Courier", 48, TQFont.Bold, false)); p.drawText(rect(), AlignCenter, "Game Over"); } if (updateR.intersects(cannonRect())) paintCannon(p); if (updateR.intersects(barrierRect())) paintBarrier(p); if (isShooting() && updateR.intersects(shotRect())) paintShot(p); if (!gameEnded && updateR.intersects(targetRect())) paintTarget(p); } private void paintShot(TQPainter p) { p.setBrush(black()); p.setPen(NoPen); p.drawRect(shotRect()); } private void paintTarget(TQPainter p) { p.setBrush(red()); p.setPen(black()); p.drawRect(targetRect()); } private void paintBarrier(TQPainter p) { p.setBrush(yellow()); p.setPen(black()); p.drawRect(barrierRect()); } private void paintCannon(TQPainter p) { TQRect cr = cannonRect(); TQPixmap pix = new TQPixmap(cr.size()); pix.fill(new TQColor(250, 250, 200)); TQPainter tmp = new TQPainter(pix); tmp.setBrush(blue()); tmp.setPen(NoPen); tmp.translate(0, pix.height() - 1); tmp.drawPie(new TQRect(-35,-35, 70, 70), 0, 90*16); tmp.rotate(-ang); tmp.drawRect(barrelRect); tmp.end(); p.drawPixmap(cr.topLeft(), pix); } private TQRect cannonRect() { TQRect r = new TQRect(0, 0, 50, 50); r.moveBottomLeft(rect().bottomLeft()); return r; } private TQRect 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; TQRect r = new TQRect(0, 0, 6, 6); r.moveCenter(new TQPoint((int) x, height() - 1 - (int) y)); return r; } private TQRect targetRect() { TQRect r = new TQRect(0, 0, 20, 10); r.moveCenter(new TQPoint(target.x(),height() - 1 - target.y())); return r; } private TQRect barrierRect() { return new TQRect(145, height() - 100, 15, 100); } private boolean barrelHit(TQPoint p) { TQWMatrix mtx = new TQWMatrix(); mtx.translate(0, height() - 1); mtx.rotate(-ang); mtx = mtx.invert(new boolean[1]); return barrelRect.contains(mtx.map(p)); } public boolean isShooting() { return autoShootTimer.isActive(); } public TQSize sizeHint() { return new TQSize(400, 300); } public TQSizePolicy sizePolicy() { return new TQSizePolicy(TQSizePolicy.Expanding, TQSizePolicy.Expanding); } }