Performance improvements, balancing

This commit is contained in:
Anuken
2017-04-30 14:59:30 -04:00
parent 1574ca33bc
commit 03c5c889e0
13 changed files with 138 additions and 70 deletions

View File

@@ -13,7 +13,7 @@ import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import io.anuke.moment.ai.Pathfind; import io.anuke.moment.ai.Pathfind;
import io.anuke.moment.entities.FlameEnemy; import io.anuke.moment.entities.BossEnemy;
import io.anuke.moment.entities.TileEntity; import io.anuke.moment.entities.TileEntity;
import io.anuke.moment.resource.ItemStack; import io.anuke.moment.resource.ItemStack;
import io.anuke.moment.world.Tile; import io.anuke.moment.world.Tile;
@@ -169,8 +169,10 @@ public class Control extends RendererModule<Moment>{
} }
//TODO //TODO
if(UInput.keyUp(Keys.G)) if(UInput.keyUp(Keys.G)){
new FlameEnemy(0).set(main.player.x, main.player.y).add(); new BossEnemy(0).set(main.player.x, main.player.y).add();
}
//new FlameEnemy(0).set(main.player.x, main.player.y).add();
if(UInput.buttonUp(Buttons.LEFT) && main.recipe != null && validPlace(tilex(), tiley(), main.recipe.result) && !get(UI.class).hasMouse()){ if(UInput.buttonUp(Buttons.LEFT) && main.recipe != null && validPlace(tilex(), tiley(), main.recipe.result) && !get(UI.class).hasMouse()){
Tile tile = main.tile(tilex(), tiley()); Tile tile = main.tile(tilex(), tiley());
@@ -386,7 +388,7 @@ public class Control extends RendererModule<Moment>{
Draw.clear(); Draw.clear();
} }
if(tile.entity != null) if(tile.entity != null)
drawHealth(tile.entity); drawHealth(tile.entity.x, tile.entity.y, tile.entity.health, tile.entity.maxhealth);
} }
} }
@@ -394,25 +396,25 @@ public class Control extends RendererModule<Moment>{
if(entity instanceof DestructibleEntity && !(entity instanceof TileEntity)){ if(entity instanceof DestructibleEntity && !(entity instanceof TileEntity)){
DestructibleEntity dest = ((DestructibleEntity) entity); DestructibleEntity dest = ((DestructibleEntity) entity);
drawHealth(dest); drawHealth(dest.x, dest.y, dest.health, dest.maxhealth);
} }
} }
//Draw.text(Gdx.graphics.getFramesPerSecond() + " FPS", main.player.x, main.player.y); //Draw.text(Gdx.graphics.getFramesPerSecond() + " FPS", main.player.x, main.player.y);
} }
void drawHealth(DestructibleEntity dest){ void drawHealth(float x, float y, float health, float maxhealth){
float len = 3; float len = 3;
float offset = 7; float offset = 7;
Draw.thickness(3f); Draw.thickness(3f);
Draw.color(Color.GRAY); Draw.color(Color.GRAY);
Draw.line(dest.x - len + 1, dest.y - offset, dest.x + len + 1, dest.y - offset); Draw.line(x - len + 1, y - offset, x + len + 1, y - offset);
Draw.thickness(1f); Draw.thickness(1f);
Draw.color(Color.BLACK); Draw.color(Color.BLACK);
Draw.line(dest.x - len + 1, dest.y - offset, dest.x + len, dest.y - offset); Draw.line(x - len + 1, y - offset, x + len, y - offset);
Draw.color(Color.RED); Draw.color(Color.RED);
Draw.line(dest.x - len + 1, dest.y - offset, dest.x - len + (int)(len * 2 * ((float) dest.health / dest.maxhealth)), dest.y - offset); Draw.line(x - len + 1, y - offset, x - len + (int)(len * 2 * ((float) health / maxhealth)), y - offset);
Draw.clear(); Draw.clear();
} }

View File

@@ -5,8 +5,7 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectMap;
import io.anuke.moment.ai.Pathfind; import io.anuke.moment.ai.Pathfind;
import io.anuke.moment.entities.Enemy; import io.anuke.moment.entities.*;
import io.anuke.moment.entities.Player;
import io.anuke.moment.resource.Item; import io.anuke.moment.resource.Item;
import io.anuke.moment.resource.ItemStack; import io.anuke.moment.resource.ItemStack;
import io.anuke.moment.resource.Recipe; import io.anuke.moment.resource.Recipe;
@@ -32,10 +31,10 @@ public class Moment extends ModuleController<Moment>{
public Recipe recipe; public Recipe recipe;
public int rotation; public int rotation;
public float placerange = 60; public float placerange = 60;
public float respawntime = 60*6; public float respawntime = 60*5;
public int wave = 1; public int wave = 1;
public float wavespace = 60*60; public float wavespace = 20*60;
public float wavetime; public float wavetime;
public float spawnspace = 65; public float spawnspace = 65;
public Tile core; public Tile core;
@@ -71,10 +70,6 @@ public class Moment extends ModuleController<Moment>{
} }
} }
//items.put(Item.stone, 200);
//items.put(Item.iron, 200);
//items.put(Item.steel, 200);
player = new Player(); player = new Player();
} }
@@ -91,10 +86,13 @@ public class Moment extends ModuleController<Moment>{
if(!playing) return; if(!playing) return;
if(Enemy.amount == 0) if(UInput.keyUp(Keys.Q))
System.out.println("Enemies: " + Enemy.amount + " Wavetime: " + wavetime + " Wave: " + wave + " Wavespace: " + wavespace);
if(Enemy.amount <= 0)
wavetime -= delta(); wavetime -= delta();
if(wavetime < 0 || UInput.keyUp(Keys.F)){ if(wavetime <= 0){
runWave(); runWave();
} }
} }
@@ -119,6 +117,10 @@ public class Moment extends ModuleController<Moment>{
items.put(Item.stone, 20); items.put(Item.stone, 20);
//items.put(Item.stone, 200);
//items.put(Item.iron, 200);
//items.put(Item.steel, 200);
if(get(UI.class).about != null) if(get(UI.class).about != null)
get(UI.class).updateItems(); get(UI.class).updateItems();
} }
@@ -170,18 +172,34 @@ public class Moment extends ModuleController<Moment>{
} }
public void runWave(){ public void runWave(){
int amount = 3*wave; int amount = wave;
for(int i = 0; i < amount; i ++){ for(int i = 0; i < amount; i ++){
int point = i%spawnpoints.size; int pos = i;
Tile tile = spawnpoints.get(point);
Timers.run((int)(i/spawnpoints.size)*40f, ()->{
Enemy e = new Enemy(point).set(tile.worldx(), tile.worldy());
Effects.effect("spawn", e);
e.add();
});
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 /*&& point == 1 */&& pos == 0){
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();
});
}
} }
wave ++; wave ++;

View File

@@ -14,6 +14,7 @@ import io.anuke.moment.world.Tile;
import io.anuke.moment.world.TileType; import io.anuke.moment.world.TileType;
import io.anuke.ucore.core.*; import io.anuke.ucore.core.*;
import io.anuke.ucore.modules.SceneModule; import io.anuke.ucore.modules.SceneModule;
import io.anuke.ucore.scene.Scene;
import io.anuke.ucore.scene.builders.*; import io.anuke.ucore.scene.builders.*;
import io.anuke.ucore.scene.style.Styles; import io.anuke.ucore.scene.style.Styles;
import io.anuke.ucore.scene.ui.*; import io.anuke.ucore.scene.ui.*;
@@ -118,8 +119,16 @@ public class UI extends SceneModule<Moment>{
about.getContentTable().add("Made by Anuken for the" + "\nGDL Metal Monstrosity jam." + "\nTools used:"); about.getContentTable().add("Made by Anuken for the" + "\nGDL Metal Monstrosity jam." + "\nTools used:");
about.addCloseButton(); about.addCloseButton();
restart = new Dialog("The core was destroyed.", "dialog"); restart = new Dialog("The core was destroyed.", "dialog"){
restart.content().add("You lasted until wave [GREEN]" + main.wave + "[].").pad(6); public Dialog show(Scene scene){
super.show(scene);
restart.content().clearChildren();
restart.content().add("You lasted until wave [GREEN]" + main.wave + "[].").pad(6);
restart.pack();
return this;
}
};
restart.getButtonTable().addButton("Back to menu", ()->{ restart.getButtonTable().addButton("Back to menu", ()->{
restart.hide(); restart.hide();
main.playing = false; main.playing = false;

View File

@@ -9,6 +9,7 @@ public class BossEnemy extends Enemy{
reload = 8; reload = 8;
bullet = BulletType.smallfast; bullet = BulletType.smallfast;
rotatespeed = 30f;
maxhealth = 260; maxhealth = 260;
hitsize = 8; hitsize = 8;
speed = 0.27f; speed = 0.27f;

View File

@@ -1,8 +1,12 @@
package io.anuke.moment.entities; package io.anuke.moment.entities;
import io.anuke.moment.Moment;
import io.anuke.moment.world.Tile;
import io.anuke.moment.world.TileType;
import io.anuke.ucore.entities.BulletEntity; import io.anuke.ucore.entities.BulletEntity;
import io.anuke.ucore.entities.Entity; import io.anuke.ucore.entities.Entity;
import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.util.Mathf;
public class Bullet extends BulletEntity{ public class Bullet extends BulletEntity{
BulletType type; BulletType type;
@@ -18,6 +22,23 @@ public class Bullet extends BulletEntity{
type.draw(this); type.draw(this);
} }
@Override
public void update(){
int tilex = Mathf.scl2(x, TileType.tilesize);
int tiley = Mathf.scl2(y, TileType.tilesize);
Tile tile = Moment.i.tile(tilex, tiley);
if(tile != null && tile.entity != null &&
tile.entity.collide(this) && !tile.entity.dead){
tile.entity.collision(this);
remove();
type.collide(this);
}
super.update();
}
@Override @Override
public void collision(SolidEntity other){ public void collision(SolidEntity other){
super.collision(other); super.collision(other);

View File

@@ -5,6 +5,7 @@ import com.badlogic.gdx.math.Vector2;
import io.anuke.moment.Control; import io.anuke.moment.Control;
import io.anuke.moment.Moment; import io.anuke.moment.Moment;
import io.anuke.moment.ai.Pathfind; import io.anuke.moment.ai.Pathfind;
import io.anuke.moment.world.TileType;
import io.anuke.ucore.core.Draw; import io.anuke.ucore.core.Draw;
import io.anuke.ucore.entities.*; import io.anuke.ucore.entities.*;
import io.anuke.ucore.util.Timers; import io.anuke.ucore.util.Timers;
@@ -22,6 +23,7 @@ public class Enemy extends DestructibleEntity{
public float range = 60; public float range = 60;
public BulletType bullet = BulletType.small; public BulletType bullet = BulletType.small;
public float length = 4; public float length = 4;
public float rotatespeed = 8f;
public Enemy(int spawn){ public Enemy(int spawn){
this.spawn = spawn; this.spawn = spawn;
@@ -40,9 +42,8 @@ public class Enemy extends DestructibleEntity{
Moment.module(Control.class).tryMove(this, vec.x*delta, vec.y*delta); Moment.module(Control.class).tryMove(this, vec.x*delta, vec.y*delta);
target = Entities.getClosest(x, y, range, e->{ //if(Timers.get(this, 10))
return (e instanceof TileEntity || e instanceof Player); target = TileType.findTileTarget(x, y, null, range, false);
});
if(target != null){ if(target != null){
if(Timers.get(this, reload)) if(Timers.get(this, reload))
@@ -84,7 +85,7 @@ public class Enemy extends DestructibleEntity{
if(target == null){ if(target == null){
direction.add(xvelocity, yvelocity); direction.add(xvelocity, yvelocity);
direction.limit(speed*8); direction.limit(speed*rotatespeed);
}else{ }else{
float angle = angleTo(target); float angle = angleTo(target);
direction.lerp(vector.set(0, 1).setAngle(angle), 0.25f); direction.lerp(vector.set(0, 1).setAngle(angle), 0.25f);

View File

@@ -6,13 +6,13 @@ public class FlameEnemy extends Enemy{
public FlameEnemy(int spawn) { public FlameEnemy(int spawn) {
super(spawn); super(spawn);
speed = 0.25f; speed = 0.3f;
maxhealth = 100; maxhealth = 150;
reload = 6; reload = 6;
bullet = BulletType.flameshot; bullet = BulletType.flameshot;
range = 30; range = 40;
heal(); heal();
} }

View File

@@ -52,6 +52,9 @@ public class Player extends DestructibleEntity{
@Override @Override
public void update(){ public void update(){
if(health < maxhealth && Timers.get(this, 30))
health ++;
vector.set(0, 0); vector.set(0, 0);
if(UInput.keyDown("up")) if(UInput.keyDown("up"))
@@ -74,9 +77,6 @@ public class Player extends DestructibleEntity{
vector.limit(speed); vector.limit(speed);
//x += vector.x*delta;
//y += vector.y*delta;
Moment.module(Control.class).tryMove(this, vector.x*delta, vector.y*delta); Moment.module(Control.class).tryMove(this, vector.x*delta, vector.y*delta);
if(!shooting){ if(!shooting){

View File

@@ -8,35 +8,31 @@ import io.anuke.moment.ai.Pathfind;
import io.anuke.moment.resource.Item; import io.anuke.moment.resource.Item;
import io.anuke.moment.world.Tile; import io.anuke.moment.world.Tile;
import io.anuke.moment.world.TileType; import io.anuke.moment.world.TileType;
import io.anuke.ucore.entities.DestructibleEntity;
import io.anuke.ucore.entities.Effects; import io.anuke.ucore.entities.Effects;
import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.entities.Entity;
public class TileEntity extends DestructibleEntity{ public class TileEntity extends Entity{
public final Tile tile; public final Tile tile;
public DelayedRemovalArray<ItemPos> convey = new DelayedRemovalArray<>(); public DelayedRemovalArray<ItemPos> convey = new DelayedRemovalArray<>();
public ObjectMap<Item, Integer> items = new ObjectMap<>(); public ObjectMap<Item, Integer> items = new ObjectMap<>();
public int shots; public int shots;
public TileEntity link; public TileEntity link;
public float rotation; public float rotation;
public int maxhealth, health;
public boolean dead = false;
public TileEntity(Tile tile){ public TileEntity(Tile tile){
this.tile = tile; this.tile = tile;
x = tile.worldx(); x = tile.worldx();
y = tile.worldy(); y = tile.worldy();
hitsize = TileType.tilesize;
maxhealth = tile.block().health; maxhealth = tile.block().health;
heal(); health = maxhealth;
} }
@Override
public boolean collides(SolidEntity other){
return (other instanceof Bullet) && ((Bullet)other).owner instanceof Enemy;
}
@Override
public void onDeath(){ public void onDeath(){
dead = true;
if(tile.block() == TileType.core){ if(tile.block() == TileType.core){
Moment.i.coreDestroyed(); Moment.i.coreDestroyed();
} }
@@ -46,6 +42,16 @@ public class TileEntity extends DestructibleEntity{
Effects.effect("explosion", this); Effects.effect("explosion", this);
} }
public void collision(Bullet other){
health -= other.getDamage();
if(health <= 0) onDeath();
}
public boolean collide(Bullet other){
return other.owner instanceof Enemy;
}
@Override @Override
public void update(){ public void update(){
tile.block().update(tile); tile.block().update(tile);

View File

@@ -22,8 +22,8 @@ public enum Recipe{
flameturret(defense, TileType.flameturret, stack(Item.iron, 12), stack(Item.steel, 12)), flameturret(defense, TileType.flameturret, stack(Item.iron, 12), stack(Item.steel, 12)),
sniperturret(defense, TileType.sniperturret, stack(Item.iron, 15), stack(Item.steel, 20)), sniperturret(defense, TileType.sniperturret, stack(Item.iron, 15), stack(Item.steel, 20)),
healturret(defense, TileType.healturret, stack(Item.iron, 30)), healturret(defense, TileType.healturret, stack(Item.iron, 40)),
megahealturret(defense, TileType.megahealturret, stack(Item.iron, 30), stack(Item.steel, 30)), megahealturret(defense, TileType.megahealturret, stack(Item.iron, 30), stack(Item.steel, 40)),
drill(production, TileType.stonedrill, stack(Item.stone, 5)), drill(production, TileType.stonedrill, stack(Item.stone, 5)),
irondrill(production, TileType.irondrill, stack(Item.stone, 30)), irondrill(production, TileType.irondrill, stack(Item.stone, 30)),

View File

@@ -32,10 +32,11 @@ public class Generator{
floor = TileType.coal; floor = TileType.coal;
} }
if(color == white){ if(color == white){
block = TileType.stoneblock; block = TileType.stoneblock;
}else if(color == blue){ }else if(color == blue){
Moment.i.core = tiles[x][y]; Moment.i.core = tiles[x][y];
}else if(color == red){ }else if(color == red){

View File

@@ -64,9 +64,10 @@ public class Tile{
public void changed(){ public void changed(){
//TODO where do the items go? if(entity != null){
if(entity != null)
entity.remove(); entity.remove();
entity = null;
}
if(block.update) if(block.update)
entity = new TileEntity(this).add(); entity = new TileEntity(this).add();

View File

@@ -106,7 +106,7 @@ public enum TileType{
public void draw(Tile tile){ public void draw(Tile tile){
Draw.rect(name() + (Timers.time() % ((20 / 100f) / speed) < (10 / 100f) / speed ? "" : "move"), tile.worldx(), tile.worldy(), tile.rotation * 90); Draw.rect(name() + (Timers.time() % ((20 / 100f) / speed) < (10 / 100f) / speed ? "" : "move"), tile.worldx(), tile.worldy(), tile.rotation * 90);
vector.set(tilesize, 0).rotate(tile.rotation * 90); vector.set(tilesize, 0).rotate(tile.rotation * 90);
vector2.set(-tilesize / 2, 0).rotate(tile.rotation * 90); vector2.set(-tilesize / 2, 0).rotate(tile.rotation * 90);
@@ -190,7 +190,7 @@ public enum TileType{
router(true, true, false){ router(true, true, false){
public void update(Tile tile){ public void update(Tile tile){
if(Timers.get(tile, 20) && tile.entity.totalItems() > 0){ if(Timers.get(tile, 10) && tile.entity.totalItems() > 0){
tryDump(tile, tile.rotation++); tryDump(tile, tile.rotation++);
tile.rotation %= 4; tile.rotation %= 4;
} }
@@ -426,7 +426,7 @@ public enum TileType{
* tile.entity.removeItem(ammo, 1); } * tile.entity.removeItem(ammo, 1); }
*/ */
//if(tile.entity.shots > 0){ //if(tile.entity.shots > 0){
tile.entity.link = findTileTarget(tile, range); tile.entity.link = findTileTarget(tile.worldx(), tile.worldy(), tile, range, true);
if(tile.entity.link != null){ if(tile.entity.link != null){
tile.entity.rotation = tile.entity.angleTo(tile.entity.link); tile.entity.rotation = tile.entity.angleTo(tile.entity.link);
@@ -475,7 +475,7 @@ public enum TileType{
} }
public void update(Tile tile){ public void update(Tile tile){
tile.entity.link = findTileTarget(tile, range); tile.entity.link = findTileTarget(tile.worldx(), tile.worldy(), tile, range, true);
if(tile.entity.link != null){ if(tile.entity.link != null){
tile.entity.rotation = tile.entity.angleTo(tile.entity.link); tile.entity.rotation = tile.entity.angleTo(tile.entity.link);
@@ -557,7 +557,6 @@ public enum TileType{
tile.entity.removeItem(ammo, 1); tile.entity.removeItem(ammo, 1);
} }
//TODO readd
if(tile.entity.shots > 0){ if(tile.entity.shots > 0){
Enemy enemy = findTarget(tile, range); Enemy enemy = findTarget(tile, range);
if(enemy != null){ if(enemy != null){
@@ -599,17 +598,26 @@ public enum TileType{
return (Enemy) closest; return (Enemy) closest;
} }
TileEntity findTileTarget(Tile tile, float range){ public static TileEntity findTileTarget(float x, float y, Tile tile, float range, boolean damaged){
Entity closest = null; Entity closest = null;
float dst = 0; float dst = 0;
Array<SolidEntity> array = Entities.getNearby(tile.worldx(), tile.worldy(), 100); int rad = (int)(range/tilesize)+1;
int tilex = Mathf.scl2(x, tilesize);
for(Entity e : array){ int tiley = Mathf.scl2(y, tilesize);
if(e == tile.entity) continue;
for(int rx = -rad; rx <= rad; rx ++){
if(e instanceof TileEntity && ((TileEntity) e).health < ((TileEntity) e).tile.block().health){ for(int ry = -rad; ry <= rad; ry ++){
float ndst = Vector2.dst(tile.worldx(), tile.worldy(), e.x, e.y); Tile other = Moment.i.tile(rx+tilex, ry+tiley);
if(other == null || other.entity == null ||(tile != null && other.entity == tile.entity)) continue;
TileEntity e = other.entity;
if(damaged && ((TileEntity) e).health >= ((TileEntity) e).tile.block().health)
continue;
float ndst = Vector2.dst(x, y, e.x, e.y);
if(ndst < range && (closest == null || ndst < dst)){ if(ndst < range && (closest == null || ndst < dst)){
dst = ndst; dst = ndst;
closest = e; closest = e;