?? world.java
字號:
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import java.util.Vector;
/**
* A container and manager for all the tiles and actors within a single
* map/level/environment in a game.
* @author Martin J. Wells
*/
public class World
{
private static final int TILE_WIDTH=16;
private static final int TILE_HEIGHT=16;
/**
* Types of tiles as bytes. Each one directly maps to a frame in the world
* image file. Set NO_TILE to leave a tile empty (the default).
*/
public static final byte NO_TILE = 0;
public static final byte WALL_TILE = 1;
private Vector actors;
private int viewX, viewY; // Current viewport coordinates.
private int viewWidth, viewHeight; // Size of the current viewport.
private int tilesWide, tilesHigh; // The number of tiles in the world.
private ImageSet tiles; // Images for the tiles.
private byte tileMap[][]; // Array of bytes representing the map
/**
* Constructs a world containing the requested number of tiles across and
* down. The size of the rendering viewport should be set to the size of the
* screen unless you wish to render only a small portion.
* @param tilesWideArg Width of the world in tiles.
* @param tilesHighArg Height of the world in tiles.
* @param viewWidthArg Width of the view port.
* @param viewHeightArg Height of the view port.
*/
public World(int tilesWideArg, int tilesHighArg, int viewWidthArg,
int viewHeightArg)
{
tilesWide = tilesWideArg;
tilesHigh = tilesHighArg;
viewWidth = viewWidthArg;
viewHeight = viewHeightArg;
// Create the level array.
tileMap = new byte[tilesHigh][tilesWide];
// Set the array elements down the left and right sides of the world.
for (int tileY=0; tileY < tilesHigh; tileY++)
{
tileMap[tileY][0] = WALL_TILE;
tileMap[tileY][tilesWide-1] = WALL_TILE;
}
// Set the array elements across the top and bottom.
for (int tileX = 0; tileX < tilesWide; tileX++)
{
tileMap[0][tileX] = WALL_TILE;
tileMap[tilesHigh-1][tileX] = WALL_TILE;
}
// Initialize the actor vector.
actors = new Vector();
// Load the tile graphics (16 x 16 pixel frames).
Image tileGraphics = ImageSet.loadClippedImage("/world.png", 0, 0,
16, 16);
tiles = new ImageSet(1);
tiles.addState(new Image[]{tileGraphics}, 0);
}
/**
* Add an Actor to the world.
* @param a The Actor to add.
*/
public void addActor(Actor a)
{
actors.addElement(a);
}
/**
* Remove an Actor from the world.
* @param a The Actor object to remove.
*/
public void removeActor(Actor a)
{
actors.removeElement(a);
}
/**
* Set the current view port position (relative to world coordinates).
* @param viewXArg The x position of the view.
* @param viewYArg The y position of the view.
*/
public final void setView(int viewXArg, int viewYArg)
{
viewX = viewXArg;
viewY = viewYArg;
}
/**
* @param x A world coordinate on the x axis.
* @return The corresponding tile location at this position.
*/
public final int getTileX(int x) { return x / TILE_WIDTH; }
/**
* @param y A world coordinate on the y axis.
* @return The corresponding tile location at this position.
*/
public final int getTileY(int y) { return y / TILE_HEIGHT; }
/**
* Safely retrieves the tile type (byte) from a given x, y position (in
* world coorindates). The x and y position will be converted into a tile
* coordinate.
* @param x The x position in world coordinates.
* @param y The y position in world coordinates.
* @return The tile type (as a byte) at the specified location.
*/
public final byte getTile(int x, int y)
{
int tileX = getTileX(x);
int tileY = getTileY(y);
if (tileX < 0 || tileX >= tilesWide || tileY < 0 || tileY >= tilesHigh)
return -1;
return tileMap[ y / TILE_HEIGHT ][ x / TILE_WIDTH ];
}
/**
* Renders the world onto the graphics context. This version starts by
* drawing a star field then the tiles and finally the actors.
* @param graphics The graphics context upon which to draw.
*/
protected void render(Graphics graphics)
{
// Draw a star field scrolling 10 times slower than the view.
Tools.drawStarField(graphics, viewX / 10, viewY / 10,
viewWidth, viewHeight);
// Render the tiles that are within the current view port rectangle.
int startTileX = (viewX / TILE_WIDTH) - 1;
int startTileY = (viewY / TILE_HEIGHT) - 1;
int endTileX = ((Math.abs(viewX) + viewWidth) / TILE_WIDTH) + 1;
int endTileY = ((Math.abs(viewY) + viewHeight) / TILE_HEIGHT) + 1;
if (endTileX > tilesWide) endTileX = tilesWide;
if (endTileY > tilesHigh) endTileY = tilesHigh;
if (startTileX < 0) startTileX = 0;
if (startTileY < 0) startTileY = 0;
byte tileType = 0;
int xpos = 0;
int ypos = 0;
// Loop through all the rows of the tile map that need to be drawn, then
// all the columns. This starts at startTileY and goes down till we get to
// the last viewable row at endTileY, then for each of these it goes
// across the map from startTileX to endTileX.
for (int drawTileY = startTileY; drawTileY < endTileY; drawTileY++)
{
for (int drawTileX = startTileX; drawTileX < endTileX; drawTileX++)
{
if (drawTileY >= 0 && drawTileX >= 0)
{
// Access the entry corresponding to this location. Since most
// tile maps contains empty space the code also does a quick
// check to see if it can just ignore this entry if the byte
// equals the default value 0 (NO_TILE).
tileType = tileMap[drawTileY][drawTileX];
if (tileType == NO_TILE) continue; // quick abort if it's nothing
// Calculate the x and y position of this tile.
xpos = (drawTileX * TILE_WIDTH) - viewX;
ypos = (drawTileY * TILE_HEIGHT) - viewY;
// Check whether this tile position is in the view port.
if (xpos > 0 - TILE_WIDTH && xpos < viewWidth &&
ypos > 0 - TILE_HEIGHT && ypos < viewHeight)
{
// Based on the byte value this code draws an image from the
// ImageSet loaded in the constructor. To keep this simpler
// I抳e mapped the frames in the graphics file to the same
// byte values in the map. That way the code doesn抰 need to
// translate the values when drawing them [--] if the tile map
// byte is the number two the second frame from the loaded
// world images will be drawn (note that I take one away from
// the byte value to account for zero meaning no tile in the
// world).
tiles.draw(graphics, 0, 0, xpos, ypos);
}
}
}
}
// Render all the actors on top.
for (int i = 0; i < actors.size(); i++)
{
Actor a = (Actor) actors.elementAt(i);
if (Tools.isPointInRect(a.getX(), a.getY(),
viewX - TILE_WIDTH, viewY - TILE_HEIGHT,
endTileX * TILE_WIDTH, endTileY * TILE_HEIGHT))
a.render(graphics, viewX, viewY);
}
}
/**
* Cycle the world. For this example we only have to call the cycle method
* on all the actors. Note that to simplify things I'm using an elasped time
* of 100 milliseconds. For a complete game this should be based on proper
* timeing (See the Star Assault GameScreen class code for an example of
* this).
*/
public void cycle()
{
for (int i = 0; i < actors.size(); i++)
((Actor) actors.elementAt(i)).cycle(100);
}
/**
* Called by the Actor to check if it has collided with anything in the
* world. See the Actor cycle method for more information.
* @param actorToCheck The Actor that needs to be checked.
* @return True if the actor is in a collision state with either a tile or
* another Actor.
*/
public boolean checkCollision(Actor actorToCheck)
{
// test if this actor object has hit a tile on layer 1 (we ignore layer 0)
// we look at all the tiles under the actor (we do a <= comparison so we
// include the bounding edge of the actor's rectangle
int actorBottom = actorToCheck.getY()+actorToCheck.getHeight();
int actorRightSide = actorToCheck.getX()+actorToCheck.getWidth();
for (int tileY=actorToCheck.getY(); tileY <= actorBottom;
tileY += TILE_HEIGHT)
{
for (int tileX=actorToCheck.getX(); tileX <= actorRightSide;
tileX += TILE_WIDTH)
{
if (getTile(tileX, tileY) > NO_TILE)
return true;
}
}
// Ignore bullet hits on other actors for now.
if (actorToCheck instanceof Bullet) return false;
// Did this ship hit another?
for (int j = 0; j < actors.size(); j++)
{
Actor another = (Actor)actors.elementAt(j);
if (another != actorToCheck && !(another instanceof Bullet) &&
Tools.isIntersectingRect(actorToCheck.getX(), actorToCheck.getY(),
actorToCheck.getWidth(),
actorToCheck.getHeight(),
another.getX(), another.getY(),
another.getWidth(),
another.getHeight()))
return true;
}
return false;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -