mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-02 20:33:50 +07:00
Added new SFX, dashing, made generation FPS-independent
This commit is contained in:
parent
347cae23e5
commit
5ea8f0b8e2
8
TODO.md
8
TODO.md
@ -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);
|
||||
}
|
||||
}
|
||||
|
BIN
core/assets/sounds/bang.wav
Normal file
BIN
core/assets/sounds/bang.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/bang2.wav
Normal file
BIN
core/assets/sounds/bang2.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/bigshot.wav
Normal file
BIN
core/assets/sounds/bigshot.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/blast.wav
Normal file
BIN
core/assets/sounds/blast.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/laser.wav
Normal file
BIN
core/assets/sounds/laser.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/lasershot.wav
Normal file
BIN
core/assets/sounds/lasershot.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/ping.wav
Normal file
BIN
core/assets/sounds/ping.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/railgun.wav
Normal file
BIN
core/assets/sounds/railgun.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/tesla.wav
Normal file
BIN
core/assets/sounds/tesla.wav
Normal file
Binary file not shown.
BIN
core/assets/sounds/waveend.wav
Normal file
BIN
core/assets/sounds/waveend.wav
Normal file
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user