diff options
| author | J08nY | 2017-11-07 18:11:44 +0100 |
|---|---|---|
| committer | J08nY | 2017-11-07 18:11:44 +0100 |
| commit | f07dcb0044e65ebff9143556adc3abe985394a14 (patch) | |
| tree | c7be0a3e202c880748ca72bb1a1e1d7dd4077912 | |
| download | ld34-master.tar.gz ld34-master.tar.zst ld34-master.zip | |
19 files changed, 1720 insertions, 0 deletions
diff --git a/core/src/sk/neuromancer/sphaera/interf/Collidable.java b/core/src/sk/neuromancer/sphaera/interf/Collidable.java new file mode 100755 index 0000000..7a1f4fb --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/interf/Collidable.java @@ -0,0 +1,7 @@ +package sk.neuromancer.sphaera.interf; + +import sk.neuromancer.sphaera.rewrite.Sphere; + +public interface Collidable { + public boolean collides(Sphere other); +} diff --git a/core/src/sk/neuromancer/sphaera/interf/Moveable.java b/core/src/sk/neuromancer/sphaera/interf/Moveable.java new file mode 100755 index 0000000..10e8a73 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/interf/Moveable.java @@ -0,0 +1,8 @@ +package sk.neuromancer.sphaera.interf; + +import com.badlogic.gdx.math.Vector3; + +public interface Moveable { + public Vector3 getVelocity(); + public void move(float howMuch); +} diff --git a/core/src/sk/neuromancer/sphaera/interf/Moving.java b/core/src/sk/neuromancer/sphaera/interf/Moving.java new file mode 100755 index 0000000..c8da69b --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/interf/Moving.java @@ -0,0 +1,9 @@ +package sk.neuromancer.sphaera.interf; + +public interface Moving { + public void forward(float angle); + public void back(float angle); + public void rotateAzimuth(float angle); + public void rotateLeft(float angle); + public void rotateRight(float angle); +} diff --git a/core/src/sk/neuromancer/sphaera/interf/Renderable.java b/core/src/sk/neuromancer/sphaera/interf/Renderable.java new file mode 100755 index 0000000..9935836 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/interf/Renderable.java @@ -0,0 +1,8 @@ +package sk.neuromancer.sphaera.interf; + +import com.badlogic.gdx.graphics.g3d.Environment; +import com.badlogic.gdx.graphics.g3d.ModelBatch; + +public interface Renderable { + public void render(ModelBatch renderer, Environment environment); +} diff --git a/core/src/sk/neuromancer/sphaera/interf/Renderer.java b/core/src/sk/neuromancer/sphaera/interf/Renderer.java new file mode 100755 index 0000000..1db302e --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/interf/Renderer.java @@ -0,0 +1,5 @@ +package sk.neuromancer.sphaera.interf; + +public interface Renderer { + public void render(); +} diff --git a/core/src/sk/neuromancer/sphaera/interf/Tickable.java b/core/src/sk/neuromancer/sphaera/interf/Tickable.java new file mode 100755 index 0000000..650cbb8 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/interf/Tickable.java @@ -0,0 +1,5 @@ +package sk.neuromancer.sphaera.interf; + +public interface Tickable { + public void tick(long tickCount); +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/DirectedSphere.java b/core/src/sk/neuromancer/sphaera/rewrite/DirectedSphere.java new file mode 100755 index 0000000..885553c --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/DirectedSphere.java @@ -0,0 +1,105 @@ +package sk.neuromancer.sphaera.rewrite; + +import com.badlogic.gdx.graphics.g3d.Material; +import com.badlogic.gdx.math.Vector3; + +import sk.neuromancer.sphaera.interf.Moving; + +public class DirectedSphere extends Sphere implements Moving { + + private Vector3 direction; + + public DirectedSphere() { + super(); + this.direction = Vector3.Zero.cpy(); + } + + public DirectedSphere(float radius) { + super(radius); + } + + public DirectedSphere(float radius, Material... mat) { + super(radius, mat); + } + + public DirectedSphere(float x, float y, float z, float radius, + Material... mat) { + super(x, y, z, radius, mat); + } + + public DirectedSphere(Sphere parent, float a, float b, float radius, + Material... mat) { + super(parent, a, b, radius, mat); + } + + public DirectedSphere(Sphere parent, float a, float b, float radius, Vector3 direction, + Material... mat) { + super(parent, a, b, radius, mat); + this.direction = direction; + } + + public void randomDirection(){ + Vector3 relative = this.getRelativePosition(); + Vector3 random = new Vector3().setToRandomDirection(); + Vector3 circleNormal = relative.cpy().crs(random); + float angle = SphereUtils.angleDeg(random, relative); + random.rotate(circleNormal, angle); + this.direction = random; + } + + @Override + public void forward(float angle) { + Vector3 oldRelative = this.getRelativePosition(); + Vector3 circleNormal = oldRelative.cpy().crs(this.direction); + Vector3 newRelative = oldRelative.cpy().rotate(circleNormal, angle); + this.setVelocity(newRelative.cpy().sub(oldRelative)); + } + + @Override + public void back(float angle) { + this.forward(-angle); + } + + @Override + public void rotateAzimuth(float angle) { + this.direction.rotate(this.getRelativePosition(), angle); + } + + @Override + public void rotateLeft(float angle) { + rotateAzimuth(angle); + } + + @Override + public void rotateRight(float angle) { + rotateAzimuth(-angle); + } + + @Override + public void move(float howMuch) { + if(this.getVelocity().len() == 0) + return; + Vector3 oldRelative = this.getRelativePosition(); + super.move(howMuch); + Vector3 newRelative = this.getRelativePosition(); + this.updateDirection(oldRelative, newRelative); + } + + private void updateDirection(Vector3 oldPos, Vector3 newPos) { + Vector3 circleNormal = oldPos.cpy().crs(newPos); + float angle = SphereUtils.angleDeg(oldPos, newPos); + this.direction = circleNormal.cpy().crs(newPos); + } + + public void setDirection(float x, float y, float z){ + this.direction = new Vector3(x,y,z); + } + + public void setDirection(Vector3 direction){ + this.direction = direction; + } + + public Vector3 getDirection(){ + return this.direction.cpy(); + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/Exit.java b/core/src/sk/neuromancer/sphaera/rewrite/Exit.java new file mode 100755 index 0000000..3fbc621 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/Exit.java @@ -0,0 +1,54 @@ +package sk.neuromancer.sphaera.rewrite; + +public class Exit extends GameState{ + + public Exit(Object... remains) { + super(remains); + } + + @Override + public void show() { + + } + + @Override + public void render(float delta) { + + } + + @Override + public void resize(int width, int height) { + + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + + } + + @Override + public void tick(long tickCount) { + + } + + @Override + public GameState next() { + return null; + } + +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/GameState.java b/core/src/sk/neuromancer/sphaera/rewrite/GameState.java new file mode 100755 index 0000000..6c91c2e --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/GameState.java @@ -0,0 +1,37 @@ +package sk.neuromancer.sphaera.rewrite; + +import sk.neuromancer.sphaera.interf.Tickable; + +import com.badlogic.gdx.InputAdapter; +import com.badlogic.gdx.Screen; + +public abstract class GameState extends InputAdapter implements Screen, Tickable{ + + private Object[] remains; + private boolean finished = false; + private GameState next; + + public GameState(Object... remains){ + this.remains = remains; + } + + public Object[] getRemains(){ + return this.remains; + } + + public GameState next(){ + return this.next; + } + + public boolean isFinished(){ + return this.finished; + } + + protected void finish(){ + this.finished = true; + } + + protected void setNext(GameState next){ + this.next = next; + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/LiveSphere.java b/core/src/sk/neuromancer/sphaera/rewrite/LiveSphere.java new file mode 100755 index 0000000..8f9235b --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/LiveSphere.java @@ -0,0 +1,65 @@ +package sk.neuromancer.sphaera.rewrite; + +import com.badlogic.gdx.graphics.g3d.Material; +import com.badlogic.gdx.math.Vector3; + +import sk.neuromancer.sphaera.interf.Tickable; + +public class LiveSphere extends DirectedSphere implements Tickable{ + + private SphereType type; + + public LiveSphere() { + super(); + } + + public LiveSphere(float radius) { + super(radius); + } + + public LiveSphere(float radius, SphereType type) { + super(radius, type.equals(SphereType.BIGGER) ? Sphere.BIGGER_MAT : Sphere.SMALLER_MAT); + this.type = type; + } + + public LiveSphere(float radius, Material... mat) { + super(radius, mat); + } + + public LiveSphere(float x, float y, float z, float radius, SphereType type) { + super(x, y, z, radius, type.equals(SphereType.BIGGER) ? Sphere.BIGGER_MAT : Sphere.SMALLER_MAT); + this.type = type; + } + + public LiveSphere(float x, float y, float z, float radius, Material... mat) { + super(x, y, z, radius, mat); + } + + + public LiveSphere(Sphere parent, float a, float b, float radius, + Vector3 direction, Material... mat) { + super(parent, a, b, radius, direction, mat); + } + + public LiveSphere(Sphere parent, float a, float b, float radius, + Material... mat) { + super(parent, a, b, radius, mat); + } + + @Override + public void tick(long tickCount) { + this.forward(0.5f); + } + + public SphereType getType(){ + return this.type; + } + + public void setType(SphereType type){ + this.type = type; + } + + public enum SphereType{ + SMALLER, BIGGER; + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/Menu.java b/core/src/sk/neuromancer/sphaera/rewrite/Menu.java new file mode 100755 index 0000000..4898e04 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/Menu.java @@ -0,0 +1,232 @@ +package sk.neuromancer.sphaera.rewrite; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.viewport.StretchViewport; +import com.badlogic.gdx.utils.viewport.Viewport; + +public class Menu extends GameState{ + + + private MenuState state; + private World world; + private float score; + + private Stage ui; + private TextButton playButton; + private TextButton exitButton; + private Image logo; + private Label scoreLabel; + private Label howToLabel; + private Label by; + + private TextButtonStyle buttonStyle; + private LabelStyle labelStyle; + + public static final String LOGO = "logo.png"; + public static final String BUTTON = "button.png"; + + public Menu(Object... remains){ + super(remains); + if(remains.length > 0){ + state = (MenuState) remains[0]; + }else{ + state = MenuState.START; + } + + switch(state){ + case WIN: + case PAUSE: + case POST: + if(remains.length > 1){ + world = (World) remains[1]; + if(remains.length > 2){ + this.score = (Float) remains[2]; + } + }else{ + world = new World(); + } + break; + case START: + world = new World(); + break; + default: + break; + } + + ui = new Stage(); + + Skin skin = new Skin(); + + logo = new Image(new Texture(Gdx.files.internal(LOGO))); + + buttonStyle = new TextButtonStyle(); + Texture buttonTexture = new Texture(Gdx.files.internal(BUTTON)); + + buttonStyle.up = new TextureRegionDrawable(new TextureRegion(buttonTexture)); + + if(!buttonTexture.getTextureData().isPrepared()){ + buttonTexture.getTextureData().prepare(); + } + + Pixmap downPixmap = buttonTexture.getTextureData().consumePixmap(); + downPixmap.setColor(0.5f, 0, 0, 0.3f); + downPixmap.fillRectangle(5, 5, 55, 23); + + buttonStyle.down = new TextureRegionDrawable(new TextureRegion(new Texture(downPixmap))); + buttonStyle.font = new BitmapFont(); + + labelStyle = new LabelStyle(new BitmapFont(), Color.BLACK); + + skin.add("default", buttonStyle); + skin.add("label", labelStyle); + + float width = Gdx.graphics.getWidth(); + float height = Gdx.graphics.getHeight(); + + playButton = new TextButton("PLAY", skin); + playButton.setSize(width/2.5f, width/6); + playButton.setPosition(width/2f - width/2.5f, height/3f); + playButton.addListener(new ClickListener(){ + @Override + public void clicked(InputEvent event, float x, float y) { + playClick(); + } + }); + + exitButton = new TextButton("EXIT", skin); + exitButton.setSize(width/2.5f, width/6); + exitButton.setPosition(width/2f, height/3f); + exitButton.addListener(new ClickListener(){ + @Override + public void clicked(InputEvent event, float x, float y) { + exitClick(); + } + }); + + logo.setPosition(width/2 - width/4, width/4); + logo.setSize(width/2, width/2); + + String scoreString = score == 0 ? "" : "Score:" + Float.toString(score); + + scoreLabel = new Label(scoreString, skin, "label"); + scoreLabel.setPosition(width/16, 7 * height/8); + scoreLabel.setFontScale(5); + + String howToString = state == MenuState.WIN ? "Congrats! You have won." : "Collect the blue spheres, avoid red ones. Grow! \nSPACE to move. A,D to rotate, SCROLL to zoom."; + + howToLabel = new Label(howToString, skin, "label"); + howToLabel.setPosition(width/12, height/8); + howToLabel.setFontScale(2.5f); + + by = new Label("by J08nY", skin, "label"); + by.setPosition(width/2 + width/4, width/2); + + + ui.addActor(logo); + ui.addActor(by); + ui.addActor(scoreLabel); + ui.addActor(howToLabel); + ui.addActor(playButton); + ui.addActor(exitButton); + } + + @Override + public void show() { + resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + Gdx.input.setInputProcessor(ui); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(1,1,1,1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + ui.draw(); + } + + public void playClick(){ + this.finish(); + if(this.world != null) + this.world.dispose(); + this.setNext(new World(this)); + } + + public void exitClick(){ + this.finish(); + if(this.world != null) + this.world.dispose(); + this.setNext(new Exit()); + } + + @Override + public void tick(long tickCount) { + ui.act(1/SphaeraGame.TPS); + } + + @Override + public void resize(int width, int height) { + + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + Gdx.gl.glClearColor(1,1,1,1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + } + + @Override + public void dispose() { + if(ui != null) + ui.dispose(); + } + + public enum MenuState{ + START, PAUSE, POST, WIN; + } + + @Override + public GameState next() { + switch(state){ + case PAUSE: + //world or exit + break; + case POST: + //world or exit + break; + case START: + //world or exit + break; + default: + break; + } + + return super.next(); + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/MovingSphere.java b/core/src/sk/neuromancer/sphaera/rewrite/MovingSphere.java new file mode 100755 index 0000000..a79bbc8 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/MovingSphere.java @@ -0,0 +1,72 @@ +package sk.neuromancer.sphaera.rewrite; + +import com.badlogic.gdx.graphics.g3d.Material; + +import sk.neuromancer.sphaera.interf.Moving; + +public class MovingSphere extends Sphere implements Moving { + + private float azimuth = 0f; + + public MovingSphere() { + super(); + } + + public MovingSphere(float radius) { + super(radius); + } + + public MovingSphere(float radius, Material... mat) { + super(radius, mat); + } + + public MovingSphere(float x, float y, float z, float radius, + Material... mat) { + super(x, y, z, radius, mat); + } + + public MovingSphere(Sphere parent, float a, float b, float radius, + Material... mat) { + super(parent, a, b, radius, mat); + } + + public MovingSphere(Sphere parent, float a, float b, float radius, float azimuth, + Material... mat) { + super(parent, a, b, radius, mat); + this.azimuth = azimuth; + } + + @Override + public void forward(float angle){ + this.setVelocity(SphereUtils.rotateDegVelocity(getSphericalPosition(), angle, azimuth)); + } + + @Override + public void back(float angle){ + this.forward(-angle); + } + + @Override + public void rotateAzimuth(float angle){ + this.azimuth+=angle; + } + + @Override + public void rotateLeft(float angle){ + rotateAzimuth(-angle); + } + + @Override + public void rotateRight(float angle){ + rotateAzimuth(angle); + } + + public float getAzimuth() { + return azimuth; + } + + public void setAzimuth(float azimuth) { + this.azimuth = azimuth; + } + +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/Player.java b/core/src/sk/neuromancer/sphaera/rewrite/Player.java new file mode 100755 index 0000000..254438e --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/Player.java @@ -0,0 +1,85 @@ +package sk.neuromancer.sphaera.rewrite; + +import sk.neuromancer.sphaera.interf.Moving; +import sk.neuromancer.sphaera.interf.Tickable; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g3d.Material; +import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; +import com.badlogic.gdx.math.Vector3; + +public class Player extends DirectedSphere implements Moving, Tickable{ + + public static float BASE_RADIUS = 1f; + public static float CAM_MULT = 1.0f; + public static float CAM_BASE = 28f; + + public static final Color DEFAULT_DIFFUSE = new Color(0.1f, 0.1f, 0.1f, 1f); + public static final Color DEFAULT_SPECULAR = new Color(1f, 1f, 1f, 0.5f); + public static final Color DEFAULT_AMBIENT = new Color(0.05f, 0.05f, 0.05f, 0.5f); + public static final Color DEFAULT_REFLECTION = new Color(1f, 1f, 1f, 0.5f); + + public static final Material BASE_MAT = new Material(ColorAttribute.createDiffuse(DEFAULT_DIFFUSE), + ColorAttribute.createReflection(DEFAULT_SPECULAR), + ColorAttribute.createAmbient(DEFAULT_AMBIENT), + ColorAttribute.createReflection(DEFAULT_REFLECTION) + ); + + public static final float MOV_SPEED = 1.2f; + public static final float ROT_SPEED = 5f; + + private float speed = MOV_SPEED; + + public Player() { + super(); + } + + public Player(float radius) { + super(radius); + } + + public Player(float radius, Material... mat) { + super(radius, mat); + } + + public Player(float x, float y, float z, float radius, Material... mat) { + super(x, y, z, radius, mat); + } + + public Player(Sphere parent, float a, float b, float radius, Vector3 direction, + Material... mat) { + super(parent, a, b, radius, direction, mat); + } + + public Vector3 getCameraPosition(){ + return this.getRelativePosition().setLength(CAM_BASE + this.getRadius() * CAM_MULT); + } + + public Vector3 getCameraDirection(){ + return this.getCameraPosition().scl(-1); + } + + public Vector3 getCameraUp(){ + return this.getDirection(); + } + + @Override + public void tick(long tickCount) { + + } + + public float getSpeed(){ + return this.speed; + } + + public void setSpeed(float speed){ + this.speed = speed; + } + + /* + @Override public void dropOnParent(Vector3 oldParentPos){ + super.dropOnParent(oldParentPos); + setDirection(this.getDirection().scl(-1)); + } +*/ +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/SoundPlayer.java b/core/src/sk/neuromancer/sphaera/rewrite/SoundPlayer.java new file mode 100755 index 0000000..31db99c --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/SoundPlayer.java @@ -0,0 +1,75 @@ +package sk.neuromancer.sphaera.rewrite; + +import java.util.Random; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.utils.Disposable; + +import sk.neuromancer.sphaera.interf.Tickable; + +public class SoundPlayer implements Tickable, Disposable{ + + private Sound[] base = new Sound[4]; + private Sound explosion; + + public static final String BASE_SOUND_NAME = "base"; + + private boolean isLoaded = false; + private boolean isPlaying = false; + + public static final int BPM = 100; + public static final float TPB = (SphaeraGame.TPS * 60) / BPM; + + public static final float VOLUME = 0.2f; + + private int[] order = {3,2,0,1}; + + private int s = 0; + + public SoundPlayer() { + + } + + @Override + public void tick(long tickCount) { + if(!isPlaying) + return; + if(!isLoaded) + return; + if(tickCount % TPB == 0){ + base[order[s]].play(VOLUME); + s++; + s%=base.length; + } + } + + public void load() { + for(int i = 0; i < base.length; i++){ + base[i] = Gdx.audio.newSound(Gdx.files.internal(BASE_SOUND_NAME + i + ".wav")); + } + explosion = Gdx.audio.newSound(Gdx.files.internal("explosion.wav")); + isLoaded = true; + } + + public void play(){ + isPlaying = true; + } + + public void pause(){ + isPlaying = false; + } + + + public void playExplosion(){ + explosion.play(); + } + + @Override + public void dispose() { + for(Sound s: base){ + s.dispose(); + } + explosion.dispose(); + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/SphaeraGame.java b/core/src/sk/neuromancer/sphaera/rewrite/SphaeraGame.java new file mode 100755 index 0000000..beb5a5a --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/SphaeraGame.java @@ -0,0 +1,119 @@ +package sk.neuromancer.sphaera.rewrite; + +import sk.neuromancer.sphaera.interf.Tickable; + +import com.badlogic.gdx.Game; +import com.badlogic.gdx.Gdx; + +public class SphaeraGame extends Game implements Tickable{ + + private Splash splash = null; + private Menu menu = null; + private World world = null; + private SoundPlayer soundPlayer; + + public static final int DEFAULT_WIDTH = 900; + public static final int DEFAULT_HEIGHT = 650; + + public static final int TPS = 30; + public static final int FOV = 75; + + private long lastTickTime; + private long ticks, frames; + + @Override + public void create(){ + Gdx.graphics.setTitle("Sphaera"); + + splash = new Splash(); + setScreen(splash); + + Gdx.input.setInputProcessor(splash); + + soundPlayer = new SoundPlayer(); + soundPlayer.load(); + //soundPlayer.play(); + + ticks = frames = 0; + lastTickTime = System.currentTimeMillis(); + } + + @Override + public void resize(int width, int height) { + super.resize(width, height); + } + + @Override + public void render() { + long now = System.currentTimeMillis(); + if(now - lastTickTime > (1/TPS) * 1000){ + tick(ticks); + lastTickTime = now; + } + draw(); + } + + @Override + public void tick(long tickCount) { + ticks++; + GameState state = getScreen(); + state.tick(tickCount); + soundPlayer.tick(tickCount); + + if(ticks % 30 == 0){ + System.out.println(Gdx.graphics.getFramesPerSecond()); + } + + if(state.isFinished()){ + if(state instanceof World){ + soundPlayer.playExplosion(); + } + + state = state.next(); + Gdx.input.setInputProcessor(state); + setScreen(state); + + if(state instanceof Menu){ + menu = (Menu) state; + }else if(state instanceof World){ + world = (World) state; + }else if(state instanceof Exit){ + this.dispose(); + state.dispose(); + Gdx.app.exit(); + } + } + } + + public void draw(){ + frames++; + super.render(); + } + + @Override + public void pause() { + super.pause(); + } + + @Override + public void resume() { + super.resume(); + } + + @Override + public void dispose() { + if(splash != null) + splash.dispose(); + if(menu != null) + menu.dispose(); + if(world != null) + world.dispose(); + if(soundPlayer != null) + soundPlayer.dispose(); + } + + @Override + public GameState getScreen() { + return (GameState) super.getScreen(); + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/Sphere.java b/core/src/sk/neuromancer/sphaera/rewrite/Sphere.java new file mode 100755 index 0000000..54966fa --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/Sphere.java @@ -0,0 +1,279 @@ +package sk.neuromancer.sphaera.rewrite; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; + +import sk.neuromancer.sphaera.interf.Collidable; +import sk.neuromancer.sphaera.interf.Moveable; +import sk.neuromancer.sphaera.interf.Renderable; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.VertexAttributes.Usage; +import com.badlogic.gdx.graphics.g3d.Environment; +import com.badlogic.gdx.graphics.g3d.Material; +import com.badlogic.gdx.graphics.g3d.ModelBatch; +import com.badlogic.gdx.graphics.g3d.ModelInstance; +import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; +import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.utils.Disposable; + +public class Sphere implements Renderable, Moveable, Collidable, Disposable{ + private static final int MAX_DIV = 50; + private static final int DIV = 12; + + public static final float BASE_RADIUS = 50f; + + public static final Color DEFAULT_DIFFUSE = new Color(0.9f, 0.9f, 0.9f, 1f); + public static final Color DEFAULT_SPECULAR = new Color(0.5f, 0.5f, 0.5f, 0.5f); + public static final Color DEFAULT_AMBIENT = new Color(1f, 1f, 1f, 0.5f); + public static final Color DEFAULT_REFLECTION = new Color(0.5f, 0.5f, 0.5f, 0.5f); + + public static final Color SMALLER_DIFFUSE = new Color(0.05f, 0.05f, 0.9f, 1f); + + public static final Color BIGGER_DIFFUSE = new Color(0.7f, 0.1f, 0.1f, 1f); + + public static final Material BASE_MAT = new Material(ColorAttribute.createDiffuse(DEFAULT_DIFFUSE), + ColorAttribute.createReflection(DEFAULT_SPECULAR), + ColorAttribute.createAmbient(DEFAULT_AMBIENT), + ColorAttribute.createReflection(DEFAULT_REFLECTION) + ); + + public static final Material SMALLER_MAT = new Material(ColorAttribute.createDiffuse(SMALLER_DIFFUSE), + ColorAttribute.createReflection(DEFAULT_SPECULAR), + ColorAttribute.createAmbient(DEFAULT_AMBIENT), + ColorAttribute.createReflection(DEFAULT_REFLECTION) + ); + + public static final Material BIGGER_MAT = new Material(ColorAttribute.createDiffuse(BIGGER_DIFFUSE), + ColorAttribute.createReflection(DEFAULT_SPECULAR), + ColorAttribute.createAmbient(DEFAULT_AMBIENT), + ColorAttribute.createReflection(DEFAULT_REFLECTION) + ); + + private Sphere parent = null;//if parent null, then + private List<Sphere> children = new LinkedList<Sphere>(); + + private ModelInstance model; + + private float radius; + + /** + * Both positions are relative to the parent, + * if parent == null, then they are absolute. + */ + private Vector3 position; + private Vector3 sphericalPosition;//degrees + + /* + * Dunno if Ill use it... + */ + private Vector3 velocity; + + public Sphere(){ + this.position = Vector3.Zero.cpy(); + this.sphericalPosition = Vector3.Zero.cpy(); + this.velocity = Vector3.Zero.cpy(); + } + + public Sphere(float radius){ + this(); + this.radius = radius; + } + + public Sphere(float radius, Material... mat){ + this(radius); + ModelBuilder mb = new ModelBuilder(); + int div = Math.min(MAX_DIV, (int) radius * DIV); + if(this instanceof Player){ + div = MAX_DIV; + } + this.model = new ModelInstance(mb.createSphere(2, 2, 2, div, div, mat[0], Usage.Position | Usage.Normal)); + /*for(Material m : mat){ + this.model.materials.add(m); + }*/ + } + + public Sphere(float x, float y, float z, float radius, Material... mat){ + this(radius, mat); + this.position.x = x; + this.position.y = y; + this.position.z = z; + this.sphericalPosition = SphereUtils.toSphericalDeg(x, y, z); + } + + public Sphere(Sphere parent, float a, float b, float radius, Material... mat){ + this(radius, mat); + this.parent = parent; + this.sphericalPosition.x = parent.getRadius() + this.radius; + this.sphericalPosition.y = a; + this.sphericalPosition.z = b; + this.position = SphereUtils.toCartesianDeg(this.sphericalPosition.x, a, b); + } + + public Sphere getParent() { + return this.parent; + } + + public void setParent(Sphere newParent){ + if(this.parent != null){ + this.parent.removeChildren(this); + } + this.parent = newParent; + this.parent.addChildren(this); + } + + public boolean addChildren(Sphere child){ + return this.children.add(child); + } + + public boolean removeChildren(Sphere child){ + return this.children.remove(child); + } + + public Collection<Sphere> getChildren(){ + return new LinkedList<Sphere>(this.children); + } + + public float getRadius() { + return this.radius; + } + + public void setRadius(float radius){ + this.radius = radius; + } + + public void scaleRadius(float newRadius){ + Vector3 newSpherical = this.getSphericalPosition(); + if(this.getParent() != null){ + newSpherical.x = this.getParent().getRadius() + newRadius; + } + Vector3 newRelative = this.getRelativePosition(); + newRelative.setLength(this.getParent().getRadius() + newRadius); + this.setSphericalPosition(newSpherical); + this.setRelativePosition(newRelative); + this.setRadius(newRadius); + } + + public void setSphericalPosition(Vector3 spherical){ + this.sphericalPosition = spherical.cpy(); + } + + public void setRelativePosition(Vector3 relative){ + this.position = relative.cpy(); + } + + public void setPositionSpherical(Vector3 spherical){ + //both + this.setSphericalPosition(spherical); + this.setRelativePosition(SphereUtils.toCartesianDeg(spherical)); + } + + public void setPositionRelative(Vector3 relative){ + //both + this.setRelativePosition(relative); + this.setSphericalPosition(SphereUtils.toSphericalDeg(relative)); + } + + public Vector3 getSphericalPosition(){ + return this.sphericalPosition.cpy(); + } + + public Vector3 getAbsolutePosition(){ + if(this.parent == null){ + return this.getRelativePosition(); + } + return this.position.cpy().add(this.getParent().getAbsolutePosition()); + } + + public Vector3 getRelativePosition(){ + return this.position.cpy(); + } + + public void dropOnParent(Vector3 oldParentPos){ + if(this.parent == null){ + return; + } + + Vector3 absolutePos = oldParentPos.add(this.position); + Vector3 fromParent = absolutePos.cpy().sub(this.parent.getAbsolutePosition()); + fromParent.setLength(this.parent.getRadius() + this.radius); + this.setPositionRelative(fromParent); + } + + public void dropOnParent(Sphere oldParent){ + this.dropOnParent(oldParent.getAbsolutePosition()); + /*potrebujem absolutne pozicie + *OH SHIT! + *mam problem, musim toto riesit pri zmene parenta!! + *pretoze tu uz nemam toho stareho takze getAbsolutePosition je BS aj getRelative... + */ + } + + public void putOnParent(float polar, float azimuth){ + if(this.getParent() == null) + return; + + float completeRadius = this.getParent().getRadius() + this.getRadius(); + this.setPositionSpherical(new Vector3(completeRadius, polar, azimuth)); + } + + public void setColorAttributes(ColorAttribute... attribs){ + this.model.materials.get(0).set(attribs); + } + + @Override + public void render(ModelBatch renderer, Environment environment) { + model.transform.setToTranslation(this.getAbsolutePosition()); + model.transform.scale(radius,radius,radius); + renderer.render(model, environment); + } + + @Override + public Vector3 getVelocity(){ + return this.velocity.cpy(); + } + + public void setVelocity(Vector3 velocity){ + this.velocity = velocity; + } + + public void move(){ + //all the way + this.move(1); + } + + @Override + public void move(float howMuch){ + if(this.velocity.len() == 0) + return; + this.velocity.scl(howMuch); + this.setPositionRelative(this.getRelativePosition().add(this.velocity)); + this.velocity = Vector3.Zero.cpy(); + //maybe leave velocity as the rest I want to go? + //that way I can call move again and hope I + } + + @Override + public boolean collides(Sphere other) { + if(this.getParent() != null && other.getParent() != null){ + return this.getRelativePosition().sub(other.getRelativePosition()).len() < this.getRadius() + other.getRadius(); + } + return this.getAbsolutePosition().sub(other.getAbsolutePosition()).len() < this.getRadius() + other.getRadius(); + } + + @Override + public String toString(){ + return "Sphere" + ":" + /*this.hashCode() +*/ "\n" + + " radius=" + this.getRadius() + "\n" + + " spherical=" + this.getSphericalPosition() + "\n" + + " relative=" + this.getRelativePosition(); + } + + @Override + public void dispose() { + this.model.model.dispose(); + } + +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/SphereUtils.java b/core/src/sk/neuromancer/sphaera/rewrite/SphereUtils.java new file mode 100755 index 0000000..e59fef3 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/SphereUtils.java @@ -0,0 +1,123 @@ +package sk.neuromancer.sphaera.rewrite; + +import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector3; + +/** + * + * + */ +public class SphereUtils { + + public static void main(String[] args){ + test(); + } + + public static void test(){ + Vector3 topSpherical = new Vector3(10,0,0); + Vector3 topCartesian = SphereUtils.toCartesianDeg(topSpherical); + System.out.println(topCartesian + " should be (0,10,0))"); + + Vector3 xSpherical = new Vector3(10,90,90); + Vector3 xCartesian = SphereUtils.toCartesianDeg(xSpherical); + System.out.println(xCartesian + "should be (10,0,0)"); + + Vector3 rotTopToX = xCartesian.cpy().sub(topCartesian); + System.out.println(rotTopToX);//seems okay + } + + public static float angleDeg(Vector3 cartesianA, Vector3 cartesianB){ + return SphereUtils.angleRad(cartesianA, cartesianB) * MathUtils.radiansToDegrees; + } + + public static float angleRad(Vector3 cartesianA, Vector3 cartesianB){ + return (float)Math.acos(((cartesianA.dot(cartesianB))/(cartesianA.len()*cartesianB.len()))); + } + + public static Vector3 sphericalToRad(Vector3 sphericalDeg){ + return new Vector3(sphericalDeg.x, sphericalDeg.y * MathUtils.degreesToRadians, sphericalDeg.z * MathUtils.degreesToRadians); + } + + public static Vector3 sphericalToDeg(Vector3 sphericalRad){ + return new Vector3(sphericalRad.x, sphericalRad.y * MathUtils.radiansToDegrees, sphericalRad.z * MathUtils.radiansToDegrees); + } + + public static Vector3 tangentDeg(Vector3 sphericalDeg, float azimuthDeg){ + return SphereUtils.tangentRad(SphereUtils.sphericalToRad(sphericalDeg), azimuthDeg * MathUtils.degreesToRadians); + } + + public static Vector3 tangentRad(Vector3 sphericalRad, float azimuthRad){ + Vector3 tangentSpherical = SphereUtils.rotateRad(sphericalRad, (float) Math.PI / 2f, azimuthRad); + return SphereUtils.toCartesianRad(tangentSpherical); + } + + public static Vector3 rotateDegDelta(Vector3 sphericalDeg, float angleDeg, float azimuthDeg){ + Vector3 newSpherical = SphereUtils.rotateDeg(sphericalDeg, angleDeg, azimuthDeg); + return newSpherical.sub(sphericalDeg); + } + + public static Vector3 rotateRadDelta(Vector3 sphericalRad, float angleRad, float azimuthRad){ + Vector3 newSpherical = SphereUtils.rotateRad(sphericalRad, angleRad, azimuthRad); + return newSpherical.sub(sphericalRad); + } + + public static Vector3 rotateDegVelocity(Vector3 sphericalDeg, float angleDeg, float azimuthDeg){ + Vector3 newSpherical = SphereUtils.rotateDeg(sphericalDeg, angleDeg, azimuthDeg); + return SphereUtils.toCartesianDeg(newSpherical).sub(SphereUtils.toCartesianDeg(sphericalDeg)); + } + + public static Vector3 rotateRadVelocity(Vector3 sphericalRad, float angleRad, float azimuthRad){ + Vector3 newSpherical = SphereUtils.rotateRad(sphericalRad, angleRad, azimuthRad); + return SphereUtils.toCartesianRad(newSpherical).sub(SphereUtils.toCartesianRad(sphericalRad)); + } + + public static Vector3 rotateDeg(Vector3 sphericalDeg, float angleDeg, float azimuthDeg){ + return new Vector3(sphericalDeg.x, (float) (sphericalDeg.y - Math.cos(azimuthDeg * MathUtils.degreesToRadians) * angleDeg), + (float) (sphericalDeg.z + Math.sin(azimuthDeg * MathUtils.degreesToRadians) * angleDeg)); + } + + public static Vector3 rotateRad(Vector3 sphericalRad, float angleRad, float azimuthRad){ + return new Vector3(sphericalRad.x, (float) (sphericalRad.y - Math.cos(azimuthRad) * angleRad), + (float) (sphericalRad.z + Math.sin(azimuthRad) * angleRad)); + } + + public static Vector3 toCartesianDeg(Vector3 spherical){ + return SphereUtils.toCartesianDeg(spherical.x, spherical.y, spherical.z); + } + + public static Vector3 toCartesianRad(Vector3 spherical){ + return SphereUtils.toCartesianRad(spherical.x, spherical.y, spherical.z); + } + + public static Vector3 toCartesianDeg(float radius, float polar, float azimuth){ + polar*=MathUtils.degreesToRadians; + azimuth*=MathUtils.degreesToRadians; + return SphereUtils.toCartesianRad(radius, polar, azimuth); + } + + public static Vector3 toCartesianRad(float radius, float polar, float azimuth){ + float x = (float) (radius * Math.sin(polar) * Math.sin(azimuth)); + float y = (float) (radius * Math.cos(polar)); + float z = (float) (radius * Math.sin(polar) * Math.cos(azimuth)); + return new Vector3(x,y,z); + } + + public static Vector3 toSphericalDeg(Vector3 cartesian){ + return SphereUtils.toSphericalDeg(cartesian.x, cartesian.y, cartesian.z); + } + + public static Vector3 toSphericalRad(Vector3 cartesian){ + return SphereUtils.toSphericalRad(cartesian.x, cartesian.y, cartesian.z); + } + + public static Vector3 toSphericalDeg(float x, float y, float z){ + return SphereUtils.sphericalToDeg(SphereUtils.toSphericalRad(x, y, z)); + } + + public static Vector3 toSphericalRad(float x, float y, float z){ + float radius = (float) Math.sqrt(x*x + y*y + z*z); + float polar = (float) Math.acos(y/radius); + float azimuth = (float) Math.atan2(z, x); + return new Vector3(radius, polar, azimuth); + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/Splash.java b/core/src/sk/neuromancer/sphaera/rewrite/Splash.java new file mode 100755 index 0000000..d38fbc5 --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/Splash.java @@ -0,0 +1,93 @@ +package sk.neuromancer.sphaera.rewrite; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.utils.viewport.FillViewport; +import com.badlogic.gdx.utils.viewport.Viewport; + +public class Splash extends GameState{ + + private Sprite splash; + private OrthographicCamera camera; + private Viewport viewport; + private SpriteBatch renderer; + + public static final String FILE = "splash.png"; + public static final Color SPLASH_COLOR = Color.valueOf("FF1E29"); + + public static final int DURATION = 2; + + public Splash(Object... remains){ + super(remains); + this.splash = new Sprite(new Texture(Gdx.files.internal(FILE))); + this.camera = new OrthographicCamera(); + this.renderer = new SpriteBatch(); + + this.viewport = new FillViewport(SphaeraGame.DEFAULT_WIDTH, SphaeraGame.DEFAULT_HEIGHT, camera); + this.viewport.apply(); + + this.camera.position.set(camera.viewportWidth/2, camera.viewportHeight/2,0); + } + + @Override + public void show() { + resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + } + + @Override + public void render(float delta) { + camera.update(); + Gdx.gl.glClearColor(SPLASH_COLOR.r, SPLASH_COLOR.g, SPLASH_COLOR.b, SPLASH_COLOR.a); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + renderer.setProjectionMatrix(camera.combined); + renderer.begin(); + splash.draw(renderer); + renderer.end(); + } + + @Override + public void tick(long tickCount) { + if(tickCount > DURATION * SphaeraGame.TPS){ + if(!isFinished()){ + this.finish(); + this.setNext(new Menu()); + } + } + } + + @Override + public void resize(int width, int height) { + viewport.update(width, height, true); + + int minSize = width > height ? width : height; + splash.setSize(minSize, minSize); + splash.setCenter(width/2, height/2); + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + Gdx.gl.glClearColor(1,1,1,1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + } + + @Override + public void dispose() { + splash.getTexture().dispose(); + } +} diff --git a/core/src/sk/neuromancer/sphaera/rewrite/World.java b/core/src/sk/neuromancer/sphaera/rewrite/World.java new file mode 100755 index 0000000..0aa0d0e --- /dev/null +++ b/core/src/sk/neuromancer/sphaera/rewrite/World.java @@ -0,0 +1,339 @@ +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<Sphere> spheres = new LinkedList<Sphere>(); + private List<LiveSphere> liveSpheres = new LinkedList<LiveSphere>(); + 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<LiveSphere> 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(); + } +} |
