javauis/lcdui_qt/src/javax/microedition/lcdui/game/TiledLayer.java
changeset 23 98ccebc37403
parent 21 2a9601315dfc
equal deleted inserted replaced
21:2a9601315dfc 23:98ccebc37403
     9 * Initial Contributors:
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    10 * Nokia Corporation - initial contribution.
    11 *
    11 *
    12 * Contributors:
    12 * Contributors:
    13 *
    13 *
    14 * Description: 
    14 * Description:
    15 *
    15 *
    16 */
    16 */
    17 package javax.microedition.lcdui.game;
    17 package javax.microedition.lcdui.game;
    18 
    18 
    19 import javax.microedition.lcdui.Graphics;
    19 import javax.microedition.lcdui.Graphics;
    20 import javax.microedition.lcdui.Image;
    20 import javax.microedition.lcdui.Image;
    21 
    21 
    22 public class TiledLayer extends Layer {
    22 public class TiledLayer extends Layer
       
    23 {
    23 
    24 
    24     // Animated tile array increment
    25     // Animated tile array increment
    25     private static final int ANIM_ARRAY_INCREMENT = 4;
    26     private static final int ANIM_ARRAY_INCREMENT = 4;
    26 
    27 
    27     private int rows;
    28     private int rows;
    29 
    30 
    30     private int[][] cells;
    31     private int[][] cells;
    31     private int[] animArray;
    32     private int[] animArray;
    32     private int animCount;
    33     private int animCount;
    33 
    34 
    34     public TiledLayer(int cols, int rows, Image tileImage, int tileWidth, int tileHeight) {
    35     public TiledLayer(int cols, int rows, Image tileImage, int tileWidth, int tileHeight)
       
    36     {
    35         super(tileImage, tileWidth, tileHeight);
    37         super(tileImage, tileWidth, tileHeight);
    36 
    38 
    37         if (cols < 1 || rows < 1) {
    39         if(cols < 1 || rows < 1)
       
    40         {
    38             throw new IllegalArgumentException(
    41             throw new IllegalArgumentException(
    39                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_DIMENSIONS);
    42                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_DIMENSIONS);
    40         }
    43         }
    41 
    44 
    42         this.cols = cols;
    45         this.cols = cols;
    43         this.rows = rows;
    46         this.rows = rows;
    44         cells = new int[rows][cols];
    47         cells = new int[rows][cols];
    45         animArray = new int[ANIM_ARRAY_INCREMENT];
    48         animArray = new int[ANIM_ARRAY_INCREMENT];
    46         animCount = 0;
    49         animCount = 0;
    47     }
    50     }
    48 
    51 
    49     public void setStaticTileSet(Image tileImage, int tileWidth, int tileHeight) {
    52     public void setStaticTileSet(Image tileImage, int tileWidth, int tileHeight)
       
    53     {
    50         final int oldTileCount = tileCount;
    54         final int oldTileCount = tileCount;
    51 
    55 
    52         setTileImage(tileImage, tileWidth, tileHeight);
    56         setTileImage(tileImage, tileWidth, tileHeight);
    53 
    57 
    54         // If the new static tile set has as many or more tiles, then the
    58         // If the new static tile set has as many or more tiles, then the
    55         // animated tiles and cell contents will be preserved.
    59         // animated tiles and cell contents will be preserved.
    56         // If not, the contents of the grid will be cleared (all cells will
    60         // If not, the contents of the grid will be cleared (all cells will
    57         // contain index 0) and all animated tiles will be deleted.
    61         // contain index 0) and all animated tiles will be deleted.
    58         //
    62         //
    59         if (tileCount < oldTileCount) {
    63         if(tileCount < oldTileCount)
       
    64         {
    60             fillCells(0, 0, cols, rows, 0);
    65             fillCells(0, 0, cols, rows, 0);
    61             animCount = 0;
    66             animCount = 0;
    62         }
    67         }
    63     }
    68     }
    64 
    69 
    65     public void setCell(int col, int row, int aTileIndex) {
    70     public void setCell(int col, int row, int aTileIndex)
       
    71     {
    66         validateTileIndex(aTileIndex);
    72         validateTileIndex(aTileIndex);
    67         cells[row][col] = aTileIndex;
    73         cells[row][col] = aTileIndex;
    68     }
    74     }
    69 
    75 
    70     public int getCell(int col, int row) {
    76     public int getCell(int col, int row)
       
    77     {
    71         return cells[row][col];
    78         return cells[row][col];
    72     }
    79     }
    73 
    80 
    74     public void fillCells(int col, int row, int numCols, int numRows, int tileIndex) {
    81     public void fillCells(int col, int row, int numCols, int numRows, int tileIndex)
    75         if (numCols < 0) {
    82     {
       
    83         if(numCols < 0)
       
    84         {
    76             throw new IllegalArgumentException(
    85             throw new IllegalArgumentException(
    77                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_NUMBER_OF_COLUMNS);
    86                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_NUMBER_OF_COLUMNS);
    78         }
    87         }
    79         if (numRows < 0) {
    88         if(numRows < 0)
       
    89         {
    80             throw new IllegalArgumentException(
    90             throw new IllegalArgumentException(
    81                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_NUMBER_OF_ROWS);
    91                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_NUMBER_OF_ROWS);
    82         }
    92         }
    83         validateTileIndex(tileIndex);
    93         validateTileIndex(tileIndex);
    84 
    94 
    85         for (int i = col + numCols; --i >= col;) {
    95         for(int i = col + numCols; --i >= col;)
       
    96         {
    86             cells[row][i] = tileIndex;
    97             cells[row][i] = tileIndex;
    87         }
    98         }
    88         for (int i = row + numRows; --i > row;) {
    99         for(int i = row + numRows; --i > row;)
       
   100         {
    89             System.arraycopy(cells[row], col, cells[i], col, numCols);
   101             System.arraycopy(cells[row], col, cells[i], col, numCols);
    90         }
   102         }
    91     }
   103     }
    92 
   104 
    93     public int createAnimatedTile(int tileIndex) {
   105     public int createAnimatedTile(int tileIndex)
    94         if (tileIndex < 0 || tileIndex > tileCount) {
   106     {
    95             throw new IndexOutOfBoundsException(
   107         if(tileIndex < 0 || tileIndex > tileCount)
    96                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_TILE_INDEX);
   108         {
       
   109             throw new IndexOutOfBoundsException(
       
   110                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_TILE_INDEX);
    97         }
   111         }
    98 
   112 
    99         final int index = animCount;
   113         final int index = animCount;
   100         checkCapacity(index + 1);
   114         checkCapacity(index + 1);
   101         animArray[index] = tileIndex;
   115         animArray[index] = tileIndex;
   104     }
   118     }
   105 
   119 
   106     /**
   120     /**
   107      * Grows the animated tile array if required.
   121      * Grows the animated tile array if required.
   108      */
   122      */
   109     private void checkCapacity(int requiredLength) {
   123     private void checkCapacity(int requiredLength)
       
   124     {
   110         int length = animArray.length;
   125         int length = animArray.length;
   111         if (requiredLength > length) {
   126         if(requiredLength > length)
       
   127         {
   112             int[] array = new int[length + ANIM_ARRAY_INCREMENT];
   128             int[] array = new int[length + ANIM_ARRAY_INCREMENT];
   113             System.arraycopy(animArray, 0, array, 0, length);
   129             System.arraycopy(animArray, 0, array, 0, length);
   114             animArray = array;
   130             animArray = array;
   115         }
   131         }
   116     }
   132     }
   117 
   133 
   118     public void setAnimatedTile(int animIndex, int tileIndex) {
   134     public void setAnimatedTile(int animIndex, int tileIndex)
       
   135     {
   119         final int index = ~animIndex;
   136         final int index = ~animIndex;
   120         if (index >= animCount) {
   137         if(index >= animCount)
   121             throw new IndexOutOfBoundsException(
   138         {
   122                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_ANIMTILE_INDEX);
   139             throw new IndexOutOfBoundsException(
   123         }
   140                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_ANIMTILE_INDEX);
   124         if (tileIndex < 0 || tileIndex > tileCount) {
   141         }
   125             throw new IndexOutOfBoundsException(
   142         if(tileIndex < 0 || tileIndex > tileCount)
   126                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_TILE_INDEX);
   143         {
       
   144             throw new IndexOutOfBoundsException(
       
   145                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_TILE_INDEX);
   127         }
   146         }
   128         animArray[index] = tileIndex;
   147         animArray[index] = tileIndex;
   129     }
   148     }
   130 
   149 
   131     public int getAnimatedTile(int animIndex) {
   150     public int getAnimatedTile(int animIndex)
       
   151     {
   132         final int index = ~animIndex;
   152         final int index = ~animIndex;
   133         if (index >= animCount) {
   153         if(index >= animCount)
   134             throw new IndexOutOfBoundsException(
   154         {
   135                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_ANIMTILE_INDEX);
   155             throw new IndexOutOfBoundsException(
       
   156                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_ANIMTILE_INDEX);
   136         }
   157         }
   137         return animArray[index];
   158         return animArray[index];
   138     }
   159     }
   139 
   160 
   140     public final int getCellWidth() {
   161     public final int getCellWidth()
       
   162     {
   141         return tileWidth;
   163         return tileWidth;
   142     }
   164     }
   143 
   165 
   144     public final int getCellHeight() {
   166     public final int getCellHeight()
       
   167     {
   145         return tileHeight;
   168         return tileHeight;
   146     }
   169     }
   147 
   170 
   148     public final int getColumns() {
   171     public final int getColumns()
       
   172     {
   149         return cols;
   173         return cols;
   150     }
   174     }
   151 
   175 
   152     public final int getRows() {
   176     public final int getRows()
       
   177     {
   153         return rows;
   178         return rows;
   154     }
   179     }
   155 
   180 
   156     public final void paint(Graphics aGraphics) {
   181     public final void paint(Graphics aGraphics)
   157         if (visible) {
   182     {
       
   183         if(visible)
       
   184         {
   158             aGraphics.translate(x, y);
   185             aGraphics.translate(x, y);
   159 
   186 
   160             int clipX1 = aGraphics.getClipX();
   187             int clipX1 = aGraphics.getClipX();
   161             int clipY1 = aGraphics.getClipY();
   188             int clipY1 = aGraphics.getClipY();
   162             int clipX2 = clipX1 + aGraphics.getClipWidth();
   189             int clipX2 = clipX1 + aGraphics.getClipWidth();
   180             int sx = begRow * th;
   207             int sx = begRow * th;
   181             int sy = begCol * tw;
   208             int sy = begCol * tw;
   182             int dx;
   209             int dx;
   183             int dy;
   210             int dy;
   184 
   211 
   185             for (int row = begRow; row <= endRow; row++) {
   212             for(int row = begRow; row <= endRow; row++)
   186                 for (int col = begCol; col <= endCol; col++) {
   213             {
       
   214                 for(int col = begCol; col <= endCol; col++)
       
   215                 {
   187                     final int index = validateTileIndex(cells[row][col]);
   216                     final int index = validateTileIndex(cells[row][col]);
   188                     if (index >= 0) {
   217                     if(index >= 0)
       
   218                     {
   189                         // Future performace improvement suggestion: accumulate
   219                         // Future performace improvement suggestion: accumulate
   190                         // region
   220                         // region
   191                         //
   221                         //
   192                         // We have a visible tile in the clip rect, if its
   222                         // We have a visible tile in the clip rect, if its
   193                         // bounding rect is disjoint from our accumulated rect,
   223                         // bounding rect is disjoint from our accumulated rect,
   209 
   239 
   210                         sx = tc * tw;
   240                         sx = tc * tw;
   211                         sy = tr * th;
   241                         sy = tr * th;
   212 
   242 
   213                         aGraphics.drawRegion(tileImage,
   243                         aGraphics.drawRegion(tileImage,
   214                                 sx, sy,
   244                                              sx, sy,
   215                                 tw, th,
   245                                              tw, th,
   216                                 Sprite.TRANS_NONE,
   246                                              Sprite.TRANS_NONE,
   217                                 dx, dy, 0);
   247                                              dx, dy, 0);
   218                     }
   248                     }
   219                 }
   249                 }
   220             }
   250             }
   221 
   251 
   222             aGraphics.translate(-x, -y);
   252             aGraphics.translate(-x, -y);
   223         }
   253         }
   224     }
   254     }
   225 
   255 
   226     private int validateTileIndex(int tileIndex) {
   256     private int validateTileIndex(int tileIndex)
   227         if (tileIndex > tileCount) {
   257     {
   228             throw new IndexOutOfBoundsException(
   258         if(tileIndex > tileCount)
   229                     MsgRepository.TILEDLAYER_EXCEPTION_INVALID_TILE_INDEX);
   259         {
       
   260             throw new IndexOutOfBoundsException(
       
   261                 MsgRepository.TILEDLAYER_EXCEPTION_INVALID_TILE_INDEX);
   230         }
   262         }
   231         // check createAnimatedTile has been called, getAnimatedTile will throw
   263         // check createAnimatedTile has been called, getAnimatedTile will throw
   232         // exception if hasn't.
   264         // exception if hasn't.
   233         if (tileIndex < 0) {
   265         if(tileIndex < 0)
       
   266         {
   234             tileIndex = getAnimatedTile(tileIndex);
   267             tileIndex = getAnimatedTile(tileIndex);
   235         }
   268         }
   236         return tileIndex - 1;
   269         return tileIndex - 1;
   237     }
   270     }
   238 
   271 
   239     boolean collidesCell(int aX1, int aY1, int aX2, int aY2) {
   272     boolean collidesCell(int aX1, int aY1, int aX2, int aY2)
       
   273     {
   240         // tiled layer rect in painter's coordinates
   274         // tiled layer rect in painter's coordinates
   241         int tlX1 = x;
   275         int tlX1 = x;
   242         int tlY1 = y;
   276         int tlY1 = y;
   243         int tlX2 = x + getWidth();
   277         int tlX2 = x + getWidth();
   244         int tlY2 = y + getHeight();
   278         int tlY2 = y + getHeight();
   249         tlY1 = Math.max(tlY1, aY1);
   283         tlY1 = Math.max(tlY1, aY1);
   250         tlX2 = Math.min(tlX2, aX2);
   284         tlX2 = Math.min(tlX2, aX2);
   251         tlY2 = Math.min(tlY2, aY2);
   285         tlY2 = Math.min(tlY2, aY2);
   252 
   286 
   253         // return false if empty intersection.
   287         // return false if empty intersection.
   254         if (!((tlX1 < tlX2) && (tlY1 < tlY2))) {
   288         if(!((tlX1 < tlX2) && (tlY1 < tlY2)))
       
   289         {
   255             return false;
   290             return false;
   256         }
   291         }
   257 
   292 
   258         // transform to tiled layer coordinates
   293         // transform to tiled layer coordinates
   259         tlX1 -= x;
   294         tlX1 -= x;
   264         int startRow = (tlY1 / tileHeight);
   299         int startRow = (tlY1 / tileHeight);
   265         int startCol = (tlX1 / tileWidth);
   300         int startCol = (tlX1 / tileWidth);
   266         int endRow = (tlY2 - 1) / tileHeight;
   301         int endRow = (tlY2 - 1) / tileHeight;
   267         int endCol = (tlX2 - 1) / tileWidth;
   302         int endCol = (tlX2 - 1) / tileWidth;
   268 
   303 
   269         for (int row = startRow; row <= endRow; row++) {
   304         for(int row = startRow; row <= endRow; row++)
   270             for (int col = startCol; col <= endCol; col++) {
   305         {
   271                 if (cells[row][col] != 0) {
   306             for(int col = startCol; col <= endCol; col++)
       
   307             {
       
   308                 if(cells[row][col] != 0)
       
   309                 {
   272                     // at least one cell is not empty
   310                     // at least one cell is not empty
   273                     return true;
   311                     return true;
   274                 }
   312                 }
   275             }
   313             }
   276         }
   314         }
   277 
   315 
   278         // all cells in overlap are empty
   316         // all cells in overlap are empty
   279         return false;
   317         return false;
   280     }
   318     }
   281 
   319 
   282     int getLayerWidth() {
   320     int getLayerWidth()
       
   321     {
   283         return cols * tileWidth;
   322         return cols * tileWidth;
   284     }
   323     }
   285 
   324 
   286     int getLayerHeight() {
   325     int getLayerHeight()
       
   326     {
   287         return rows * tileHeight;
   327         return rows * tileHeight;
   288     }
   328     }
   289 }
   329 }