⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 world.java

📁 j2me游戏编程光盘源码
💻 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 + -