Better Android keyboard support

This commit is contained in:
Anuken 2019-09-21 15:35:59 -04:00
parent 1957b6aa12
commit 0d25d83651
10 changed files with 78 additions and 59 deletions

View File

@ -200,7 +200,7 @@ project(":core"){
}
dependencies{
if(System.properties["user.name"] == "anuke2"){
if(System.properties["user.name"] == "anuke"){
task cleanGen{
doFirst{
delete{
@ -270,7 +270,6 @@ project(":tools"){
dependencies{
compile project(":core")
//for render tests
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop"

View File

@ -535,6 +535,7 @@ setting.antialias.name = Antialias[lightgray] (requires restart)[]
setting.indicators.name = Enemy/Ally Indicators
setting.autotarget.name = Auto-Target
setting.keyboard.name = Mouse+Keyboard Controls
setting.touchscreen.name = Touchscreen Controls
setting.fpscap.name = Max FPS
setting.fpscap.none = None
setting.fpscap.text = {0} FPS

View File

@ -204,9 +204,16 @@ public class Control implements ApplicationListener, Loadable{
player.add();
}
Events.on(ClientLoadEvent.class, e -> {
Core.input.addProcessor(input);
});
Events.on(ClientLoadEvent.class, e -> input.add());
}
public void setInput(InputHandler newInput){
boolean added = Core.input.getInputProcessors().contains(input);
input.remove();
this.input = newInput;
if(added){
newInput.add();
}
}
public void playMap(Map map, Rules rules){
@ -379,7 +386,7 @@ public class Control implements ApplicationListener, Loadable{
//update and load any requested assets
assets.update();
input.updateController();
input.updateState();
//autosave global data if it's modified
data.checkSave();

View File

@ -22,6 +22,7 @@ import io.anuke.mindustry.entities.type.EffectEntity;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.game.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.input.*;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.defense.ForceProjector.*;
@ -128,7 +129,7 @@ public class Renderer implements ApplicationListener{
}else{
camera.position.lerpDelta(position, 0.08f);
}
}else if(!mobile || settings.getBool("keyboard")){
}else if(control.input instanceof DesktopInput){
camera.position.lerpDelta(position, 0.08f);
}

View File

@ -567,7 +567,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
data.unlockContent(mech);
}
if(mobile && !Core.settings.getBool("keyboard")){
if(control.input instanceof MobileInput){
updateTouch();
}else{
updateKeyboard();
@ -723,50 +723,41 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
//update shooting if not building, not mining and there's ammo left
if(!isBuilding() && getMineTile() == null){
//autofire: mobile only!
if(mobile){
if(target == null){
isShooting = false;
if(Core.settings.getBool("autotarget")){
target = Units.closestTarget(team, x, y, getWeapon().bullet.range(), u -> u.getTeam() != Team.derelict, u -> u.getTeam() != Team.derelict);
//autofire
if(target == null){
isShooting = false;
if(Core.settings.getBool("autotarget")){
target = Units.closestTarget(team, x, y, getWeapon().bullet.range(), u -> u.getTeam() != Team.derelict, u -> u.getTeam() != Team.derelict);
if(mech.canHeal && target == null){
target = Geometry.findClosest(x, y, indexer.getDamaged(Team.sharded));
if(target != null && dst(target) > getWeapon().bullet.range()){
target = null;
}else if(target != null){
target = ((Tile)target).entity;
}
}
if(target != null){
setMineTile(null);
if(mech.canHeal && target == null){
target = Geometry.findClosest(x, y, indexer.getDamaged(Team.sharded));
if(target != null && dst(target) > getWeapon().bullet.range()){
target = null;
}else if(target != null){
target = ((Tile)target).entity;
}
}
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity)target).damaged() && target.getTeam() == team &&
mech.canHeal && dst(target) < getWeapon().bullet.range())){
//rotate toward and shoot the target
if(mech.turnCursor){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
if(target != null){
setMineTile(null);
}
Vector2 intercept = Predict.intercept(this, target, getWeapon().bullet.speed);
pointerX = intercept.x;
pointerY = intercept.y;
updateShooting();
isShooting = true;
}
}else if(target.isValid() || (target instanceof TileEntity && ((TileEntity)target).damaged() && target.getTeam() == team &&
mech.canHeal && dst(target) < getWeapon().bullet.range())){
//rotate toward and shoot the target
if(mech.turnCursor){
rotation = Mathf.slerpDelta(rotation, angleTo(target), 0.2f);
}
}else if(isShooting()){
Vector2 vec = Core.input.mouseWorld(control.input.getMouseX(),
control.input.getMouseY());
pointerX = vec.x;
pointerY = vec.y;
Vector2 intercept = Predict.intercept(this, target, getWeapon().bullet.speed);
pointerX = intercept.x;
pointerY = intercept.y;
updateShooting();
isShooting = true;
}
}
}

View File

@ -280,7 +280,7 @@ public class DesktopInput extends InputHandler{
}
@Override
public void updateController(){
public void updateState(){
if(state.is(State.menu)){
droppingItem = false;
mode = none;

View File

@ -132,7 +132,7 @@ public abstract class InputHandler implements InputProcessor{
}
public void updateController(){
public void updateState(){
}
@ -275,6 +275,10 @@ public abstract class InputHandler implements InputProcessor{
frag.remove();
}
public void add(){
Core.input.addProcessor(this);
}
public boolean canShoot(){
return block == null && !Core.scene.hasMouse() && !onConfigurable() && !isDroppingItem();
}

View File

@ -36,6 +36,7 @@ public class MobileInput extends InputHandler implements GestureListener{
//gesture data
private Vector2 vector = new Vector2();
private float lastZoom = -1;
private GestureDetector detector;
/** Position where the player started dragging a line. */
private int lineStartX, lineStartY;
@ -65,12 +66,6 @@ public class MobileInput extends InputHandler implements GestureListener{
private int prevX, prevY, prevRotation;
public MobileInput(){
Events.on(ClientLoadEvent.class, e -> {
Core.input.getInputProcessors().add(new GestureDetector(20, 0.5f, 0.4f, 0.15f, this));
});
}
//region utility methods
/** Check and assign targets for a specific position. */
@ -445,6 +440,20 @@ public class MobileInput extends InputHandler implements GestureListener{
//endregion
//region input events
@Override
public void add(){
super.add();
Core.input.addProcessor(detector = new GestureDetector(20, 0.5f, 0.4f, 0.15f, this));
}
@Override
public void remove(){
super.remove();
if(detector != null){
Core.input.removeProcessor(detector);
}
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, KeyCode button){
if(state.is(State.menu) || player.isDead()) return false;

View File

@ -13,13 +13,7 @@ public class ControlsDialog extends KeybindDialog{
setFillParent(true);
title.setAlignment(Align.center);
titleTable.row();
titleTable.add(new Image())
.growX().height(3f).pad(4f).get().setColor(Pal.accent);
if(Vars.mobile){
cont.row();
cont.add("$keybinds.mobile")
.center().growX().wrap().get().setAlignment(Align.center);
}
titleTable.add(new Image()).growX().height(3f).pad(4f).get().setColor(Pal.accent);
}
@Override

View File

@ -17,6 +17,7 @@ import io.anuke.mindustry.core.GameState.*;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.gen.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.input.*;
import io.anuke.mindustry.ui.*;
import static io.anuke.arc.Core.bundle;
@ -202,8 +203,20 @@ public class SettingsMenuDialog extends SettingsDialog{
game.screenshakePref();
if(mobile){
game.checkPref("autotarget", true);
game.checkPref("keyboard", false);
game.checkPref("keyboard", false, val -> control.setInput(val ? new DesktopInput() : new MobileInput()));
if(Core.settings.getBool("keyboard")){
control.setInput(new DesktopInput());
}
}
//the issue with touchscreen support on desktop is that:
//1) I can't test it
//2) the SDL backend doesn't support multitouch
/*else{
game.checkPref("touchscreen", false, val -> control.setInput(!val ? new DesktopInput() : new MobileInput()));
if(Core.settings.getBool("touchscreen")){
control.setInput(new MobileInput());
}
}*/
game.sliderPref("saveinterval", 60, 10, 5 * 120, i -> Core.bundle.format("setting.seconds", i));
if(!mobile){