Tile Grid Applet
<< Stone Game | FinalProjectsTrailIndex | SpaceInvadersApplet >>
Library
You can make subclasses and override if you add this external library and use
import sfhs.cct.tilegrid.*;
Tile.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
/**
* Tile Class for TileGrid, TileGridApplet
* @author Chris Thiel
* @version 25 May 2010 3pm
*
*/
public class Tile {
protected int row;
protected int col;
protected TileGrid grid;
protected Color color;
protected BufferedImage img;
protected double angle;
public Tile(int row,int col){
this.row=row;
this.col=col;
this.grid=null;
this.color=Color.RED;
img=null;
angle=0.0;
}
public Tile(){
this(-1, -1);
}
public BufferedImage getImg(){
return img;
}
public void setImg(BufferedImage img){
this.img=img;
}
public double getAngle(){
return angle;
}
public void setAngle(double angle){
this.angle=angle;
}
public void turnUp(){
this.angle=0;
}
public void turnDown(){
this.angle=Math.PI;
}
public void turnLeft(){
this.angle=Math.PI/-2.0;
}
public void turnRight(){
this.angle=Math.PI/2.0;
}
public Tile(int row, int col, Color color){
this(row,col);
this.color=color;
}
public Tile(Color color){
this(-1,-1);
this.color=color;
}
public Tile(BufferedImage img){
this(-1,-1);
this.img=img;
}
public int getRow() {
return row;
}
public void setRow(int row){
this.row=row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col= col;
}
public Color getColor(){
return color;
}
public void setColor(Color color){
this.color=color;
}
public void act(){
}
public void draw(Graphics g, int x, int y, int size) {
if(img==null){
g.setColor(color);
g.fillOval(x+3, y+3, size-6, size-6);
}else{
Graphics2D g2=(Graphics2D)g;
AffineTransform at=new AffineTransform();
at.setToIdentity();
double anchorx=(x+size/2.0);
double anchory=(y+size/2.0);
at.rotate(angle, anchorx, anchory);
double xFactor=(double)size/img.getWidth();
double yFactor=(double)size/img.getHeight();
at.scale(xFactor, yFactor);
at.translate(x/xFactor, y/yFactor);
g2.drawImage(img, at,null);
}
}
public void setGrid(TileGrid tileGrid) {
this.grid=tileGrid;
}
public TileGrid getGrid(){
return this.grid;
}
public void removeSelfFromGrid(){
grid.remove(this);
grid=null;
}
}
TileGrid.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
/**
* TileGrid for TileGridApplet
* @author Chris Thiel
* @version 25 May 2010 3pm
*
*/
public class TileGrid {
private int rows;
private int cols;
private int x;
private int y;
private int size;
private boolean showLines;
private ArrayList<Tile> tiles;
private Tile[][] map;
private Color bgColor;
private Color lineColor;
public TileGrid(int rows, int cols){
this.rows=rows;
this.cols=cols;
this.x=0;
this.y=0;
this.size=50;
this.showLines=true;
tiles=new ArrayList<Tile>();
map = new Tile[rows][cols];
this.bgColor=new Color(244,223,195);
this.lineColor=new Color(93,66,58);
}
public TileGrid(int rows, int cols, boolean s){
this(rows, cols);
this.showLines=s;
}
public TileGrid(int rows, int cols, int x, int y, int size){
this(rows, cols);
this.x=x;
this.y=y;
this.size=size;
this.showLines=true;
}
public TileGrid(int rows, int cols, int x, int y, int size,boolean s){
this(rows,cols);
this.x=x;
this.y=y;
this.size=size;
this.showLines=s;
}
public boolean getShowLines(){
return showLines;
}
public void setShowLines(boolean value){
this.showLines=value;
}
public int getSize(){
return size;
}
public int getNumTiles(){
return tiles.size();
}
public void setSize(int value){
this.size=value;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void setX(int x){
this.x=x;
}
public void setY(int y){
this.y=y;
}
public void setLocation(int x, int y){
this.x=x;
this.y=y;
}
public void setLocation(Point p){
this.x=p.x;
this.y=p.y;
}
public Point getLocation(){
return new Point(x,y);
}
public void setBGColor(Color c){
bgColor=c;
}
public Color getBGColor(){
return bgColor;
}
/**
* Draws grid on Graphics g with top left corner (x,y)
* with each cell being size pixels square. It will
* update the grid's location and size.
*
* @param g the Graphics Object to draw upon
* @param x the horizontal location of top left
* @param y the vertical location of top left
* @param size the size in pixels of each square
*/
public void draw(Graphics g, int x, int y, int size){
this.x=x;
this.y=y;
this.size=size;
Color currentColor=g.getColor();
g.setColor(bgColor);
g.fillRect(x, y, cols*size, rows*size);
for(Tile t:tiles)
t.draw(g, col2X(t.getCol()), row2Y(t.getRow()),size);
if (showLines) drawLines(g);
g.setColor(currentColor);
}
private int row2Y(int r) {
return y+size*r;
}
private int col2X(int c) {
return x+size*c;
}
/**
* Adds a tile to the grid, telling the tile its new grid, row and column
* @param tile
* @param row
* @param col
* @return true if successful, false if occupied or invalid location
*/
public boolean add(Tile tile, int row, int col){
if (!isEmpty(row,col)) return false;
map[row][col]=tile;
tiles.add(tile);
tile.setGrid(this);
tile.setRow(row);
tile.setCol(col);
return true;
}
public boolean move(Tile tile, int row, int col){
if (!isEmpty(row,col)) return false;
map[row][col]=map[tile.getRow()][tile.getCol()];
map[tile.getRow()][tile.getCol()]=null;
tile.setRow(row);
tile.setCol(col);
return true;
}
/**
* Activate tells all the tiles to act
* (Usually called after the passage of time).
*/
public void activate(){
int i=0;
while(i<tiles.size()){
Tile t=tiles.get(i);
if (t.getGrid()!=null){//if still alive
t.act();
i++;
}else{
tiles.remove(t);
}
}
}
/**
* Removes a tile from the grid, setting the tile to a null grid and an invalid location
* @param tile
* @return
*/
public boolean remove(Tile tile){
int r=tile.getRow();
int c=tile.getCol();
//if (isEmpty(r,c))return false;
map[r][c]=null;
tiles.remove(tile);
tile.setRow(-1);
tile.setCol(-1);
tile.setGrid(null);
return true;
}
/**
* checks to see if row r and column c is on the grid
* @param r the row to check
* @param c the column to check
* @return
*/
public boolean isValid(int r, int c) {
return r>=0 && r<rows && c>=0 && c<cols;
}
/**
* checks to see if a tile exists in the
* row r and column c
* @param r
* @param c
* @return true if it is an empty cell, false if invalid cell or not empty
*/
public boolean isEmpty(int r, int c) {
if (!isValid(r,c))
return false;
return map[r][c]==null;
}
/**
* Uses the (x,y) location of the screen location
* to return a string indicating the (row,col) on the grid
* that it corresponds to.
* @param x the horizontal location
* @param y the vertical location
* @return a String with the corresponding grid location
*/
public String getRowColString(int x, int y){
String result="(";
result+=getRow(y)+", ";
result+=getCol(x);
return result+")";
}
/**
* Converts a vertical screen location to a grid row
* @param y the vertical location in pixels
* @return the row of the click
*/
public int getRow(int y){
if (y<this.y) return -1;
return (y-this.y)/this.size;
}
/**
* Converts a horizontal screen location to a grid column
* @param x the horizontal location in pixels
* @return the column of the click
*/
public int getCol(int x){
if (x<this.x)return -1;
return (x-this.x)/this.size;
}
public Point getRowCol(int x, int y){
return new Point(getRow(y),getCol(x));
}
public int getRowFromPoint(Point p){
return (p.y-this.y)/this.size;
}
public int getColFromPoint(Point p){
return (p.x-this.x)/this.size;
}
public Tile get(int row, int col){
return map[row][col];
}
private void drawLines(Graphics g){
g.setColor(Color.WHITE);
for (int r=0; r<=rows;r++)
g.drawLine(x, y+r*size-2, x+cols*size, y+r*size-2);
for(int c=0; c<=cols; c++)
g.drawLine(x+c*size-2, y, x+c*size-2, y+rows*size);
g.setColor(lineColor);
for (int r=0; r<=rows;r++)
g.drawLine(x, y+r*size, x+cols*size, y+r*size);
for(int c=0; c<=cols; c++)
g.drawLine(x+c*size, y, x+c*size, y+rows*size);
}
}
TileGridApplet.java
import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Timer;
/**
* TileGridApplet is a simple Applet that
* should be reminiscent of GridWorld
* @author Chris Thiel
* @version 25 May 2010 9pm
*
*/
@SuppressWarnings("serial")
public class TileGridApplet extends Applet implements ActionListener, MouseListener, KeyListener
{
protected Timer timer;
protected Image virtualMem;
protected TileGrid grid;
Button myButton;
int secs;
private String message;
private int keyCode;
private String key;
public void init()
{
grid= new TileGrid(4, 4 );
timer=new Timer(1000, this);
virtualMem = createImage(getWidth(),getHeight());
myButton= new Button("Start");
//the class is its own button listener
myButton.addActionListener (this);
addMouseListener(this);
this.addKeyListener(this);
add(myButton);
setMessage("Click Start to begin");
this.requestFocus();
}
public void paint(Graphics g)
{
// We draw using the object methods of
// the graphics buffer, not what is
// currently on the screen
virtualMem = createImage(getWidth(),getHeight());
Graphics gBuffer = virtualMem.getGraphics();
gBuffer.setColor(Color.white);
gBuffer.fillRect(0,0,getWidth(),getHeight());
gBuffer.setColor(Color.black);
grid.draw(gBuffer, getWidth()/6, getHeight()/6,
getWidth()/6);
gBuffer.drawString("Time: "+getTime(), 20,20);
gBuffer.drawString(getMessage(), 20, getHeight()-20);
//Now we send the result to the screen
g.drawImage(virtualMem,0,0,this);
}
public void update(Graphics g)
{
paint(g); //get rid of flicker with this method
}
public int randInt(int max){
return (int)(max*Math.random());
}
public boolean isTimerRunning(){
return timer.isRunning();
}
public int getTime(){
return secs;
}
public void setTime(int t){
secs=t;
}
public void resetTimer(){
secs=0;
timer.stop();
}
public Color randomColor(){
int red=randInt(255);
int green=randInt(255);
int blue=randInt(255);
return new Color(red,green,blue);
}
public boolean isTimerEvent(ActionEvent e){
Object source = e.getSource();
return source == timer;
}
//implement the ActionListener
public void actionPerformed(ActionEvent e) {
if ( isTimerEvent(e)) {
setTime(getTime()+1);
}else{
//restart button pressed
if (isTimerRunning()) {
stopTimer();
setMessage("Click Start to begin a New Puzzle");
}else{
resetTimer();
startTimer();
grid= new TileGrid(4, 4 );
setMessage("Click Grid to move Tiles");
}
}
this.requestFocus();
repaint();
}
public void startTimer() {
timer.start();
myButton.setLabel("Stop");
}
public void stopTimer() {
timer.stop();
myButton.setLabel("Start");
}
public String getMessage(){
return message;
}
public void setMessage(String message){
this.message=message;
}
// implement the MouseListener
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
this.requestFocus();
if (isTimerRunning()){
int x = e.getX();
int y = e.getY();
int r = grid.getRow(y);
int c = grid.getCol(x);
setMessage("Clicked "+grid.getRowColString(x, y));
if (grid.isEmpty(r, c)){
// img can be any size, place in same folder as class files
// File f=new File("Ship.gif");
// BufferedImage img=null;
// try {
// img = ImageIO.read(f);
// } catch (IOException err) {
// err.printStackTrace();
// }
// Tile t=new Tile(img);
// or else default is random colored disk
Tile t=new Tile(randomColor());
grid.add(t, r, c);
setMessage(getMessage()+" New Tile Added");
}else{
setMessage(getMessage()+" Not a Valid Move");
}
}else{
setMessage("Hummm...Try pressing the Start Button First");
}
repaint();
}
//KeyListener Methods
public void keyPressed(KeyEvent e) {
keyCode=e.getKeyCode();
key=KeyEvent.getKeyText(keyCode);
message="You pressed code "+keyCode+" \""+key+"\"";
repaint();
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
