📄 tiledlayer.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Copyright(c) 2004 Jordi Martin Perez
*/
package org.piratis.j2me.core.game;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import org.piratis.j2me.core.BBox2D;
import org.piratis.j2me.core.QuickList;
/**
* A type of Layer composed of a grid of
* cells which can contain a reduced set of predefined images.
* This class allows large virtual layers to be created
* without the need for an extremely large Image. It is
* commonly used to creat very large scrolling backgrounds.
*
* @author Jordi Mart韓
* @copyright Copyright (c) 2004
* @created 30-jun-2004
* @version $Id: TiledLayer.java,v 1.5 2004/07/29 20:13:06 piratis Exp $
*/
public class TiledLayer
extends Layer
{
/**
* Tile's columns
*/
private int columns;
/**
* Tile's rows
*/
private int rows;
/**
* Height of one tile
*/
private int tileHeight;
/**
* Width of one tile
*/
private int tileWidth;
/**
* Grid
*/
private int[][] grid;
/**
* Where common tiles will be stored
*/
private QuickList commonTiles;
/**
* The image containing the tiles
*/
private Image tiles;
private int nTilesRow;
/**
* Creates a new TiledLayer.<br>
* <br>
* TODO:
* @param columns
* @param rows
* @param image
* @param tileWidth
* @param tileHeight
*/
public TiledLayer (int columns, int rows, Image image,
int tileWidth, int tileHeight)
{
this.columns = columns;
this.rows = rows;
this.grid = new int [columns][rows];
this.tiles = image;
this.nTilesRow = image.getWidth() / tileWidth;
// void initialization
this.fillCells(0, 0, columns, rows, 0);
// layer values
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.bbox.width = columns * tileWidth;
this.bbox.height = rows * tileHeight;
// animated tiles
this.commonTiles = new QuickList();
}
/**
* Sets the given tileIndex in a given region.
* @param col top-left region column
* @param row top-left region row
* @param colNumber region col number
* @param rowNumber region row number
* @param tileIndex tile index to set
*/
public void fillCells(int col, int row,
int colNumber, int rowNumber, int tileIndex)
{
int i, j;
for (i = col + colNumber - 1; i >= col; i--)
for (j = row + rowNumber - 1; j >= row; j--)
this.grid[i][j] = tileIndex;
}
/**
* Sets the contents of a cell.
* @param col column from the grid
* @param row row from the grid
* @param tileIndex the index of the tile
*/
public void setCell(int col, int row, int tileIndex)
{
this.grid[col][row] = tileIndex;
}
/**
* Gets cell's contents
* @param col column from the grid
* @param row row from the grid
* @return the index of the tile in the cell
*/
public int getCell(int col, int row)
{
return this.grid[col][row];
}
/**
* Cretates a new common tile returning the index referring to this new
* common tile. It is initially assigned with the provided tileIndex.
* @param tileIndex
* @return
*/
public int createCommonTile(int tileIndex)
{
this.commonTiles.add(new Integer(tileIndex));
return -this.commonTiles.length();
}
/**
* Gets the tile referenced by the given common tile.
* @param commonTileIndex the index of the common tile.
* @return the tile index currently associated with the common tile.
*/
public int getCommonTile(int commonTileIndex)
{
return ((Integer) this.commonTiles.elementAt((-commonTileIndex)-1)).intValue();
}
/**
* Changes the tile associated to this common tile.
* @param commonTileIndex
* @param tileIndex
*/
public void setCommonTile(int commonTileIndex, int tileIndex)
{
this.commonTiles.setElementAt(new Integer(tileIndex),
(-commonTileIndex)-1);
}
/**
* @see org.piratis.j2me.core.game.Layer#paint(javax.microedition.lcdui.Graphics)
*/
public void paint(Graphics g)
{
// get clipping
int clipX, clipY, clipW, clipH;
clipX = g.getClipX(); clipY = g.getClipY();
clipW = g.getClipWidth(); clipH = g.getClipWidth();
// check inside clipping
if (!this.bbox.collide(clipX, clipY, clipW, clipH)) return;
// where to begin
int startCol = (clipX - this.bbox.x) / this.tileWidth;
int startRow = (clipY - this.bbox.y) / this.tileHeight;
// where to end
int endCol = Math.min(startCol + (clipW / this.tileWidth) + 1,
this.columns - 1);
int endRow = Math.min(startRow + (clipH / this.tileHeight) + 1,
this.rows - 1);
// go, go, go!
int i, j, transX, transY, oldTransX, oldTransY, tileNum, auxTrans;
// store previous translation values
oldTransX = g.getTranslateX();
oldTransY = g.getTranslateY();
// start moving translation through the drawn tiles
g.translate(this.bbox.x + (endCol * this.tileWidth),
this.bbox.y + (endRow * this.tileHeight));
for (i = endCol; i >= startCol; i--)
{
for (j = endRow; j >= startRow; j--)
{
tileNum = this.grid[i][j];
// check if 'common' (i.e. animated) tile
if (tileNum < 0)
tileNum = this.getCommonTile(tileNum);
if (tileNum > 0)
{
// store clipping
clipX = g.getClipX(); clipY = g.getClipY();
clipW = g.getClipWidth(); clipH = g.getClipWidth();
// set new clipping -> drawing at '0,0' because of translation!
g.clipRect(0, 0, this.tileWidth, this.tileHeight);
// calc image to draw
tileNum--; // easier to calc image location
transX = (tileNum % this.nTilesRow) * this.tileWidth; // tileNum % nTilesRow = col
transY = (tileNum / this.nTilesRow) * this.tileHeight; // tileNum / nTilesRow = row
// draw there
g.drawImage(this.tiles, -transX, -transY, Layer.TOP_LEFT);
// restore clipping
g.setClip(clipX, clipY, clipW, clipH);
}
// move clipping
g.translate(0, -this.tileHeight);
}
// move clipping
g.translate(-this.tileWidth, this.tileHeight*(endRow-startRow+1));
}
// restore clipping
g.translate(oldTransX - g.getTranslateX(),
oldTransY - g.getTranslateY());
}
/**
* Check colliding but checking cells.
* @param l Layer to check
* @return whether colliding exists
*/
public boolean cellCollides(Layer l)
{
// where to begin
BBox2D layerBox = l.bbox;
int startCol = Math.max(0, (layerBox.x - this.bbox.x) / this.tileWidth);
int startRow = Math.max(0, (layerBox.y - this.bbox.y) / this.tileHeight);
// where to end
int endCol = Math.min(startCol + (layerBox.width / this.tileWidth) + 1,
this.columns - 1);
int endRow = Math.min(startRow + (layerBox.height / this.tileHeight) + 1,
this.rows - 1);
// go, go, go!!
int i, j, boxX, boxY;
// limits will be calculated incrementaly (boxX and boxY) -> more efficient
boxX = this.bbox.x + endCol*this.tileWidth;
for (i = endCol; i >= startCol; i--)
{
boxY = this.bbox.y + endRow*this.tileHeight;
for (j = endRow; j >= startRow; j--)
{
if (this.grid[i][j] != 0)
{
if (layerBox.collide(boxX, boxY, tileWidth, tileHeight))
{
return true;
}
}
boxY -= tileHeight;
}
boxX -= tileWidth;
}
return false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -