| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.replica.replicaisland; |
| |
| import android.content.res.AssetManager; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| /** |
| * Manages information about the current level, including setup, deserialization, and tear-down. |
| */ |
| public class LevelSystem extends BaseObject { |
| |
| public int mWidthInTiles; |
| public int mHeightInTiles; |
| public int mTileWidth; |
| public int mTileHeight; |
| public GameObject mBackgroundObject; |
| public ObjectManager mRoot; |
| private byte[] mWorkspaceBytes; |
| private TiledWorld mSpawnLocations; |
| private GameFlowEvent mGameFlowEvent; |
| private int mAttempts; |
| private LevelTree.Level mCurrentLevel; |
| |
| public LevelSystem() { |
| super(); |
| mWorkspaceBytes = new byte[4]; |
| mGameFlowEvent = new GameFlowEvent(); |
| reset(); |
| } |
| |
| @Override |
| public void reset() { |
| if (mBackgroundObject != null && mRoot != null) { |
| mBackgroundObject.removeAll(); |
| mBackgroundObject.commitUpdates(); |
| mRoot.remove(mBackgroundObject); |
| mBackgroundObject = null; |
| mRoot = null; |
| } |
| mSpawnLocations = null; |
| mAttempts = 0; |
| mCurrentLevel = null; |
| } |
| |
| public float getLevelWidth() { |
| return mWidthInTiles * mTileWidth; |
| } |
| |
| public float getLevelHeight() { |
| return mHeightInTiles * mTileHeight; |
| } |
| |
| public void sendRestartEvent() { |
| mGameFlowEvent.post(GameFlowEvent.EVENT_RESTART_LEVEL, 0, |
| sSystemRegistry.contextParameters.context); |
| } |
| |
| public void sendNextLevelEvent() { |
| mGameFlowEvent.post(GameFlowEvent.EVENT_GO_TO_NEXT_LEVEL, 0, |
| sSystemRegistry.contextParameters.context); |
| } |
| |
| public void sendGameEvent(int type, int index, boolean immediate) { |
| if (immediate) { |
| mGameFlowEvent.postImmediate(type, index, |
| sSystemRegistry.contextParameters.context); |
| } else { |
| mGameFlowEvent.post(type, index, |
| sSystemRegistry.contextParameters.context); |
| } |
| } |
| |
| /** |
| * Loads a level from a binary file. The file consists of several layers, including background |
| * tile layers and at most one collision layer. Each layer is used to bootstrap related systems |
| * and provide them with layer data. |
| * @param stream The input stream for the level file resource. |
| * @param tiles A tile library to use when constructing tiled background layers. |
| * @param background An object to assign background layer rendering components to. |
| * @return |
| */ |
| public boolean loadLevel(LevelTree.Level level, InputStream stream, ObjectManager root) { |
| boolean success = false; |
| mCurrentLevel = level; |
| AssetManager.AssetInputStream byteStream = (AssetManager.AssetInputStream) stream; |
| int signature; |
| try { |
| signature = (byte)byteStream.read(); |
| if (signature == 96) { |
| final int layerCount = (byte)byteStream.read(); |
| final int backgroundIndex = (byte)byteStream.read(); |
| |
| mRoot = root; |
| mTileWidth = 32; |
| mTileHeight = 32; |
| |
| ContextParameters params = sSystemRegistry.contextParameters; |
| int currentPriority = SortConstants.BACKGROUND_START + 1; |
| for (int x = 0; x < layerCount; x++) { |
| final int type = (byte)byteStream.read(); |
| final int tileIndex = (byte)byteStream.read(); |
| byteStream.read(mWorkspaceBytes, 0, 4); |
| final float scrollSpeed = Utils.byteArrayToFloat(mWorkspaceBytes); |
| |
| // TODO: use a pool here? Seems pointless. |
| TiledWorld world = new TiledWorld(byteStream); |
| |
| if (type == 0) { // it's a background layer |
| assert mWidthInTiles != 0; |
| assert mTileWidth != 0; |
| |
| // We require a collision layer to set up the tile sizes before we load. |
| // TODO: this really sucks. there's no reason each layer can't have its |
| // own tile widths and heights. Refactor this crap. |
| if (mWidthInTiles > 0 && mTileWidth > 0) { |
| |
| LevelBuilder builder = sSystemRegistry.levelBuilder; |
| |
| if (mBackgroundObject == null) { |
| mBackgroundObject = |
| builder.buildBackground( |
| backgroundIndex, |
| mWidthInTiles * mTileWidth, |
| mHeightInTiles * mTileHeight); |
| root.add(mBackgroundObject); |
| } |
| |
| |
| builder.addTileMapLayer(mBackgroundObject, currentPriority, |
| scrollSpeed, params.gameWidth, params.gameHeight, |
| mTileWidth, mTileHeight, world, tileIndex); |
| |
| |
| currentPriority++; |
| } |
| |
| } else if (type == 1) { // collision |
| // Collision always defines the world boundaries. |
| mWidthInTiles = world.getWidth(); |
| mHeightInTiles = world.getHeight(); |
| |
| |
| CollisionSystem collision = sSystemRegistry.collisionSystem; |
| if (collision != null) { |
| collision.initialize(world, mTileWidth, mTileHeight); |
| } |
| } else if (type == 2) { // objects |
| mSpawnLocations = world; |
| spawnObjects(); |
| } else if (type == 3) { // hot spots |
| HotSpotSystem hotSpots = sSystemRegistry.hotSpotSystem; |
| if (hotSpots != null) { |
| hotSpots.setWorld(world); |
| } |
| |
| } |
| } |
| |
| // hack! |
| sSystemRegistry.levelBuilder.promoteForegroundLayer(mBackgroundObject); |
| |
| } |
| |
| } catch (IOException e) { |
| //TODO: figure out the best way to deal with this. Assert? |
| } |
| |
| return success; |
| } |
| |
| public void spawnObjects() { |
| GameObjectFactory factory = sSystemRegistry.gameObjectFactory; |
| if (factory != null && mSpawnLocations != null) { |
| DebugLog.d("LevelSystem", "Spawning Objects!"); |
| |
| factory.spawnFromWorld(mSpawnLocations, mTileWidth, mTileHeight); |
| } |
| } |
| |
| public void incrementAttemptsCount() { |
| mAttempts++; |
| } |
| |
| public int getAttemptsCount() { |
| return mAttempts; |
| } |
| |
| public LevelTree.Level getCurrentLevel() { |
| return mCurrentLevel; |
| } |
| } |