/* * Aphelion * Copyright (c) 2013 Joris van der Wel * * This file is part of Aphelion * * Aphelion is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, version 3 of the License. * * Aphelion is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Aphelion. If not, see <http://www.gnu.org/licenses/>. * * In addition, the following supplemental terms apply, based on section 7 of * the GNU Affero General Public License (version 3): * a) Preservation of all legal notices and author attributions * b) Prohibition of misrepresentation of the origin of this material, and * modified versions are required to be marked in reasonable ways as * different from the original version (for example by appending a copyright notice). * * Linking this library statically or dynamically with other modules is making a * combined work based on this library. Thus, the terms and conditions of the * GNU Affero General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent modules, * and to copy and distribute the resulting executable under terms of your * choice, provided that you also meet, for each linked independent module, * the terms and conditions of the license of that module. An independent * module is a module which is not derived from or based on this library. */ package aphelion.client.graphics; import aphelion.client.Client; import aphelion.client.RENDER_LAYER; import aphelion.client.graphics.screen.Camera; import aphelion.client.graphics.world.ActorShip; import aphelion.client.graphics.world.MapEntities; import aphelion.client.graphics.world.StarField; import aphelion.server.ServerConfigException; import aphelion.shared.event.LoopEvent; import aphelion.shared.event.TickEvent; import aphelion.shared.event.TickedEventLoop; import aphelion.shared.gameconfig.GameConfig; import aphelion.shared.map.MapClassic; import aphelion.shared.map.tile.TileType; import aphelion.shared.physics.DualRunnerEnvironment; import aphelion.shared.physics.EnvironmentConf; import aphelion.shared.physics.PhysicsEnvironment; import aphelion.shared.physics.SimpleEnvironment; import aphelion.shared.resource.ResourceDB; import aphelion.shared.swissarmyknife.Point; import aphelion.shared.swissarmyknife.SwissArmyKnife; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.lwjgl.LWJGLException; import org.lwjgl.opengl.Display; import org.lwjgl.opengl.DisplayMode; import org.newdawn.slick.Color; /** * * @author Joris */ public class ScenarioPlayer { private static final Logger log = Logger.getLogger("aphelion.test.client.scenario"); private final TickedEventLoop loop; private Scenario scene; private ResourceDB resourceDB; private Camera camera; private MapClassic mapClassic; private StarField stars; private boolean setup; // Recreated for each scenario: private MapEntities mapEntities; private PhysicsEnvironment env; public ScenarioPlayer(TickedEventLoop loop) { this.loop = loop; } public void run() throws LWJGLException, IOException, ServerConfigException { Display.setTitle("Aphelion Scenario"); Display.setFullscreen(false); Display.setVSyncEnabled(false); Display.setResizable(true); Display.setInitialBackground(0f, 0f, 0f); Display.setDisplayMode(new DisplayMode(1024, 768)); Display.create(); resourceDB = new ResourceDB(loop); loop.addLoopEvent(resourceDB); resourceDB.addZip(new File("assets/gui.zip")); resourceDB.addZip(new File("assets/classic.zip")); { InputStream in = ScenarioPlayer.class.getResourceAsStream("/client/graphics/scenario.lvl"); assert in != null; mapClassic = new MapClassic(resourceDB, true); byte[] b = SwissArmyKnife.inputStreamToBytes(in); mapClassic.read(b, true); } camera = new Camera(resourceDB); camera.setScreenPosition(0, 0); stars = new StarField(1234, resourceDB); loop.setup(); setup = true; while (!loop.isInterruped()) { Display.update(); if (Display.isCloseRequested()) { loop.interrupt(); break; } camera.setDimension(Display.getWidth(), Display.getHeight()); loop.loop(); Graph.graphicsLoop(); Client.initGL(); if (scene == null) { camera.setPosition(512 * 16, 512 * 16); } else { mapEntities.tryInitialize(env, null); mapEntities.updateGraphicsFromPhysics(); ActorShip localShip = mapEntities.getLocalShip(); Point cameraPos = new Point(); localShip.getCameraPosition(cameraPos); camera.setPosition(cameraPos); } stars.render(camera); if (scene != null) { camera.renderEntities(mapEntities.animations(RENDER_LAYER.BACKGROUND, camera)); } camera.renderTiles(mapClassic, TileType.TILE_LAYER.PLAIN); camera.renderTiles(mapClassic, TileType. TILE_LAYER.ANIMATED); if (scene == null) { Graph.g.setColor(Color.white); Graph.g.drawString("No scene selected", Display.getWidth() / 2 - Graph.g.getFont().getWidth("No scene selected") / 2, Display.getHeight() / 2 - Graph.g.getFont().getLineHeight() / 2); } else { camera.renderEntities(mapEntities.animations(RENDER_LAYER.AFTER_TILES, camera)); camera.renderEntities(mapEntities.projectiles(false)); camera.renderEntities(mapEntities.animations(RENDER_LAYER.AFTER_PROJECTILES, camera)); camera.renderEntities(mapEntities.shipsNoLocal()); camera.renderEntities(mapEntities.animations(RENDER_LAYER.AFTER_SHIPS, camera)); camera.renderEntity(mapEntities.getLocalShip()); } camera.renderTiles(mapClassic, TileType.TILE_LAYER.PLAIN_OVER_SHIP); if (scene != null) { camera.renderEntities(mapEntities.animations(RENDER_LAYER.AFTER_LOCAL_SHIP, camera)); } } breakdown(); } private void removeLoopEvents() { loop.removeTickEvent((TickEvent) env); if (env instanceof LoopEvent) { loop.removeLoopEvent((LoopEvent) env); } loop.removeTickEvent(mapEntities); loop.removeLoopEvent(mapEntities); loop.removeTickEvent(scene); } public void setScenario(Scenario scene, boolean dualRunner) { if (!setup) { throw new IllegalArgumentException(); } this.scene = scene; removeLoopEvents(); if (env instanceof DualRunnerEnvironment) { ((DualRunnerEnvironment) env).done(); // blocks } mapEntities = null; env = null; if (scene != null) { log.log(Level.INFO, "Playing scenario {0}", scene.getClass().getName()); if (dualRunner) { env = new DualRunnerEnvironment(loop, mapClassic); } else { env = new SimpleEnvironment(false, mapClassic); } mapEntities = new MapEntities(resourceDB); mapEntities.tryInitialize(env, null); loop.addTickEvent((TickEvent) env); if (env instanceof LoopEvent) { loop.addLoopEvent((LoopEvent) env); } loop.addTickEvent(mapEntities); loop.addLoopEvent(mapEntities); scene.doSetup(env, mapEntities, resourceDB); loop.addTickEvent(scene); } } public void addConfig(String config) { List<Object> yamlDocuments; try { yamlDocuments = GameConfig.loadYaml(config); } catch (Exception ex) { throw new Error(ex); } env.loadConfig(env.getTick() - env.getConfig().HIGHEST_DELAY, "player", yamlDocuments); } public void interrupt() { loop.interrupt(); } public void breakdown() { Display.destroy(); if (loop != null) { loop.breakdown(); } } public static void main(String[] args) throws Exception { final TickedEventLoop loop = new TickedEventLoop(EnvironmentConf.TICK_LENGTH, 2, null); final ScenarioPlayer player = new ScenarioPlayer(loop); ScenarioSelector frame = new ScenarioSelector(new ScenarioSelector.ScenarioSelectorListener() { @Override public void selected(Class klass, final String config, final boolean dualRunner) { try { final Scenario scene = (Scenario) klass.newInstance(); loop.runOnMain(new Runnable() { @Override public void run() { player.setScenario(scene, dualRunner); player.addConfig(config); } }); } catch (InstantiationException | IllegalAccessException ex) { throw new Error(ex); } } }); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { player.interrupt(); } }); frame.setVisible(true); player.run(); frame.dispose(); } }