Finished new placement controls

This commit is contained in:
Anuken
2017-12-15 20:28:11 -05:00
parent 6c5d74d7a5
commit 9c0d9f4e13
21 changed files with 407 additions and 296 deletions

View File

@ -12,6 +12,15 @@ _Keep in mind that this is just a basic outline of planned features, and will be
- 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 - Investigate #6
- Edit descriptions for conveyors to be more clear about how to use them
- Add link to Mindustry discord everywhere
### Major Bugs
- Black screen when tabbing out on Android
- Infinite explosions that destroy blocks
- Random map reload when playing, leading to a crash (UI cause?)
- Google Payments verify crash
- Google Payments IllegalArgument crash
### 4.0 Planned ### 4.0 Planned
- Multiplayer framework, possibly implementation - Multiplayer framework, possibly implementation

View File

@ -79,7 +79,7 @@ project(":core") {
apply plugin: "java" apply plugin: "java"
dependencies { dependencies {
compile 'com.github.Anuken:ucore:6eea0a3' compile 'com.github.Anuken:ucore:5984abc'
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"
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 77 KiB

View File

@ -9,7 +9,7 @@ import io.anuke.mindustry.entities.Player;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
public class Vars{ public class Vars{
public static final boolean testAndroid = true; public static final boolean testAndroid = false;
//shorthand for whether or not this is running on android //shorthand for whether or not this is running on android
public static final boolean android = (Gdx.app.getType() == ApplicationType.Android) || testAndroid; public static final boolean android = (Gdx.app.getType() == ApplicationType.Android) || testAndroid;
//shorthand for whether or not this is running on GWT //shorthand for whether or not this is running on GWT

View File

@ -421,6 +421,7 @@ public class Control extends Module{
public void update(){ public void update(){
if(debug){ if(debug){
//debug actions
if(Inputs.keyUp(Keys.P)){ if(Inputs.keyUp(Keys.P)){
Effects.effect(Fx.shellsmoke, player); Effects.effect(Fx.shellsmoke, player);
Effects.effect(Fx.shellexplosion, player); Effects.effect(Fx.shellexplosion, player);
@ -436,7 +437,10 @@ public class Control extends Module{
} }
if(Inputs.keyUp(Keys.C)){ if(Inputs.keyUp(Keys.C)){
GameState.set(State.playing); //crash cause:
//map is null.
//core is null.
//tiles are null.
} }
if(Inputs.keyUp(Keys.U)){ if(Inputs.keyUp(Keys.U)){
@ -452,7 +456,7 @@ public class Control extends Module{
new HealerEnemy().set(player.x, player.y).add(); new HealerEnemy().set(player.x, player.y).add();
}else{ }else{
float px = player.x, py = player.y; float px = player.x, py = player.y;
Timers.run(30f, ()->new BlastEnemy().set(px, py).add()); Timers.run(30f, ()-> new BlastEnemy().set(px, py).add());
} }
} }
} }

View File

@ -520,29 +520,32 @@ public class Renderer extends RendererModule{
int tilex = control.input.getBlockX(); int tilex = control.input.getBlockX();
int tiley = control.input.getBlockY(); int tiley = control.input.getBlockY();
//draw placement box
if((player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && (!ui.hasMouse() || android)
&& control.input.drawPlace()) || (player.placeMode.delete && Inputs.keyDown("area_delete_mode"))){
player.placeMode.draw(tilex, tiley, control.input.getBlockEndX(), control.input.getBlockEndY());
Draw.thickness(1f);
Draw.color(Color.SCARLET);
for(SpawnPoint spawn : control.getSpawnPoints()){
Draw.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
}
Draw.reset();
}
if(Vars.android){ if(Vars.android){
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); tilex = Mathf.scl2(vec.x, tilesize);
tiley = Mathf.scl2(vec.y, tilesize); tiley = Mathf.scl2(vec.y, tilesize);
} }
//draw placement box
if((player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && (!ui.hasMouse() || android)
&& control.input.drawPlace()) || (player.placeMode.delete && Inputs.keyDown("area_delete_mode"))){
player.placeMode.draw(control.input.getBlockX(), control.input.getBlockY(), control.input.getBlockEndX(), control.input.getBlockEndY());
Draw.thickness(1f);
Draw.color(Color.SCARLET);
for(SpawnPoint spawn : control.getSpawnPoints()){
Draw.dashCircle(spawn.start.worldx(), spawn.start.worldy(), enemyspawnspace);
}
PlaceMode.holdDelete.draw(tilex, tiley, 0, 0);
}else if(player.breakMode.delete && control.input.drawPlace()){
player.breakMode.draw(control.input.getBlockX(), control.input.getBlockY(),
control.input.getBlockEndX(), control.input.getBlockEndY());
}
PlaceMode.breaker.draw(tilex, tiley, 0, 0); Draw.reset();
//draw selected block health //draw selected block health
if(player.recipe == null && !ui.hasMouse()){ if(player.recipe == null && !ui.hasMouse()){

View File

@ -27,6 +27,7 @@ public class Player extends DestructibleEntity{
public transient Recipe recipe; public transient Recipe recipe;
public transient int rotation; public transient int rotation;
public transient PlaceMode placeMode = android ? PlaceMode.cursor : PlaceMode.hold; public transient PlaceMode placeMode = android ? PlaceMode.cursor : PlaceMode.hold;
public transient PlaceMode breakMode = PlaceMode.holdDelete;
public Player(){ public Player(){
hitbox.setSize(5); hitbox.setSize(5);

View File

@ -3,7 +3,6 @@ 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.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.input.GestureDetector; import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
@ -22,7 +21,7 @@ public class AndroidInput extends InputHandler{
public float lmousex, lmousey; public float lmousex, lmousey;
public float mousex, mousey; public float mousex, mousey;
public boolean brokeBlock = false; public boolean brokeBlock = false;
private boolean placing = true; private boolean placing = false;
private float warmup; private float warmup;
private float warmupDelay = 20; private float warmupDelay = 20;
@ -34,23 +33,19 @@ public class AndroidInput extends InputHandler{
@Override public float getCursorEndY(){ return Gdx.input.getY(0); } @Override public float getCursorEndY(){ return Gdx.input.getY(0); }
@Override public float getCursorX(){ return mousex; } @Override public float getCursorX(){ return mousex; }
@Override public float getCursorY(){ return mousey; } @Override public float getCursorY(){ return mousey; }
@Override public boolean drawPlace(){ return placing; } @Override public boolean drawPlace(){ return placing || (player.placeMode.pan && player.recipe != null); }
@Override
public boolean keyDown(int keycode){
if(keycode == Keys.E){
}
return false;
}
@Override @Override
public boolean touchUp(int screenX, int screenY, int pointer, int button){ public boolean touchUp(int screenX, int screenY, int pointer, int button){
//if(ui.hasMouse()) return false;
brokeBlock = false; brokeBlock = false;
if(placing && pointer == 0 && !player.placeMode.pan){ if(placing && pointer == 0 && !player.placeMode.pan){
player.placeMode.released(getBlockX(), getBlockY(), getBlockEndX(), getBlockEndY()); player.placeMode.released(getBlockX(), getBlockY(), getBlockEndX(), getBlockEndY());
placing = false; }else if(pointer == 0 && !player.breakMode.pan && player.recipe == null && drawPlace()){
player.breakMode.released(getBlockX(), getBlockY(), getBlockEndX(), getBlockEndY());
} }
placing = false;
return false; return false;
} }
@ -62,16 +57,15 @@ public class AndroidInput extends InputHandler{
lmousex = screenX; lmousex = screenX;
lmousey = screenY; lmousey = screenY;
if(!player.placeMode.pan){ if((!player.placeMode.pan || player.recipe == null) && pointer == 0){
if(pointer == 0){ mousex = screenX;
placing = true; mousey = screenY;
}
mousex = screenX;
mousey = screenY; if(pointer != 0){
placing = false;
}else{ }else{
placing = false; placing = true;
}
} }
warmup = 0; warmup = 0;

View File

@ -28,20 +28,27 @@ public class GestureHandler extends GestureAdapter{
@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(!player.placeMode.pan){ if(ui.hasMouse()) return false;
if(!player.placeMode.pan || player.recipe == null){
input.mousex = x; input.mousex = x;
input.mousey = y; input.mousey = y;
player.placeMode.tapped(input.getBlockX(), input.getBlockY());
if(player.recipe == null)
player.breakMode.tapped(input.getBlockX(), input.getBlockY());
else
player.placeMode.tapped(input.getBlockX(), input.getBlockY());
} }
return false; return false;
} }
@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) || !player.placeMode.lockCamera){ if(!(player.recipe != null && Vars.control.hasItems(player.recipe.requirements) && player.placeMode.lockCamera) &&
!(player.recipe == null && player.breakMode.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(player.placeMode.lockCamera){ }else if(player.placeMode.lockCamera && (player.placeMode.pan && player.recipe != null)){
input.mousex += deltaX; input.mousex += deltaX;
input.mousey += deltaY; input.mousey += deltaY;
} }

View File

@ -224,7 +224,7 @@ public abstract class InputHandler extends InputAdapter{
Vars.control.addItem(tile.block().drops.item, tile.block().drops.amount); Vars.control.addItem(tile.block().drops.item, tile.block().drops.amount);
} }
Effects.shake(3f, 1f, player); //Effects.shake(3f, 1f, player);
Sounds.play("break"); Sounds.play("break");
if(!tile.block().isMultiblock() && !tile.isLinked()){ if(!tile.block().isMultiblock() && !tile.isLinked()){

View File

@ -58,7 +58,6 @@ public enum PlaceMode{
} }
public void tapped(int tilex, int tiley){ public void tapped(int tilex, int tiley){
System.out.println("tap " + tilex + " " + tiley);
control.getInput().tryPlaceBlock(tilex, tiley); control.getInput().tryPlaceBlock(tilex, tiley);
} }
}, },
@ -74,6 +73,45 @@ public enum PlaceMode{
control.getInput().tryPlaceBlock(x, y); control.getInput().tryPlaceBlock(x, y);
} }
}, },
holdDelete{
{
delete = true;
shown = true;
}
public void draw(int tilex, int tiley, int endx, int endy){
Tile tile = world.tile(tilex, tiley);
if(tile != null && control.getInput().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(Colors.get("breakStart"), Colors.get("break"), fract);
Draw.polygon(25, tile.worldx() + offset.x, tile.worldy() + offset.y, 4 + (1f - fract) * 26);
}
Draw.reset();
}
}
},
touchDelete{
{
shown = true;
lockCamera = false;
showRotate = true;
showCancel = true;
delete = true;
}
public void tapped(int x, int y){
control.getInput().tryDeleteBlock(x, y);
}
},
areaDelete{ areaDelete{
int maxlen = 10; int maxlen = 10;
int tilex; int tilex;
@ -306,27 +344,6 @@ public enum PlaceMode{
this.tilex = tilex; this.tilex = tilex;
this.tiley = tiley; this.tiley = tiley;
} }
},
breaker{
public void draw(int tilex, int tiley, int endx, int endy){
Tile tile = world.tile(tilex, tiley);
if(tile != null && control.getInput().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(Colors.get("breakStart"), Colors.get("break"), fract);
Draw.polygon(25, tile.worldx() + offset.x, tile.worldy() + offset.y, 4 + (1f - fract) * 26);
}
Draw.reset();
}
}
}; };
public boolean lockCamera; public boolean lockCamera;
public boolean pan = false; public boolean pan = false;

View File

@ -2,6 +2,7 @@ package io.anuke.mindustry.ui.fragments;
import static io.anuke.mindustry.Vars.*; import static io.anuke.mindustry.Vars.*;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Align;
import io.anuke.mindustry.core.GameState; import io.anuke.mindustry.core.GameState;
@ -11,8 +12,10 @@ import io.anuke.ucore.scene.builders.imagebutton;
import io.anuke.ucore.scene.builders.table; import io.anuke.ucore.scene.builders.table;
import io.anuke.ucore.scene.event.Touchable; import io.anuke.ucore.scene.event.Touchable;
import io.anuke.ucore.scene.ui.ButtonGroup; import io.anuke.ucore.scene.ui.ButtonGroup;
import io.anuke.ucore.scene.ui.Image;
import io.anuke.ucore.scene.ui.ImageButton; import io.anuke.ucore.scene.ui.ImageButton;
import io.anuke.ucore.scene.ui.layout.Unit; import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Mathf;
public class PlacementFragment implements Fragment{ public class PlacementFragment implements Fragment{
@ -24,54 +27,91 @@ public class PlacementFragment implements Fragment{
abottom(); abottom();
aleft(); aleft();
Image image = new Image("icon-arrow");
image.setVisible(() -> player.recipe != null && player.recipe.result.rotate);
image.update(() -> {
image.setRotation(player.rotation*90);
image.setOrigin(Align.center);
});
new table("pane"){{ new table("pane"){{
get().setTouchable(Touchable.enabled); add(image).size(40f).units(Unit.dp);
//new label(()->"Placement Mode: [orange]" + player.placeMode.name()).pad(4).units(Unit.dp); }}.size(54f).units(Unit.dp).end();
//row();
row();
new table(){{
touchable(Touchable.enabled);
aleft(); aleft();
new table(){{ new table("pane"){{
get().pad(5);
aleft(); aleft();
ButtonGroup<ImageButton> group = new ButtonGroup<>(); ButtonGroup<ImageButton> group = new ButtonGroup<>();
defaults().size(52, 56).pad(0).units(Unit.dp); defaults().size(54, 58).pad(0).units(Unit.dp);
int d = 0;
for(PlaceMode mode : PlaceMode.values()){ for(PlaceMode mode : PlaceMode.values()){
if(!mode.shown) continue; if(!mode.shown || mode.delete) continue;
defaults().padBottom(-5.5f);
new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{ new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{
control.getInput().resetCursor(); control.getInput().resetCursor();
player.placeMode = mode; player.placeMode = mode;
}){{ }).group(group).units(Unit.dp);
group.add(get());
}}.padBottom(-5.5f).units(Unit.dp);
if(++d % 2 == 0){
row();
}
} }
row();
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 && player.placeMode.showCancel); }).imageColor(Color.valueOf("4d4d4d"))
.visible(()->player.recipe != null);
new imagebutton("icon-rotate-arrow", Unit.dp.inPixels(14*3), ()->{ new imagebutton("icon-rotate-left", Unit.dp.inPixels(14*3), ()->{
player.rotation ++; player.rotation = Mathf.mod(player.rotation + 1, 4);
player.rotation %= 4; }).imageColor(Color.valueOf("4d4d4d")).visible(() -> player.recipe != null);
}).update(i->{
i.getImage().setOrigin(Align.center); new imagebutton("icon-rotate-right", Unit.dp.inPixels(14*3), ()->{
i.getImage().setRotation(player.rotation*90); player.rotation = Mathf.mod(player.rotation - 1, 4);
}).visible(() -> player.recipe != null && player.placeMode.showRotate }).imageColor(Color.valueOf("4d4d4d")).visible(() -> player.recipe != null);
&& player.recipe.result.rotate);
}}.left().end(); }}.left().end();
}}.end(); }}.end();
}}.end(); }}.end();
new table(){{
visible(()->player.recipe == null && !GameState.is(State.menu));
abottom();
aleft();
new table("pane"){{
get().pad(5);
touchable(Touchable.enabled);
aleft();
ButtonGroup<ImageButton> group = new ButtonGroup<>();
defaults().size(54, 58).pad(0).units(Unit.dp);
int d = 0;
for(PlaceMode mode : PlaceMode.values()){
if(!mode.shown || !mode.delete) continue;
defaults().padBottom(d < 2 ? -5.5f : 0);
new imagebutton("icon-" + mode.name(), "toggle", Unit.dp.inPixels(10*3), ()->{
control.getInput().resetCursor();
player.breakMode = mode;
}){{
group.add(get());
}}.units(Unit.dp);
}
}}.end();
}}.end();
} }
} }
} }

View File

@ -144,7 +144,7 @@ public class Block{
* containers, it gets added to the block's inventory.*/ * containers, it gets added to the block's inventory.*/
protected void offloadNear(Tile tile, Item item){ protected void offloadNear(Tile tile, Item item){
byte i = tile.getDump(); byte i = tile.getDump();
byte pdump = i; byte pdump = (byte)(i % 4);
Tile[] tiles = tile.getNearby(); Tile[] tiles = tile.getNearby();

View File

@ -36,7 +36,7 @@ public class Router extends Block{
//TODO fix, check issue //TODO fix, check issue
tile.setRotation((byte)Mathf.mod(tile.getRotation(), 4)); tile.setRotation((byte)Mathf.mod(tile.getRotation(), 4));
if(tile.entity.timer.get(timerDump, 2) && tile.entity.totalItems() > 0){ if(tile.entity.totalItems() > 0){
if(tile.getExtra() != tile.getRotation() if(tile.getExtra() != tile.getRotation()
|| Mathf.chance(0.35)){ //sometimes dump backwards at a 1/4 chance... this somehow works? || Mathf.chance(0.35)){ //sometimes dump backwards at a 1/4 chance... this somehow works?
tryDump(tile, tile.getRotation(), null); tryDump(tile, tile.getRotation(), null);

View File

@ -38,6 +38,7 @@ public class Teleporter extends Block implements Configurable{
super(name); super(name);
update = true; update = true;
solid = true; solid = true;
health = 80;
} }
@Override @Override