Added new SFX, dashing, made generation FPS-independent

This commit is contained in:
Anuken
2017-12-10 17:01:14 -05:00
parent 347cae23e5
commit 5ea8f0b8e2
27 changed files with 110 additions and 44 deletions

View File

@@ -2,12 +2,12 @@ _Keep in mind that this is just a basic outline of planned features, and will be
### 3.0 Release ### 3.0 Release
- New tutorial with the power blocks - New tutorial with the power blocks
- New SFX for specific blocks, especially turrets - [DONE] New SFX for specific blocks, especially turrets
- [DONE] Block drawing layers. Refactor/remove `Block#drawOver()`, add `Layer` enum. Should fix 'glitchy' lasers and conveyor clipping - [DONE] Block drawing layers. Refactor/remove `Block#drawOver()`, add `Layer` enum. Should fix 'glitchy' lasers and conveyor clipping
- [DONE] Balance nuclear reactor, improve effectiveness as they are currently underpowered - [DONE] Balance nuclear reactor, improve effectiveness as they are currently underpowered
- Make generation frame independent - [DONE] Make generation frame independent
- Investigate issue #5 (enemies stuck in blocks) - [DONE/MOVED] Investigate issue #5 (enemies stuck in blocks) - looks like it's caused by map loading lag, needs to be fixed with a slightly different physics system
- Faster mech movement, possibly with a "boost" key - [DONE] Faster mech movement, possibly with a "boost" key
- Balance enemy difficulty - Balance enemy difficulty
### 3.x Planned ### 3.x Planned

View File

@@ -13,11 +13,12 @@ import android.util.DisplayMetrics;
import io.anuke.mindustry.io.Formatter; import io.anuke.mindustry.io.Formatter;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
public class AndroidLauncher extends AndroidApplication { public class AndroidLauncher extends AndroidApplication{
boolean doubleScaleTablets = false;
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
@Override @Override
protected void onCreate (Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.useImmersiveMode = true; config.useImmersiveMode = true;
@@ -37,19 +38,21 @@ public class AndroidLauncher extends AndroidApplication {
} }
}; };
if(doubleScaleTablets){
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics); getWindowManager().getDefaultDisplay().getMetrics(metrics);
float yInches= metrics.heightPixels/metrics.ydpi; float yInches = metrics.heightPixels / metrics.ydpi;
float xInches= metrics.widthPixels/metrics.xdpi; float xInches = metrics.widthPixels / metrics.xdpi;
double diagonalInches = Math.sqrt(xInches*xInches + yInches*yInches); double diagonalInches = Math.sqrt(xInches * xInches + yInches * yInches);
if (diagonalInches>=6.5){ if(diagonalInches >= 6.5){
// 6.5inch device or bigger // 6.5inch device or bigger
Unit.dp.multiplier = 2f; Unit.dp.multiplier = 2f;
}else{ }else{
// smaller device // smaller device
Unit.dp.multiplier = 1f; Unit.dp.multiplier = 1f;
} }
}
//Mindustry.args.add("-debug"); //Mindustry.args.add("-debug");

BIN
core/assets/sounds/bang.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
core/assets/sounds/ping.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -22,8 +22,10 @@ public class Vars{
public static final float respawnduration = 60*4; public static final float respawnduration = 60*4;
//time between waves in frames (on normal mode) //time between waves in frames (on normal mode)
public static final float wavespace = 50*60*(android ? 1 : 1); public static final float wavespace = 50*60*(android ? 1 : 1);
//waves can last no longer than 6 minutes, otherwise the next one spawns //waves can last no longer than 5 minutes, otherwise the next one spawns
public static final float maxwavespace = 60*60*6; public static final float maxwavespace = 60*60*5;
//advance time the pathfinding starts at
public static final float aheadPathfinding = 60*20;
//how far away from spawn points the player can't place blocks //how far away from spawn points the player can't place blocks
public static final float enemyspawnspace = 65; public static final float enemyspawnspace = 65;
//scale of the font //scale of the font
@@ -43,7 +45,7 @@ public class Vars{
//whether to draw chunk borders //whether to draw chunk borders
public static boolean debugChunks = false; public static boolean debugChunks = false;
//whether turrets have infinite ammo (only with debug) //whether turrets have infinite ammo (only with debug)
public static boolean infiniteAmmo = false; public static boolean infiniteAmmo = true;
//whether to show paths of enemies //whether to show paths of enemies
public static boolean showPaths = false; public static boolean showPaths = false;
//if false, player is always hidden //if false, player is always hidden

View File

@@ -109,6 +109,15 @@ public class Pathfind{
} }
} }
public boolean finishedUpdating(){
for(SpawnPoint point : Vars.control.getSpawnPoints()){
if(point.pathTiles == null){
return false;
}
}
return true;
}
public void updatePath(){ public void updatePath(){
for(SpawnPoint point : Vars.control.getSpawnPoints()){ for(SpawnPoint point : Vars.control.getSpawnPoints()){
point.finder = new IndexedAStarPathFinder<Tile>(graph); point.finder = new IndexedAStarPathFinder<Tile>(graph);

View File

@@ -50,6 +50,7 @@ public class Control extends Module{
Array<EnemySpawn> spawns = new Array<>(); Array<EnemySpawn> spawns = new Array<>();
int wave = 1; int wave = 1;
int lastUpdated = -1;
float wavetime; float wavetime;
float extrawavetime; float extrawavetime;
int enemies = 0; int enemies = 0;
@@ -90,7 +91,8 @@ public class Control extends Module{
Sounds.load("shoot.wav", "place.wav", "explosion.wav", "enemyshoot.wav", Sounds.load("shoot.wav", "place.wav", "explosion.wav", "enemyshoot.wav",
"corexplode.wav", "break.wav", "spawn.wav", "flame.wav", "die.wav", "corexplode.wav", "break.wav", "spawn.wav", "flame.wav", "die.wav",
"respawn.wav", "purchase.wav", "flame2.wav"); "respawn.wav", "purchase.wav", "flame2.wav", "bigshot.wav", "laser.wav", "lasershot.wav",
"ping.wav", "tesla.wav", "waveend.wav", "railgun.wav", "blast.wav", "bang2.wav");
Sounds.setFalloff(9000f); Sounds.setFalloff(9000f);
@@ -103,7 +105,8 @@ public class Control extends Module{
"right", Keys.D, "right", Keys.D,
"zoom_hold", Keys.CONTROL_LEFT, "zoom_hold", Keys.CONTROL_LEFT,
"menu", Gdx.app.getType() == ApplicationType.Android ? Keys.BACK : Keys.ESCAPE, "menu", Gdx.app.getType() == ApplicationType.Android ? Keys.BACK : Keys.ESCAPE,
"pause", Keys.SPACE "pause", Keys.SPACE,
"dash", Keys.SHIFT_LEFT
); );
for(int i = 0; i < Vars.saveSlots; i ++){ for(int i = 0; i < Vars.saveSlots; i ++){
@@ -129,6 +132,7 @@ public class Control extends Module{
weapons.add(Weapon.blaster); weapons.add(Weapon.blaster);
player.weapon = weapons.first(); player.weapon = weapons.first();
lastUpdated = -1;
wave = 1; wave = 1;
extrawavetime = maxwavespace; extrawavetime = maxwavespace;
wavetime = waveSpacing(); wavetime = waveSpacing();
@@ -232,7 +236,10 @@ public class Control extends Module{
public void runWave(){ public void runWave(){
Sounds.play("spawn"); Sounds.play("spawn");
if(lastUpdated < wave + 1){
world.pathfinder().updatePath(); world.pathfinder().updatePath();
lastUpdated = wave + 1;
}
for(EnemySpawn spawn : spawns){ for(EnemySpawn spawn : spawns){
for(int lane = 0; lane < spawnpoints.size; lane ++){ for(int lane = 0; lane < spawnpoints.size; lane ++){
@@ -471,6 +478,15 @@ public class Control extends Module{
if(enemies <= 0){ if(enemies <= 0){
wavetime -= delta(); wavetime -= delta();
if(Vars.debug && Inputs.keyDown(Keys.I)){
wavetime -= delta() * 10f;
}
if(lastUpdated < wave + 1 && wavetime < Vars.aheadPathfinding){ //start updatingbeforehand
world.pathfinder().updatePath();
lastUpdated = wave + 1;
}
} }
} }

View File

@@ -280,8 +280,8 @@ public class Renderer extends RendererModule{
Graphics.end(); Graphics.end();
int crangex = Math.round(camera.viewportWidth * camera.zoom / (chunksize * tilesize)); int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1;
int crangey = Math.round(camera.viewportHeight * camera.zoom / (chunksize * tilesize)); int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1;
drawCache(0, crangex, crangey); drawCache(0, crangex, crangey);

View File

@@ -3,7 +3,6 @@ package io.anuke.mindustry.entities;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Input.Buttons; import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
@@ -26,7 +25,8 @@ public class Player extends DestructibleEntity{
public int rotation; public int rotation;
private Vector2 direction = new Vector2(); private Vector2 direction = new Vector2();
private float speed = 1f; private float speed = 1.1f;
private float dashSpeed = 1.8f;
public Player(){ public Player(){
hitbox.setSize(5); hitbox.setSize(5);
@@ -71,8 +71,13 @@ public class Player extends DestructibleEntity{
float speed = this.speed; float speed = this.speed;
if(Vars.debug && Inputs.keyDown(Keys.SHIFT_LEFT)) if(Inputs.keyDown("dash")){
speed *= 3f; speed = dashSpeed;
if(Vars.debug){
// speed *= 3f;
}
}
if(health < maxhealth && Timers.get(this, "regen", 50)) if(health < maxhealth && Timers.get(this, "regen", 50))
health ++; health ++;
@@ -88,13 +93,18 @@ public class Player extends DestructibleEntity{
if(Inputs.keyDown("right")) if(Inputs.keyDown("right"))
vector.x += speed; vector.x += speed;
boolean shooting = Inputs.buttonDown(Buttons.LEFT) && recipe == null && !ui.hasMouse() && !Input.onConfigurable(); boolean shooting = !Inputs.keyDown("dash") && Inputs.buttonDown(Buttons.LEFT) && recipe == null && !ui.hasMouse() && !Input.onConfigurable();
if(shooting && Timers.get(this, "reload", weapon.reload)){ if(shooting && Timers.get(this, "reload", weapon.reload)){
weapon.shoot(this); weapon.shoot(this);
Sounds.play(weapon.shootsound); Sounds.play(weapon.shootsound);
} }
if(Inputs.keyDown("dash") && Timers.get(this, "dashfx", 3) && vector.len() > 0){
Angles.translation(direction.angle() + 180, 3f);
Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y());
}
vector.limit(speed); vector.limit(speed);
if(!Vars.noclip){ if(!Vars.noclip){

View File

@@ -438,6 +438,14 @@ public class Fx{
Draw.reset(); Draw.reset();
}), }),
dashsmoke = new Effect(30, e -> {
Draw.color(Color.CORAL, Color.GRAY, e.ifract());
//Draw.alpha(e.fract());
float size = e.fract()*4f;
Draw.rect("circle", e.x, e.y, size, size);
Draw.reset();
}),
spawn = new Effect(23, e -> { spawn = new Effect(23, e -> {
Draw.thickness(2f); Draw.thickness(2f);
Draw.color(Color.DARK_GRAY, Color.SCARLET, e.ifract()); Draw.color(Color.DARK_GRAY, Color.SCARLET, e.ifract());

View File

@@ -203,7 +203,7 @@ public class Enemy extends DestructibleEntity{
public void onDeath(){ public void onDeath(){
Effects.effect(Fx.explosion, this); Effects.effect(Fx.explosion, this);
Effects.shake(3f, 4f, this); Effects.shake(3f, 4f, this);
Effects.sound("explosion", this); Effects.sound("bang2", this);
remove(); remove();
dead = true; dead = true;
} }

View File

@@ -83,7 +83,7 @@ public class HealerEnemy extends Enemy{
void explode(){ void explode(){
Bullet b = new Bullet(BulletType.blast, this, x, y, 0).add(); Bullet b = new Bullet(BulletType.blast, this, x, y, 0).add();
b.damage = BulletType.blast.damage + (tier-1) * 40; b.damage = BulletType.blast.damage + (tier-1) * 30;
damage(999); damage(999);
} }

View File

@@ -69,6 +69,10 @@ public enum Weapon{
}, },
railgun(40, BulletType.sniper, "Shoots one long-range bullet.", stack(Item.steel, 60), stack(Item.iron, 60)){ railgun(40, BulletType.sniper, "Shoots one long-range bullet.", stack(Item.steel, 60), stack(Item.iron, 60)){
{
shootsound = "railgun";
}
@Override @Override
public void shoot(Player p){ public void shoot(Player p){
float ang = mouseAngle(p); float ang = mouseAngle(p);
@@ -79,6 +83,10 @@ public enum Weapon{
}, },
mortar(100, BulletType.shell, "Shoots a slow, but damaging shell.", stack(Item.titanium, 40), stack(Item.steel, 60)){ mortar(100, BulletType.shell, "Shoots a slow, but damaging shell.", stack(Item.titanium, 40), stack(Item.steel, 60)){
{
shootsound = "bigshot";
}
@Override @Override
public void shoot(Player p){ public void shoot(Player p){
float ang = mouseAngle(p); float ang = mouseAngle(p);

View File

@@ -99,6 +99,7 @@ public class WeaponBlocks{
sniperturret = new Turret("sniperturret"){ sniperturret = new Turret("sniperturret"){
{ {
shootsound = "railgun";
formalName = "railgun turret"; formalName = "railgun turret";
range = 120; range = 120;
reload = 50f; reload = 50f;
@@ -113,6 +114,7 @@ public class WeaponBlocks{
mortarturret = new Turret("mortarturret"){ mortarturret = new Turret("mortarturret"){
{ {
shootsound = "bigshot";
rotatespeed = 0.1f; rotatespeed = 0.1f;
formalName = "flak turret"; formalName = "flak turret";
range = 120; range = 120;
@@ -131,6 +133,7 @@ public class WeaponBlocks{
laserturret = new LaserTurret("laserturret"){ laserturret = new LaserTurret("laserturret"){
{ {
shootsound = "laser";
beamColor = Color.SKY; beamColor = Color.SKY;
formalName = "laser turret"; formalName = "laser turret";
range = 60; range = 60;
@@ -145,6 +148,7 @@ public class WeaponBlocks{
teslaturret = new PowerTurret("waveturret"){ teslaturret = new PowerTurret("waveturret"){
{ {
shootsound = "tesla";
formalName = "tesla turret"; formalName = "tesla turret";
range = 70; range = 70;
reload = 15f; reload = 15f;
@@ -166,6 +170,7 @@ public class WeaponBlocks{
plasmaturret = new Turret("plasmaturret"){ plasmaturret = new Turret("plasmaturret"){
{ {
shootsound = "flame2";
inaccuracy = 7f; inaccuracy = 7f;
formalName = "plasma turret"; formalName = "plasma turret";
range = 60f; range = 60f;
@@ -181,6 +186,7 @@ public class WeaponBlocks{
chainturret = new Turret("chainturret"){ chainturret = new Turret("chainturret"){
{ {
shootsound = "bigshot";
inaccuracy = 8f; inaccuracy = 8f;
formalName = "chain turret"; formalName = "chain turret";
range = 80f; range = 80f;
@@ -219,6 +225,7 @@ public class WeaponBlocks{
titanturret = new Turret("titancannon"){ titanturret = new Turret("titancannon"){
{ {
shootsound = "blast";
formalName = "titan cannon"; formalName = "titan cannon";
range = 120f; range = 120f;
reload = 23f; reload = 23f;

View File

@@ -25,6 +25,7 @@ public class LaserTurret extends PowerTurret{
super(name); super(name);
shootsound = null; shootsound = null;
layer2 = Layer.laser; layer2 = Layer.laser;
soundReload = 20;
} }
@Override @Override

View File

@@ -33,6 +33,7 @@ public class Turret extends Block{
protected final int timerTarget = timers++; protected final int timerTarget = timers++;
protected final int timerReload = timers++; protected final int timerReload = timers++;
protected final int timerSound = timers++;
protected float range = 50f; protected float range = 50f;
protected float reload = 10f; protected float reload = 10f;
@@ -48,6 +49,7 @@ public class Turret extends Block{
protected float shootCone = 5f; protected float shootCone = 5f;
protected Effect shootEffect = null; protected Effect shootEffect = null;
protected float shootShake = 0f; protected float shootShake = 0f;
protected int soundReload = 0;
public Turret(String name) { public Turret(String name) {
super(name); super(name);
@@ -161,7 +163,7 @@ public class Turret extends Block{
float reload = Vars.multiplier*this.reload; float reload = Vars.multiplier*this.reload;
if(Angles.angleDist(entity.rotation, targetRot) < shootCone && entity.timer.get(timerReload, reload)){ if(Angles.angleDist(entity.rotation, targetRot) < shootCone && entity.timer.get(timerReload, reload)){
if(shootsound != null) Effects.sound(shootsound, entity); if(shootsound != null && entity.timer.get(timerSound, soundReload)) Effects.sound(shootsound, entity);
shoot(tile); shoot(tile);
consumeAmmo(tile); consumeAmmo(tile);
entity.ammo --; entity.ammo --;

View File

@@ -72,8 +72,8 @@ public class ItemPowerGenerator extends Generator{
public void update(Tile tile){ public void update(Tile tile){
PowerEntity entity = tile.entity(); PowerEntity entity = tile.entity();
float maxPower = Math.min(powerCapacity - entity.power, powerOutput); float maxPower = Math.min(powerCapacity - entity.power, powerOutput * Timers.delta());
float mfract = maxPower/powerOutput; float mfract = maxPower/(powerOutput * Timers.delta());
if(entity.time > 0f){ if(entity.time > 0f){
entity.time -= 1f/itemDuration*mfract; entity.time -= 1f/itemDuration*mfract;

View File

@@ -65,9 +65,8 @@ public class LiquidPowerGenerator extends Generator implements LiquidAcceptor{
public void update(Tile tile){ public void update(Tile tile){
LiquidPowerEntity entity = tile.entity(); LiquidPowerEntity entity = tile.entity();
//TODO don't generate when full of energy
if(entity.liquidAmount > 0){ if(entity.liquidAmount > 0){
float used = Math.min(entity.liquidAmount, maxLiquidGenerate); float used = Math.min(entity.liquidAmount, maxLiquidGenerate * Timers.delta());
used = Math.min(used, (powerCapacity - entity.power)/powerPerLiquid); used = Math.min(used, (powerCapacity - entity.power)/powerPerLiquid);
entity.liquidAmount -= used; entity.liquidAmount -= used;

View File

@@ -54,7 +54,8 @@ public class NuclearReactor extends LiquidItemPowerGenerator{
if(fuel > 0){ if(fuel > 0){
entity.heat += fullness * heating; entity.heat += fullness * heating;
entity.power += powerMultiplier * fullness; entity.power += powerMultiplier * fullness * Timers.delta();
entity.power = Mathf.clamp(entity.power);
if(entity.timer.get(timerFuel, fuelUseTime)){ if(entity.timer.get(timerFuel, fuelUseTime)){
entity.removeItem(generateItem, 1); entity.removeItem(generateItem, 1);
} }