Lizard Splat

<< Basic Cannon | OtherProjectsTrailIndex | Connect 4 Game >>

See a Working demo here

This project features

  • A Hybrid Application/Applet
  • User Input that uses combinations of keys
  • Animated lizard movement

UserInput.java




import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class UserInput implements KeyListener, FocusListener, MouseListener, MouseMotionListener
{
	private boolean[] key=new boolean[68836];
	private static int mouseX,mouseY, mouseButton;
	public boolean[] getKeys(){
		return key;
	}
	public int getX(){
		return mouseX;
	}
	public int getY(){
		return mouseY;
	}
	public int getMouseButton(){
		return mouseButton;
	}
	@Override
	public void mouseClicked(MouseEvent e) {
		mouseButton = e.getButton();

	}

	@Override
	public void mouseEntered(MouseEvent e) {}

	@Override
	public void mouseExited(MouseEvent e) {}

	@Override
	public void mousePressed(MouseEvent e) {}

	@Override
	public void mouseReleased(MouseEvent e) {}

	@Override
	public void focusGained(FocusEvent e) {}

	@Override
	public void focusLost(FocusEvent e) {
		for(int i=0;i<key.length;i++){
			key[i]=false;
		}

	}

	@Override
	public void keyPressed(KeyEvent e) {
		int keyCode=e.getKeyCode();
		if(keyCode>0 && keyCode<key.length){
			key[keyCode]=true;
		}

	}

	@Override
	public void keyReleased(KeyEvent e) {
		int keyCode=e.getKeyCode();
		if(keyCode>0 && keyCode<key.length){
			key[keyCode]=false;
		}

	}

	@Override
	public void keyTyped(KeyEvent e) {}

	@Override
	public void mouseDragged(MouseEvent e) {}

	@Override
	public void mouseMoved(MouseEvent e) {
		mouseX=e.getX();
		mouseY=e.getY();

	}

}

Controller.java


import java.awt.Rectangle;
import java.awt.event.KeyEvent;


public class Controller {
	private UserInput input;
	private Lizard liz;
	private int speed;
	public Controller(UserInput input, Lizard liz)
	{
		//time=0;
		this.input=input;
		this.liz = liz;

	}

	public void tick(){
		//time++;
		boolean[] key=input.getKeys();
		Rectangle lLoc=new Rectangle(liz.getLocation());
		boolean forward = key[KeyEvent.VK_W]||key[KeyEvent.VK_UP];
		boolean back = key[KeyEvent.VK_S]||key[KeyEvent.VK_DOWN];
		boolean left = key[KeyEvent.VK_A]||key[KeyEvent.VK_LEFT];
		boolean right = key[KeyEvent.VK_D]||key[KeyEvent.VK_RIGHT];
		//boolean jump = key[KeyEvent.VK_SPACE];
		//boolean crouch = key[KeyEvent.VK_CONTROL];
		boolean run = key[KeyEvent.VK_SHIFT];
		speed=1;
		if (run){
			speed=3;
		}
		if (forward){			
			if(lLoc.y>0)
				lLoc.y-=speed;
			liz.goNorth();
		}
		if (back){		
			liz.goSouth();
			if(lLoc.y+lLoc.height<LizzardSplatApp.HEIGHT){
				lLoc.y+=speed;
			}
		}
		if(right){
			if (lLoc.x+lLoc.width<LizzardSplatApp.WIDTH)
				lLoc.x+=speed;
		}
		if(left){
			if (lLoc.x>0)
				lLoc.x-=speed;
		}
		if (!lLoc.equals(liz.getLocation())){
			liz.setLocation(lLoc);
			liz.nextState();
		}


	}
}

Lizard.java


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;

public class Lizard {
	private Rectangle location;
	private int state;
	private boolean alive, northBound;
	private BufferedImage aliveImg, deadImg;
	private Color[] c = { Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW };

	public Lizard(BufferedImage normalImage, BufferedImage deadImage) {
		this.aliveImg = normalImage;
		this.deadImg = deadImage;
		this.setAlive(true);
		this.goNorth();
		location = new Rectangle(
				(LizzardSplatApp.WIDTH - deadImage.getWidth() )/ 2,
				(LizzardSplatApp.HEIGHT- deadImage.getHeight() )/ 2, 
				deadImage.getWidth(),
				deadImage.getHeight());

	}

	public void goNorth() {
		northBound = true;
	}

	public void goSouth() {
		northBound = false;
	}

	public boolean isNorthbound() {
		return northBound;
	}

	public void changeDirection() {
		northBound = !northBound;
	}

	public void draw(Graphics g) {
		// g.setColor(c[state]);
		// g.fillRect(location.x, location.y, location.width, location.height);
		int dx1 = location.x;
		int dy1 = location.y;
		int dx2 = dx1 + location.width;
		int dy2 = dy1 + location.height;
		int sy1 = 0;
		int sy2 = location.height;
		int sx1 = state * location.width;
		int sx2 = sx1 + location.width;
		BufferedImage image = aliveImg;
		if (!alive) {
			sx1 = 0;
			sx2 = location.width;
			image = deadImg;
		}
		if (northBound) {
			g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
		} else {
			g.drawImage(image, dx1, dy2, dx2, dy1, sx1, sy1, sx2, sy2, null);
		}
	}

	public void nextState() {
		state = (state + 1) % 4;
	}

	public void setLocation(Rectangle r) {
		if (alive)
			location = r;
	}

	public Rectangle getLocation() {
		return location;
	}

	public boolean isAlive() {
		return alive;
	}

	public void setAlive(boolean alive) {
		this.alive = alive;
	}

}

LizzardSplatApp.java



import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

import javax.imageio.ImageIO;
import javax.swing.JFrame;


public class LizzardSplatApp extends Canvas implements Runnable {
	private static final long serialVersionUID = 1L;
	public static final int WIDTH = 800, HEIGHT = 600;
	public static final String TITLE = "Minefront Pre-Alpha 0.01";

	private Thread thread;
	private Controller controls;
	private BufferedImage img;
	private boolean running = false;
	private int[] pixels;
	private UserInput input;
	private Lizard lizard;

	private int fps;

	public LizzardSplatApp() {
		Dimension size = new Dimension(WIDTH, HEIGHT);
		setPreferredSize(size);
		setMinimumSize(size);
		setMaximumSize(size);
		input = new UserInput();

		lizard = new Lizard(loadImage("/images/lizard.png"),
				loadImage("/images/splat.png"));

		controls = new Controller(input, lizard);
		img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
		// pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();

		addKeyListener(input);
		addFocusListener(input);
		addMouseListener(input);
		addMouseMotionListener(input);

	}

	public synchronized void start() {
		if (running)
			return;
		running = true;
		thread = new Thread(this);
		thread.start();
	}

	public synchronized void stop() {
		if (!running)
			return;
		running = false;
		try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
			System.exit(0);
		}
	}

	@Override
	public void run() {
		int frames = 0;
		double unprocessedSeconds = 0;
		long previousTime = System.nanoTime();
		double secondsPerTick = 1 / 60.0;
		int tickCount = 0;
		boolean ticked = false;

		while (running) {
			long currentTime = System.nanoTime();
			long passedTime = currentTime - previousTime;
			previousTime = currentTime;
			unprocessedSeconds += passedTime / 1000000000.0;
			requestFocus();
			while (unprocessedSeconds > secondsPerTick) {
				tick();
				unprocessedSeconds -= secondsPerTick;
				ticked = true;
				tickCount++;
				if (tickCount % 60 == 0) {
					// System.out.println(frames + "fps");
					fps = frames;
					previousTime += 1000;
					frames = 0;
				}
			}
			if (ticked) {
				render();
				frames++;
			}
			render();
			frames++;

		}

	}

	private void tick() {

		controls.tick();
	}

	private void render() {
		BufferStrategy bs = this.getBufferStrategy();
		if (bs == null) {
			createBufferStrategy(3);
			return;
		}

		Graphics g = bs.getDrawGraphics();
		g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
		g.setColor(Color.YELLOW);
		g.setFont(new Font("Verdana", Font.ITALIC | Font.BOLD, 35));
		g.drawString(fps + " fps", 20, 50);
		lizard.draw(g);
		g.dispose();
		bs.show();
	}

	public static void main(String[] args) {
		BufferedImage cursor = new BufferedImage(16, 16,
				BufferedImage.TYPE_INT_ARGB);
		Cursor blank = Toolkit.getDefaultToolkit().createCustomCursor(cursor,
				new Point(0, 0), "blank");
		LizzardSplatApp game = new LizzardSplatApp();
		JFrame frame = new JFrame();
		frame.add(game);
		frame.pack();
		// frame.getContentPane().setCursor(blank);
		frame.setTitle(TITLE);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(WIDTH, HEIGHT);
		frame.setLocationRelativeTo(null);
		frame.setResizable(false);
		frame.setVisible(true);
		game.start();

	}

	public BufferedImage loadImage(String filename) {
		try {
			BufferedImage image = ImageIO.read(this.getClass().getResource(
					filename));

			return image;
		} catch (Exception e) {
			System.out.println("Problem loading " + filename);
			throw new RuntimeException(e);
		}
	}

}

LizzardSplatApplet.java

import java.applet.Applet;
import java.awt.BorderLayout;

public class LizzardSplatApplet extends Applet
{
	private static final long serialVersionUID=1L;
	private LizzardSplatApp game = new LizzardSplatApp();
	public void init(){
		setLayout(new BorderLayout());
		add(game);
	}
	public void start(){
		game.start();		
	}
	public void stop(){
		game.stop();
	}
}