Implemented local multiplayer fully

This commit is contained in:
Anuken
2018-05-13 20:48:44 -07:00
parent d1a3752b2d
commit ca24e64c42
14 changed files with 161 additions and 49 deletions

View File

@ -23,6 +23,7 @@ text.level.mode=Gamemode:
text.savegame=Save Game
text.loadgame=Load Game
text.joingame=Join Game
text.addplayers=Add/Remove Players
text.newgame=New Game
text.quit=Quit
text.about.button=About

View File

@ -166,9 +166,11 @@ public class Control extends Module{
InputHandler[] oldi = inputs;
inputs = new InputHandler[index + 1];
System.arraycopy(old, 0, inputs, 0, oldi.length);
System.arraycopy(oldi, 0, inputs, 0, oldi.length);
}
Player setTo = (index == 0 ? null : players[0]);
Player player = new Player();
player.name = Settings.getString("name");
player.mech = mobile ? Mechs.standardShip : Mechs.standard;
@ -177,6 +179,14 @@ public class Control extends Module{
player.playerIndex = index;
players[index] = player;
if(setTo != null){
player.set(setTo.x, setTo.y);
}
if(!state.is(State.menu)){
player.add();
}
InputHandler input;
if(mobile){
@ -189,6 +199,19 @@ public class Control extends Module{
Inputs.addProcessor(input);
}
public void removePlayer(){
players[players.length-1].remove();
inputs[inputs.length-1].remove();
Player[] old = players;
players = new Player[players.length - 1];
System.arraycopy(old, 0, players, 0, players.length);
InputHandler[] oldi = inputs;
inputs = new InputHandler[inputs.length - 1];
System.arraycopy(oldi, 0, inputs, 0, inputs.length);
}
public Input gdxInput(){
return gdxInput;
}

View File

@ -11,7 +11,6 @@ import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.BulletType;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.SyncEntity;
import io.anuke.mindustry.gen.CallEvent;
import io.anuke.mindustry.io.Platform;
import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.net.*;

View File

@ -52,6 +52,7 @@ public class UI extends SceneModule{
public AdminsDialog admins;
public TraceDialog traces;
public ChangelogDialog changelog;
public LocalPlayerDialog localplayers;
public final MenuFragment menufrag = new MenuFragment();
public final HudFragment hudfrag = new HudFragment();
@ -171,6 +172,7 @@ public class UI extends SceneModule{
bans = new BansDialog();
admins = new AdminsDialog();
traces = new TraceDialog();
localplayers = new LocalPlayerDialog();
build.begin(scene);

View File

@ -279,8 +279,10 @@ public class Player extends Unit{
movement.set(0, 0);
float xa = Inputs.getAxis("move_x");
float ya = Inputs.getAxis("move_y");
String section = "player_"+(playerIndex + 1);
float xa = Inputs.getAxis(section, "move_x");
float ya = Inputs.getAxis(section, "move_y");
if(Math.abs(xa) < 0.3) xa = 0;
if(Math.abs(ya) < 0.3) ya = 0;
@ -310,7 +312,7 @@ public class Player extends Unit{
rotation = Mathf.slerpDelta(rotation, movement.angle(), 0.13f);
}
}else{
float angle = Angles.mouseAngle(x, y);
float angle = control.input(playerIndex).mouseAngle(x, y);
this.rotation = Mathf.slerpDelta(this.rotation, angle, 0.1f);
}
}

View File

@ -74,7 +74,8 @@ public class OverlayRenderer {
//draw selected block bars and info
if (input.recipe == null && !ui.hasMouse() && !input.frag.config.isShown()) {
Tile tile = world.tileWorld(Graphics.mouseWorld().x, Graphics.mouseWorld().y);
Vector2 vec = Graphics.world(input.getMouseX(), input.getMouseY());
Tile tile = world.tileWorld(vec.x, vec.y);
if (tile != null && tile.block() != Blocks.air) {
Tile target = tile;
@ -134,7 +135,7 @@ public class OverlayRenderer {
}
if (input.isDroppingItem()) {
Vector2 v = Graphics.mouseWorld();
Vector2 v = Graphics.world(input.getMouseX(), input.getMouseY());
float size = 8;
Draw.rect(player.inventory.getItem().item.region, v.x, v.y, size, size);
Draw.color("accent");

View File

@ -16,7 +16,7 @@ public class DefaultKeybinds {
for(String section : sections) {
KeyBinds.defaultSection(section, DeviceType.keyboard,
new Category("General"),
new Category("General"),
"move_x", new Axis(Input.A, Input.D),
"move_y", new Axis(Input.S, Input.W),
"select", Input.MOUSE_LEFT,
@ -44,6 +44,7 @@ public class DefaultKeybinds {
);
KeyBinds.defaultSection(section, DeviceType.controller,
new Category("General"),
"move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS),
"move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS),
"cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS),
@ -51,13 +52,15 @@ public class DefaultKeybinds {
"select", Input.CONTROLLER_R_BUMPER,
"break", Input.CONTROLLER_L_BUMPER,
"shoot", Input.CONTROLLER_R_TRIGGER,
"dash", Input.CONTROLLER_Y,
"rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT),
"rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B),
new Category("View"),
"zoom_hold", Input.ANY_KEY,
"zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP),
"menu", Input.CONTROLLER_X,
"pause", Input.CONTROLLER_L_TRIGGER,
"dash", Input.CONTROLLER_Y,
"rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT),
"rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B),
new Category("Multiplayer"),
"player_list", Input.CONTROLLER_START
);

View File

@ -62,25 +62,26 @@ public class DesktopInput extends InputHandler{
if(Inputs.keyTap(section, "select") && recipe == null && player.inventory.hasItem()){
Vector2 vec = Graphics.screen(player.x, player.y);
if(vec.dst(Gdx.input.getX(), Gdx.graphics.getHeight() - Gdx.input.getY()) <= playerSelectRange){
if(vec.dst(getMouseX(), Gdx.graphics.getHeight() - getMouseY()) <= playerSelectRange){
canBeginShoot = false;
droppingItem = true;
}
}
if((Inputs.keyTap(section, "select") && recipe != null) || Inputs.keyTap(section, "break")){
Vector2 vec = Graphics.world(Gdx.input.getX(), Gdx.input.getY());
Vector2 vec = Graphics.world(getMouseX(), getMouseY());
mousex = vec.x;
mousey = vec.y;
}
if(!Inputs.keyDown(section, "select") && !Inputs.keyDown(section, "break")){
mousex = Graphics.mouseWorld().x;
mousey = Graphics.mouseWorld().y;
Vector2 vec = Graphics.world(getMouseX(), getMouseY());
mousex = vec.x;
mousey = vec.y;
}
endx = Gdx.input.getX();
endy = Gdx.input.getY();
endx = getMouseX();
endy = getMouseY();
boolean controller = KeyBinds.getSection(section).device.type == DeviceType.controller;
@ -229,11 +230,11 @@ public class DesktopInput extends InputHandler{
}
if(Inputs.keyTap(section,"select")){
Inputs.getProcessor().touchDown(Gdx.input.getX(), Gdx.input.getY(), player.playerIndex, Buttons.LEFT);
Inputs.getProcessor().touchDown((int)getMouseX(), (int)getMouseY(), player.playerIndex, Buttons.LEFT);
}
if(Inputs.keyRelease(section,"select")){
Inputs.getProcessor().touchUp(Gdx.input.getX(), Gdx.input.getY(), player.playerIndex, Buttons.LEFT);
Inputs.getProcessor().touchUp((int)getMouseX(), (int)getMouseY(), player.playerIndex, Buttons.LEFT);
}
float xa = Inputs.getAxis(section, "cursor_x");
@ -245,9 +246,11 @@ public class DesktopInput extends InputHandler{
controly -= ya*baseControllerSpeed*scl;
controlling = true;
Gdx.input.setCursorCatched(true);
if(index == 0){
Gdx.input.setCursorCatched(true);
}
Inputs.getProcessor().touchDragged(Gdx.input.getX(), Gdx.input.getY(), player.playerIndex);
Inputs.getProcessor().touchDragged((int)getMouseX(), (int)getMouseY(), player.playerIndex);
}
controlx = Mathf.clamp(controlx, 0, Gdx.graphics.getWidth());
@ -266,17 +269,12 @@ public class DesktopInput extends InputHandler{
public int tilex(){
return (recipe != null && recipe.result.isMultiblock() &&
recipe.result.size % 2 == 0) ?
Mathf.scl(Graphics.mouseWorld().x, tilesize) : Mathf.scl2(Graphics.mouseWorld().x, tilesize);
Mathf.scl(Graphics.world(getMouseX(), getMouseY()).x, tilesize) : Mathf.scl2(Graphics.world(getMouseX(), getMouseY()).x, tilesize);
}
public int tiley(){
return (recipe != null && recipe.result.isMultiblock() &&
recipe.result.size % 2 == 0) ?
Mathf.scl(Graphics.mouseWorld().y, tilesize) : Mathf.scl2(Graphics.mouseWorld().y, tilesize);
}
@Override
public boolean keyDown(int keycode) {
return super.keyDown(keycode);
Mathf.scl(Graphics.world(getMouseX(), getMouseY()).y, tilesize) : Mathf.scl2(Graphics.world(getMouseX(), getMouseY()).y, tilesize);
}
}

View File

@ -60,6 +60,10 @@ public abstract class InputHandler extends InputAdapter{
public void resetCursor(){}
public boolean isCursorVisible(){ return false; }
public float mouseAngle(float x, float y){
return Graphics.world(getMouseX(), getMouseY()).sub(x, y).angle();
}
public void remove(){
Inputs.removeProcessor(this);
frag.remove();

View File

@ -52,7 +52,8 @@ public class Weapon extends Upgrade{
p.timer.reset(t2, reload/2f);
}
tr.set(Graphics.mouseWorld()).sub(p.x, p.y);
tr.set(Graphics.world(Vars.control.input(p.playerIndex).getMouseX(),
Vars.control.input(p.playerIndex).getMouseY())).sub(p.x, p.y);
if(tr.len() < minPlayerDist) tr.setLength(minPlayerDist);
float cx = tr.x + p.x, cy = tr.y + p.y;

View File

@ -0,0 +1,59 @@
package io.anuke.mindustry.ui.dialogs;
import com.badlogic.gdx.utils.Scaling;
import static io.anuke.mindustry.Vars.*;
import io.anuke.mindustry.entities.Player;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.layout.Stack;
import io.anuke.ucore.scene.ui.layout.Table;
public class LocalPlayerDialog extends FloatingDialog{
public LocalPlayerDialog() {
super("$text.addplayers");
addCloseButton();
shown(this::rebuild);
}
private void rebuild(){
float size = 140f;
content().clear();
if(players.length > 1) {
content().addImageButton("icon-cancel", 14 * 2, () -> {
control.removePlayer();
rebuild();
}).size(50f, size).pad(5).bottom();
}else{
content().add().size(50f, size);
}
for(Player player : players){
Table table = new Table();
Stack stack = new Stack();
stack.add(new Image("button"));
Image img = new Image(Draw.region("icon-chat"));
img.setScaling(Scaling.fill);
stack.add(img);
table.add("Player " + (player.playerIndex + 1)).update(label -> label.setColor(player.color));
table.row();
table.add(stack).size(size);
content().add(table).pad(5);
}
if(players.length < 4) {
content().addImageButton("icon-add", 14 * 2, () -> {
control.addPlayer(players.length);
rebuild();
}).size(50f, size).pad(5).bottom();
}
}
}

View File

@ -54,6 +54,11 @@ public class PausedDialog extends FloatingDialog{
load.show();
}).disabled(b -> Net.active());
content().row();
content().addButton("$text.addplayers", () -> {
ui.localplayers.show();
}).disabled(b -> Net.active());
content().row();
if(!gwt) {

View File

@ -14,12 +14,11 @@ import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.ui.layout.Table;
public class BlockConfigFragment implements Fragment {
private Table table;
private Table table = new Table();
private Tile configTile;
@Override
public void build(Group parent) {
table = new Table();
parent.addChild(table);
}

View File

@ -8,6 +8,7 @@ import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntSet;
import io.anuke.mindustry.content.Recipes;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.input.InputHandler;
import io.anuke.mindustry.resource.Item;
import io.anuke.mindustry.resource.ItemStack;
@ -161,30 +162,44 @@ public class BlocksFragment implements Fragment{
}
});
image.clicked(() -> {
// note: input.recipe only gets set here during a click.
// during a hover only the visual description will be updated.
boolean nothingSelectedYet = input.recipe == null;
boolean selectedSomethingElse = !nothingSelectedYet && input.recipe != r;
boolean shouldMakeSelection = nothingSelectedYet || selectedSomethingElse;
if (shouldMakeSelection) {
input.recipe = r;
hoveredDescriptionRecipe = r;
updateRecipe(r);
} else {
input.recipe = null;
hoveredDescriptionRecipe = null;
updateRecipe(null);
}
});
image.addListener(new ClickListener(){
@Override
public void clicked(InputEvent event, float x, float y){
// note: input.recipe only gets set here during a click.
// during a hover only the visual description will be updated.
InputHandler handler = mobile ? input : control.input(event.getPointer());
boolean nothingSelectedYet = handler.recipe == null;
boolean selectedSomethingElse = !nothingSelectedYet && handler.recipe != r;
boolean shouldMakeSelection = nothingSelectedYet || selectedSomethingElse;
if (shouldMakeSelection) {
handler.recipe = r;
hoveredDescriptionRecipe = r;
updateRecipe(r);
} else {
handler.recipe = null;
hoveredDescriptionRecipe = null;
updateRecipe(null);
}
}
});
table.add(image).size(size + 8);
image.update(() -> {
boolean has = (state.inventory.hasItems(r.requirements));
image.setChecked(input.recipe == r);
image.setTouchable(Touchable.enabled);
for(Element e : istack.getChildren()) e.setColor(has ? Color.WHITE : Hue.lightness(0.33f));
for(Element e : istack.getChildren()){
e.setColor(has ? Color.WHITE : Hue.lightness(0.33f));
}
for(Player player : players){
if(control.input(player.playerIndex).recipe == r){
image.setChecked(true);
return;
}
}
image.setChecked(false);
});
if (i % rows == rows - 1)