A simple sliding blocks game (Game logic and the paint component method)
I'm building a simple sliding blocks game. I use the repaint() method to draw blocks of a puzzle image and then I draw a null block with the help of a BufferedImage array (puzzle[empty_row][empty_col] = null;). The null block is the blank box that you usually have in puzzles.
The thing is, I "call" the paint method to dr开发者_如何学Goaw all the blocks of my puzzle and I have the one block that is empty. Every time the user clicks next to it, I change the empty_row, empty_col to the mouse event's getX(), getY(), in order to --move-- the blank box to the desired position.
What... puzzles me in this puzzle :) is that the previous blank boxes still appear after I have drawn the new one. Does it make sense to you?
With repaint() I would expect that the blocks would be redrawn leaving just the one blank box.
Any thoughts on that? This is my second post here and I see that people are very willing to help. I really appreciate it. Thank you in advance for your answers.
Zoi
Bits of my code from my SlidingBlockPanel class:
public SlidingBlockPanel(int nc, int nr)
{
numCols = nc;
numRows = nr;
addMouseListener(this);
SBModel= new SlidingBlockModel(numCols, numRows, "puzzle.jpg");
}
public void mouseClicked(MouseEvent event)
{
int thisCol = getCol(event.getX());
int thisRow = getRow(event.getY());
System.out.println
("you clicked in row " + thisRow);
System.out.println
("you clicked in column " + thisCol);
if (SBModel.slideBlock(thisRow,thisCol)==true)
repaint();
}
Rectangle getRect(int thisCol, int thisRow)
{
// if input is out of range, return "null"
if(thisCol <0 || thisRow < 0)
return null;
if(thisCol>=numCols || thisRow>=numRows)
return null;
// otherwise, make and return the Rectangle
int w = getWidth()/numCols;
int h = getHeight()/numRows;
int x = thisCol*w;
int y = thisRow*h;
Rectangle myRect = new Rectangle(x,y,w,h);
return myRect;
}
public void paint(Graphics g)
{
//g.setColor(Color.gray);
g.fillRect(0,0,getWidth(), getHeight());
g.setColor(Color.black);
Graphics2D g2 = (Graphics2D)g;
// we'll use Graphics2D for it's "drawImage" method this time
for (int i = 0;i<numCols;i++)
{
for(int j = 0;j<numRows;j++)
{
Rectangle r = getRect(i, j);
g2.drawImage(SBModel.getSubimage(i, j),r.x,r.y,r.width,r.height,null);
}
}
}
and the SlidingBlockModel class:
import java.awt.image.; import java.io.; import javax.imageio.; import java.awt.Image.; import java.awt.Graphics.*;
class SlidingBlockModel {
BufferedImage original_image; // the image to be cut up into blocks
int numCols; // number of columns in the grid of blocks
int numRows; // number of rows in the grid of blocks
int empty_col=0; // holds the column index of the one empty grid element
int empty_row=3; // holds the row index of the one empty grid element
BufferedImage[][] puzzle; // the two '[][]' allows a 2-D array
// to be created - each element is an image
public SlidingBlockModel (int input_numCols, int input_numRows, String filename) {
String image_filename=filename;
numCols=input_numCols;
numRows=input_numRows;
original_image = null;
try
{
original_image = ImageIO.read(new File(image_filename));
System.out.println("image " + image_filename + " loaded in ok." );
System.out.println("Width: " + original_image.getWidth() + ", height: " + original_image.getHeight());
}
catch (Exception e)
{
System.out.println("Sorry - couldn't load in file " + image_filename);
}
//cut up the original image into 'blocks' and
//assign each of these to the elements of the puzzle 2D array
puzzle = new BufferedImage[numCols][numRows];
for (int i=0;i<numCols;i++) {
for (int j=0;j<numRows;j++){
puzzle[i][j]=getImageRect(i,j);
}
}
//Initialise the empty block
puzzle[empty_row][empty_col] = null;
}
//slide the block indicated by the two parameters, if possible
boolean slideBlock(int thisCol, int thisRow) {
if(thisCol<0 || thisCol>numCols)
return false;
if (thisRow<0 || thisRow>numRows)
return false;
if (thisRow==empty_row) {
if ((thisCol==empty_col-1) || (thisCol==empty_col+1)) {
empty_col=thisCol;
puzzle[empty_row][empty_col]=null;
return true;
}
}
else
if (thisCol==empty_col) {
if ((thisRow==empty_row-1) || (thisRow==empty_row+1)) {
empty_row=thisRow;
puzzle[empty_row][empty_col]=null;
return true;
}
}
return false;
}
//return the BufferedImage for any given grid element
BufferedImage getSubimage(int thisCol, int thisRow) {
if(thisCol<0 || thisCol>numCols)
return null;
//if(thisRow<0 || thisRow>=max_num_counters)
if (thisRow<0 || thisRow>numRows)
return null;
else
return puzzle[thisCol][thisRow];
}
private BufferedImage getImageRect(int thisCol, int thisRow){
// if input is out of range, return "null"
if(thisCol <0 || thisRow < 0)
return null;
if(thisCol>=numCols || thisRow>=numRows)
return null;
else {
// otherwise, make and return the Rectangle
int w = original_image.getWidth()/numCols;
int h = original_image.getHeight()/numRows;
int x = thisCol*w;
int y = thisRow*h;
BufferedImage myRect;
myRect=original_image.getSubimage(x,y,w,h);
return myRect;
}
}
public static void main (String[] args) {
}
}
I think your problem is the next one:
if (SBModel.slideBlock(thisRow,thisCol)==true)
repaint();
You call your slide function and then repaint (wich is not all wrong), but in your slide function you only move the blank piece, in any moment you slide the piece with an image. In your slide function you need to move first the piece with an image and the move the blank one, then you repaint.
精彩评论