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();
}
}
