1cfd74d65d832137e20e193c960802afba73b5d38sm/* 23c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Copyright (C) 2010 The Android Open Source Project 3cfd74d65d832137e20e193c960802afba73b5d38sm * 4cfd74d65d832137e20e193c960802afba73b5d38sm * Licensed under the Apache License, Version 2.0 (the "License"); 5cfd74d65d832137e20e193c960802afba73b5d38sm * you may not use this file except in compliance with the License. 6cfd74d65d832137e20e193c960802afba73b5d38sm * You may obtain a copy of the License at 7cfd74d65d832137e20e193c960802afba73b5d38sm * 8cfd74d65d832137e20e193c960802afba73b5d38sm * http://www.apache.org/licenses/LICENSE-2.0 9cfd74d65d832137e20e193c960802afba73b5d38sm * 10cfd74d65d832137e20e193c960802afba73b5d38sm * Unless required by applicable law or agreed to in writing, software 11cfd74d65d832137e20e193c960802afba73b5d38sm * distributed under the License is distributed on an "AS IS" BASIS, 12cfd74d65d832137e20e193c960802afba73b5d38sm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cfd74d65d832137e20e193c960802afba73b5d38sm * See the License for the specific language governing permissions and 14cfd74d65d832137e20e193c960802afba73b5d38sm * limitations under the License. 15cfd74d65d832137e20e193c960802afba73b5d38sm */ 16cfd74d65d832137e20e193c960802afba73b5d38sm 17cfd74d65d832137e20e193c960802afba73b5d38smpackage com.replica.replicaisland; 18cfd74d65d832137e20e193c960802afba73b5d38sm 19cfd74d65d832137e20e193c960802afba73b5d38smimport java.io.IOException; 20cfd74d65d832137e20e193c960802afba73b5d38smimport java.io.InputStream; 21cfd74d65d832137e20e193c960802afba73b5d38smimport android.content.res.AssetManager; 22cfd74d65d832137e20e193c960802afba73b5d38sm 23cfd74d65d832137e20e193c960802afba73b5d38sm/** 24cfd74d65d832137e20e193c960802afba73b5d38sm * TiledWorld manages a 2D map of tile indexes that define a "world" of tiles. These may be 25cfd74d65d832137e20e193c960802afba73b5d38sm * foreground or background layers in a scrolling game, or a layer of collision tiles, or some other 26cfd74d65d832137e20e193c960802afba73b5d38sm * type of tile map entirely. The TiledWorld maps xy positions to tile indices and also handles 27cfd74d65d832137e20e193c960802afba73b5d38sm * deserialization of tilemap files. 28cfd74d65d832137e20e193c960802afba73b5d38sm */ 29cfd74d65d832137e20e193c960802afba73b5d38smpublic class TiledWorld extends AllocationGuard { 30cfd74d65d832137e20e193c960802afba73b5d38sm private int[][] mTilesArray; 31cfd74d65d832137e20e193c960802afba73b5d38sm private int mRowCount; 32cfd74d65d832137e20e193c960802afba73b5d38sm private int mColCount; 33cfd74d65d832137e20e193c960802afba73b5d38sm private byte[] mWorkspaceBytes; 34cfd74d65d832137e20e193c960802afba73b5d38sm 35cfd74d65d832137e20e193c960802afba73b5d38sm public TiledWorld(int cols, int rows) { 36cfd74d65d832137e20e193c960802afba73b5d38sm super(); 37cfd74d65d832137e20e193c960802afba73b5d38sm mTilesArray = new int[cols][rows]; 38cfd74d65d832137e20e193c960802afba73b5d38sm mRowCount = rows; 39cfd74d65d832137e20e193c960802afba73b5d38sm mColCount = cols; 40cfd74d65d832137e20e193c960802afba73b5d38sm 41cfd74d65d832137e20e193c960802afba73b5d38sm for (int x = 0; x < cols; x++) { 42cfd74d65d832137e20e193c960802afba73b5d38sm for (int y = 0; y < rows; y++) { 43cfd74d65d832137e20e193c960802afba73b5d38sm mTilesArray[x][y] = -1; 44cfd74d65d832137e20e193c960802afba73b5d38sm } 45cfd74d65d832137e20e193c960802afba73b5d38sm } 46cfd74d65d832137e20e193c960802afba73b5d38sm 47cfd74d65d832137e20e193c960802afba73b5d38sm mWorkspaceBytes = new byte[4]; 48cfd74d65d832137e20e193c960802afba73b5d38sm 49cfd74d65d832137e20e193c960802afba73b5d38sm calculateSkips(); 50cfd74d65d832137e20e193c960802afba73b5d38sm } 51cfd74d65d832137e20e193c960802afba73b5d38sm 52cfd74d65d832137e20e193c960802afba73b5d38sm public TiledWorld(InputStream stream) { 53cfd74d65d832137e20e193c960802afba73b5d38sm super(); 54cfd74d65d832137e20e193c960802afba73b5d38sm mWorkspaceBytes = new byte[4]; 55cfd74d65d832137e20e193c960802afba73b5d38sm parseInput(stream); 56cfd74d65d832137e20e193c960802afba73b5d38sm calculateSkips(); 57cfd74d65d832137e20e193c960802afba73b5d38sm } 58cfd74d65d832137e20e193c960802afba73b5d38sm 59cfd74d65d832137e20e193c960802afba73b5d38sm public int getTile(int x, int y) { 60cfd74d65d832137e20e193c960802afba73b5d38sm int result = -1; 61cfd74d65d832137e20e193c960802afba73b5d38sm if (x >= 0 && x < mColCount && y >= 0 && y < mRowCount) { 62cfd74d65d832137e20e193c960802afba73b5d38sm result = mTilesArray[x][y]; 63cfd74d65d832137e20e193c960802afba73b5d38sm } 64cfd74d65d832137e20e193c960802afba73b5d38sm return result; 65cfd74d65d832137e20e193c960802afba73b5d38sm } 66cfd74d65d832137e20e193c960802afba73b5d38sm 67cfd74d65d832137e20e193c960802afba73b5d38sm // Builds a tiled world from a simple map file input source. The map file format is as follows: 68cfd74d65d832137e20e193c960802afba73b5d38sm // First byte: signature. Must always be decimal 42. 69cfd74d65d832137e20e193c960802afba73b5d38sm // Second byte: width of the world in tiles. 70cfd74d65d832137e20e193c960802afba73b5d38sm // Third byte: height of the world in tiles. 71cfd74d65d832137e20e193c960802afba73b5d38sm // Subsequent bytes: actual tile data in column-major order. 72cfd74d65d832137e20e193c960802afba73b5d38sm // TODO: add a checksum in here somewhere. 73cfd74d65d832137e20e193c960802afba73b5d38sm protected boolean parseInput(InputStream stream) { 74cfd74d65d832137e20e193c960802afba73b5d38sm boolean success = false; 75cfd74d65d832137e20e193c960802afba73b5d38sm AssetManager.AssetInputStream byteStream = (AssetManager.AssetInputStream) stream; 76cfd74d65d832137e20e193c960802afba73b5d38sm int signature; 77cfd74d65d832137e20e193c960802afba73b5d38sm try { 78cfd74d65d832137e20e193c960802afba73b5d38sm signature = (byte)byteStream.read(); 79cfd74d65d832137e20e193c960802afba73b5d38sm if (signature == 42) { 80cfd74d65d832137e20e193c960802afba73b5d38sm byteStream.read(mWorkspaceBytes, 0, 4); 81cfd74d65d832137e20e193c960802afba73b5d38sm final int width = Utils.byteArrayToInt(mWorkspaceBytes); 82cfd74d65d832137e20e193c960802afba73b5d38sm byteStream.read(mWorkspaceBytes, 0, 4); 83cfd74d65d832137e20e193c960802afba73b5d38sm final int height = Utils.byteArrayToInt(mWorkspaceBytes); 84cfd74d65d832137e20e193c960802afba73b5d38sm 85cfd74d65d832137e20e193c960802afba73b5d38sm final int totalTiles = width * height; 86cfd74d65d832137e20e193c960802afba73b5d38sm final int bytesRemaining = byteStream.available(); 87cfd74d65d832137e20e193c960802afba73b5d38sm assert bytesRemaining >= totalTiles; 88cfd74d65d832137e20e193c960802afba73b5d38sm if (bytesRemaining >= totalTiles) { 89cfd74d65d832137e20e193c960802afba73b5d38sm mTilesArray = new int[width][height]; 90cfd74d65d832137e20e193c960802afba73b5d38sm mRowCount = height; 91cfd74d65d832137e20e193c960802afba73b5d38sm mColCount = width; 92cfd74d65d832137e20e193c960802afba73b5d38sm for (int y = 0; y < height; y++) { 93cfd74d65d832137e20e193c960802afba73b5d38sm for (int x = 0; x < width; x++) { 94cfd74d65d832137e20e193c960802afba73b5d38sm mTilesArray[x][y] = (byte)byteStream.read(); 95cfd74d65d832137e20e193c960802afba73b5d38sm } 96cfd74d65d832137e20e193c960802afba73b5d38sm } 97cfd74d65d832137e20e193c960802afba73b5d38sm success = true; 98cfd74d65d832137e20e193c960802afba73b5d38sm } 99cfd74d65d832137e20e193c960802afba73b5d38sm } 100cfd74d65d832137e20e193c960802afba73b5d38sm 101cfd74d65d832137e20e193c960802afba73b5d38sm } catch (IOException e) { 102cfd74d65d832137e20e193c960802afba73b5d38sm //TODO: figure out the best way to deal with this. Assert? 103cfd74d65d832137e20e193c960802afba73b5d38sm } 104cfd74d65d832137e20e193c960802afba73b5d38sm 105cfd74d65d832137e20e193c960802afba73b5d38sm return success; 106cfd74d65d832137e20e193c960802afba73b5d38sm } 107cfd74d65d832137e20e193c960802afba73b5d38sm 108cfd74d65d832137e20e193c960802afba73b5d38sm protected void calculateSkips() { 109cfd74d65d832137e20e193c960802afba73b5d38sm int emptyTileCount = 0; 110cfd74d65d832137e20e193c960802afba73b5d38sm for (int y = mRowCount - 1; y >= 0; y--) { 111cfd74d65d832137e20e193c960802afba73b5d38sm for (int x = mColCount - 1; x >= 0; x--) { 112cfd74d65d832137e20e193c960802afba73b5d38sm if (mTilesArray[x][y] < 0) { 113cfd74d65d832137e20e193c960802afba73b5d38sm emptyTileCount++; 114cfd74d65d832137e20e193c960802afba73b5d38sm mTilesArray[x][y] = -emptyTileCount; 115cfd74d65d832137e20e193c960802afba73b5d38sm } else { 116cfd74d65d832137e20e193c960802afba73b5d38sm emptyTileCount = 0; 117cfd74d65d832137e20e193c960802afba73b5d38sm } 118cfd74d65d832137e20e193c960802afba73b5d38sm } 119cfd74d65d832137e20e193c960802afba73b5d38sm } 120cfd74d65d832137e20e193c960802afba73b5d38sm } 121cfd74d65d832137e20e193c960802afba73b5d38sm 122cfd74d65d832137e20e193c960802afba73b5d38sm public final int getWidth() { 123cfd74d65d832137e20e193c960802afba73b5d38sm return mColCount; 124cfd74d65d832137e20e193c960802afba73b5d38sm } 125cfd74d65d832137e20e193c960802afba73b5d38sm 126cfd74d65d832137e20e193c960802afba73b5d38sm public final int getHeight() { 127cfd74d65d832137e20e193c960802afba73b5d38sm return mRowCount; 128cfd74d65d832137e20e193c960802afba73b5d38sm } 129cfd74d65d832137e20e193c960802afba73b5d38sm 130cfd74d65d832137e20e193c960802afba73b5d38sm public final int[][] getTiles() { 131cfd74d65d832137e20e193c960802afba73b5d38sm return mTilesArray; 132cfd74d65d832137e20e193c960802afba73b5d38sm } 133cfd74d65d832137e20e193c960802afba73b5d38sm 134cfd74d65d832137e20e193c960802afba73b5d38sm} 135