This class is a TiledLayer
that draws the grassy
field and water. The water tiles are animated so that they constantly change
a little, simulating waves. Its tile image is shown in the figure below.
Create the Field
class
file.
Import the required classes.
// unnamed package import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.*;
Set Field
to
extend TiledLayer
. A TiledLayer
is
a visual element composed of a grid of cells that can be filled with a set
of tile images. This class allows large virtual layers to be created without
the need for an extremely large Image
.
For more information, see TiledLayer
in
the MIDP 2.0 API specification.
class Field extends TiledLayer {
Create the background field for the game.
private static final int WIDTH_IN_TILES = 12; private static final int HEIGHT_IN_TILES = 12; private static final int TILE_WIDTH = 16; private static final int TILE_HEIGHT = 16; private static int[][] cellTiles = {{-3, -2, -3, -1, -2, -1, -3, -1, -2, -3, -1, -2}, {-2, 3, 4, 3, 1, 2, 3, 2, 1, 5, 2, -3}, {-1, 2, 1, 2, 3, 4, 5, 3, 2, 4, 3, -1}, {-2, 1, 4, 9, 9, 9, 9, 4, 5, 2, 1, -2}, {-3, 3, 5, 9, 10, 10, 10, 2, 1, 3, 5, -1}, {-2, 2, 3, 9, 10, 10, 10, 5, 4, 2, 1, -3}, {-1, 4, 2, 9, 9, 9, 9, 3, 1, 3, 2, -2}, {-3, 2, 5, 1, 3, 1, 4, 2, 5, 4, 3, -3}, {-2, 1, 4, 2, 5, 2, 3, 4, 2, 1, 2, -1}, {-1, 5, 1, 4, 3, 4, 1, 2, 3, 4, 1, -2}, {-3, 2, 4, 5, 2, 3, 2, 4, 1, 2, 3, -3}, {-2, -3, -2, -1, -2, -1, -3, -2, -1, -3, -1, -2}}; private static int FOLD_TILE = 10; private static int FENCE_TILE = 9; private static int[][] waterFrames = {{6, 7, 8}, {7, 8, 6}, {8, 6, 7}}; private int tickCount = 0;
Create a method
for creating the field. The createAnimatedTile
method
creates a new animated tile and returns the index that refers to the new animated
tile. The setCell
method sets the contents of a cell.
For
more information, see createAnimatedTile
and setCell
in the MIDP 2.0 API specification.
Field() { super(WIDTH_IN_TILES, HEIGHT_IN_TILES, SheepdogMIDlet.createImage("/field.png"), TILE_WIDTH, TILE_HEIGHT); createAnimatedTile(waterFrames[0][0]); // tile -1 createAnimatedTile(waterFrames[1][0]); // tile -2 createAnimatedTile(waterFrames[2][0]); // tile -3 for (int row = 0; row < HEIGHT_IN_TILES; ++row) { for (int column = 0; column < WIDTH_IN_TILES; ++column) { setCell(column, row, cellTiles[row][column]); } } }
Write the methods for determining the starting position of the dog and a method for determining the tick rate.
int getSheepdogStartX() { return getWidth() - 50; } int getSheepdogStartY() { return getHeight() - 50; } void tick() { int tickState = (tickCount++ >> 3); // slow down x8 int tile = tickState % 3; setAnimatedTile(-1 - tile, waterFrames[tile][(tickState % 9) / 3]); }
Create a method for checking passage into impassable areas.
// return true if any part of the rectangle overlaps a water tile // or the fence boolean containsImpassableArea(int x, int y, int width, int height) { int rowMin = y / TILE_HEIGHT; int rowMax = (y + height - 1) / TILE_HEIGHT; int columnMin = x / TILE_WIDTH; int columnMax = (x + width - 1) / TILE_WIDTH; for (int row = rowMin; row <= rowMax; ++row) { for (int column = columnMin; column <= columnMax; ++column) { int cell = getCell(column, row); if ((cell < 0) || (cell == FENCE_TILE)) { return true; } } } return false; }
Create a method for detecting if a sheep has entered the fold.
// returns true if every pixel of the sprite is in the fold boolean inFold(Sprite s) { // we can assume that the sprite's reference pixel is unchanged int rowMin = s.getY() / TILE_HEIGHT; int rowMax = (s.getY() + s.getHeight() - 1) / TILE_HEIGHT; int columnMin = s.getX() / TILE_WIDTH; int columnMax = (s.getX() + s.getWidth() - 1) / TILE_WIDTH; for (int row = rowMin; row <= rowMax; ++row) { for (int column = columnMin; column <= columnMax; ++column) { if (getCell(column, row) != FOLD_TILE) { return false; } } } return true; } }