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