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

📄 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;

   public static final byte START_ACTIVATOR_TILE = 2;
   public static final byte FIGHTER_ACTIVATOR_TILE = 2;
   public static final byte END_ACTIVATOR_TILE = 2;

   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

   private Ship playerShip;			      // A link to the player's object.

   /**
    * 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;

      // 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);
   }

   /**
    * Set the reference to the player's ship.
    */
   public void setPlayerShip(Ship s)
   {
      playerShip = s;
   }

   /**
    * Generate a new level.
    */
   public void generateLevel(int levelNum)
   {
      LevelGenerator lg = new LevelGenerator();
      tileMap = lg.generateLevel(levelNum);

      tilesWide = tileMap[0].length;
      tilesHigh = tileMap.length;
      int levelStartX = lg.getPlayerStartX();
      int levelStartY = lg.getPlayerStartY();

      playerShip.setX(levelStartX * TILE_WIDTH);
      playerShip.setY(levelStartY * TILE_HEIGHT);
   }

   /**
    * 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

               if (tileType >= START_ACTIVATOR_TILE &&
                   tileType <= END_ACTIVATOR_TILE)
                  activateTile(drawTileX, drawTileY);
               else
               {
                  // 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;
   }

   /**
    * Activates a tile at a specific location.
    * @param tileX
    * @param tileY
    */
   private final void activateTile(int tileX, int tileY)
   {

      byte tileType = tileMap[tileY][tileX];
      int xpos = (tileX * TILE_WIDTH);
      int ypos = (tileY * TILE_HEIGHT);

      switch (tileType)
      {
         case FIGHTER_ACTIVATOR_TILE:
            Ship s = new Ship(this, true, xpos, ypos);
            addActor(s);
            break;
      }

      // clear the activator tile
      tileMap[tileY][tileX] = NO_TILE;
   }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -