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

View File

@@ -7,7 +7,6 @@ import java.util.Arrays;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.utils.Array;
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.HealerEnemy;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.GestureHandler;
import io.anuke.mindustry.input.Input;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Weapon;
@@ -61,6 +60,7 @@ public class Control extends Module{
boolean shouldUpdateItems = false;
float respawntime;
InputHandler input;
public Control(){
if(Mindustry.args.contains("-debug", false))
@@ -81,10 +81,13 @@ public class Control extends Module{
Gdx.input.setCatchBackKey(true);
if(android){
Inputs.addProcessor(new GestureDetector(20, 0.5f, 2, 0.15f, new GestureHandler()));
Inputs.addProcessor(new AndroidInput());
input = new AndroidInput();
}else{
input = new Input();
}
Inputs.addProcessor(input);
Effects.setShakeFalloff(10000f);
Core.atlas = new Atlas("sprites.atlas");
@@ -190,6 +193,10 @@ public class Control extends Module{
this.core = tile;
}
public InputHandler getInput(){
return input;
}
public void addSpawnPoint(Tile tile){
SpawnPoint point = new SpawnPoint();
point.start = tile;
@@ -518,11 +525,7 @@ public class Control extends Module{
Profiler.end("entityUpdate");
}
if(!android){
Input.doInput();
}else{
AndroidInput.doInput();
}
input.update();
}
}

View File

@@ -0,0 +1,7 @@
package io.anuke.mindustry.core;
import io.anuke.ucore.modules.Module;
public class Network extends Module{
//TODO implementation
}

View File

@@ -4,10 +4,8 @@ import static io.anuke.mindustry.Vars.*;
import static io.anuke.ucore.core.Core.camera;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.profiling.GLProfiler;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
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.effect.Shaders;
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.world.Layer;
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.modules.RendererModule;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.scene.utils.Cursors;
import io.anuke.ucore.util.*;
public class Renderer extends RendererModule{
@@ -88,9 +83,7 @@ public class Renderer extends RendererModule{
if(Mathf.in(camera.zoom, targetzoom, 0.005f)){
camera.zoom = 1f;
Graphics.setCameraScale(targetscale);
AndroidInput.mousex = Gdx.graphics.getWidth() / 2;
AndroidInput.mousey = Gdx.graphics.getHeight() / 2;
control.input.resetCursor();
}
}
@@ -99,6 +92,7 @@ public class Renderer extends RendererModule{
}else{
boolean smoothcam = Settings.getBool("smoothcam");
//TODO identify the source of this bug
if(control.core == null){
ui.showGameError();
GameState.set(State.menu);
@@ -160,15 +154,13 @@ public class Renderer extends RendererModule{
camera.position.set(lastx - deltax, lasty - deltay, 0);
//if(Vars.debug){
record();
//}
record(); //this only does something if GdxGifRecorder is on the class path, which it usually isn't
}
}
@Override
public void draw(){
//clera shield surface
//clears shield surface
Graphics.surface(shieldSurface);
Graphics.surface();
@@ -205,9 +197,7 @@ public class Renderer extends RendererModule{
@Override
public void resize(int width, int height){
super.resize(width, height);
AndroidInput.mousex = Gdx.graphics.getWidth() / 2;
AndroidInput.mousey = Gdx.graphics.getHeight() / 2;
control.input.resetCursor();
camera.position.set(player.x, player.y, 0);
}
@@ -481,86 +471,35 @@ public class Renderer extends RendererModule{
}
Draw.reset();
}
int tilex = control.input.getBlockX();
int tiley = control.input.getBlockY();
//draw placement box
if(player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && (!ui.hasMouse() || android) && AndroidInput.mode == PlaceMode.cursor){
float x = 0;
float y = 0;
if(player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && (!ui.hasMouse() || android)){
int tilex = 0;
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);
}
player.placeMode.draw(tilex, tiley, control.input.getBlockEndX(), control.input.getBlockEndY()); //TODO proper end points
Draw.thickness(1f);
Draw.color("scarlet");
Draw.color(Color.SCARLET);
for(SpawnPoint spawn : control.getSpawnPoints()){
Draw.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
}
if(valid)
Cursors.setHand();
else
Cursors.restoreCursor();
Draw.reset();
}
//block breaking
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
if(Vars.android){
Vector2 vec = Graphics.world(Gdx.input.getX(0), Gdx.input.getY(0));
if(world.validBreak(Mathf.scl2(vec.x, tilesize), 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();
}
tilex = Mathf.scl2(vec.x, tilesize);
tiley = Mathf.scl2(vec.y, tilesize);
}
PlaceMode.breaker.draw(tilex, tiley, 0, 0);
//draw selected block health
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){
Tile target = tile;

View File

@@ -36,7 +36,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
},
iron = new BulletType(1.7f, 2){
public void draw(Bullet b){
Draw.color("gray");
Draw.color(Color.GRAY);
Draw.rect("bullet", b.x, b.y, b.angle());
Draw.reset();
}
@@ -241,7 +241,7 @@ public abstract class BulletType extends BaseBulletType<Bullet>{
},
smallSlow = new BulletType(1.2f, 2){
public void draw(Bullet b){
Draw.color("orange");
Draw.color(Color.ORANGE);
Draw.rect("shot", b.x, b.y, b.angle() - 45);
Draw.reset();
}

View File

@@ -3,30 +3,30 @@ package io.anuke.mindustry.entities;
import static io.anuke.mindustry.Vars.*;
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.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.Recipe;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.DestructibleEntity;
import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf;
public class Player extends DestructibleEntity{
private static final float speed = 1.1f;
private static final float dashSpeed = 1.8f;
public Weapon weapon;
public Mech mech = Mech.standard;
public float breaktime = 0;
public float angle;
public Recipe recipe;
public int rotation;
private Vector2 direction = new Vector2();
private float speed = 1.1f;
private float dashSpeed = 1.8f;
public transient float breaktime = 0;
public transient Recipe recipe;
public transient int rotation;
public transient PlaceMode placeMode = PlaceMode.touch;
public Player(){
hitbox.setSize(5);
@@ -59,9 +59,9 @@ public class Player extends DestructibleEntity{
if(Vars.debug && (!Vars.showPlayer || !Vars.showUI)) return;
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{
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
public void update(){
float speed = this.speed;
if(Inputs.keyDown("dash")){
speed = dashSpeed;
if(Vars.debug){
// speed *= 3f;
}
}
float speed = Inputs.keyDown("dash") ? Player.dashSpeed : Player.speed;
if(health < maxhealth && Timers.get(this, "regen", 50))
health ++;
@@ -93,7 +85,8 @@ public class Player extends DestructibleEntity{
if(Inputs.keyDown("right"))
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)){
weapon.shoot(this);
@@ -101,7 +94,7 @@ public class Player extends DestructibleEntity{
}
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());
}
@@ -115,14 +108,10 @@ public class Player extends DestructibleEntity{
}
if(!shooting){
direction.add(vector);
direction.limit(speed*6);
angle = Mathf.lerpAngDelta(angle, vector.angle(), 0.13f);
}else{
float angle = Angles.mouseAngle(x, y);
direction.lerp(vector.set(0, 1).setAngle(angle), 0.26f);
if(MathUtils.isEqual(angle, direction.angle(), 0.05f)){
direction.setAngle(angle);
}
this.angle = Mathf.lerpAngDelta(this.angle, angle, 0.1f);
}
}
}

View File

@@ -455,7 +455,7 @@ public class Fx{
ind = new Effect(100, e -> {
Draw.thickness(3f);
Draw.color("royal");
Draw.color(Color.ROYAL);
Draw.circle(e.x, e.y, 3);
Draw.reset();
}),

View File

@@ -4,7 +4,7 @@ import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.math.Vector2;
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.blocks.types.Configurable;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf;
public class AndroidInput extends InputAdapter{
public static float mousex, mousey;
public static PlaceMode mode = PlaceMode.cursor;
public static boolean brokeBlock = false;
private static float lmousex, lmousey;
private static float warmup;
private static float warmupDelay = 20;
public class AndroidInput extends InputHandler{
public float mousex, mousey;
public boolean brokeBlock = false;
private float lmousex, lmousey;
private float warmup;
private 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
public boolean keyDown(int keycode){
@@ -62,13 +71,24 @@ public class AndroidInput extends InputAdapter{
}
return false;
}
@Override
public void resetCursor(){
mousex = Gdx.graphics.getWidth()/2;
mousey = Gdx.graphics.getHeight()/2;
}
@Override
public boolean cursorNear(){
return true;
}
public static Tile selected(){
public Tile selected(){
Vector2 vec = Graphics.world(mousex, mousey);
return Vars.world.tile(Mathf.scl2(vec.x, tilesize), Mathf.scl2(vec.y, tilesize));
}
public static void breakBlock(){
public void breakBlock(){
Tile tile = selected();
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);
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))
&& !ui.hasMouse()){
@@ -133,7 +154,7 @@ public class AndroidInput extends InputAdapter{
}
}
public static int touches(){
public int touches(){
int sum = 0;
for(int i = 0; i < 10; i++){
if(Gdx.input.isTouched(i))

View File

@@ -9,35 +9,33 @@ import com.badlogic.gdx.math.Vector2;
import io.anuke.mindustry.Vars;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf;
public class GestureHandler extends GestureAdapter{
AndroidInput input;
Vector2 pinch1 = new Vector2(-1, -1), pinch2 = pinch1.cpy();
Vector2 vector = new Vector2();
float initzoom = -1;
boolean zoomed = false;
GestureHandler(AndroidInput input){
this.input = input;
}
@Override
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;
}
@Override
public boolean tap (float x, float y, int count, int button) {
if(AndroidInput.mode == PlaceMode.touch && !ui.hasMouse() && player.recipe != null &&
Vars.control.hasItems(player.recipe.requirements) && !Vars.ui.hasMouse() && !AndroidInput.brokeBlock){
AndroidInput.mousex = x;
AndroidInput.mousey = y;
AndroidInput.place();
if(!ui.hasMouse() && player.recipe != null &&
Vars.control.hasItems(player.recipe.requirements) && !Vars.ui.hasMouse() && !input.brokeBlock){
player.placeMode.tapped(Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize), Mathf.scl2(x, Vars.tilesize), Mathf.scl2(y, Vars.tilesize));
input.mousex = x;
input.mousey = y;
return true;
}
return false;
@@ -45,12 +43,12 @@ public class GestureHandler extends GestureAdapter{
@Override
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.y += deltaY*Core.camera.zoom/Core.cameraScale;
}else if(AndroidInput.mode == PlaceMode.cursor){
AndroidInput.mousex += deltaX;
AndroidInput.mousey += deltaY;
}else if(player.placeMode.lockCamera){
input.mousex += deltaX;
input.mousey += deltaY;
}
return false;

View File

@@ -2,6 +2,7 @@ package io.anuke.mindustry.input;
import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.Input.Keys;
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.util.Mathf;
public class Input{
public class Input extends InputHandler{
float mousex, mousey;
public static void doInput(){
//player is dead
if(player.health <= 0) return;
@Override public float getCursorEndX(){ return Gdx.input.getX(); }
@Override public float getCursorEndY(){ return Gdx.input.getY(); }
@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()){
Vars.renderer.scaleCamera(Inputs.scroll());
@@ -52,21 +78,7 @@ public class Input{
Tile cursor = Vars.world.tile(tilex(), tiley());
if(Inputs.buttonUp(Buttons.LEFT) && player.recipe != 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)){
if(Inputs.buttonUp(Buttons.LEFT) && cursor != null){
Tile linked = cursor.isLinked() ? cursor.getLinked() : cursor;
if(linked != null && linked.block() instanceof Configurable){
Vars.ui.showConfig(linked);
@@ -98,28 +110,40 @@ public class Input{
}
public static boolean cursorNear(){
return Vector2.dst(player.x, player.y, tilex() * tilesize, tiley() * 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();
}
}
}
public static boolean onConfigurable(){
Tile tile = Vars.world.tile(tilex(), tiley());
return tile != null && (tile.block() instanceof Configurable || (tile.isLinked() && tile.getLinked().block() instanceof Configurable));
public boolean cursorNear(){
return Vector2.dst(player.x, player.y, tilex() * tilesize, tiley() * tilesize) <= placerange;
}
public static int tilex(){
public int tilex(){
return (player.recipe != null && player.recipe.result.isMultiblock() &&
player.recipe.result.width % 2 == 0) ?
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() &&
player.recipe.result.height % 2 == 0) ?
Mathf.scl(Graphics.mouseWorld().y, tilesize) : Mathf.scl2(Graphics.mouseWorld().y, tilesize);
}
public static int currentWeapon(){
public int currentWeapon(){
int i = 0;
for(Weapon weapon : control.getWeapons()){
if(player.weapon == weapon)

View File

@@ -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();
}
}
}
}

View File

@@ -1,5 +1,144 @@
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{
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){
}
}

View File

@@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.Align;
import io.anuke.mindustry.core.GameState;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.PlaceMode;
import io.anuke.ucore.scene.builders.imagebutton;
import io.anuke.ucore.scene.builders.label;
@@ -29,7 +28,7 @@ public class PlacementFragment implements Fragment{
new table("pane"){{
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();
aleft();
@@ -42,7 +41,7 @@ public class PlacementFragment implements Fragment{
for(PlaceMode mode : PlaceMode.values()){
new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{
AndroidInput.mode = mode;
player.placeMode = mode;
}){{
group.add(get());
}};
@@ -50,7 +49,7 @@ public class PlacementFragment implements Fragment{
new imagebutton("icon-cancel", Unit.dp.inPixels(14*3), ()->{
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), ()->{
player.rotation ++;
@@ -58,7 +57,7 @@ public class PlacementFragment implements Fragment{
}).update(i->{
i.getImage().setOrigin(Align.center);
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);
}}.left().end();

View File

@@ -7,7 +7,6 @@ import com.badlogic.gdx.utils.Align;
import io.anuke.mindustry.core.GameState;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.input.AndroidInput;
import io.anuke.mindustry.input.PlaceMode;
import io.anuke.ucore.core.Core;
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), ()->{
AndroidInput.place();
player.placeMode.tapped(control.getInput().getBlockX(), control.getInput().getBlockY(),
control.getInput().getBlockEndX(), control.getInput().getBlockEndY());
});
Core.scene.add(tools);
tools.setVisible(()->
!GameState.is(State.menu) && android && player.recipe != null && control.hasItems(player.recipe.requirements) &&
AndroidInput.mode == PlaceMode.cursor
player.placeMode == PlaceMode.cursor
);
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);
});
}
}

View File

@@ -42,7 +42,7 @@ public class PowerTurret extends Turret implements PowerAcceptor{
public void drawSelect(Tile tile){
Vector2 offset = getPlaceOffset();
Draw.color("green");
Draw.color(Color.GREEN);
Draw.dashCircle(tile.worldx() + offset.x, tile.worldy() + offset.y, range);
Draw.reset();

View File

@@ -1,5 +1,6 @@
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.Vector2;
import com.badlogic.gdx.utils.Array;
@@ -69,7 +70,7 @@ public class RepairTurret extends PowerTurret{
@Override
public void drawSelect(Tile tile){
Draw.color("green");
Draw.color(Color.GREEN);
Draw.dashCircle(tile.worldx(), tile.worldy(), range);
Draw.reset();

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.world.blocks.types.distribution;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
@@ -26,14 +27,14 @@ public class PowerBooster extends Generator{
public void drawSelect(Tile tile){
super.drawSelect(tile);
Draw.color("yellow");
Draw.color(Color.YELLOW);
Draw.dashCircle(tile.worldx(), tile.worldy(), powerRange * Vars.tilesize);
Draw.reset();
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
Draw.color("purple");
Draw.color(Color.PURPLE);
Draw.thick(1f);
Draw.dashCircle(x * Vars.tilesize, y * Vars.tilesize, powerRange * Vars.tilesize);
Draw.reset();

View File

@@ -57,7 +57,7 @@ public class Generator extends PowerBlock{
if(drawRangeOverlay){
int rotation = tile.getRotation();
if(hasLasers){
Draw.color("yellow");
Draw.color(Color.YELLOW);
Draw.thick(2f);
for(int i = 0; i < laserDirections; i++){
@@ -81,7 +81,7 @@ public class Generator extends PowerBlock{
@Override
public void drawPlace(int x, int y, int rotation, boolean valid){
if(hasLasers){
Draw.color("purple");
Draw.color(Color.PURPLE);
Draw.thick(2f);
for(int i = 0; i < laserDirections; i++){