Refactor input, fix color crash bugs, prototype multi-block placement

This commit is contained in:
Anuken
2017-12-13 23:28:20 -05:00
parent a100ee0e91
commit 949288393b
20 changed files with 373 additions and 209 deletions
+1 -11
View File
@@ -1,15 +1,5 @@
_Keep in mind that this is just a basic outline of planned features, and will be constantly changing!_ _Keep in mind that this is just a basic outline of planned features, and will be constantly changing!_
### 3.0 Release
- [DONE] New tutorial with the power blocks
- [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
- [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
- [DONE] Balance enemy difficulty
### 3.x Planned ### 3.x Planned
- New save system: toggleable autosave, named slots, less clunky save UI - New save system: toggleable autosave, named slots, less clunky save UI
- Teleporter UI changes, more colors (?) - Teleporter UI changes, more colors (?)
@@ -21,7 +11,7 @@ _Keep in mind that this is just a basic outline of planned features, and will be
- More indicators for when the core is damaged and/or under attack - More indicators for when the core is damaged and/or under attack
- Fix bugs with junction not accepting blocks(low FPS) - Fix bugs with junction not accepting blocks(low FPS)
- Fix bugs with tunnel merging and/or removing items (low FPS) - Fix bugs with tunnel merging and/or removing items (low FPS)
- Investigate #6
### 4.0 Planned ### 4.0 Planned
- Multiplayer framework, possibly implementation - Multiplayer framework, possibly implementation
+2 -2
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.anuke.mindustry" package="io.anuke.mindustry"
android:versionCode="30" android:versionCode="31"
android:versionName="3.03" > android:versionName="3.04" >
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="25" /> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="25" />
<uses-permission android:name="com.android.vending.BILLING" /> <uses-permission android:name="com.android.vending.BILLING" />
+1 -1
View File
@@ -79,7 +79,7 @@ project(":core") {
apply plugin: "java" apply plugin: "java"
dependencies { dependencies {
compile 'com.github.Anuken:ucore:dfceb01' compile 'com.github.Anuken:ucore:a1a3bd9'
compile "com.badlogicgames.gdx:gdx:$gdxVersion" compile "com.badlogicgames.gdx:gdx:$gdxVersion"
compile "com.badlogicgames.gdx:gdx-ai:1.8.1" compile "com.badlogicgames.gdx:gdx-ai:1.8.1"
} }
+12 -9
View File
@@ -7,7 +7,6 @@ import java.util.Arrays;
import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.ClassReflection;
@@ -20,8 +19,8 @@ import io.anuke.mindustry.entities.enemies.BlastEnemy;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.entities.enemies.HealerEnemy; import io.anuke.mindustry.entities.enemies.HealerEnemy;
import io.anuke.mindustry.input.AndroidInput; import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.GestureHandler;
import io.anuke.mindustry.input.Input; import io.anuke.mindustry.input.Input;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.resource.Item; import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
@@ -61,6 +60,7 @@ public class Control extends Module{
boolean shouldUpdateItems = false; boolean shouldUpdateItems = false;
float respawntime; float respawntime;
InputHandler input;
public Control(){ public Control(){
if(Mindustry.args.contains("-debug", false)) if(Mindustry.args.contains("-debug", false))
@@ -81,10 +81,13 @@ public class Control extends Module{
Gdx.input.setCatchBackKey(true); Gdx.input.setCatchBackKey(true);
if(android){ if(android){
Inputs.addProcessor(new GestureDetector(20, 0.5f, 2, 0.15f, new GestureHandler())); input = new AndroidInput();
Inputs.addProcessor(new AndroidInput()); }else{
input = new Input();
} }
Inputs.addProcessor(input);
Effects.setShakeFalloff(10000f); Effects.setShakeFalloff(10000f);
Core.atlas = new Atlas("sprites.atlas"); Core.atlas = new Atlas("sprites.atlas");
@@ -190,6 +193,10 @@ public class Control extends Module{
this.core = tile; this.core = tile;
} }
public InputHandler getInput(){
return input;
}
public void addSpawnPoint(Tile tile){ public void addSpawnPoint(Tile tile){
SpawnPoint point = new SpawnPoint(); SpawnPoint point = new SpawnPoint();
point.start = tile; point.start = tile;
@@ -518,11 +525,7 @@ public class Control extends Module{
Profiler.end("entityUpdate"); Profiler.end("entityUpdate");
} }
if(!android){ input.update();
Input.doInput();
}else{
AndroidInput.doInput();
}
} }
} }
@@ -0,0 +1,7 @@
package io.anuke.mindustry.core;
import io.anuke.ucore.modules.Module;
public class Network extends Module{
//TODO implementation
}
+17 -78
View File
@@ -4,10 +4,8 @@ import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.core.Core.camera; import static io.anuke.ucore.core.Core.camera;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.graphics.*; import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.profiling.GLProfiler; import com.badlogic.gdx.graphics.profiling.GLProfiler;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.FloatArray; import com.badlogic.gdx.utils.FloatArray;
@@ -17,8 +15,6 @@ import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.effect.Shaders; import io.anuke.mindustry.entities.effect.Shaders;
import io.anuke.mindustry.entities.enemies.Enemy; import io.anuke.mindustry.entities.enemies.Enemy;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.Input;
import io.anuke.mindustry.input.PlaceMode; import io.anuke.mindustry.input.PlaceMode;
import io.anuke.mindustry.world.Layer; import io.anuke.mindustry.world.Layer;
import io.anuke.mindustry.world.SpawnPoint; import io.anuke.mindustry.world.SpawnPoint;
@@ -35,7 +31,6 @@ import io.anuke.ucore.graphics.CacheBatch;
import io.anuke.ucore.graphics.Surface; import io.anuke.ucore.graphics.Surface;
import io.anuke.ucore.modules.RendererModule; import io.anuke.ucore.modules.RendererModule;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.*; import io.anuke.ucore.util.*;
public class Renderer extends RendererModule{ public class Renderer extends RendererModule{
@@ -88,9 +83,7 @@ public class Renderer extends RendererModule{
if(Mathf.in(camera.zoom, targetzoom, 0.005f)){ if(Mathf.in(camera.zoom, targetzoom, 0.005f)){
camera.zoom = 1f; camera.zoom = 1f;
Graphics.setCameraScale(targetscale); Graphics.setCameraScale(targetscale);
control.input.resetCursor();
AndroidInput.mousex = Gdx.graphics.getWidth() / 2;
AndroidInput.mousey = Gdx.graphics.getHeight() / 2;
} }
} }
@@ -99,6 +92,7 @@ public class Renderer extends RendererModule{
}else{ }else{
boolean smoothcam = Settings.getBool("smoothcam"); boolean smoothcam = Settings.getBool("smoothcam");
//TODO identify the source of this bug
if(control.core == null){ if(control.core == null){
ui.showGameError(); ui.showGameError();
GameState.set(State.menu); GameState.set(State.menu);
@@ -160,15 +154,13 @@ public class Renderer extends RendererModule{
camera.position.set(lastx - deltax, lasty - deltay, 0); camera.position.set(lastx - deltax, lasty - deltay, 0);
//if(Vars.debug){ record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't
record();
//}
} }
} }
@Override @Override
public void draw(){ public void draw(){
//clera shield surface //clears shield surface
Graphics.surface(shieldSurface); Graphics.surface(shieldSurface);
Graphics.surface(); Graphics.surface();
@@ -205,9 +197,7 @@ public class Renderer extends RendererModule{
@Override @Override
public void resize(int width, int height){ public void resize(int width, int height){
super.resize(width, height); super.resize(width, height);
control.input.resetCursor();
AndroidInput.mousex = Gdx.graphics.getWidth() / 2;
AndroidInput.mousey = Gdx.graphics.getHeight() / 2;
camera.position.set(player.x, player.y, 0); camera.position.set(player.x, player.y, 0);
} }
@@ -482,85 +472,34 @@ public class Renderer extends RendererModule{
Draw.reset(); Draw.reset();
} }
int tilex = control.input.getBlockX();
int tiley = control.input.getBlockY();
//draw placement box //draw placement box
if(player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && (!ui.hasMouse() || android) && AndroidInput.mode == PlaceMode.cursor){ if(player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && (!ui.hasMouse() || android)){
float x = 0;
float y = 0;
int tilex = 0; player.placeMode.draw(tilex, tiley, control.input.getBlockEndX(), control.input.getBlockEndY()); //TODO proper end points
int tiley = 0;
if(android){
Vector2 vec = Graphics.world(AndroidInput.mousex, AndroidInput.mousey);
tilex = Mathf.scl2(vec.x, tilesize);
tiley = Mathf.scl2(vec.y, tilesize);
}else{
tilex = Input.tilex();
tiley = Input.tiley();
}
x = tilex * tilesize;
y = tiley * tilesize;
boolean valid = world.validPlace(tilex, tiley, player.recipe.result) && (android || Input.cursorNear());
Vector2 offset = player.recipe.result.getPlaceOffset();
float si = MathUtils.sin(Timers.time() / 6f) + 1;
Draw.color(valid ? Color.PURPLE : Color.SCARLET);
Draw.thickness(2f);
Draw.linecrect(x + offset.x, y + offset.y, tilesize * player.recipe.result.width + si, tilesize * player.recipe.result.height + si);
player.recipe.result.drawPlace(tilex, tiley, player.rotation, valid);
Draw.thickness(2f);
if(player.recipe.result.rotate){
Draw.color("orange");
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.thickness(1f);
Draw.color("scarlet"); Draw.color(Color.SCARLET);
for(SpawnPoint spawn : control.getSpawnPoints()){ for(SpawnPoint spawn : control.getSpawnPoints()){
Draw.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace); Draw.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
} }
if(valid)
Cursors.setHand();
else
Cursors.restoreCursor();
Draw.reset(); Draw.reset();
} }
//block breaking if(Vars.android){
if(Inputs.buttonDown(Buttons.RIGHT) && world.validBreak(Input.tilex(), Input.tiley())){
Tile tile = world.tile(Input.tilex(), Input.tiley());
if(tile.isLinked())
tile = tile.getLinked();
Vector2 offset = tile.block().getPlaceOffset();
Draw.color(Color.YELLOW, Color.SCARLET, player.breaktime / tile.getBreakTime());
Draw.linecrect(tile.worldx() + offset.x, tile.worldy() + offset.y, tile.block().width * Vars.tilesize, tile.block().height * Vars.tilesize);
Draw.reset();
}else if(android && player.breaktime > 0){ //android block breaking
Vector2 vec = Graphics.world(Gdx.input.getX(0), Gdx.input.getY(0)); Vector2 vec = Graphics.world(Gdx.input.getX(0), Gdx.input.getY(0));
tilex = Mathf.scl2(vec.x, tilesize);
if(world.validBreak(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize))){ tiley = Mathf.scl2(vec.y, tilesize);
Tile tile = world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
float fract = player.breaktime / tile.getBreakTime();
Draw.color(Color.YELLOW, Color.SCARLET, fract);
Draw.circle(tile.worldx(), tile.worldy(), 4 + (1f - fract) * 26);
Draw.reset();
}
} }
PlaceMode.breaker.draw(tilex, tiley, 0, 0);
//draw selected block health //draw selected block health
if(player.recipe == null && !ui.hasMouse()){ if(player.recipe == null && !ui.hasMouse()){
Tile tile = world.tile(Input.tilex(), Input.tiley()); Tile tile = world.tile(tilex, tiley);
if(tile != null && tile.block() != Blocks.air){ if(tile != null && tile.block() != Blocks.air){
Tile target = tile; Tile target = tile;
@@ -36,7 +36,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}, },
iron = new BulletType(1.7f, 2){ iron = new BulletType(1.7f, 2){
public void draw(Bullet b){ public void draw(Bullet b){
Draw.color("gray"); Draw.color(Color.GRAY);
Draw.rect("bullet", b.x, b.y, b.angle()); Draw.rect("bullet", b.x, b.y, b.angle());
Draw.reset(); Draw.reset();
} }
@@ -241,7 +241,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
}, },
smallSlow = new BulletType(1.2f, 2){ smallSlow = new BulletType(1.2f, 2){
public void draw(Bullet b){ public void draw(Bullet b){
Draw.color("orange"); Draw.color(Color.ORANGE);
Draw.rect("shot", b.x, b.y, b.angle() - 45); Draw.rect("shot", b.x, b.y, b.angle() - 45);
Draw.reset(); Draw.reset();
} }
@@ -3,30 +3,30 @@ 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.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.effect.Fx; import io.anuke.mindustry.entities.effect.Fx;
import io.anuke.mindustry.input.Input; import io.anuke.mindustry.input.PlaceMode;
import io.anuke.mindustry.resource.Mech; import io.anuke.mindustry.resource.Mech;
import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.ucore.core.*; import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.DestructibleEntity; import io.anuke.ucore.entities.DestructibleEntity;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class Player extends DestructibleEntity{ public class Player extends DestructibleEntity{
private static final float speed = 1.1f;
private static final float dashSpeed = 1.8f;
public Weapon weapon; public Weapon weapon;
public Mech mech = Mech.standard; public Mech mech = Mech.standard;
public float breaktime = 0; public float angle;
public Recipe recipe; public transient float breaktime = 0;
public int rotation; public transient Recipe recipe;
public transient int rotation;
private Vector2 direction = new Vector2(); public transient PlaceMode placeMode = PlaceMode.touch;
private float speed = 1.1f;
private float dashSpeed = 1.8f;
public Player(){ public Player(){
hitbox.setSize(5); hitbox.setSize(5);
@@ -59,9 +59,9 @@ public class Player extends DestructibleEntity{
if(Vars.debug && (!Vars.showPlayer || !Vars.showUI)) return; if(Vars.debug && (!Vars.showPlayer || !Vars.showUI)) return;
if(Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){ if(Vars.snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate")){
Draw.rect("mech-"+mech.name(), (int)x, (int)y, direction.angle()-90); Draw.rect("mech-"+mech.name(), (int)x, (int)y, angle-90);
}else{ }else{
Draw.rect("mech-"+mech.name(), x, y, direction.angle()-90); Draw.rect("mech-"+mech.name(), x, y, angle-90);
} }
} }
@@ -69,15 +69,7 @@ public class Player extends DestructibleEntity{
@Override @Override
public void update(){ public void update(){
float speed = this.speed; float speed = Inputs.keyDown("dash") ? Player.dashSpeed : Player.speed;
if(Inputs.keyDown("dash")){
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 ++;
@@ -93,7 +85,8 @@ public class Player extends DestructibleEntity{
if(Inputs.keyDown("right")) if(Inputs.keyDown("right"))
vector.x += speed; vector.x += speed;
boolean shooting = !Inputs.keyDown("dash") && Inputs.buttonDown(Buttons.LEFT) && recipe == null && !ui.hasMouse() && !Input.onConfigurable(); boolean shooting = !Inputs.keyDown("dash") && Inputs.buttonDown(Buttons.LEFT) && recipe == null
&& !ui.hasMouse() && !control.getInput().onConfigurable();
if(shooting && Timers.get(this, "reload", weapon.reload)){ if(shooting && Timers.get(this, "reload", weapon.reload)){
weapon.shoot(this); weapon.shoot(this);
@@ -101,7 +94,7 @@ public class Player extends DestructibleEntity{
} }
if(Inputs.keyDown("dash") && Timers.get(this, "dashfx", 3) && vector.len() > 0){ if(Inputs.keyDown("dash") && Timers.get(this, "dashfx", 3) && vector.len() > 0){
Angles.translation(direction.angle() + 180, 3f); Angles.translation(angle + 180, 3f);
Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y()); Effects.effect(Fx.dashsmoke, x + Angles.x(), y + Angles.y());
} }
@@ -115,14 +108,10 @@ public class Player extends DestructibleEntity{
} }
if(!shooting){ if(!shooting){
direction.add(vector); angle = Mathf.lerpAngDelta(angle, vector.angle(), 0.13f);
direction.limit(speed*6);
}else{ }else{
float angle = Angles.mouseAngle(x, y); float angle = Angles.mouseAngle(x, y);
direction.lerp(vector.set(0, 1).setAngle(angle), 0.26f); this.angle = Mathf.lerpAngDelta(this.angle, angle, 0.1f);
if(MathUtils.isEqual(angle, direction.angle(), 0.05f)){
direction.setAngle(angle);
}
} }
} }
} }
@@ -455,7 +455,7 @@ public class Fx{
ind = new Effect(100, e -> { ind = new Effect(100, e -> {
Draw.thickness(3f); Draw.thickness(3f);
Draw.color("royal"); Draw.color(Color.ROYAL);
Draw.circle(e.x, e.y, 3); Draw.circle(e.x, e.y, 3);
Draw.reset(); Draw.reset();
}), }),
@@ -4,7 +4,7 @@ import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
@@ -14,17 +14,26 @@ import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Configurable; import io.anuke.mindustry.world.blocks.types.Configurable;
import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class AndroidInput extends InputAdapter{ public class AndroidInput extends InputHandler{
public static float mousex, mousey; public float mousex, mousey;
public static PlaceMode mode = PlaceMode.cursor; public boolean brokeBlock = false;
public static boolean brokeBlock = false; private float lmousex, lmousey;
private static float lmousex, lmousey; private float warmup;
private static float warmup; private float warmupDelay = 20;
private static float warmupDelay = 20;
public AndroidInput(){
Inputs.addProcessor(new GestureDetector(20, 0.5f, 2, 0.15f, new GestureHandler(this)));
}
@Override public float getCursorEndX(){ return Gdx.input.getX(0); }
@Override public float getCursorEndY(){ return Gdx.input.getY(0); }
@Override public float getCursorX(){ return mousex; }
@Override public float getCursorY(){ return mousey; }
@Override @Override
public boolean keyDown(int keycode){ public boolean keyDown(int keycode){
@@ -63,12 +72,23 @@ public class AndroidInput extends InputAdapter{
return false; return false;
} }
public static Tile selected(){ @Override
public void resetCursor(){
mousex = Gdx.graphics.getWidth()/2;
mousey = Gdx.graphics.getHeight()/2;
}
@Override
public boolean cursorNear(){
return true;
}
public Tile selected(){
Vector2 vec = Graphics.world(mousex, mousey); Vector2 vec = Graphics.world(mousex, mousey);
return Vars.world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize)); return Vars.world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
} }
public static void breakBlock(){ public void breakBlock(){
Tile tile = selected(); Tile tile = selected();
player.breaktime += Timers.delta(); player.breaktime += Timers.delta();
@@ -79,7 +99,7 @@ public class AndroidInput extends InputAdapter{
} }
} }
public static void place(){ public void place(){
Vector2 vec = Graphics.world(mousex, mousey); Vector2 vec = Graphics.world(mousex, mousey);
int tilex = Mathf.scl2(vec.x, tilesize); int tilex = Mathf.scl2(vec.x, tilesize);
@@ -95,7 +115,8 @@ public class AndroidInput extends InputAdapter{
} }
} }
public static void doInput(){ @Override
public void update(){
if(Gdx.input.isTouched(0) && Mathf.near2d(lmousex, lmousey, Gdx.input.getX(0), Gdx.input.getY(0), Unit.dp.inPixels(50)) if(Gdx.input.isTouched(0) && Mathf.near2d(lmousex, lmousey, Gdx.input.getX(0), Gdx.input.getY(0), Unit.dp.inPixels(50))
&& !ui.hasMouse()){ && !ui.hasMouse()){
@@ -133,7 +154,7 @@ public class AndroidInput extends InputAdapter{
} }
} }
public static int touches(){ public int touches(){
int sum = 0; int sum = 0;
for(int i = 0; i < 10; i++){ for(int i = 0; i < 10; i++){
if(Gdx.input.isTouched(i)) if(Gdx.input.isTouched(i))
@@ -9,35 +9,33 @@ import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Core;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf;
public class GestureHandler extends GestureAdapter{ public class GestureHandler extends GestureAdapter{
AndroidInput input;
Vector2 pinch1 = new Vector2(-1, -1), pinch2 = pinch1.cpy(); Vector2 pinch1 = new Vector2(-1, -1), pinch2 = pinch1.cpy();
Vector2 vector = new Vector2(); Vector2 vector = new Vector2();
float initzoom = -1; float initzoom = -1;
boolean zoomed = false; boolean zoomed = false;
GestureHandler(AndroidInput input){
this.input = input;
}
@Override @Override
public boolean longPress(float x, float y){ public boolean longPress(float x, float y){
/*
Tile tile = World.cursorTile();
player.breaktime += Timers.delta();
if(!GameState.is(State.menu) && player.breaktime >= tile.block().breaktime){
Effects.effect("break", tile.worldx(), tile.worldy());
Effects.shake(3f, 1f);
tile.setBlock(Blocks.air);
player.breaktime = 0f;
Sounds.play("break");
}*/
return false; return false;
} }
@Override @Override
public boolean tap (float x, float y, int count, int button) { public boolean tap (float x, float y, int count, int button) {
if(AndroidInput.mode == PlaceMode.touch && !ui.hasMouse() && player.recipe != null && if(!ui.hasMouse() && player.recipe != null &&
Vars.control.hasItems(player.recipe.requirements) && !Vars.ui.hasMouse() && !AndroidInput.brokeBlock){ Vars.control.hasItems(player.recipe.requirements) && !Vars.ui.hasMouse() && !input.brokeBlock){
AndroidInput.mousex = x;
AndroidInput.mousey = y; player.placeMode.tapped(Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize), Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize));
AndroidInput.place();
input.mousex = x;
input.mousey = y;
return true; return true;
} }
return false; return false;
@@ -45,12 +43,12 @@ public class GestureHandler extends GestureAdapter{
@Override @Override
public boolean pan(float x, float y, float deltaX, float deltaY){ public boolean pan(float x, float y, float deltaX, float deltaY){
if(player.recipe == null || !Vars.control.hasItems(player.recipe.requirements) || AndroidInput.mode == PlaceMode.touch){ if(player.recipe == null || !Vars.control.hasItems(player.recipe.requirements) || !player.placeMode.lockCamera){
player.x -= deltaX*Core.camera.zoom/Core.cameraScale; player.x -= deltaX*Core.camera.zoom/Core.cameraScale;
player.y += deltaY*Core.camera.zoom/Core.cameraScale; player.y += deltaY*Core.camera.zoom/Core.cameraScale;
}else if(AndroidInput.mode == PlaceMode.cursor){ }else if(player.placeMode.lockCamera){
AndroidInput.mousex += deltaX; input.mousex += deltaX;
AndroidInput.mousey += deltaY; input.mousey += deltaY;
} }
return false; return false;
+52 -28
View File
@@ -2,6 +2,7 @@ package io.anuke.mindustry.input;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons; import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
@@ -19,11 +20,36 @@ import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.utils.Cursors; import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class Input{ public class Input extends InputHandler{
float mousex, mousey;
public static void doInput(){ @Override public float getCursorEndX(){ return Gdx.input.getX(); }
//player is dead @Override public float getCursorEndY(){ return Gdx.input.getY(); }
if(player.health <= 0) return; @Override public float getCursorX(){ return mousex; }
@Override public float getCursorY(){ return mousey; }
@Override
public boolean touchDown (int screenX, int screenY, int pointer, int button) {
if(button == Buttons.LEFT){
mousex = screenX;
mousey = screenY;
}
return false;
}
public boolean touchUp(int screenX, int screenY, int pointer, int button){
player.placeMode.tapped(getBlockX(), getBlockY(), getBlockEndX(), getBlockEndY());
return false;
}
@Override
public void update(){
if(player.isDead()) return;
if(!Inputs.buttonDown(Buttons.LEFT)){
mousex = Gdx.input.getX();
mousey = Gdx.input.getY();
}
if(Inputs.scrolled() && Inputs.keyDown("zoom_hold") && !GameState.is(State.menu) && !Vars.ui.onDialog()){ if(Inputs.scrolled() && Inputs.keyDown("zoom_hold") && !GameState.is(State.menu) && !Vars.ui.onDialog()){
Vars.renderer.scaleCamera(Inputs.scroll()); Vars.renderer.scaleCamera(Inputs.scroll());
@@ -52,21 +78,7 @@ public class Input{
Tile cursor = Vars.world.tile(tilex(), tiley()); Tile cursor = Vars.world.tile(tilex(), tiley());
if(Inputs.buttonUp(Buttons.LEFT) && player.recipe != null && if(Inputs.buttonUp(Buttons.LEFT) && cursor != null){
Vars.world.validPlace(tilex(), tiley(), player.recipe.result) && !ui.hasMouse() && cursorNear() &&
Vars.control.hasItems(player.recipe.requirements)){
Vars.world.placeBlock(tilex(), tiley(), player.recipe.result, player.rotation, true);
for(ItemStack stack : player.recipe.requirements){
Vars.control.removeItem(stack);
}
if(!Vars.control.hasItems(player.recipe.requirements)){
Cursors.restoreCursor();
}
}else if(Inputs.buttonUp(Buttons.LEFT)){
Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor; Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor;
if(linked != null && linked.block() instanceof Configurable){ if(linked != null && linked.block() instanceof Configurable){
Vars.ui.showConfig(linked); Vars.ui.showConfig(linked);
@@ -98,28 +110,40 @@ public class Input{
} }
public static boolean cursorNear(){ public void tryPlaceBlock(int x, int y){
if(player.recipe != null &&
Vars.world.validPlace(x, y, player.recipe.result) && !ui.hasMouse() && cursorNear() &&
Vars.control.hasItems(player.recipe.requirements)){
Vars.world.placeBlock(x, y, player.recipe.result, player.rotation, true);
for(ItemStack stack : player.recipe.requirements){
Vars.control.removeItem(stack);
}
if(!Vars.control.hasItems(player.recipe.requirements)){
Cursors.restoreCursor();
}
}
}
public boolean cursorNear(){
return Vector2.dst(player.x, player.y, tilex() * tilesize, tiley() * tilesize) <= placerange; return Vector2.dst(player.x, player.y, tilex() * tilesize, tiley() * tilesize) <= placerange;
} }
public static boolean onConfigurable(){ public int tilex(){
Tile tile = Vars.world.tile(tilex(), tiley());
return tile != null && (tile.block() instanceof Configurable || (tile.isLinked() && tile.getLinked().block() instanceof Configurable));
}
public static int tilex(){
return (player.recipe != null && player.recipe.result.isMultiblock() && return (player.recipe != null && player.recipe.result.isMultiblock() &&
player.recipe.result.width % 2 == 0) ? player.recipe.result.width % 2 == 0) ?
Mathf.scl(Graphics.mouseWorld().x, tilesize) : Mathf.scl2(Graphics.mouseWorld().x, tilesize); Mathf.scl(Graphics.mouseWorld().x, tilesize) : Mathf.scl2(Graphics.mouseWorld().x, tilesize);
} }
public static int tiley(){ public int tiley(){
return (player.recipe != null && player.recipe.result.isMultiblock() && return (player.recipe != null && player.recipe.result.isMultiblock() &&
player.recipe.result.height % 2 == 0) ? player.recipe.result.height % 2 == 0) ?
Mathf.scl(Graphics.mouseWorld().y, tilesize) : Mathf.scl2(Graphics.mouseWorld().y, tilesize); Mathf.scl(Graphics.mouseWorld().y, tilesize) : Mathf.scl2(Graphics.mouseWorld().y, tilesize);
} }
public static int currentWeapon(){ public int currentWeapon(){
int i = 0; int i = 0;
for(Weapon weapon : control.getWeapons()){ for(Weapon weapon : control.getWeapons()){
if(player.weapon == weapon) if(player.weapon == weapon)
@@ -0,0 +1,53 @@
package io.anuke.mindustry.input;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Configurable;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.Mathf;
public abstract class InputHandler extends InputAdapter{
public abstract void update();
public abstract float getCursorX();
public abstract float getCursorY();
public abstract float getCursorEndX();
public abstract float getCursorEndY();
public int getBlockX(){ return Mathf.scl2(Graphics.world(getCursorX(), getCursorY()).x, Vars.tilesize); }
public int getBlockY(){ return Mathf.scl2(Graphics.world(getCursorX(), getCursorY()).y, Vars.tilesize); }
public int getBlockEndX(){ return Mathf.scl2(Graphics.world(getCursorEndX(), getCursorEndY()).x, Vars.tilesize); }
public int getBlockEndY(){ return Mathf.scl2(Graphics.world(getCursorEndX(), getCursorEndY()).y, Vars.tilesize); }
public void resetCursor(){}
public boolean onConfigurable(){
Tile tile = Vars.world.tile(getBlockX(), getBlockY());
return tile != null && (tile.block() instanceof Configurable || (tile.isLinked() && tile.getLinked().block() instanceof Configurable));
}
public boolean cursorNear(){
return Vector2.dst(player.x, player.y, getBlockX() * tilesize, getBlockY() * tilesize) <= placerange;
}
public void tryPlaceBlock(int x, int y){
if(player.recipe != null &&
Vars.world.validPlace(x, y, player.recipe.result) && !ui.hasMouse() && cursorNear() &&
Vars.control.hasItems(player.recipe.requirements)){
Vars.world.placeBlock(x, y, player.recipe.result, player.rotation, true);
for(ItemStack stack : player.recipe.requirements){
Vars.control.removeItem(stack);
}
if(!Vars.control.hasItems(player.recipe.requirements)){
Cursors.restoreCursor();
}
}
}
}
@@ -1,5 +1,144 @@
package io.anuke.mindustry.input; package io.anuke.mindustry.input;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Draw;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.Tmp;
public enum PlaceMode{ public enum PlaceMode{
cursor, touch; cursor{
public void draw(int tilex, int tiley, int endx, int endy){
float x = tilex * Vars.tilesize;
float y = tiley * Vars.tilesize;
boolean valid = world.validPlace(tilex, tiley, player.recipe.result) && (android || control.getInput().cursorNear());
Vector2 offset = player.recipe.result.getPlaceOffset();
float si = MathUtils.sin(Timers.time() / 6f) + 1;
Draw.color(valid ? Color.PURPLE : Color.SCARLET);
Draw.thickness(2f);
Draw.linecrect(x + offset.x, y + offset.y, tilesize * player.recipe.result.width + si, tilesize * player.recipe.result.height + si);
player.recipe.result.drawPlace(tilex, tiley, player.rotation, valid);
Draw.thickness(2f);
if(player.recipe.result.rotate){
Draw.color(Color.ORANGE);
Tmp.v1.set(7, 0).rotate(player.rotation * 90);
Draw.line(x, y, x + Tmp.v1.x, y + Tmp.v1.y);
}
if(valid)
Cursors.setHand();
else
Cursors.restoreCursor();
}
},
touch{
{
lockCamera = true;
}
public void draw(int tilex, int tiley, int endx, int endy){
float t = Vars.tilesize;
float x = tilex * t, y = tiley * t,
x2 = endx * t, y2 = endy * t;
if(x2 < x){
float d = x;
x = x2;
x2 = d;
}
if(y2 < y){
float d = y;
y = y2;
y2 = d;
}
if(x2 >= x){
x -= t/2;
x2 += t/2;
}
if(y2 >= y){
y -= t/2;
y2 += t/2;
}
if(tilex == endx && tiley == endy){
cursor.draw(tilex, tiley, endx, endy);
}else{
Draw.color(Color.GREEN);
Draw.linerect(x, y, x2 - x, y2 - y);
Draw.alpha(0.3f);
Draw.crect("blank", x, y, x2 - x, y2 - y);
Draw.reset();
}
}
public void tapped(int tilex, int tiley, int endx, int endy){
if(endx < tilex){
int t = endx;
endx = tilex;
tilex = t;
}
if(endy < tiley){
int t = endy;
endy = tiley;
tiley = t;
}
for(int x = tilex; x <= endx; x ++){
for(int y = tiley; y <= endy; y ++){
control.getInput().tryPlaceBlock(x, y);
}
}
}
},
breaker{
public void draw(int tilex, int tiley, int endx, int endy){
Tile tile = world.tile(tilex, tiley);
if(tile != null && world.validBreak(tilex, tiley)){
if(tile.isLinked())
tile = tile.getLinked();
Vector2 offset = tile.block().getPlaceOffset();
float fract = player.breaktime / tile.getBreakTime();
if(Inputs.buttonDown(Buttons.RIGHT)){
Draw.color(Color.YELLOW, Color.SCARLET, fract);
Draw.linecrect(tile.worldx() + offset.x, tile.worldy() + offset.y, tile.block().width * Vars.tilesize, tile.block().height * Vars.tilesize);
}else if(android && player.breaktime > 0){
Draw.color(Color.YELLOW, Color.SCARLET, fract);
Draw.circle(tile.worldx(), tile.worldy(), 4 + (1f - fract) * 26);
}
Draw.reset();
}
}
};
public boolean lockCamera;
public void draw(int tilex, int tiley, int endx, int endy){
}
public void tapped(int tilex, int tiley, int endx, int endy){
}
} }
@@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.Align;
import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.PlaceMode; import io.anuke.mindustry.input.PlaceMode;
import io.anuke.ucore.scene.builders.imagebutton; import io.anuke.ucore.scene.builders.imagebutton;
import io.anuke.ucore.scene.builders.label; import io.anuke.ucore.scene.builders.label;
@@ -29,7 +28,7 @@ public class PlacementFragment implements Fragment{
new table("pane"){{ new table("pane"){{
get().setTouchable(Touchable.enabled); get().setTouchable(Touchable.enabled);
new label(()->"Placement Mode: [orange]" + AndroidInput.mode.name()).pad(4).units(Unit.dp); new label(()->"Placement Mode: [orange]" + player.placeMode.name()).pad(4).units(Unit.dp);
row(); row();
aleft(); aleft();
@@ -42,7 +41,7 @@ public class PlacementFragment implements Fragment{
for(PlaceMode mode : PlaceMode.values()){ for(PlaceMode mode : PlaceMode.values()){
new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{ new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{
AndroidInput.mode = mode; player.placeMode = mode;
}){{ }){{
group.add(get()); group.add(get());
}}; }};
@@ -50,7 +49,7 @@ public class PlacementFragment implements Fragment{
new imagebutton("icon-cancel", Unit.dp.inPixels(14*3), ()->{ new imagebutton("icon-cancel", Unit.dp.inPixels(14*3), ()->{
player.recipe = null; player.recipe = null;
}).visible(()->player.recipe != null && AndroidInput.mode == PlaceMode.touch); }).visible(()->player.recipe != null && player.placeMode == PlaceMode.touch);
new imagebutton("icon-rotate-arrow", Unit.dp.inPixels(14*3), ()->{ new imagebutton("icon-rotate-arrow", Unit.dp.inPixels(14*3), ()->{
player.rotation ++; player.rotation ++;
@@ -58,7 +57,7 @@ public class PlacementFragment implements Fragment{
}).update(i->{ }).update(i->{
i.getImage().setOrigin(Align.center); i.getImage().setOrigin(Align.center);
i.getImage().setRotation(player.rotation*90); i.getImage().setRotation(player.rotation*90);
}).visible(()->player.recipe != null && AndroidInput.mode == PlaceMode.touch }).visible(()->player.recipe != null && player.placeMode == PlaceMode.touch
&& player.recipe.result.rotate); && player.recipe.result.rotate);
}}.left().end(); }}.left().end();
@@ -7,7 +7,6 @@ import com.badlogic.gdx.utils.Align;
import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.PlaceMode; import io.anuke.mindustry.input.PlaceMode;
import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Core;
import io.anuke.ucore.scene.ui.layout.Table; import io.anuke.ucore.scene.ui.layout.Table;
@@ -28,18 +27,19 @@ public class ToolFragment implements Fragment{
}); });
tools.addIButton("icon-check", Unit.dp.inPixels(42), ()->{ tools.addIButton("icon-check", Unit.dp.inPixels(42), ()->{
AndroidInput.place(); player.placeMode.tapped(control.getInput().getBlockX(), control.getInput().getBlockY(),
control.getInput().getBlockEndX(), control.getInput().getBlockEndY());
}); });
Core.scene.add(tools); Core.scene.add(tools);
tools.setVisible(()-> tools.setVisible(()->
!GameState.is(State.menu) && android && player.recipe != null && control.hasItems(player.recipe.requirements) && !GameState.is(State.menu) && android && player.recipe != null && control.hasItems(player.recipe.requirements) &&
AndroidInput.mode == PlaceMode.cursor player.placeMode == PlaceMode.cursor
); );
tools.update(()->{ tools.update(()->{
tools.setPosition(AndroidInput.mousex, Gdx.graphics.getHeight()-AndroidInput.mousey-15*Core.cameraScale, Align.top); tools.setPosition(control.getInput().getCursorX(), Gdx.graphics.getHeight() - control.getInput().getCursorY() - 15*Core.cameraScale, Align.top);
}); });
} }
} }
@@ -42,7 +42,7 @@ public class PowerTurret extends Turret implements PowerAcceptor{
public void drawSelect(Tile tile){ public void drawSelect(Tile tile){
Vector2 offset = getPlaceOffset(); Vector2 offset = getPlaceOffset();
Draw.color("green"); Draw.color(Color.GREEN);
Draw.dashCircle(tile.worldx() + offset.x, tile.worldy() + offset.y, range); Draw.dashCircle(tile.worldx() + offset.x, tile.worldy() + offset.y, range);
Draw.reset(); Draw.reset();
@@ -1,5 +1,6 @@
package io.anuke.mindustry.world.blocks.types.defense; package io.anuke.mindustry.world.blocks.types.defense;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
@@ -69,7 +70,7 @@ public class RepairTurret extends PowerTurret{
@Override @Override
public void drawSelect(Tile tile){ public void drawSelect(Tile tile){
Draw.color("green"); Draw.color(Color.GREEN);
Draw.dashCircle(tile.worldx(), tile.worldy(), range); Draw.dashCircle(tile.worldx(), tile.worldy(), range);
Draw.reset(); Draw.reset();
@@ -1,5 +1,6 @@
package io.anuke.mindustry.world.blocks.types.distribution; package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
@@ -26,14 +27,14 @@ public class PowerBooster extends Generator{
public void drawSelect(Tile tile){ public void drawSelect(Tile tile){
super.drawSelect(tile); super.drawSelect(tile);
Draw.color("yellow"); Draw.color(Color.YELLOW);
Draw.dashCircle(tile.worldx(), tile.worldy(), powerRange * Vars.tilesize); Draw.dashCircle(tile.worldx(), tile.worldy(), powerRange * Vars.tilesize);
Draw.reset(); Draw.reset();
} }
@Override @Override
public void drawPlace(int x, int y, int rotation, boolean valid){ public void drawPlace(int x, int y, int rotation, boolean valid){
Draw.color("purple"); Draw.color(Color.PURPLE);
Draw.thick(1f); Draw.thick(1f);
Draw.dashCircle(x * Vars.tilesize, y * Vars.tilesize, powerRange * Vars.tilesize); Draw.dashCircle(x * Vars.tilesize, y * Vars.tilesize, powerRange * Vars.tilesize);
Draw.reset(); Draw.reset();
@@ -57,7 +57,7 @@ public class Generator extends PowerBlock{
if(drawRangeOverlay){ if(drawRangeOverlay){
int rotation = tile.getRotation(); int rotation = tile.getRotation();
if(hasLasers){ if(hasLasers){
Draw.color("yellow"); Draw.color(Color.YELLOW);
Draw.thick(2f); Draw.thick(2f);
for(int i = 0; i < laserDirections; i++){ for(int i = 0; i < laserDirections; i++){
@@ -81,7 +81,7 @@ public class Generator extends PowerBlock{
@Override @Override
public void drawPlace(int x, int y, int rotation, boolean valid){ public void drawPlace(int x, int y, int rotation, boolean valid){
if(hasLasers){ if(hasLasers){
Draw.color("purple"); Draw.color(Color.PURPLE);
Draw.thick(2f); Draw.thick(2f);
for(int i = 0; i < laserDirections; i++){ for(int i = 0; i < laserDirections; i++){