Worm Game
<< Gridworld Tile Game | FinalProjectsTrailIndex | Hunt the Wumpus >>
Worm.java
import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.util.ArrayList; public class Worm { private ArrayList<Rectangle> segments; private int dir; public static final int NORTH=0,EAST=90,SOUTH=180, WEST=270; private Rectangle bounds; private Color color; public Worm(int x, int y, int size, Rectangle bounds){ segments = new ArrayList<Rectangle>(); dir= EAST; this.bounds =bounds; segments.add(new Rectangle(x,y,size,size)); addSegment(); addSegment(); color=Color.MAGENTA; } public boolean addSegment(){ //make a copy of the last segment Rectangle tail = new Rectangle(segments.get(segments.size()-1)); // if possible move to the left of the last segment tail.translate(-1*tail.width, 0); if (bounds.contains(tail)){ segments.add(tail); return true; } return false; //coun't add segment } public boolean move(){ //get a copy of the head Rectangle head=new Rectangle(segments.get(0)); int dx=0; int dy=0; if (dir==NORTH) dy=-1*head.height; if (dir==SOUTH) dy=head.height; if (dir==EAST) dx=head.width; if (dir==WEST) dx=-1*head.width; head.translate(dx, dy); if (bounds.contains(head)){ //segments move to previous segments position segments.remove(segments.size()-1); segments.add(0, head); return true; } return false;// ran into edge } public void setDirection(int d){ dir=d; } public int getDirection(){ return dir; } public void setColor(Color c){ color=c; } public Color getColor(){ return color; } public void draw(Graphics g){ g.setColor(Color.BLACK); for(Rectangle s:segments) g.fillOval(s.x, s.y, s.width, s.height); g.setColor(color); for(Rectangle s:segments) g.fillOval(s.x+2, s.y+2, s.width-4, s.height-4); } public int getLength() { return segments.size(); } public boolean isTwisted(){ for(int i=0; i<segments.size()-1;i++) for(int j=i+1;j<segments.size();j++) if (segments.get(i).intersects(segments.get(j))) return true; return false; } public boolean intersects(Rectangle r){ for(int i=0; i<segments.size()-1;i++) for(int j=i+1;j<segments.size();j++) if (segments.get(i).intersects(r)) return true; return false; } public Rectangle getBounds(){ return bounds; } public Rectangle getHead(){ return segments.get(0); } }
Prize.java
import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; public class Prize { private int value; BufferedImage img; Rectangle box; public Prize(int value, int width, int height, Worm w){ this.value=value; Rectangle bounds=w.getBounds(); int x = randomInt(bounds.x, bounds.x+bounds.width-width); int y = randomInt(bounds.y, bounds.y+bounds.height-height); box = new Rectangle(x,y,width, height); while(!bounds.contains(box) || w.intersects(box)){ x = randomInt(bounds.x, bounds.x+bounds.width-width); y = randomInt(bounds.y, bounds.y+bounds.height-height); box = new Rectangle(x,y,width, height); } } private int randomInt(int a, int b) { int low = Math.min(a, b); int hi = Math.max(a, b); return low+(int)((hi-low+1)*Math.random()); } public void setImage(String filename) { try { img = ImageIO.read(getClass().getResource("/"+filename)); } catch (Exception e) { } } public void setImage(BufferedImage img){ this.img=img; } public void draw(Graphics g){ if (img==null){ g.setColor(Color.RED); g.fillOval(box.x, box.y, box.width, box.height); }else{ g.drawImage(img, box.x, box.y, box.width, box.height, null); } } public boolean isEaten(Worm w){ return box.intersects(w.getHead()); } }
WormTester.java
import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.Timer; public class WormTester extends Applet implements KeyListener, ActionListener { private Rectangle area; private Image screen2; private Graphics g2; private Worm w; private Timer timer; private static final Color brown = new Color(100,50,25); private int addSgmtTic, prizeTic; private String message; private Prize p; public void init(){ area = new Rectangle(20, 20, 700,500); w = new Worm(200,300,20,area); addKeyListener(this); screen2 = createImage(getWidth(),getHeight()); g2 = screen2.getGraphics(); this.setFocusable(true); this.requestFocus(); timer = new Timer (100, this); addSgmtTic=0; prizeTic=0; message=""; timer.start(); } public void paint(Graphics g){ screen2 = createImage(getWidth(),getHeight()); g2 = screen2.getGraphics(); g2.setColor(Color.WHITE); g2.fillRect(0, 0, getWidth(), getHeight()); g2.setColor(brown); g2.fillRect(area.x, area.y, area.width, area.height); w.draw(g2); if (p!=null) p.draw(g2); g2.setColor(Color.BLUE); g2.drawString("Length is "+w.getLength(), area.x, area.y+area.height+20); g2.drawString(message, area.x+200, area.y+area.height+20); // finally draw to actual screen: g.drawImage(screen2, 0,0,this); } public void update(){ repaint(); } @Override public void keyTyped(KeyEvent e) {} @Override public void keyPressed(KeyEvent e) {} @Override public void keyReleased(KeyEvent e) { int code = e.getKeyCode(); if (w.getDirection()!=Worm.EAST && (code == KeyEvent.VK_LEFT || code== KeyEvent.VK_A ) ){ w.setDirection(Worm.WEST); } if (w.getDirection()!=Worm.WEST && (code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_D)){ w.setDirection(Worm.EAST); } if (w.getDirection()!=Worm.SOUTH && (code == KeyEvent.VK_UP || code == KeyEvent.VK_W)){ w.setDirection(Worm.NORTH); } if (w.getDirection()!=Worm.NORTH && (code == KeyEvent.VK_DOWN || code == KeyEvent.VK_S)){ w.setDirection(Worm.SOUTH); } w.move(); repaint(); } @Override public void actionPerformed(ActionEvent e) {//from the timer addSgmtTic++; if (addSgmtTic>20){ if (w.addSegment())//reset if sucessful addSgmtTic=0; } prizeTic++; if (prizeTic>30){ p=new Prize(10, 20, 20, w); prizeTic=0; } message=""; if (!w.move()) message="Wall collision detected"; if(w.isTwisted()) message+=" Collision with self detected"; if(p!=null && p.isEaten(w)){ message+=" Prize eaten!"; p=null; //increase score? } repaint(); } }