From c00c1c014face28e39accbb5ce2a2333693b87b2 Mon Sep 17 00:00:00 2001 From: Nathan Dane Date: Thu, 18 Nov 2010 20:43:00 +0000 Subject: [PATCH] initial commit --- .play | 1 + Makefile | 12 +++ README | 5 ++ src/game/Game.java | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/game/Tank.java | 77 ++++++++++++++++++ src/game/Tanks.java | 9 +++ src/images/tank.png | Bin 0 -> 2799 bytes src/images/tank.xcf | Bin 0 -> 7129 bytes 8 files changed, 327 insertions(+) create mode 120000 .play create mode 100644 Makefile create mode 100644 README create mode 100644 src/game/Game.java create mode 100644 src/game/Tank.java create mode 100644 src/game/Tanks.java create mode 100644 src/images/tank.png create mode 100644 src/images/tank.xcf diff --git a/.play b/.play new file mode 120000 index 0000000..f2c76e7 --- /dev/null +++ b/.play @@ -0,0 +1 @@ +bin/play \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d48127f --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +all: + mkdir -p bin/ + rm -rf bin/* + javac -d bin/ src/game/*.java + cp -r src/images bin/ + echo -e "#!/bin/bash\njava game/Tanks" > bin/play + ln -s bin/play play + chmod 755 bin/play + +clean: + rm -rf bin + rm -f play diff --git a/README b/README new file mode 100644 index 0000000..d32dbe0 --- /dev/null +++ b/README @@ -0,0 +1,5 @@ +Compile on UNIX systems with `make`. +Built files are placed in .bin/ +Run the bin/play file to start from GUI or cd to bin/ and do `java game/Tanks` + +`make clean` cleans directory of build files and compiled files diff --git a/src/game/Game.java b/src/game/Game.java new file mode 100644 index 0000000..dc1fa04 --- /dev/null +++ b/src/game/Game.java @@ -0,0 +1,223 @@ +package game; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.Toolkit; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.image.BufferStrategy; + +import javax.swing.ImageIcon; +import javax.swing.JFrame; + +@SuppressWarnings("serial") +public class Game extends JFrame implements KeyListener, Runnable +{ + private BufferStrategy bufferStrategy = null; + private boolean gameRunning = true; + + private boolean keyUp = false, keyDown = false, keyLeft = false, keyRight = false; + private boolean debugInfo = false; + + private Tank playerTank = new Tank(); + + private long lastTime = System.nanoTime(); + + public Game() + { + this.setTitle("Tanks"); + this.setLayout(null); + this.setIgnoreRepaint(true); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setSize(new Dimension(800, 600)); + this.setLocation(300, 50); + this.setResizable(false); + this.addKeyListener(this); + this.setVisible(true); + + // Try to make the system use hardware acceleration with Java2d + System.setProperty("sun.java2d.transaccel", "True"); + System.setProperty("sun.java2d.opengl", "True"); + System.setProperty("sun.java2d.d3d", "True"); + System.setProperty("sun.java2d.ddforcevram", "True"); + + try { + this.createBufferStrategy(2); + bufferStrategy = this.getBufferStrategy(); + } catch (Exception e) { + // try to recreate game. + new Game(); + this.dispose(); + } + + // Start new thread for game loop + new Thread(this).start(); + } + + public void run() + { + Graphics2D g = null; // 2D graphics buffer + + Image tank = new ImageIcon("images/tank.png").getImage(); + + playerTank.setImage(tank); + playerTank.setSize(tank.getWidth(null), tank.getHeight(null)); + + playerTank.move(200, 200); + + while (gameRunning) + { + g = (Graphics2D)bufferStrategy.getDrawGraphics(); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + + // Clear background to black + g.setColor(Color.black); + g.fillRect(0, 0, this.getWidth(), this.getHeight()); + + // Update objects + update(); + + // Draw objects to screen + render(g); + + // flush the G2D object and show the backbuffer + g.dispose(); + bufferStrategy.show(); + + // We sync display on linux systems + Toolkit.getDefaultToolkit().sync(); + try { Thread.sleep(20); } catch (InterruptedException e) {} + Thread.yield(); + } + } + + /*** + * Render all visible objects to screen + */ + private void render(Graphics2D g) + { + playerTank.draw(g); + + if (debugInfo == true) // Draw debug info + { + g.setColor(Color.white); + g.drawString("DEG: " + Math.toDegrees(playerTank.getDirection()), 10, 50); + g.drawString("RAD: " + playerTank.getDirection(), 10, 65); + } + } + + /*** + * Update state of all entities. Handle user input + */ + private void update() + { + // Calculate how far objects should move + long currentTime = System.nanoTime(); + double passedTime = (currentTime - lastTime) * 0.0000001; + + lastTime = currentTime; + + if (keyRight) + { + if (keyDown) // Change the way it rotates in reverse + playerTank.rotate(-playerTank.getTurnSpeed() * passedTime); + else + playerTank.rotate(playerTank.getTurnSpeed() * passedTime); + } + + if (keyLeft) + { + if(keyDown) + playerTank.rotate(playerTank.getTurnSpeed() * passedTime); + else + playerTank.rotate(-playerTank.getTurnSpeed() * passedTime); + } + + // Move tank forward + if (keyUp) + { + if (keyRight || keyLeft) // Slow tank + playerTank.setSpeed(0.3); + else + playerTank.setSpeed(0.8); + + playerTank.move(-Math.sin(playerTank.getDirection()) * (passedTime * playerTank.getSpeed()), + Math.cos(playerTank.getDirection()) * (passedTime * playerTank.getSpeed())); + } + + // Reverse tank + if (keyDown) + { + if (keyRight || keyLeft) // Slow tank + playerTank.setSpeed(0.3); + else + playerTank.setSpeed(0.4); + + + // Tank is slower in reverse (hence -speed) + playerTank.move(Math.sin(playerTank.getDirection()) * (passedTime * playerTank.getSpeed()), + -Math.cos(playerTank.getDirection()) * (passedTime * playerTank.getSpeed())); + + // Reset speed to 1 + playerTank.setSpeed(1); + } + + // Update all objects + + } + + public void keyPressed(KeyEvent e) + { + switch (e.getKeyCode()) + { + case KeyEvent.VK_W: + keyUp = true; + break; + + case KeyEvent.VK_S: + keyDown = true; + break; + + case KeyEvent.VK_D: + keyRight = true; + break; + + case KeyEvent.VK_A: + keyLeft = true; + break; + + case KeyEvent.VK_F1: + debugInfo ^= true; + break; + } + } + + + public void keyReleased(KeyEvent e) { + switch (e.getKeyCode()) + { + case KeyEvent.VK_W: + keyUp = false; + break; + + case KeyEvent.VK_S: + keyDown = false; + break; + + case KeyEvent.VK_D: + keyRight = false; + break; + + case KeyEvent.VK_A: + keyLeft = false; + break; + } + } + + + public void keyTyped(KeyEvent arg0) {} + +} diff --git a/src/game/Tank.java b/src/game/Tank.java new file mode 100644 index 0000000..b0d197d --- /dev/null +++ b/src/game/Tank.java @@ -0,0 +1,77 @@ +package game; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.geom.AffineTransform; + +public class Tank +{ + private double x, y, tankCenterX, tankCenterY; + private double height = 0, width = 0; + private double speed = 1, turnSpeed = 0.01; + private double direction = 0.0; + + private AffineTransform matrix = null; + private Image tankImage = null; + + public void draw(Graphics2D g) + { + // Get center of tank using h and w + tankCenterX = width/2; + tankCenterY = height/2; + + matrix = g.getTransform(); // "push" the current matrix + + g.translate(x, y); // Move to the current tank location + + g.setColor(Color.cyan); + g.drawString("Player 1", -10.0f, -10.0f); + + g.rotate(direction, tankCenterX, tankCenterY); // Rotate from the center of the tank + + g.drawImage(tankImage, 0, 0, null); + + g.setTransform(matrix); // "pop" the matrix back to the default + } + + public void move(double xchange, double ychange) + { + x += xchange; + y += ychange; + } + + public void rotate(double amount) + { + direction += amount; + } + + public double getDirection() { + return direction; + } + + public void setDirection(double d) { + direction = d; + } + + public void setSpeed(double newspeed) { + speed = newspeed; + } + + public double getSpeed() { + return speed; + } + + public double getTurnSpeed() { + return turnSpeed; + } + + public void setImage(Image img) { + tankImage = img; + } + + public void setSize(int w, int h) { + width = w; + height = h; + } +} diff --git a/src/game/Tanks.java b/src/game/Tanks.java new file mode 100644 index 0000000..6d97c78 --- /dev/null +++ b/src/game/Tanks.java @@ -0,0 +1,9 @@ +package game; + +public class Tanks +{ + public static void main(String args[]) + { + new Game(); + } +} diff --git a/src/images/tank.png b/src/images/tank.png new file mode 100644 index 0000000000000000000000000000000000000000..3377548063609d6f94cef9640562733749837ec8 GIT binary patch literal 2799 zcwPbT3J~>)P)P001%w1^@s6se*8p00001b5ch_0Itp) z=>Px#24YJ`L;y$tZ2%57cin>k000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igk_ z5CkN?g8qO2000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000U~Nkl8MUN5DimmiR6&Ip(2iO$Lr4WNs+d+{ z$g~s02&6KpDxwAzsZuJ8s329ErU`Zu6DRhyeP6!sbIv~dvDW$+?Cb06AfbX_#&;(B zXlt$i`dKDVtRfxncDTH-%*Or>s|#o2H;ajUYx8|y2*9;3WZ%@8 z{)YFwGTBvz15wj=vECW@X>~|lR}n)84`dJirRwyWQjMV)L*9inO(_o&ym&3Dsfbq;2+8D|lbXB(N+5b6H$CcD z#L!Twayth56NqiNL?ki7)HtRh^d-?GR5i0gk$te@IddW7dq4P?>9|H!c>bjxbr~sV z9;8NrDtbi;#!^JDjdPL#GYc?Uak+?m!8(?#qi0-5h=R3kNoiDWzcVJph;`tb$oR0K zJ10aHdVPx+m=!_NjF@DyXB=-Psk|{=-mR3|%MZ^b>ict~3I!jdL z(Stx!!|#6e6@KmIvlKJ2#40Bi=`%Dp#*B@a*MFSW=D-E5-+g{zAg9|K?>7MO6unB1uaJ<}&f zAsjQJw2?`VcWgmKq$L?4DlPdL2T3Zt@WORI_ww)X;~NjzpKfsJ@&&|L@@_^@&;I^C zel{Zpr93hKY7!J!J&w+aC&vvTDuPZo+e)zlRZ*~he~rACu=S|GYvkRx*2r^9F)0uU zeEQ`}q=~f07L2wYTz$%u<3D>M2#O5n<8h&YNi0n*WO>5z*7D&; z@3FPF#@fR*uDmp2d;PF&^Qgp#Mg6QR*sk>&^ST z`t2Jm&o43>jMzUMqp4?adxk1liKK~;rB;&MVyvvuPEscz!B{d>4FYxmW?nFJU^0k4 zFx_c*@fR=B?+(zAu>Nq$`n{r^yIdfO5)qQrN|stlQ+q>1p7KP2KQPEbr)wFEgv1#J z3kH)YNw=MUhW$RvODj}W#YeYxkLxp{9q65de8G_Qon*N&#+VBtWKYqGhzxBaR*a!m zAtna829pam7xIB&R#lW$#qRzQy+wzlN;Xnl1}m2ndMko6LXudFm9MM*ClH)5m=K_8 z0@W;1PXg+pY?N#mnHEzTUlO&%4JwlPNNAwjF&Gu_k;Vs_I=C33Q&sm=PE@&Ipl^*p zX_2N?pH3g}Fh2Bz*ie*X7M2HWeOxlzj)W;>RvB*vrn^d225Bna35`E7O9 zBPNEx>@ZLjf$E^WCPWX66f45n<+B)Pc;>>0`#1M-S)e=+no4P!NE~?)#f6}W*i*Ek z5-SnYvk6kyL9Mj9YY*~Gj{d^ zG7nADR#3N}($AyV{>W}VJg|oo@19&8h6W|USj%WW!*;sVz5xuy6wEGk67V)Mo;1u2 zI^?+{?SKp{p@FpPFeGFl#S{(wG@+Qq@}z{bA4U96nu1D@VbbAAOgPf`g7~fu^?69ft-kgq~eJ=geJMUHhdNhfXNvZisxWt+7 zqzj3jzw9<-M_=z@V`H)2cu!yo+hzMh_znlCli zoz1aX%B=Lv{FEPkxBN=`w&b_JF)u1=Y(`oZ@vS5`)t%Qu{Yj1I#tQ>K0DGH(|F{1W`wwyYQy=BYhwcCX002ovPDHLkV1lUs BC87WT literal 0 HcwPel00001 diff --git a/src/images/tank.xcf b/src/images/tank.xcf new file mode 100644 index 0000000000000000000000000000000000000000..24c563a0116463d57b4458f832dc5a701cde1e0a GIT binary patch literal 7129 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 bdwKsE``Gsy?@xAtU7h#8knlYDPVIjH5clH~ literal 0 HcwPel00001 -- 2.11.4.GIT