Added new SFX, dashing, made generation FPS-independent
This commit is contained in:
@@ -2,12 +2,12 @@ _Keep in mind that this is just a basic outline of planned features, and will be
|
||||
|
||||
### 3.0 Release
|
||||
- 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] Balance nuclear reactor, improve effectiveness as they are currently underpowered
|
||||
- Make generation frame independent
|
||||
- Investigate issue #5 (enemies stuck in blocks)
|
||||
- Faster mech movement, possibly with a "boost" key
|
||||
- [DONE] Make generation frame independent
|
||||
- [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
|
||||
- [DONE] Faster mech movement, possibly with a "boost" key
|
||||
- Balance enemy difficulty
|
||||
|
||||
### 3.x Planned
|
||||
|
||||
@@ -13,19 +13,20 @@ import android.util.DisplayMetrics;
|
||||
import io.anuke.mindustry.io.Formatter;
|
||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||
|
||||
public class AndroidLauncher extends AndroidApplication {
|
||||
|
||||
public class AndroidLauncher extends AndroidApplication{
|
||||
boolean doubleScaleTablets = false;
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
@Override
|
||||
protected void onCreate (Bundle savedInstanceState) {
|
||||
protected void onCreate(Bundle savedInstanceState){
|
||||
super.onCreate(savedInstanceState);
|
||||
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
|
||||
config.useImmersiveMode = true;
|
||||
|
||||
|
||||
Mindustry.formatter = new Formatter(){
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm");
|
||||
|
||||
|
||||
@Override
|
||||
public String format(Date date){
|
||||
return format.format(date);
|
||||
@@ -36,23 +37,25 @@ public class AndroidLauncher extends AndroidApplication {
|
||||
return NumberFormat.getIntegerInstance().format(number);
|
||||
}
|
||||
};
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
float yInches= metrics.heightPixels/metrics.ydpi;
|
||||
float xInches= metrics.widthPixels/metrics.xdpi;
|
||||
double diagonalInches = Math.sqrt(xInches*xInches + yInches*yInches);
|
||||
if (diagonalInches>=6.5){
|
||||
// 6.5inch device or bigger
|
||||
Unit.dp.multiplier = 2f;
|
||||
}else{
|
||||
// smaller device
|
||||
Unit.dp.multiplier = 1f;
|
||||
if(doubleScaleTablets){
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
float yInches = metrics.heightPixels / metrics.ydpi;
|
||||
float xInches = metrics.widthPixels / metrics.xdpi;
|
||||
double diagonalInches = Math.sqrt(xInches * xInches + yInches * yInches);
|
||||
if(diagonalInches >= 6.5){
|
||||
// 6.5inch device or bigger
|
||||
Unit.dp.multiplier = 2f;
|
||||
}else{
|
||||
// smaller device
|
||||
Unit.dp.multiplier = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Mindustry.args.add("-debug");
|
||||
|
||||
|
||||
initialize(new Mindustry(), config);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -22,8 +22,10 @@ public class Vars{
|
||||
public static final float respawnduration = 60*4;
|
||||
//time between waves in frames (on normal mode)
|
||||
public static final float wavespace = 50*60*(android ? 1 : 1);
|
||||
//waves can last no longer than 6 minutes, otherwise the next one spawns
|
||||
public static final float maxwavespace = 60*60*6;
|
||||
//waves can last no longer than 5 minutes, otherwise the next one spawns
|
||||
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
|
||||
public static final float enemyspawnspace = 65;
|
||||
//scale of the font
|
||||
@@ -43,7 +45,7 @@ public class Vars{
|
||||
//whether to draw chunk borders
|
||||
public static boolean debugChunks = false;
|
||||
//whether turrets have infinite ammo (only with debug)
|
||||
public static boolean infiniteAmmo = false;
|
||||
public static boolean infiniteAmmo = true;
|
||||
//whether to show paths of enemies
|
||||
public static boolean showPaths = false;
|
||||
//if false, player is always hidden
|
||||
|
||||
@@ -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(){
|
||||
for(SpawnPoint point : Vars.control.getSpawnPoints()){
|
||||
point.finder = new IndexedAStarPathFinder<Tile>(graph);
|
||||
|
||||
@@ -50,6 +50,7 @@ public class Control extends Module{
|
||||
|
||||
Array<EnemySpawn> spawns = new Array<>();
|
||||
int wave = 1;
|
||||
int lastUpdated = -1;
|
||||
float wavetime;
|
||||
float extrawavetime;
|
||||
int enemies = 0;
|
||||
@@ -90,7 +91,8 @@ public class Control extends Module{
|
||||
|
||||
Sounds.load("shoot.wav", "place.wav", "explosion.wav", "enemyshoot.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);
|
||||
|
||||
@@ -103,7 +105,8 @@ public class Control extends Module{
|
||||
"right", Keys.D,
|
||||
"zoom_hold", Keys.CONTROL_LEFT,
|
||||
"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 ++){
|
||||
@@ -129,6 +132,7 @@ public class Control extends Module{
|
||||
weapons.add(Weapon.blaster);
|
||||
player.weapon = weapons.first();
|
||||
|
||||
lastUpdated = -1;
|
||||
wave = 1;
|
||||
extrawavetime = maxwavespace;
|
||||
wavetime = waveSpacing();
|
||||
@@ -232,7 +236,10 @@ public class Control extends Module{
|
||||
public void runWave(){
|
||||
Sounds.play("spawn");
|
||||
|
||||
world.pathfinder().updatePath();
|
||||
if(lastUpdated < wave + 1){
|
||||
world.pathfinder().updatePath();
|
||||
lastUpdated = wave + 1;
|
||||
}
|
||||
|
||||
for(EnemySpawn spawn : spawns){
|
||||
for(int lane = 0; lane < spawnpoints.size; lane ++){
|
||||
@@ -471,6 +478,15 @@ public class Control extends Module{
|
||||
|
||||
if(enemies <= 0){
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -280,8 +280,8 @@ public class Renderer extends RendererModule{
|
||||
|
||||
Graphics.end();
|
||||
|
||||
int crangex = Math.round(camera.viewportWidth * camera.zoom / (chunksize * tilesize));
|
||||
int crangey = Math.round(camera.viewportHeight * camera.zoom / (chunksize * tilesize));
|
||||
int crangex = (int)(camera.viewportWidth * camera.zoom / (chunksize * tilesize))+1;
|
||||
int crangey = (int)(camera.viewportHeight * camera.zoom / (chunksize * tilesize))+1;
|
||||
|
||||
drawCache(0, crangex, crangey);
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.anuke.mindustry.entities;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
import com.badlogic.gdx.Input.Buttons;
|
||||
import com.badlogic.gdx.Input.Keys;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
@@ -26,7 +25,8 @@ public class Player extends DestructibleEntity{
|
||||
public int rotation;
|
||||
|
||||
private Vector2 direction = new Vector2();
|
||||
private float speed = 1f;
|
||||
private float speed = 1.1f;
|
||||
private float dashSpeed = 1.8f;
|
||||
|
||||
public Player(){
|
||||
hitbox.setSize(5);
|
||||
@@ -71,8 +71,13 @@ public class Player extends DestructibleEntity{
|
||||
|
||||
float speed = this.speed;
|
||||
|
||||
if(Vars.debug && Inputs.keyDown(Keys.SHIFT_LEFT))
|
||||
speed *= 3f;
|
||||
if(Inputs.keyDown("dash")){
|
||||
speed = dashSpeed;
|
||||
|
||||
if(Vars.debug){
|
||||
// speed *= 3f;
|
||||
}
|
||||
}
|
||||
|
||||
if(health < maxhealth && Timers.get(this, "regen", 50))
|
||||
health ++;
|
||||
@@ -88,13 +93,18 @@ public class Player extends DestructibleEntity{
|
||||
if(Inputs.keyDown("right"))
|
||||
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)){
|
||||
weapon.shoot(this);
|
||||
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);
|
||||
|
||||
if(!Vars.noclip){
|
||||
|
||||
@@ -438,6 +438,14 @@ public class Fx{
|
||||
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 -> {
|
||||
Draw.thickness(2f);
|
||||
Draw.color(Color.DARK_GRAY, Color.SCARLET, e.ifract());
|
||||
|
||||
@@ -203,7 +203,7 @@ public class Enemy extends DestructibleEntity{
|
||||
public void onDeath(){
|
||||
Effects.effect(Fx.explosion, this);
|
||||
Effects.shake(3f, 4f, this);
|
||||
Effects.sound("explosion", this);
|
||||
Effects.sound("bang2", this);
|
||||
remove();
|
||||
dead = true;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ public class HealerEnemy extends Enemy{
|
||||
|
||||
void explode(){
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,10 @@ public enum Weapon{
|
||||
},
|
||||
railgun(40, BulletType.sniper, "Shoots one long-range bullet.", stack(Item.steel, 60), stack(Item.iron, 60)){
|
||||
|
||||
{
|
||||
shootsound = "railgun";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shoot(Player 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)){
|
||||
|
||||
{
|
||||
shootsound = "bigshot";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shoot(Player p){
|
||||
float ang = mouseAngle(p);
|
||||
|
||||
@@ -99,6 +99,7 @@ public class WeaponBlocks{
|
||||
|
||||
sniperturret = new Turret("sniperturret"){
|
||||
{
|
||||
shootsound = "railgun";
|
||||
formalName = "railgun turret";
|
||||
range = 120;
|
||||
reload = 50f;
|
||||
@@ -113,6 +114,7 @@ public class WeaponBlocks{
|
||||
|
||||
mortarturret = new Turret("mortarturret"){
|
||||
{
|
||||
shootsound = "bigshot";
|
||||
rotatespeed = 0.1f;
|
||||
formalName = "flak turret";
|
||||
range = 120;
|
||||
@@ -131,6 +133,7 @@ public class WeaponBlocks{
|
||||
|
||||
laserturret = new LaserTurret("laserturret"){
|
||||
{
|
||||
shootsound = "laser";
|
||||
beamColor = Color.SKY;
|
||||
formalName = "laser turret";
|
||||
range = 60;
|
||||
@@ -145,6 +148,7 @@ public class WeaponBlocks{
|
||||
|
||||
teslaturret = new PowerTurret("waveturret"){
|
||||
{
|
||||
shootsound = "tesla";
|
||||
formalName = "tesla turret";
|
||||
range = 70;
|
||||
reload = 15f;
|
||||
@@ -166,6 +170,7 @@ public class WeaponBlocks{
|
||||
|
||||
plasmaturret = new Turret("plasmaturret"){
|
||||
{
|
||||
shootsound = "flame2";
|
||||
inaccuracy = 7f;
|
||||
formalName = "plasma turret";
|
||||
range = 60f;
|
||||
@@ -181,6 +186,7 @@ public class WeaponBlocks{
|
||||
|
||||
chainturret = new Turret("chainturret"){
|
||||
{
|
||||
shootsound = "bigshot";
|
||||
inaccuracy = 8f;
|
||||
formalName = "chain turret";
|
||||
range = 80f;
|
||||
@@ -219,6 +225,7 @@ public class WeaponBlocks{
|
||||
|
||||
titanturret = new Turret("titancannon"){
|
||||
{
|
||||
shootsound = "blast";
|
||||
formalName = "titan cannon";
|
||||
range = 120f;
|
||||
reload = 23f;
|
||||
|
||||
@@ -25,6 +25,7 @@ public class LaserTurret extends PowerTurret{
|
||||
super(name);
|
||||
shootsound = null;
|
||||
layer2 = Layer.laser;
|
||||
soundReload = 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,6 +33,7 @@ public class Turret extends Block{
|
||||
|
||||
protected final int timerTarget = timers++;
|
||||
protected final int timerReload = timers++;
|
||||
protected final int timerSound = timers++;
|
||||
|
||||
protected float range = 50f;
|
||||
protected float reload = 10f;
|
||||
@@ -48,6 +49,7 @@ public class Turret extends Block{
|
||||
protected float shootCone = 5f;
|
||||
protected Effect shootEffect = null;
|
||||
protected float shootShake = 0f;
|
||||
protected int soundReload = 0;
|
||||
|
||||
public Turret(String name) {
|
||||
super(name);
|
||||
@@ -161,7 +163,7 @@ public class Turret extends Block{
|
||||
|
||||
float reload = Vars.multiplier*this.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);
|
||||
consumeAmmo(tile);
|
||||
entity.ammo --;
|
||||
|
||||
@@ -72,8 +72,8 @@ public class ItemPowerGenerator extends Generator{
|
||||
public void update(Tile tile){
|
||||
PowerEntity entity = tile.entity();
|
||||
|
||||
float maxPower = Math.min(powerCapacity - entity.power, powerOutput);
|
||||
float mfract = maxPower/powerOutput;
|
||||
float maxPower = Math.min(powerCapacity - entity.power, powerOutput * Timers.delta());
|
||||
float mfract = maxPower/(powerOutput * Timers.delta());
|
||||
|
||||
if(entity.time > 0f){
|
||||
entity.time -= 1f/itemDuration*mfract;
|
||||
|
||||
@@ -65,9 +65,8 @@ public class LiquidPowerGenerator extends Generator implements LiquidAcceptor{
|
||||
public void update(Tile tile){
|
||||
LiquidPowerEntity entity = tile.entity();
|
||||
|
||||
//TODO don't generate when full of energy
|
||||
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);
|
||||
|
||||
entity.liquidAmount -= used;
|
||||
|
||||
@@ -54,7 +54,8 @@ public class NuclearReactor extends LiquidItemPowerGenerator{
|
||||
|
||||
if(fuel > 0){
|
||||
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)){
|
||||
entity.removeItem(generateItem, 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user