package sk.neuromancer.sphaera.rewrite; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Random; import sk.neuromancer.sphaera.rewrite.LiveSphere.SphereType; import sk.neuromancer.sphaera.rewrite.Menu.MenuState; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.g3d.Environment; import com.badlogic.gdx.graphics.g3d.ModelBatch; import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; import com.badlogic.gdx.graphics.g3d.environment.DirectionalShadowLight; import com.badlogic.gdx.graphics.g3d.utils.DepthShaderProvider; @SuppressWarnings("deprecation") public class World extends GameState{ private Environment environment; private ModelBatch renderBatch; private PerspectiveCamera camera; private float zoom = 1f; /* * TODO SpriteBatch overlay, android control!! * two buttons!!! */ private ModelBatch shadowBatch; private DirectionalShadowLight shadowLight; private List spheres = new LinkedList(); private List liveSpheres = new LinkedList(); private Player player; private boolean isGenerated = false; private int level = 1; public static final int LIVE_SPHERES_BASE = 30; /* public static final int INITIAL_LAYERS = 3; */ /** * TODO what about this? Should just be Gdx.graphics.getWidth(? */ public static final int VIEW_WIDTH = 400; public static final int VIEW_HEIGHT = 300; public World(Object... remains) { super(remains); this.camera = new PerspectiveCamera(SphaeraGame.FOV, VIEW_WIDTH, VIEW_HEIGHT); this.camera.near = 1f; this.camera.far = 300f; this.camera.update(); this.shadowLight = new DirectionalShadowLight(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), VIEW_WIDTH, VIEW_HEIGHT, 1f, 200f); this.shadowLight.set(Color.WHITE, 0, -1, 0); this.environment = new Environment(); this.environment.add(this.shadowLight); this.environment.shadowMap = this.shadowLight; environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.3f, 0.3f, 0.3f, 0.05f)); //TODO environment attibutes this.shadowBatch = new ModelBatch(new DepthShaderProvider()); this.renderBatch = new ModelBatch(); } /* public void generateNextLayer(int layer){ Random r = new Random(); Sphere parent = spheres.get(layer); float polar = 90 + r.nextInt(90); float azimuth = r.nextInt(360); float radius = (layer+1) * (layer+1) * Sphere.BASE_RADIUS * 5; Sphere next = new Sphere(parent, polar, azimuth, radius, Sphere.BASE_MAT); spheres.add(next); for(int i = 0; i < LIVE_SPHERES_BASE; i++){ //populate sphere polar = r.nextInt(180); azimuth = r.nextInt(360); radius = parent.getRadius()/(i*1.7f); SphereType type = radius > Player.BASE_RADIUS ? SphereType.BIGGER : SphereType.SMALLER; LiveSphere ls = new LiveSphere(radius, type); ls.setParent(parent); ls.putOnParent(polar, azimuth); if(layer < 2){ if(ls.collides(player) || ls.collides(next)){ parent.removeChildren(ls); i--; continue; } } liveSpheres.add(ls); } } public void generateNew(Player player){ this.player = player; Sphere base = new Sphere(Sphere.BASE_RADIUS, Sphere.BASE_MAT); player.setParent(base); player.putOnParent(90, 0); player.setDirection(0, 0, 1); spheres.add(base); Random r = new Random(); for(int layer = 0; layer < INITIAL_LAYERS; layer++){ generateNextLayer(layer); } isGenerated = true; } public void generateNew(){ Player playa = new Player(Player.BASE_RADIUS, Player.BASE_MAT); generateNew(playa); } */ public void generateNew(int level){ for(Sphere s: spheres){ s.dispose(); } for(LiveSphere ls: liveSpheres){ ls.dispose(); } this.spheres.clear(); this.liveSpheres.clear(); if(player == null){ player = new Player(Player.BASE_RADIUS, Player.BASE_MAT); } Sphere base = new Sphere(Sphere.BASE_RADIUS*level, Sphere.BASE_MAT); player.setParent(base); player.putOnParent(90, 0); player.setDirection(0, 0, 1); spheres.add(base); Random r = new Random(); float radius = player.getRadius(); for(int i = 0; i < LIVE_SPHERES_BASE; i++){ //populate sphere float polar = r.nextInt(180); float azimuth = r.nextInt(360); if(i > 3) radius += player.getRadius()/2; SphereType type = radius > Player.BASE_RADIUS ? SphereType.BIGGER : SphereType.SMALLER; LiveSphere ls = new LiveSphere(radius, type); ls.setParent(base); ls.putOnParent(polar, azimuth); ls.randomDirection(); if(ls.collides(player)){ base.removeChildren(ls); i--; continue; } liveSpheres.add(ls); } this.level++; isGenerated = true; } @Override public void show() { if(!isGenerated) generateNew(level); resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); } @Override public void render(float delta) { Gdx.gl.glClearColor(1,1,1,1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); shadowLight.begin(camera.position, camera.direction); shadowBatch.begin(camera); this.renderThings(shadowBatch, environment); shadowBatch.end(); shadowLight.end(); renderBatch.begin(camera); this.renderThings(renderBatch, environment); renderBatch.end(); } private void renderThings(ModelBatch batch, Environment environment){ for(Sphere s: spheres){ s.render(batch, environment); } for(LiveSphere ls : liveSpheres){ ls.render(batch, environment); } if(player != null) player.render(batch, environment); } @Override public void tick(long tickCount) { if(liveSpheres.size() == 0){ //win! this.finish(); this.setNext(new Menu(MenuState.WIN, this, player.getRadius())); } if(Gdx.input.isKeyPressed(Keys.A) || Gdx.input.isKeyJustPressed(Keys.LEFT) || Gdx.input.isKeyPressed(Keys.ALT_LEFT)){ player.rotateLeft(Player.ROT_SPEED); }else if(Gdx.input.isKeyPressed(Keys.D) || Gdx.input.isKeyJustPressed(Keys.RIGHT) || Gdx.input.isKeyPressed(Keys.ALT_RIGHT)){ player.rotateRight(Player.ROT_SPEED); } if(Gdx.input.isKeyPressed(Keys.SPACE) || Gdx.input.isKeyPressed(Keys.SHIFT_LEFT) || Gdx.input.isKeyPressed(Keys.ENTER) || Gdx.input.isKeyPressed(Keys.W)){ player.forward(player.getSpeed()); } player.move(); Iterator live = liveSpheres.iterator(); while(live.hasNext()){ LiveSphere ls = live.next(); ls.tick(tickCount); ls.move(); if(player.getRadius() >= ls.getRadius() && ls.getType().equals(SphereType.BIGGER)){ ls.setColorAttributes(ColorAttribute.createDiffuse((Sphere.SMALLER_DIFFUSE))); } if(player.collides(ls)){ if(player.getRadius() >= ls.getRadius()){ player.scaleRadius(player.getRadius() + ls.getRadius()/(player.getRadius()*0.7f)); ls.getParent().removeChildren(ls); ls.dispose(); live.remove(); }else{ this.finish(); this.setNext(new Menu(MenuState.POST, this, player.getRadius())); } } } /* for(Sphere s: spheres){ if(s.getParent() == player.getParent()){ if(s.collides(player)){ Sphere oldParent = player.getParent(); player.setParent(s); player.dropOnParent(oldParent); } } } */ camera.position.set(player.getAbsolutePosition().add(player.getCameraPosition().scl(zoom))); camera.direction.set(player.getCameraDirection()); camera.up.set(player.getCameraUp()); //camera.far = player.getCameraDirection().len()*3; camera.update(); } @Override public void resize(int width, int height) { } @Override public boolean keyDown(int keycode) { if(keycode == Keys.ESCAPE){ this.finish(); this.setNext(new Menu(MenuState.PAUSE, this, player.getRadius())); return true; } return false; } @Override public boolean scrolled(int amount) { this.zoom+=amount*0.1f; return true; } @Override public void pause() { } @Override public void resume() { } @Override public void hide() { } @Override public void dispose() { if(this.shadowBatch != null) this.shadowBatch.dispose(); if(this.renderBatch != null) this.renderBatch.dispose(); for(Sphere s: spheres){ s.dispose(); } for(LiveSphere ls: liveSpheres){ ls.dispose(); } if(player != null) player.dispose(); } }