Major restructuring of Vars class- made global state less messy

This commit is contained in:
Anuken
2017-07-15 14:16:41 -04:00
parent 922ab26b0d
commit c3712d6f78
23 changed files with 420 additions and 388 deletions

View File

@@ -6,12 +6,15 @@ import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.GameState.State;
import io.anuke.mindustry.ai.Pathfind;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.GestureHandler;
import io.anuke.mindustry.input.Input;
import io.anuke.mindustry.world.Generator;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.ProductionBlocks;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.Entities;
@@ -23,6 +26,19 @@ import io.anuke.ucore.util.Timers;
public class Control extends RendererModule{
public int rangex = 10, rangey = 10;
public float targetzoom = 1f;
boolean showedTutorial;
boolean hiscore = false;
final Array<Weapon> weapons = new Array<>();
//final ObjectMap<Weapon, Boolean> weapons = new ObjectMap<Weapon, Boolean>();
int wave = 1;
float wavetime;
int enemies = 0;
float respawntime;
//GifRecorder recorder = new GifRecorder(batch);
public Control(){
@@ -46,7 +62,7 @@ public class Control extends RendererModule{
Musics.load("1.mp3", "2.mp3", "3.mp3");
Generator.loadMaps();
World.loadMaps();
KeyBinds.defaults(
"up", Keys.W,
@@ -67,6 +83,163 @@ public class Control extends RendererModule{
player = new Player();
}
public void reset(){
weapons.clear();
weapons.add(Weapon.blaster);
player.weapon = weapons.first();
wave = 1;
wavetime = waveSpacing();
Entities.clear();
enemies = 0;
if(!android)
player.add();
player.heal();
Inventory.clearItems();
World.spawnpoints.clear();
respawntime = -1;
hiscore = false;
ui.updateItems();
ui.updateWeapons();
}
public void play(){
player.x = World.core.worldx();
player.y = World.core.worldy()-8;
control.camera.position.set(player.x, player.y, 0);
wavetime = waveSpacing();
if(showedTutorial || !Settings.getBool("tutorial")){
GameState.set(State.playing);
}else{
GameState.set(State.paused);
ui.showTutorial();
showedTutorial = true;
}
}
public boolean hasWeapon(Weapon weapon){
return weapons.contains(weapon, true);
}
public void addWeapon(Weapon weapon){
weapons.add(weapon);
}
public Array<Weapon> getWeapons(){
return weapons;
}
void runWave(){
int amount = wave;
Sounds.play("spawn");
Pathfind.updatePath();
for(int i = 0; i < amount; i ++){
int pos = i;
for(int w = 0; w < World.spawnpoints.size; w ++){
int point = w;
Tile tile = World.spawnpoints.get(w);
Timers.run(i*30f, ()->{
Enemy enemy = null;
if(wave%5 == 0 & pos < wave/5){
enemy = new BossEnemy(point);
}else if(wave > 3 && pos < amount/2){
enemy = new FastEnemy(point);
}else if(wave > 8 && pos % 3 == 0 && wave%2==1){
enemy = new FlameEnemy(point);
}else{
enemy = new Enemy(point);
}
enemy.set(tile.worldx(), tile.worldy());
Effects.effect("spawn", enemy);
enemy.add();
});
enemies ++;
}
}
wave ++;
int last = Settings.getInt("hiscore"+maps[World.getMap()]);
if(wave > last){
Settings.putInt("hiscore"+maps[World.getMap()], wave);
Settings.save();
hiscore = true;
}
wavetime = waveSpacing();
}
public void enemyDeath(){
enemies --;
}
public void coreDestroyed(){
Effects.shake(5, 6);
Sounds.play("corexplode");
Tile core = World.core;
for(int i = 0; i < 16; i ++){
Timers.run(i*2, ()->{
Effects.effect("explosion", core.worldx()+Mathf.range(40), core.worldy()+Mathf.range(40));
});
}
Effects.effect("coreexplosion", core.worldx(), core.worldy());
Timers.run(60, ()->{
ui.showRestart();
});
}
float waveSpacing(){
int scale = Settings.getInt("difficulty");
float out = (scale == 0 ? 2f : scale == 1f ? 1f : 0.5f);
return wavespace*out;
}
public void clampZoom(){
targetzoom = Mathf.clamp(targetzoom, 0.5f, 2f);
camera.zoom = Mathf.clamp(camera.zoom, 0.5f, 2f);
}
public boolean isHighScore(){
return hiscore;
}
public int getEnemiesRemaining(){
return enemies;
}
public float getWaveCountdown(){
return wavetime;
}
public float getRespawnTime(){
return respawntime;
}
public void setRespawnTime(float respawntime){
this.respawntime = respawntime;
}
public int getWave(){
return wave;
}
@Override
public void init(){
Musics.shuffleAll();
@@ -80,11 +253,6 @@ public class Control extends RendererModule{
EffectLoader.create();
}
public void clampZoom(){
targetzoom = Mathf.clamp(targetzoom, 0.5f, 2f);
camera.zoom = Mathf.clamp(camera.zoom, 0.5f, 2f);
}
@Override
public void update(){
@@ -94,30 +262,30 @@ public class Control extends RendererModule{
//camera.zoom = MathUtils.lerp(camera.zoom, targetzoom, 0.5f*delta());
if(Inputs.keyUp(Keys.SPACE) && debug)
Effects.sound("shoot", core.worldx(), core.worldy());
Effects.sound("shoot", World.core.worldx(), World.core.worldy());
if(!playing){
if(GameState.is(State.menu)){
clearScreen();
}else{
if(Inputs.keyUp("menu")){
if(paused){
if(GameState.is(State.paused)){
ui.hideMenu();
paused = false;
GameState.set(State.paused);
}else{
ui.showMenu();
paused = true;
GameState.set(State.paused);
}
}
if(!paused){
if(!GameState.is(State.paused)){
if(respawntime > 0){
respawntime -= delta();
if(respawntime <= 0){
player.set(core.worldx(), core.worldy()-8);
player.set(World.core.worldx(), World.core.worldy()-8);
player.heal();
player.add();
Effects.sound("respawn");
@@ -128,7 +296,7 @@ public class Control extends RendererModule{
wavetime -= delta();
if(wavetime <= 0 || (debug && Inputs.keyUp(Keys.F))){
GameState.runWave();
runWave();
}
Entities.update();
@@ -141,15 +309,15 @@ public class Control extends RendererModule{
}
if(core.block() == ProductionBlocks.core){
if(World.core.block() == ProductionBlocks.core){
smoothCamera(player.x, player.y, android ? 0.3f : 0.14f);
}else{
smoothCamera(core.worldx(), core.worldy(), 0.4f);
smoothCamera(World.core.worldx(), World.core.worldy(), 0.4f);
}
updateShake(0.5f);
float prevx = camera.position.x, prevy = camera.position.y;
clampCamera(-tilesize / 2f, -tilesize / 2f, pixsize - tilesize / 2f, pixsize - tilesize / 2f);
clampCamera(-tilesize / 2f, -tilesize / 2f, World.pixsize - tilesize / 2f, World.pixsize - tilesize / 2f);
if(android){
player.x += camera.position.x-prevx;
@@ -178,7 +346,7 @@ public class Control extends RendererModule{
//recorder.update();
}
if(!paused){
if(!GameState.is(State.paused)){
Inputs.update();
Timers.update(Gdx.graphics.getDeltaTime()*60f);
}
@@ -201,4 +369,5 @@ public class Control extends RendererModule{
AndroidInput.mousex = Gdx.graphics.getWidth()/2;
AndroidInput.mousey = Gdx.graphics.getHeight()/2;
}
}

View File

@@ -1,130 +1,17 @@
package io.anuke.mindustry;
import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.ai.Pathfind;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Sounds;
import io.anuke.ucore.entities.Entities;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timers;
public class GameState{
private static State state = State.menu;
public static void reset(){
for(Weapon weapon : Weapon.values()){
weapons.put(weapon, weapon.unlocked);
}
currentWeapon = Weapon.blaster;
wave = 1;
wavetime = waveSpacing();
Entities.clear();
enemies = 0;
if(!android)
player.add();
player.heal();
Inventory.clearItems();
spawnpoints.clear();
respawntime = -1;
hiscore = false;
ui.updateItems();
ui.updateWeapons();
public static void set(State astate){
state = astate;
}
public static void play(){
player.x = core.worldx();
player.y = core.worldy()-8;
control.camera.position.set(player.x, player.y, 0);
wavetime = waveSpacing();
if(showedTutorial || !Settings.getBool("tutorial")){
playing = true;
paused = false;
}else{
playing = true;
paused = true;
ui.showTutorial();
showedTutorial = true;
}
public static boolean is(State astate){
return state == astate;
}
public static void runWave(){
int amount = wave;
Sounds.play("spawn");
Pathfind.updatePath();
for(int i = 0; i < amount; i ++){
int pos = i;
for(int w = 0; w < spawnpoints.size; w ++){
int point = w;
Tile tile = spawnpoints.get(w);
Timers.run(i*30f, ()->{
Enemy enemy = null;
if(wave%5 == 0 & pos < wave/5){
enemy = new BossEnemy(point);
}else if(wave > 3 && pos < amount/2){
enemy = new FastEnemy(point);
}else if(wave > 8 && pos % 3 == 0 && wave%2==1){
enemy = new FlameEnemy(point);
}else{
enemy = new Enemy(point);
}
enemy.set(tile.worldx(), tile.worldy());
Effects.effect("spawn", enemy);
enemy.add();
});
enemies ++;
}
}
wave ++;
int last = Settings.getInt("hiscore"+maps[currentMap]);
if(wave > last){
Settings.putInt("hiscore"+maps[currentMap], wave);
Settings.save();
hiscore = true;
}
wavetime = waveSpacing();
}
public static void coreDestroyed(){
Effects.shake(5, 6);
Sounds.play("corexplode");
for(int i = 0; i < 16; i ++){
Timers.run(i*2, ()->{
Effects.effect("explosion", core.worldx()+Mathf.range(40), core.worldy()+Mathf.range(40));
});
}
Effects.effect("coreexplosion", core.worldx(), core.worldy());
Timers.run(60, ()->{
ui.showRestart();
});
}
public static float waveSpacing(){
int scale = Settings.getInt("difficulty");
float out = (scale == 0 ? 2f : scale == 1f ? 1f : 0.5f);
return wavespace*out;
public static enum State{
paused, playing, menu, dead
}
}

View File

@@ -2,10 +2,13 @@ package io.anuke.mindustry;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
public class Inventory{
final static ObjectMap<Item, Integer> items = new ObjectMap<>();
public static void clearItems(){
items.clear();
@@ -20,6 +23,14 @@ public class Inventory{
}
}
public static Iterable<Item> getItemTypes(){
return items.keys();
}
public static int getAmount(Item item){
return items.get(item, 0);
}
public static void addItem(Item item, int amount){
items.put(item, items.get(item, 0)+amount);
ui.updateItems();

View File

@@ -12,6 +12,6 @@ public class Mindustry extends Core {
@Override
public void postInit(){
GameState.reset();
Vars.control.reset();
}
}

View File

@@ -22,9 +22,7 @@ import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.graphics.Cache;
import io.anuke.ucore.graphics.Caches;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.GridMap;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.Timers;
import io.anuke.ucore.util.*;
public class Renderer{
private static int chunksize = 32;
@@ -82,8 +80,8 @@ public class Renderer{
int worldx = Mathf.scl(camera.position.x, tilesize) + x;
int worldy = Mathf.scl(camera.position.y, tilesize) + y;
if(Mathf.inBounds(worldx, worldy, tiles)){
Tile tile = tiles[worldx][worldy];
if( World.tile(worldx, worldy) != null){
Tile tile = World.tile(worldx, worldy);
if(l == 0){
if(tile.block() != Blocks.air)
Draw.rect(tile.block().shadow, worldx * tilesize, worldy * tilesize);
@@ -106,7 +104,7 @@ public class Renderer{
public static void renderPixelOverlay(){
if(recipe != null && (!ui.hasMouse() || android)){
if(player.recipe != null && (!ui.hasMouse() || android)){
float x = 0;
float y = 0;
@@ -126,21 +124,21 @@ public class Renderer{
tiley = World.tiley();
}
boolean valid = World.validPlace(tilex, tiley, recipe.result);
boolean valid = World.validPlace(tilex, tiley, player.recipe.result);
Draw.color(valid ? Color.PURPLE : Color.SCARLET);
Draw.thickness(2f);
Draw.square(x, y, tilesize / 2 + MathUtils.sin(Timers.time() / 6f) + 1);
if(recipe.result.rotate){
if(player.recipe.result.rotate){
Draw.color("orange");
vector.set(7, 0).rotate(rotation * 90);
Draw.line(x, y, x + vector.x, y + vector.y);
Tmp.v1.set(7, 0).rotate(player.rotation * 90);
Draw.line(x, y, x + Tmp.v1.x, y + Tmp.v1.y);
}
Draw.thickness(1f);
Draw.color("scarlet");
for(Tile spawn : spawnpoints){
for(Tile spawn : World.spawnpoints){
Draw.dashcircle(spawn.worldx(), spawn.worldy(), enemyspawnspace);
}
@@ -156,23 +154,23 @@ public class Renderer{
if(Inputs.buttonDown(Buttons.RIGHT) && World.cursorNear()){
Tile tile = World.cursorTile();
if(tile.breakable() && tile.block() != ProductionBlocks.core){
Draw.color(Color.YELLOW, Color.SCARLET, breaktime / tile.block().breaktime);
Draw.color(Color.YELLOW, Color.SCARLET, player.breaktime / tile.block().breaktime);
Draw.square(tile.worldx(), tile.worldy(), 4);
Draw.reset();
}
}
if(android && breaktime > 0){
if(android && player.breaktime > 0){
Tile tile = AndroidInput.selected();
if(tile.breakable() && tile.block() != ProductionBlocks.core){
float fract = breaktime / tile.block().breaktime;
float fract = player.breaktime / tile.block().breaktime;
Draw.color(Color.YELLOW, Color.SCARLET, fract);
Draw.circle(tile.worldx(), tile.worldy(), 4 + (1f-fract)*26);
Draw.reset();
}
}
if(recipe == null && !ui.hasMouse()){
if(player.recipe == null && !ui.hasMouse()){
Tile tile = World.cursorTile();
if(tile != null && tile.block() != Blocks.air){

View File

@@ -13,6 +13,7 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Timer;
import com.badlogic.gdx.utils.Timer.Task;
import io.anuke.mindustry.GameState.State;
import io.anuke.mindustry.entities.Weapon;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.resource.*;
@@ -40,9 +41,9 @@ public class UI extends SceneModule{
Dialog about, menu, restart, tutorial, levels, upgrades;
Tooltip tooltip;
VisibilityProvider play = () -> playing;
VisibilityProvider play = () -> !GameState.is(State.menu);
VisibilityProvider nplay = () -> !playing;
VisibilityProvider nplay = () -> GameState.is(State.menu);
public UI() {
Dialog.setShowAction(()-> sequence(Actions.moveToAligned(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight(), Align.center),
@@ -95,7 +96,7 @@ public class UI extends SceneModule{
@Override
public void update(){
if(!playing){
if(nplay.visible()){
scene.getBatch().getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
scene.getBatch().begin();
@@ -142,11 +143,11 @@ public class UI extends SceneModule{
public Dialog show(Scene scene){
super.show(scene);
restart.content().clearChildren();
if(hiscore){
if(control.isHighScore()){
restart.content().add("[YELLOW]New highscore!").pad(6);
restart.content().row();
}
restart.content().add("You lasted until wave [GREEN]" + wave + "[].").pad(6);
restart.content().add("You lasted until wave [GREEN]" + control.getWave() + "[].").pad(6);
restart.pack();
return this;
}
@@ -154,8 +155,8 @@ public class UI extends SceneModule{
restart.getButtonTable().addButton("Back to menu", ()->{
restart.hide();
playing = false;
GameState.reset();
GameState.set(State.menu);
control.reset();
});
weapontable = fill();
@@ -209,7 +210,7 @@ public class UI extends SceneModule{
image.clicked(()->{
if(Inventory.hasItems(r.requirements))
recipe = r;
player.recipe = r;
});
table.add(image).size(size+8).pad(4).units(Unit.dp);
@@ -219,7 +220,7 @@ public class UI extends SceneModule{
boolean has = Inventory.hasItems(r.requirements);
image.setDisabled(!has);
image.setChecked(recipe == r && has);
image.setChecked(player.recipe == r && has);
//image.setTouchable(has ? Touchable.enabled : Touchable.disabled);
image.getImage().setColor(has ? Color.WHITE : Color.GRAY);
});
@@ -242,7 +243,7 @@ public class UI extends SceneModule{
ItemStack[] req = r.requirements;
for(ItemStack s : req){
tiptable.row();
int amount = Math.min(items.get(s.item, 0), s.amount);
int amount = Math.min(Inventory.getAmount(s.item), s.amount);
tiptable.add(
(amount >= s.amount ? "[YELLOW]" : "[RED]")
+s.item + ": " + amount + " / " +s.amount, fontscale).left();
@@ -345,12 +346,12 @@ public class UI extends SceneModule{
new table(){{
get().background("button");
new label(()->"[YELLOW]Wave " + wave).scale(fontscale*2f).left();
new label(()->"[YELLOW]Wave " + control.getWave()).scale(fontscale*2f).left();
row();
new label(()->enemies > 0 ?
enemies + " Enemies remaining" : "New wave in " + (int) (wavetime / 60f))
new label(()-> control.getEnemiesRemaining() > 0 ?
control.getEnemiesRemaining() + " Enemies remaining" : "New wave in " + (int) (control.getWaveCountdown() / 60f))
.minWidth(150);
get().pad(Unit.dp.inPixels(12));
@@ -440,26 +441,26 @@ public class UI extends SceneModule{
new label("Respawning in"){{
get().update(()->{
get().setText("[yellow]Respawning in " + (int)(respawntime/60));
get().setText("[yellow]Respawning in " + (int)(control.getRespawnTime()/60));
});
get().setFontScale(0.75f);
}};
visible(()->{
return respawntime > 0 && playing;
return control.getRespawnTime() > 0 && !GameState.is(State.menu);
});
}};
}}.end();
tools = new Table();
tools.addIButton("icon-cancel", Unit.dp.inPixels(42), ()->{
recipe = null;
player.recipe = null;
});
tools.addIButton("icon-rotate", Unit.dp.inPixels(42), ()->{
rotation++;
player.rotation++;
rotation %= 4;
player.rotation %= 4;
});
tools.addIButton("icon-check", Unit.dp.inPixels(42), ()->{
AndroidInput.place();
@@ -469,7 +470,7 @@ public class UI extends SceneModule{
scene.add(tools);
tools.setVisible(()->{
return playing && android && recipe != null;
return !GameState.is(State.menu) && android && player.recipe != null;
});
tools.update(()->{
@@ -484,32 +485,33 @@ public class UI extends SceneModule{
public void updateWeapons(){
weapontable.clearChildren();
for(Weapon weapon : Weapon.values()){
if(weapons.get(weapon) == Boolean.TRUE){
ImageButton button = new ImageButton(Draw.region("weapon-"+weapon.name()), "static");
button.getImageCell().size(40);
button.setDisabled(true);
if(weapon != currentWeapon)
button.setColor(Color.GRAY);
weapontable.add(button).size(48, 52);
for(Weapon weapon : control.getWeapons()){
ImageButton button = new ImageButton(Draw.region("weapon-"+weapon.name()), "static");
button.getImageCell().size(40);
button.setDisabled(true);
if(weapon != player.weapon)
button.setColor(Color.GRAY);
weapontable.add(button).size(48, 52);
Table tiptable = new Table();
String description = weapon.description;
Table tiptable = new Table();
String description = weapon.description;
tiptable.background("button");
tiptable.add("[PURPLE]" + weapon.name(), 0.75f).left().padBottom(2f);
tiptable.row();
tiptable.row();
tiptable.add("[ORANGE]" + description).left();
tiptable.pad(10f);
tiptable.background("button");
tiptable.add("[PURPLE]" + weapon.name(), 0.75f).left().padBottom(2f);
Tooltip tip = new Tooltip(tiptable);
tip.setInstant(true);
tiptable.row();
tiptable.row();
tiptable.add("[ORANGE]" + description).left();
tiptable.pad(10f);
Tooltip tip = new Tooltip(tiptable);
tip.setInstant(true);
button.addListener(tip);
}
button.addListener(tip);
}
}
@@ -545,9 +547,9 @@ public class UI extends SceneModule{
public void updateItems(){
itemtable.clear();
for(Item stack : items.keys()){
for(Item stack : Inventory.getItemTypes()){
Image image = new Image(Draw.region("icon-" + stack.name()));
Label label = new Label("" + items.get(stack));
Label label = new Label("" + Inventory.getAmount(stack));
label.setFontScale(fontscale*2f);
itemtable.add(image).size(32).units(Unit.dp);
itemtable.add(label);

View File

@@ -2,17 +2,8 @@ package io.anuke.mindustry;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.Weapon;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.scene.ui.layout.Unit;
/**ick, global state*/
@@ -23,52 +14,23 @@ public class Vars{
public static final float respawnduration = 60*4;
public static final float wavespace = 20*60*(android ? 2 : 1);
public static final float enemyspawnspace = 65;
public static boolean debug = false;
public static float fontscale = Unit.dp.inPixels(1f)/2f;
public static final float fontscale = Unit.dp.inPixels(1f)/2f;
public static final int baseCameraScale = Math.round(Unit.dp.inPixels(4));
public static final int zoomScale = Math.round(Unit.dp.inPixels(1));
public static int multiplier = android ? 2 : 1;
public static final Vector2 vector = new Vector2();
//not marked as final, because of warnings
public static boolean debug = false;
public static final int multiplier = android ? 2 : 1;
public static final int tilesize = 8;
public static Control control;
public static UI ui;
public static final ObjectMap<Item, Integer> items = new ObjectMap<>();
public static final ObjectMap<Weapon, Boolean> weapons = new ObjectMap<Weapon, Boolean>();
public static Weapon currentWeapon;
public static Player player;
public static float breaktime = 0;
public static final String[] maps = {"delta", "canyon", "pit", "maze"};
public static Pixmap[] mapPixmaps;
public static Texture[] mapTextures;
public static int currentMap;
public static int worldsize = 128;
public static int pixsize = worldsize*tilesize;
public static Tile[][] tiles = new Tile[worldsize][worldsize];
public static boolean hiscore = false;
public static Recipe recipe;
public static int rotation;
public static int wave = 1;
public static float wavetime;
public static int enemies = 0;
public static float respawntime;
public static Tile core;
public static Array<Tile> spawnpoints = new Array<Tile>();
public static boolean playing = false;
public static boolean paused = false;
public static boolean showedTutorial = false;
public static String[] aboutText = {
"Made by [ROYAL]Anuken[] for the" + "\nGDL Metal Monstrosity jam.",

View File

@@ -2,8 +2,12 @@ package io.anuke.mindustry;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.ai.Pathfind;
import io.anuke.mindustry.entities.TileEntity;
@@ -20,20 +24,34 @@ import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.util.Mathf;
public class World{
public static int worldsize = 128;
public static int pixsize = worldsize*tilesize;
private static Pixmap[] mapPixmaps;
private static Texture[] mapTextures;
private static int currentMap;
private static Tile[][] tiles = new Tile[worldsize][worldsize];
private static Tile[] temptiles = new Tile[4];
public static Tile core;
public static Array<Tile> spawnpoints = new Array<Tile>();
public static boolean solid(int x, int y){
Tile tile = tile(x, y);
return tile == null || tile.block().solid || (tile.floor().solid && (tile.block() == Blocks.air));
}
public static int getMap(){
return currentMap;
}
public static int width(){
return Vars.mapPixmaps[Vars.currentMap].getWidth();
return mapPixmaps[currentMap].getWidth();
}
public static int height(){
return Vars.mapPixmaps[Vars.currentMap].getHeight();
return mapPixmaps[currentMap].getHeight();
}
public static Tile tile(int x, int y){
@@ -53,6 +71,21 @@ public class World{
return temptiles;
}
public static Texture getTexture(int map){
return mapTextures[map];
}
public static void loadMaps(){
mapPixmaps = new Pixmap[maps.length];
mapTextures = new Texture[maps.length];
for(int i = 0; i < maps.length; i ++){
Pixmap pix = new Pixmap(Gdx.files.internal("maps/"+maps[i]+".png"));
mapPixmaps[i] = pix;
mapTextures[i] = new Texture(pix);
}
}
public static void loadMap(int id){
spawnpoints.clear();
@@ -70,7 +103,7 @@ public class World{
Entities.resizeTree(0, 0, pixsize, pixsize);
Generator.generate(id);
Generator.generate(mapPixmaps[id]);
Pathfind.reset();

View File

@@ -1,11 +1,10 @@
package io.anuke.mindustry.ai;
import static io.anuke.mindustry.Vars.worldsize;
import com.badlogic.gdx.ai.pfa.Connection;
import com.badlogic.gdx.ai.pfa.indexed.IndexedGraph;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.World;
import io.anuke.mindustry.world.Tile;
/**Tilegraph that ignores player-made tiles.*/
public class PassTileGraph implements IndexedGraph<Tile>{
@@ -28,11 +27,11 @@ public class PassTileGraph implements IndexedGraph<Tile>{
@Override
public int getIndex(Tile node){
return node.x+node.y*worldsize;
return node.x+node.y*World.worldsize;
}
@Override
public int getNodeCount(){
return worldsize*worldsize;
return World.worldsize*World.worldsize;
}
}

View File

@@ -1,13 +1,12 @@
package io.anuke.mindustry.ai;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.ai.pfa.DefaultGraphPath;
import com.badlogic.gdx.ai.pfa.PathFinder;
import com.badlogic.gdx.ai.pfa.indexed.IndexedAStarPathFinder;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.World;
import io.anuke.mindustry.entities.Enemy;
import io.anuke.mindustry.world.Tile;
public class Pathfind{
@@ -52,8 +51,8 @@ public class Pathfind{
static public void updatePath(){
if(paths.size == 0){
pathSequences = new Tile[spawnpoints.size][0];
for(int i = 0; i < spawnpoints.size; i ++){
pathSequences = new Tile[World.spawnpoints.size][0];
for(int i = 0; i < World.spawnpoints.size; i ++){
DefaultGraphPath<Tile> path = new DefaultGraphPath<>();
paths.add(path);
}
@@ -64,8 +63,8 @@ public class Pathfind{
path.clear();
passpathfinder.searchNodePath(
spawnpoints.get(i),
core, heuristic, path);
World.spawnpoints.get(i),
World.core, heuristic, path);
pathSequences[i] = new Tile[path.getCount()];

View File

@@ -84,7 +84,7 @@ public class Enemy extends DestructibleEntity{
@Override
public void removed(){
if(!dead)
Vars.enemies --;
Vars.control.enemyDeath();
}
@Override

View File

@@ -7,16 +7,21 @@ import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.Recipe;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.DestructibleEntity;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Timers;
public class Player extends DestructibleEntity{
Vector2 direction = new Vector2();
float speed = 1f;
float rotation;
float reload;
public Weapon weapon;
public float breaktime = 0;
public Recipe recipe;
public int rotation;
private Vector2 direction = new Vector2();
private float speed = 1f;
public Player(){
hitsize = 5;
@@ -32,7 +37,7 @@ public class Player extends DestructibleEntity{
Effects.shake(4f, 5f);
Effects.sound("die", this);
respawntime = respawnduration;
Vars.control.setRespawnTime(respawnduration);
}
@Override
@@ -62,14 +67,11 @@ public class Player extends DestructibleEntity{
if(Inputs.keyDown("right"))
vector.x += speed;
reload -= delta;
boolean shooting = Inputs.buttonDown(Buttons.LEFT) && recipe == null && !ui.hasMouse();
if(shooting && reload <= 0){
currentWeapon.shoot(this);
Sounds.play(currentWeapon.shootsound);
reload = currentWeapon.reload;
if(shooting && Timers.get(this, "reload", weapon.reload)){
weapon.shoot(this);
Sounds.play(weapon.shootsound);
}
vector.limit(speed);

View File

@@ -2,7 +2,7 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.GameState;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Blocks;
@@ -33,7 +33,7 @@ public class TileEntity extends Entity{
dead = true;
if(tile.block() == ProductionBlocks.core){
GameState.coreDestroyed();
Vars.control.coreDestroyed();
}
tile.setBlock(Blocks.air);

View File

@@ -51,12 +51,12 @@ public class AndroidInput extends InputAdapter{
public static void breakBlock(){
Tile tile = selected();
breaktime += Mathf.delta();
if(breaktime >= tile.block().breaktime){
player.breaktime += Mathf.delta();
if(player.breaktime >= tile.block().breaktime){
Effects.effect("break", tile.worldx(), tile.worldy());
Effects.shake(3f, 1f);
tile.setBlock(Blocks.air);
breaktime = 0f;
player.breaktime = 0f;
Sounds.play("break");
}
}
@@ -67,27 +67,27 @@ public class AndroidInput extends InputAdapter{
int tilex = Mathf.scl2(vec.x, tilesize);
int tiley = Mathf.scl2(vec.y, tilesize);
if(recipe != null &&
World.validPlace(tilex, tiley, recipe.result)){
if(player.recipe != null &&
World.validPlace(tilex, tiley, player.recipe.result)){
Tile tile = World.tile(tilex, tiley);
if(tile == null)
return; //just in case
tile.setBlock(recipe.result);
tile.rotation = rotation;
tile.setBlock(player.recipe.result);
tile.rotation = player.rotation;
Effects.effect("place", tilex*tilesize, tiley*tilesize);
Effects.shake(2f, 2f);
Sounds.play("place");
for(ItemStack stack : recipe.requirements){
for(ItemStack stack : player.recipe.requirements){
Inventory.removeItem(stack);
}
if(!Inventory.hasItems(recipe.requirements)){
recipe = null;
if(!Inventory.hasItems(player.recipe.requirements)){
player.recipe = null;
Cursors.restoreCursor();
}
}
@@ -96,7 +96,7 @@ public class AndroidInput extends InputAdapter{
public static void doInput(){
if(Gdx.input.isTouched(0)
&& Mathf.near2d(lmousex, lmousey, Gdx.input.getX(0), Gdx.input.getY(0), 50)
&& !ui.hasMouse() && recipe == null){
&& !ui.hasMouse() && player.recipe == null){
warmup += Mathf.delta();
mousex = Gdx.input.getX(0);
@@ -107,18 +107,18 @@ public class AndroidInput extends InputAdapter{
if(sel == null) return;
if(warmup > warmupDelay && sel.block() != ProductionBlocks.core && sel.breakable()){
breaktime += Mathf.delta();
player.breaktime += Mathf.delta();
if(breaktime > selected().block().breaktime){
if(player.breaktime > selected().block().breaktime){
breakBlock();
breaktime = 0;
player.breaktime = 0;
}
}
}else{
warmup = 0;
lmousex = Gdx.input.getX(0);
lmousey = Gdx.input.getY(0);
breaktime = 0;
player.breaktime = 0;
}
}

View File

@@ -21,12 +21,12 @@ public class GestureHandler extends GestureAdapter{
@Override
public boolean longPress(float x, float y){
Tile tile = World.cursorTile();
breaktime += Mathf.delta();
if(breaktime >= tile.block().breaktime){
player.breaktime += Mathf.delta();
if(player.breaktime >= tile.block().breaktime){
Effects.effect("break", tile.worldx(), tile.worldy());
Effects.shake(3f, 1f);
tile.setBlock(Blocks.air);
breaktime = 0f;
player.breaktime = 0f;
Sounds.play("break");
}
return false;
@@ -34,7 +34,7 @@ public class GestureHandler extends GestureAdapter{
@Override
public boolean pan(float x, float y, float deltaX, float deltaY){
if(recipe == null){
if(player.recipe == null){
player.x -= deltaX*control.camera.zoom/control.cameraScale;
player.y += deltaY*control.camera.zoom/control.cameraScale;
}else{
@@ -47,7 +47,7 @@ public class GestureHandler extends GestureAdapter{
@Override
public boolean pinch (Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
if(recipe == null)
if(player.recipe == null)
return false;
if(pinch1.x < 0){

View File

@@ -25,71 +25,56 @@ public class Input{
if(player.health <= 0) return;
if(Inputs.scrolled()){
Weapon[] val = Weapon.values();
int index = 0;
for(int i = 0; i < val.length; i ++)
if(val[i] == currentWeapon){
index = i;
break;
}
int index = currentWeapon();
for(int i = 0; i < val.length; i ++){
index += Inputs.scroll();
if(index >= 0 && index < val.length){
if(weapons.get(val[index])){
currentWeapon = (val[index]);
break;
}
}else{
break;
}
}
index -= Inputs.scroll();
player.weapon = control.getWeapons().get(Mathf.clamp(index, 0, control.getWeapons().size-1));
ui.updateWeapons();
}
if(Inputs.keyUp("rotate"))
rotation++;
player.rotation++;
rotation %= 4;
player.rotation %= 4;
if(recipe != null && !Inventory.hasItems(recipe.requirements)){
recipe = null;
if(player.recipe != null && !Inventory.hasItems(player.recipe.requirements)){
player.recipe = null;
Cursors.restoreCursor();
}
for(int i = 0; i < 9; i ++)
if(Inputs.keyUp(Keys.valueOf(""+(i+1))) && getWeapon(i) != null){
currentWeapon = getWeapon(i);
if(Inputs.keyUp(Keys.valueOf(""+(i+1))) && i < control.getWeapons().size){
player.weapon = control.getWeapons().get(i);
ui.updateWeapons();
}
if(Inputs.buttonUp(Buttons.LEFT) && recipe != null &&
World.validPlace(World.tilex(), World.tiley(), recipe.result) && !ui.hasMouse()){
if(Inputs.buttonUp(Buttons.LEFT) && player.recipe != null &&
World.validPlace(World.tilex(), World.tiley(), player.recipe.result) && !ui.hasMouse()){
Tile tile = World.tile(World.tilex(), World.tiley());
if(tile == null)
return; //just in case
tile.setBlock(recipe.result);
tile.rotation = rotation;
tile.setBlock(player.recipe.result);
tile.rotation = player.rotation;
Effects.effect("place", World.roundx(), World.roundy());
Effects.shake(2f, 2f);
Sounds.play("place");
for(ItemStack stack : recipe.requirements){
for(ItemStack stack : player.recipe.requirements){
Inventory.removeItem(stack);
}
if(!Inventory.hasItems(recipe.requirements)){
recipe = null;
if(!Inventory.hasItems(player.recipe.requirements)){
player.recipe = null;
Cursors.restoreCursor();
}
}
if(recipe != null && Inputs.buttonUp(Buttons.RIGHT)){
recipe = null;
if(player.recipe != null && Inputs.buttonUp(Buttons.RIGHT)){
player.recipe = null;
Cursors.restoreCursor();
}
@@ -99,38 +84,27 @@ public class Input{
if(Inputs.buttonDown(Buttons.RIGHT) && World.cursorNear() && cursor.breakable()
&& cursor.block() != ProductionBlocks.core){
Tile tile = cursor;
breaktime += Mathf.delta();
if(breaktime >= tile.block().breaktime){
player.breaktime += Mathf.delta();
if(player.breaktime >= tile.block().breaktime){
Effects.effect("break", tile.worldx(), tile.worldy());
Effects.shake(3f, 1f);
tile.setBlock(Blocks.air);
breaktime = 0f;
player.breaktime = 0f;
Sounds.play("break");
}
}else{
breaktime = 0f;
player.breaktime = 0f;
}
}
public static int currentWeapons(){
public static int currentWeapon(){
int i = 0;
for(Weapon w : Weapon.values())
if(weapons.get(w))
i ++;
return i;
}
public static Weapon getWeapon(int id){
int i = 0;
for(Weapon w : Weapon.values())
if(weapons.get(w))
if(i ++ == id)
return w;
return null;
for(Weapon weapon : control.getWeapons()){
if(player.weapon == weapon)
return i;
i ++;
}
return 0;
}
}

View File

@@ -0,0 +1,7 @@
package io.anuke.mindustry.io;
import io.anuke.mindustry.world.Tile;
public class SaveState{
public Tile[][] tiles;
}

View File

@@ -1,10 +1,10 @@
package io.anuke.mindustry.ui;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.maps;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.GameState;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.World;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.scene.ui.*;
@@ -29,7 +29,7 @@ public class LevelDialog extends Dialog{
getButtonTable().addButton("Play", ()->{
hide();
World.loadMap(selectedMap);
GameState.play();
Vars.control.play();
});
ButtonGroup<ImageButton> mapgroup = new ButtonGroup<>();
@@ -42,7 +42,7 @@ public class LevelDialog extends Dialog{
for(int i = 0; i < maps.length; i ++){
int index = i;
ImageButton image = new ImageButton(new TextureRegion(mapTextures[i]), "togglemap");
ImageButton image = new ImageButton(new TextureRegion(World.getTexture(i)), "togglemap");
mapgroup.add(image);
image.clicked(()->{
selectedMap = index;

View File

@@ -1,7 +1,9 @@
package io.anuke.mindustry.ui;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.ui;
import io.anuke.mindustry.GameState;
import io.anuke.mindustry.GameState.State;
import io.anuke.ucore.scene.ui.ConfirmDialog;
import io.anuke.ucore.scene.ui.Dialog;
import io.anuke.ucore.scene.ui.layout.Unit;
@@ -16,7 +18,7 @@ public class MenuDialog extends Dialog{
void setup(){
content().addButton("Back", ()->{
hide();
paused = false;
GameState.set(State.playing);
}).width(200).units(Unit.dp);
content().row();
@@ -33,8 +35,7 @@ public class MenuDialog extends Dialog{
content().addButton("Back to menu", ()->{
new ConfirmDialog("Confirm", "Are you sure you want to quit?", ()->{
hide();
paused = false;
playing = false;
GameState.set(State.menu);
}).show();
}).width(200).units(Unit.dp);
}

View File

@@ -2,6 +2,8 @@ package io.anuke.mindustry.ui;
import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.GameState;
import io.anuke.mindustry.GameState.State;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.scene.ui.TextDialog;
@@ -16,8 +18,7 @@ public class TutorialDialog extends TextDialog{
setDialog();
hidden(()->{
playing = true;
paused = false;
GameState.set(State.playing);
});
getButtonTable().addButton("OK", ()->{

View File

@@ -4,6 +4,8 @@ import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.graphics.Color;
import io.anuke.mindustry.GameState;
import io.anuke.mindustry.GameState.State;
import io.anuke.mindustry.Inventory;
import io.anuke.mindustry.entities.Weapon;
import io.anuke.mindustry.resource.ItemStack;
@@ -25,10 +27,10 @@ public class UpgradeDialog extends Dialog{
addCloseButton();
hidden(()->{
paused = false;
GameState.set(State.playing);
});
shown(()->{
paused = true;
GameState.set(State.paused);
});
getButtonTable().addButton("Ok", ()->{
@@ -51,7 +53,7 @@ public class UpgradeDialog extends Dialog{
button.update(()->{
if(weapons.get(weapon) == Boolean.TRUE){
if(control.hasWeapon(weapon)){
button.setDisabled(true);
button.setColor(Color.GRAY);
button.setTouchable(Touchable.disabled);
@@ -80,11 +82,11 @@ public class UpgradeDialog extends Dialog{
tiptable.background("button");
tiptable.add("[PURPLE]" + weapon.name(), 0.75f).left().padBottom(2f);
if(weapons.get(weapon) != Boolean.TRUE){
if(!control.hasWeapon(weapon)){
ItemStack[] req = weapon.requirements;
for(ItemStack s : req){
tiptable.row();
int amount = Math.min(items.get(s.item, 0), s.amount);
int amount = Math.min(Inventory.getAmount(s.item), s.amount);
tiptable.add(
(amount >= s.amount ? "[YELLOW]" : "[RED]")
+s.item + ": " + amount + " / " +s.amount, 0.5f).left();
@@ -96,7 +98,7 @@ public class UpgradeDialog extends Dialog{
tiptable.row();
tiptable.add("[ORANGE]" + description).left();
tiptable.row();
if(weapons.get(weapon) == Boolean.TRUE)
if(control.hasWeapon(weapon))
tiptable.add("[LIME]Purchased!").left();
tiptable.pad(10f);
};
@@ -113,7 +115,7 @@ public class UpgradeDialog extends Dialog{
if(button.isDisabled()) return;
Inventory.removeItems(weapon.requirements);
weapons.put(weapon, true);
control.addWeapon(weapon);
ui.updateWeapons();
run.listen();
Effects.sound("purchase");

View File

@@ -1,14 +1,11 @@
package io.anuke.mindustry.world;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.mindustry.World;
import io.anuke.mindustry.world.blocks.Blocks;
import io.anuke.ucore.graphics.Hue;
import io.anuke.ucore.noise.Noise;
@@ -29,16 +26,15 @@ public class Generator{
);
/**Returns world size.*/
public static void generate(int map){
Pixmap pix = mapPixmaps[map];
public static void generate(Pixmap pixmap){
Noise.setSeed(MathUtils.random(0, 99999));
for(int x = 0; x < tiles.length; x ++){
for(int y = 0; y < tiles.length; y ++){
for(int x = 0; x < pixmap.getWidth(); x ++){
for(int y = 0; y < pixmap.getHeight(); y ++){
Block floor = Blocks.stone;
Block block = Blocks.air;
int color = pix.getPixel(x, pix.getHeight()-1-y);
int color = pixmap.getPixel(x, pixmap.getHeight()-1-y);
if(colors.containsKey(color)){
//TODO less hacky method
@@ -48,9 +44,9 @@ public class Generator{
floor = colors.get(color);
}
}else if(color == start){
core = tiles[x][y];
World.core = World.tile(x, y);
}else if(color == spawn){
spawnpoints.add(tiles[x][y]);
World.spawnpoints.add(World.tile(x, y));
floor = Blocks.dirt;
}else{
if(Mathf.chance(0.02)){
@@ -81,23 +77,12 @@ public class Generator{
block = Blocks.shrub;
}
tiles[x][y].setBlock(block);
tiles[x][y].setFloor(floor);
World.tile(x, y).setBlock(block);
World.tile(x, y).setFloor(floor);
}
}
}
public static void loadMaps(){
mapPixmaps = new Pixmap[maps.length];
mapTextures = new Texture[maps.length];
for(int i = 0; i < maps.length; i ++){
Pixmap pix = new Pixmap(Gdx.files.internal("maps/"+maps[i]+".png"));
mapPixmaps[i] = pix;
mapTextures[i] = new Texture(pix);
}
}
private static ObjectMap<Integer, Block> map(Object...objects){
ObjectMap<Integer, Block> out = new ObjectMap<>();

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.world;
import static io.anuke.mindustry.Vars.*;
import static io.anuke.mindustry.Vars.tilesize;
import io.anuke.mindustry.World;
import io.anuke.mindustry.entities.TileEntity;
@@ -36,7 +36,7 @@ public class Tile{
}
public int id(){
return x + y * worldsize;
return x + y * World.worldsize;
}
public float worldx(){