summaryrefslogtreecommitdiffstats
path: root/qtjava/javalib/tutorial/t14/CannonField.java
diff options
context:
space:
mode:
Diffstat (limited to 'qtjava/javalib/tutorial/t14/CannonField.java')
-rw-r--r--qtjava/javalib/tutorial/t14/CannonField.java261
1 files changed, 261 insertions, 0 deletions
diff --git a/qtjava/javalib/tutorial/t14/CannonField.java b/qtjava/javalib/tutorial/t14/CannonField.java
new file mode 100644
index 00000000..1ace9c78
--- /dev/null
+++ b/qtjava/javalib/tutorial/t14/CannonField.java
@@ -0,0 +1,261 @@
+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 QPoint target;
+
+ private boolean gameEnded;
+ private boolean barrelPressed;
+
+ 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;
+ target = new QPoint(0, 0);
+ gameEnded = false;
+ barrelPressed = false;
+
+ setPalette(new QPalette(new QColor(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() {
+ QRegion r = new QRegion(targetRect());
+ target = new QPoint((int) (200 + Math.random()*190),
+ (int) (10 + Math.random()*255));
+ repaint(r.unite(new QRegion(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() {
+ QRegion r = new QRegion(shotRect());
+ timerCount++;
+
+ QRect 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 QRegion(shotR));
+ }
+
+ repaint(r);
+ }
+
+ protected void mousePressEvent(QMouseEvent e) {
+ if (e.button() != LeftButton)
+ return;
+ if (barrelHit(e.pos()))
+ barrelPressed = true;
+ }
+
+ protected void mouseMoveEvent(QMouseEvent e) {
+ if (!barrelPressed)
+ return;
+ QPoint 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(QMouseEvent e) {
+ if (e.button() == LeftButton)
+ barrelPressed = true;
+ }
+
+
+ protected void paintEvent(QPaintEvent e) {
+ QRect updateR = e.rect();
+ QPainter p = new QPainter(this);
+
+ if (gameEnded) {
+ p.setPen(black());
+ p.setFont(new QFont("Courier", 48, QFont.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(QPainter p) {
+ p.setBrush(black());
+ p.setPen(NoPen);
+ p.drawRect(shotRect());
+ }
+
+ private void paintTarget(QPainter p) {
+ p.setBrush(red());
+ p.setPen(black());
+ p.drawRect(targetRect());
+ }
+
+ private void paintBarrier(QPainter p) {
+ p.setBrush(yellow());
+ p.setPen(black());
+ p.drawRect(barrierRect());
+ }
+
+ 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;
+ }
+
+ private QRect targetRect() {
+ QRect r = new QRect(0, 0, 20, 10);
+ r.moveCenter(new QPoint(target.x(),height() - 1 - target.y()));
+ return r;
+ }
+
+ private QRect barrierRect() {
+ return new QRect(145, height() - 100, 15, 100);
+ }
+
+ private boolean barrelHit(QPoint p) {
+ QWMatrix mtx = new QWMatrix();
+ 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 QSize sizeHint() {
+ return new QSize(400, 300);
+ }
+
+ public QSizePolicy sizePolicy() {
+ return new QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding);
+ }
+}