Time.delta cleanup / Basic mobile input

This commit is contained in:
Anuken
2020-07-19 12:21:21 -04:00
parent f9ed74c15a
commit a074010eb7
91 changed files with 414 additions and 247 deletions

View File

@@ -186,7 +186,7 @@ public class DesktopInput extends InputHandler{
if(!(scene.getKeyboardFocus() instanceof TextField) && !scene.hasDialog()){
//move camera around
float camSpeed = !Core.input.keyDown(Binding.boost) ? 3f : 8f;
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed));
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta * camSpeed));
if(Core.input.keyDown(Binding.mouse_move)){
Core.camera.position.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2f) * 0.005f, -1, 1) * camSpeed;
@@ -592,17 +592,18 @@ public class DesktopInput extends InputHandler{
}else{
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
if(!movement.isZero() && legs){
unit.vel().rotateTo(movement.angle(), unit.type().rotateSpeed * Time.delta());
unit.vel.rotateTo(movement.angle(), unit.type().rotateSpeed * Time.delta);
}
}
unit.aim(unit.type().faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation(), Core.input.mouseWorld().dst(unit)).add(unit.x(), unit.y()));
unit.aim(unit.type().faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation, Core.input.mouseWorld().dst(unit)).add(unit.x, unit.y));
unit.controlWeapons(true, player.shooting && !boosted);
player.boosting = Core.input.keyDown(Binding.boost) && !movement.isZero();
player.mouseX = unit.aimX();
player.mouseY = unit.aimY();
//update payload input
if(unit instanceof Payloadc){
Payloadc pay = (Payloadc)unit;
@@ -611,7 +612,7 @@ public class DesktopInput extends InputHandler{
if(target != null){
Call.pickupUnitPayload(player, target);
}else if(!pay.hasPayload()){
Building tile = world.entWorld(pay.x(), pay.y());
Building tile = world.buildWorld(pay.x(), pay.y());
if(tile != null && tile.team() == unit.team){
Call.pickupBlockPayload(player, tile);
@@ -625,6 +626,7 @@ public class DesktopInput extends InputHandler{
}
}
//update commander inut
if(unit instanceof Commanderc){
if(Core.input.keyTap(Binding.command)){
Call.unitCommand(player);

View File

@@ -322,7 +322,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
if(controlledType != null){
Unit unit = Units.closest(player.team(), player.x, player.y, u -> !u.isPlayer() && u.type() == controlledType);
if(unit == null && controlledType == UnitTypes.block){
unit = world.entWorld(player.x, player.y) instanceof ControlBlock ? ((ControlBlock)world.entWorld(player.x, player.y)).unit() : null;
unit = world.buildWorld(player.x, player.y) instanceof ControlBlock ? ((ControlBlock)world.buildWorld(player.x, player.y)).unit() : null;
}
if(unit != null){
@@ -798,7 +798,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
Building entAt(float x, float y){
return world.ent(tileX(x), tileY(y));
return world.build(tileX(x), tileY(y));
}
/** Returns the tile at the specified MOUSE coordinates. */
@@ -856,7 +856,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
}
}
Building tile = world.entWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
Building tile = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
if(tile instanceof ControlBlock && tile.team() == player.team()){
return ((ControlBlock)tile).unit();
}

View File

@@ -1,7 +1,6 @@
package mindustry.input;
import arc.*;
import arc.struct.*;
import arc.func.*;
import arc.graphics.g2d.*;
import arc.input.GestureDetector.*;
@@ -11,15 +10,17 @@ import arc.math.geom.*;
import arc.scene.*;
import arc.scene.ui.ImageButton.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.entities.*;
import mindustry.gen.*;
import mindustry.entities.units.*;
import mindustry.game.EventType.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
import mindustry.ui.*;
import mindustry.world.*;
@@ -33,7 +34,7 @@ public class MobileInput extends InputHandler implements GestureListener{
private final float edgePan = Scl.scl(60f);
//gesture data
private Vec2 vector = new Vec2();
private Vec2 vector = new Vec2(), movement = new Vec2(), targetPos = new Vec2();
private float lastZoom = -1;
/** Position where the player started dragging a line. */
@@ -62,7 +63,7 @@ public class MobileInput extends InputHandler implements GestureListener{
/** Down tracking for panning.*/
private boolean down = false;
private Teamc target;
private Teamc target, moveTarget;
//region utility methods
@@ -74,16 +75,15 @@ public class MobileInput extends InputHandler implements GestureListener{
player.miner().mineTile(null);
target = unit;
}else{
Building tile = world.entWorld(x, y);
Building tile = world.buildWorld(x, y);
if(tile != null && player.team().isEnemy(tile.team())){
player.miner().mineTile(null);
target = tile;
//TODO implement healing
}//else if(tile != null && player.unit().canHeal && tile.entity != null && tile.team() == player.team() && tile.entity.damaged()){
/// player.miner().mineTile(null);
// target = tile.entity;
// }
}else if(tile != null && player.unit().type().canHeal && tile.team == player.team() && tile.damaged()){
player.miner().mineTile(null);
target = tile;
}
}
}
@@ -505,27 +505,40 @@ public class MobileInput extends InputHandler implements GestureListener{
@Override
public boolean longPress(float x, float y){
if(state.isMenu() || mode == none || player.dead()) return false;
if(state.isMenu()|| player.dead()) return false;
//get tile on cursor
Tile cursor = tileAt(x, y);
//ignore off-screen taps
if(cursor == null || Core.scene.hasMouse(x, y) || schematicMode) return false;
if(Core.scene.hasMouse(x, y) || schematicMode) return false;
//remove request if it's there
//long pressing enables line mode otherwise
lineStartX = cursor.x;
lineStartY = cursor.y;
lastLineX = cursor.x;
lastLineY = cursor.y;
lineMode = true;
//handle long tap when player isn't building
if(mode == none){
if(mode == breaking){
Fx.tapBlock.at(cursor.worldx(), cursor.worldy(), 1f);
}else if(block != null){
updateLine(lineStartX, lineStartY, cursor.x, cursor.y);
Fx.tapBlock.at(cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size);
//control a unit/block
Unit on = selectedUnit();
if(on != null){
Call.unitControl(player, on);
}
}else{
//ignore off-screen taps
if(cursor == null) return false;
//remove request if it's there
//long pressing enables line mode otherwise
lineStartX = cursor.x;
lineStartY = cursor.y;
lastLineX = cursor.x;
lastLineY = cursor.y;
lineMode = true;
if(mode == breaking){
Fx.tapBlock.at(cursor.worldx(), cursor.worldy(), 1f);
}else if(block != null){
updateLine(lineStartX, lineStartY, cursor.x, cursor.y);
Fx.tapBlock.at(cursor.worldx() + block.offset(), cursor.worldy() + block.offset(), block.size);
}
}
return false;
@@ -584,7 +597,7 @@ public class MobileInput extends InputHandler implements GestureListener{
if(!Core.settings.getBool("keyboard")){
//move camera around
float camSpeed = 6f;
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed));
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta * camSpeed));
}
if(Core.settings.getBool("keyboard")){
@@ -597,6 +610,10 @@ public class MobileInput extends InputHandler implements GestureListener{
}
}
if(!player.dead() && !state.isPaused()){
updateMovement(player.unit());
}
//reset state when not placing
if(mode == none){
lineMode = false;
@@ -755,5 +772,137 @@ public class MobileInput extends InputHandler implements GestureListener{
return true;
}
//endregion
//region movement
protected void updateMovement(Unit unit){
Rect rect = Tmp.r3;
UnitType type = unit.type();
boolean flying = type.flying;
boolean omni = !(unit instanceof WaterMovec);
boolean legs = unit.isGrounded();
boolean allowHealing = type.canHeal;
boolean validHealTarget = allowHealing && target instanceof Building && ((Building)target).isValid() && target.team() == unit.team &&
((Building)target).damaged() && target.within(unit, type.range);
boolean boosted = (unit instanceof Mechc && unit.isFlying());
//reset target if:
// - in the editor, or...
// - it's both an invalid standard target and an invalid heal target
if((Units.invalidateTarget(target, unit, type.range) && !validHealTarget) || state.isEditor()){
target = null;
}
targetPos.set(Core.camera.position);
float attractDst = 15f;
float strafePenalty = legs ? 1f : Mathf.lerp(1f, type.strafePenalty, Angles.angleDist(unit.vel.angle(), unit.rotation) / 180f);
float speed = type.speed * Mathf.lerp(1f, type.canBoost ? type.boostMultiplier : 1f, unit.elevation()) * strafePenalty;
float range = unit.hasWeapons() ? unit.range() : 0f;
float bulletSpeed = unit.hasWeapons() ? type.weapons.first().bullet.speed : 0f;
float mouseAngle = unit.angleTo(unit.aimX(), unit.aimY());
boolean aimCursor = omni && player.shooting && type.hasWeapons() && type.faceTarget && !boosted && type.rotateShooting;
if(aimCursor){
unit.lookAt(mouseAngle);
}else{
if(unit.moving()){
unit.lookAt(unit.vel.angle());
}
}
if(moveTarget != null){
targetPos.set(moveTarget);
attractDst = 0f;
if(unit.within(moveTarget, 2f * Time.delta)){
handleTapTarget(moveTarget);
moveTarget = null;
}
}
movement.set(targetPos).sub(player).limit(speed);
movement.setAngle(Mathf.slerp(movement.angle(), unit.vel.angle(), 0.05f));
//pathfind for ground units
if(!flying && !type.canBoost && !(unit instanceof WaterMovec)){
Tile on = unit.tileOn();
if(on != null && !on.solid()){
Tile to = pathfinder.getTargetTile(unit.tileOn(), unit.team, targetPos);
if(to != null){
movement.set(to).sub(unit).setLength(speed);
}
}
}
if(player.within(targetPos, attractDst)){
movement.setZero();
}
float expansion = 3f;
unit.hitbox(rect);
rect.x -= expansion;
rect.y -= expansion;
rect.width += expansion * 2f;
rect.height += expansion * 2f;
player.boosting = collisions.overlapsTile(rect) || !unit.within(targetPos, 85f);
if(omni){
unit.moveAt(movement);
}else{
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
if(!movement.isZero() && legs){
unit.vel.rotateTo(movement.angle(), type.rotateSpeed * Time.delta);
}
}
if(flying){
//hovering effect
unit.x += Mathf.sin(Time.time(), 25f, 0.08f);
unit.y += Mathf.cos(Time.time(), 25f, 0.08f);
}
//update shooting if not building + not mining
if(!player.builder().isBuilding() && player.miner().mineTile() == null){
//autofire
if(target == null){
player.shooting = false;
if(Core.settings.getBool("autotarget")){
target = Units.closestTarget(unit.team, unit.x, unit.y, range, u -> u.team != Team.derelict, u -> u.team != Team.derelict);
if(allowHealing && target == null){
target = Geometry.findClosest(unit.x, unit.y, indexer.getDamaged(Team.sharded));
if(target != null && !unit.within(target, range)){
target = null;
}
}
if(target != null && player.isMiner()){
player.miner().mineTile(null);
}
}
}else{
Vec2 intercept = Predict.intercept(unit, target, bulletSpeed);
player.mouseX = intercept.x;
player.mouseY = intercept.y;
player.shooting = true;
unit.aim(player.mouseX, player.mouseY);
}
}
unit.controlWeapons(player.shooting && !boosted);
}
protected void handleTapTarget(Teamc target){
}
//endregion
}