mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-13 12:16:53 +07:00
Implemented block breaking on Android
This commit is contained in:
parent
24e7d755eb
commit
13b0c8880d
BIN
core/assets-raw/sprites/ui/icons/icon-break.png
Normal file
BIN
core/assets-raw/sprites/ui/icons/icon-break.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 224 B |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 110 KiB |
@ -24,7 +24,7 @@ import io.anuke.ucore.util.OS;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class Vars{
|
public class Vars{
|
||||||
public static final boolean testMobile = false;
|
public static final boolean testMobile = true;
|
||||||
//shorthand for whether or not this is running on android or ios
|
//shorthand for whether or not this is running on android or ios
|
||||||
public static boolean mobile;
|
public static boolean mobile;
|
||||||
public static boolean ios;
|
public static boolean ios;
|
||||||
|
@ -61,9 +61,11 @@ public class Control extends Module{
|
|||||||
Core.atlas = new Atlas("sprites.atlas");
|
Core.atlas = new Atlas("sprites.atlas");
|
||||||
|
|
||||||
for(Item item : Item.all()){
|
for(Item item : Item.all()){
|
||||||
item.init();
|
item.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.load();
|
||||||
|
|
||||||
gdxInput = Gdx.input;
|
gdxInput = Gdx.input;
|
||||||
|
|
||||||
proxy = new InputProxy(Gdx.input){
|
proxy = new InputProxy(Gdx.input){
|
||||||
@ -337,8 +339,14 @@ public class Control extends Module{
|
|||||||
input.update();
|
input.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Timers.get("timerCheckUnlock", 60)){
|
//check unlocks every 2 seconds
|
||||||
|
if(Timers.get("timerCheckUnlock", 120)){
|
||||||
checkUnlockableBlocks();
|
checkUnlockableBlocks();
|
||||||
|
|
||||||
|
//save if the db changed
|
||||||
|
if(db.isDirty()){
|
||||||
|
db.save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Inputs.keyTap("pause") && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){
|
if(Inputs.keyTap("pause") && !ui.restart.isShown() && (state.is(State.paused) || state.is(State.playing))){
|
||||||
|
@ -30,7 +30,7 @@ public class Units {
|
|||||||
|
|
||||||
Units.getNearby(rect, unit -> {
|
Units.getNearby(rect, unit -> {
|
||||||
if(value[0]) return;
|
if(value[0]) return;
|
||||||
if(unit.hitbox.getRect(unit.x, unit.y).overlaps(rect)){
|
if(!unit.isFlying() && unit.hitbox.getRect(unit.x, unit.y).overlaps(rect)){
|
||||||
value[0] = true;
|
value[0] = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,10 @@ import io.anuke.ucore.core.Events;
|
|||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
|
|
||||||
public class ContentDatabase {
|
public class ContentDatabase {
|
||||||
|
/**Maps unlockable type names to a set of unlocked content.*/
|
||||||
private ObjectMap<String, ObjectSet<String>> unlocked = new ObjectMap<>();
|
private ObjectMap<String, ObjectSet<String>> unlocked = new ObjectMap<>();
|
||||||
|
/**Whether unlockables have changed since the last save.*/
|
||||||
|
private boolean dirty;
|
||||||
|
|
||||||
/**Returns whether or not this piece of content is unlocked yet.*/
|
/**Returns whether or not this piece of content is unlocked yet.*/
|
||||||
public boolean isUnlocked(Content content){
|
public boolean isUnlocked(Content content){
|
||||||
@ -36,14 +39,24 @@ public class ContentDatabase {
|
|||||||
//fire unlock event so other classes can use it
|
//fire unlock event so other classes can use it
|
||||||
if(ret){
|
if(ret){
|
||||||
Events.fire(UnlockEvent.class, content);
|
Events.fire(UnlockEvent.class, content);
|
||||||
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//saving/loading currently disabled for testing.
|
/**Returns whether unlockables have changed since the last save.*/
|
||||||
|
public boolean isDirty(){
|
||||||
|
return dirty;
|
||||||
|
}
|
||||||
|
|
||||||
private void load(){
|
/**Clears all unlocked content.*/
|
||||||
|
public void reset(){
|
||||||
|
unlocked.clear();
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(){
|
||||||
ObjectMap<String, Array<String>> result = Settings.getJson("content-database", ObjectMap.class);
|
ObjectMap<String, Array<String>> result = Settings.getJson("content-database", ObjectMap.class);
|
||||||
|
|
||||||
for(Entry<String, Array<String>> entry : result.entries()){
|
for(Entry<String, Array<String>> entry : result.entries()){
|
||||||
@ -51,9 +64,12 @@ public class ContentDatabase {
|
|||||||
set.addAll(entry.value);
|
set.addAll(entry.value);
|
||||||
unlocked.put(entry.key, set);
|
unlocked.put(entry.key, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void save(){
|
public void save(){
|
||||||
|
|
||||||
ObjectMap<String, Array<String>> write = new ObjectMap<>();
|
ObjectMap<String, Array<String>> write = new ObjectMap<>();
|
||||||
|
|
||||||
for(Entry<String, ObjectSet<String>> entry : unlocked.entries()){
|
for(Entry<String, ObjectSet<String>> entry : unlocked.entries()){
|
||||||
@ -61,6 +77,8 @@ public class ContentDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Settings.putJson("content-database", write);
|
Settings.putJson("content-database", write);
|
||||||
|
Settings.save();
|
||||||
|
dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import com.badlogic.gdx.math.Rectangle;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import io.anuke.mindustry.content.blocks.Blocks;
|
||||||
import io.anuke.mindustry.content.fx.Fx;
|
import io.anuke.mindustry.content.fx.Fx;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
@ -32,7 +33,7 @@ import io.anuke.ucore.scene.ui.layout.Unit;
|
|||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
import static io.anuke.mindustry.Vars.*;
|
||||||
import static io.anuke.mindustry.input.PlaceMode.none;
|
import static io.anuke.mindustry.input.PlaceMode.*;
|
||||||
|
|
||||||
public class AndroidInput extends InputHandler implements GestureListener{
|
public class AndroidInput extends InputHandler implements GestureListener{
|
||||||
private static Rectangle r1 = new Rectangle(), r2 = new Rectangle();
|
private static Rectangle r1 = new Rectangle(), r2 = new Rectangle();
|
||||||
@ -55,7 +56,7 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
private float lineScale;
|
private float lineScale;
|
||||||
|
|
||||||
/**List of currently selected tiles to place.*/
|
/**List of currently selected tiles to place.*/
|
||||||
private Array<PlaceRequest> placement = new Array<>();
|
private Array<PlaceRequest> selection = new Array<>();
|
||||||
/**Place requests to be removed.*/
|
/**Place requests to be removed.*/
|
||||||
private Array<PlaceRequest> removals = new Array<>();
|
private Array<PlaceRequest> removals = new Array<>();
|
||||||
/**Whether or not the player is currently shifting all placed tiles.*/
|
/**Whether or not the player is currently shifting all placed tiles.*/
|
||||||
@ -64,6 +65,8 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
private boolean lineMode;
|
private boolean lineMode;
|
||||||
/**Current place mode.*/
|
/**Current place mode.*/
|
||||||
private PlaceMode mode = none;
|
private PlaceMode mode = none;
|
||||||
|
/**Whether no recipe was available when switching to break mode.*/
|
||||||
|
private Recipe lastRecipe;
|
||||||
|
|
||||||
public AndroidInput(Player player){
|
public AndroidInput(Player player){
|
||||||
super(player);
|
super(player);
|
||||||
@ -75,15 +78,15 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
return getRequest(tile) != null;
|
return getRequest(tile) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Returns whether this block overlaps any placement requests.*/
|
/**Returns whether this block overlaps any selection requests.*/
|
||||||
boolean checkOverlapPlacement(int x, int y, Block block){
|
boolean checkOverlapPlacement(int x, int y, Block block){
|
||||||
r2.setSize(block.size * tilesize);
|
r2.setSize(block.size * tilesize);
|
||||||
r2.setCenter(x * tilesize + block.offset(), y * tilesize + block.offset());
|
r2.setCenter(x * tilesize + block.offset(), y * tilesize + block.offset());
|
||||||
|
|
||||||
for(PlaceRequest req : placement){
|
for(PlaceRequest req : selection){
|
||||||
Tile other = req.tile();
|
Tile other = req.tile();
|
||||||
|
|
||||||
if(other == null) continue;
|
if(other == null || req.remove) continue;
|
||||||
|
|
||||||
r1.setSize(req.recipe.result.size * tilesize);
|
r1.setSize(req.recipe.result.size * tilesize);
|
||||||
r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset());
|
r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset());
|
||||||
@ -95,44 +98,61 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Returns the placement request that overlaps this tile, or null.*/
|
/**Returns the selection request that overlaps this tile, or null.*/
|
||||||
PlaceRequest getRequest(Tile tile){
|
PlaceRequest getRequest(Tile tile){
|
||||||
r2.setSize(tilesize);
|
r2.setSize(tilesize);
|
||||||
r2.setCenter(tile.worldx(), tile.worldy());
|
r2.setCenter(tile.worldx(), tile.worldy());
|
||||||
|
|
||||||
for(PlaceRequest req : placement){
|
for(PlaceRequest req : selection){
|
||||||
Tile other = req.tile();
|
Tile other = req.tile();
|
||||||
|
|
||||||
if(other == null) continue;
|
if(other == null) continue;
|
||||||
|
|
||||||
r1.setSize(req.recipe.result.size * tilesize);
|
if(!req.remove){
|
||||||
r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset());
|
r1.setSize(req.recipe.result.size * tilesize);
|
||||||
|
r1.setCenter(other.worldx() + req.recipe.result.offset(), other.worldy() + req.recipe.result.offset());
|
||||||
|
|
||||||
if(r2.overlaps(r1)){
|
if (r2.overlaps(r1)) {
|
||||||
return req;
|
return req;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
|
||||||
|
r1.setSize(other.block().size * tilesize);
|
||||||
|
r1.setCenter(other.worldx() + other.block().offset(), other.worldy() + other.block().offset());
|
||||||
|
|
||||||
|
if (r2.overlaps(r1)) {
|
||||||
|
return req;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeRequest(PlaceRequest request){
|
void removeRequest(PlaceRequest request){
|
||||||
placement.removeValue(request, true);
|
selection.removeValue(request, true);
|
||||||
removals.add(request);
|
removals.add(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawRequest(PlaceRequest request){
|
void drawRequest(PlaceRequest request){
|
||||||
Tile tile = request.tile();
|
Tile tile = request.tile();
|
||||||
|
|
||||||
float offset = request.recipe.result.offset();
|
if(!request.remove) {
|
||||||
TextureRegion[] regions = request.recipe.result.getBlockIcon();
|
//draw placing request
|
||||||
|
float offset = request.recipe.result.offset();
|
||||||
|
TextureRegion[] regions = request.recipe.result.getBlockIcon();
|
||||||
|
|
||||||
Draw.alpha(Mathf.clamp((1f - request.scale) / 0.5f));
|
Draw.alpha(Mathf.clamp((1f - request.scale) / 0.5f));
|
||||||
Draw.tint(Color.WHITE, Palette.breakInvalid, request.redness);
|
Draw.tint(Color.WHITE, Palette.breakInvalid, request.redness);
|
||||||
|
|
||||||
for(TextureRegion region : regions){
|
for (TextureRegion region : regions) {
|
||||||
Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset,
|
Draw.rect(region, tile.worldx() + offset, tile.worldy() + offset,
|
||||||
region.getRegionWidth() * request.scale, region.getRegionHeight() * request.scale,
|
region.getRegionWidth() * request.scale, region.getRegionHeight() * request.scale,
|
||||||
request.recipe.result.rotate ? request.rotation * 90 : 0);
|
request.recipe.result.rotate ? request.rotation * 90 : 0);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Draw.color(Palette.remove);
|
||||||
|
//draw removing request
|
||||||
|
Lines.poly(tile.drawx(), tile.drawy(), 4, tile.block().size * tilesize/2f * request.scale, 45 + 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,29 +163,47 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
new table(){{
|
new table(){{
|
||||||
abottom().aleft();
|
abottom().aleft();
|
||||||
|
|
||||||
|
new table("pane"){{
|
||||||
|
margin(5);
|
||||||
|
defaults().size(60f);
|
||||||
|
|
||||||
|
//Add a break button.
|
||||||
|
new imagebutton("icon-break", "toggle", 16 * 2f, () -> {
|
||||||
|
mode = mode == breaking ? recipe == null ? none : placing : breaking;
|
||||||
|
lastRecipe = recipe;
|
||||||
|
}).update(l -> l.setChecked(mode == breaking));
|
||||||
|
}}.end();
|
||||||
|
|
||||||
new table("pane"){{
|
new table("pane"){{
|
||||||
margin(5);
|
margin(5);
|
||||||
defaults().size(60f);
|
defaults().size(60f);
|
||||||
|
|
||||||
//Add a cancel button, which clears the selection.
|
//Add a cancel button, which clears the selection.
|
||||||
new imagebutton("icon-cancel", 16 * 2f, () -> recipe = null);
|
new imagebutton("icon-cancel", 16 * 2f, () -> selection.clear())
|
||||||
|
.cell.disabled(i -> selection.size == 0);
|
||||||
|
|
||||||
//Add an accept button, which places everything.
|
//Add an accept button, which places everything.
|
||||||
new imagebutton("icon-check", 16 * 2f, () -> {
|
new imagebutton("icon-check", 16 * 2f, () -> {
|
||||||
for (PlaceRequest request : placement) {
|
for (PlaceRequest request : selection) {
|
||||||
Tile tile = request.tile();
|
Tile tile = request.tile();
|
||||||
|
|
||||||
|
//actually place/break all selected blocks
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
rotation = request.rotation;
|
if(!request.remove) {
|
||||||
recipe = request.recipe;
|
rotation = request.rotation;
|
||||||
tryPlaceBlock(tile.x, tile.y);
|
recipe = request.recipe;
|
||||||
|
tryPlaceBlock(tile.x, tile.y);
|
||||||
|
}else{
|
||||||
|
tryBreakBlock(tile.x, tile.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removals.addAll(placement);
|
//move all current requests to removal array to they fade out
|
||||||
placement.clear();
|
removals.addAll(selection);
|
||||||
|
selection.clear();
|
||||||
selecting = false;
|
selecting = false;
|
||||||
}).cell.disabled(i -> placement.size == 0);
|
}).cell.disabled(i -> selection.size == 0);
|
||||||
|
|
||||||
//Add a rotate button
|
//Add a rotate button
|
||||||
new imagebutton("icon-arrow", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4))
|
new imagebutton("icon-arrow", 16 * 2f, () -> rotation = Mathf.mod(rotation + 1, 4))
|
||||||
@ -173,8 +211,8 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
i.getImage().setRotation(rotation * 90);
|
i.getImage().setRotation(rotation * 90);
|
||||||
i.getImage().setOrigin(Align.center);
|
i.getImage().setOrigin(Align.center);
|
||||||
}).cell.disabled(i -> recipe == null || !recipe.result.rotate);
|
}).cell.disabled(i -> recipe == null || !recipe.result.rotate);
|
||||||
}}.end();
|
}}.visible(() -> mode != none).end();
|
||||||
}}.visible(this::isPlacing).end();
|
}}.visible(() -> !state.is(State.menu)).end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -196,19 +234,21 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//draw normals
|
//draw normals
|
||||||
for(PlaceRequest request : placement){
|
for(PlaceRequest request : selection){
|
||||||
Tile tile = request.tile();
|
Tile tile = request.tile();
|
||||||
|
|
||||||
if(tile == null) continue;
|
if(tile == null) continue;
|
||||||
|
|
||||||
if(validPlace(tile.x, tile.y, request.recipe.result, request.rotation)){
|
if ((!request.remove && validPlace(tile.x, tile.y, request.recipe.result, request.rotation))
|
||||||
|
|| (request.remove && validBreak(tile.x, tile.y))) {
|
||||||
request.scale = Mathf.lerpDelta(request.scale, 1f, 0.2f);
|
request.scale = Mathf.lerpDelta(request.scale, 1f, 0.2f);
|
||||||
request.redness = Mathf.lerpDelta(request.redness, 0f, 0.2f);
|
request.redness = Mathf.lerpDelta(request.redness, 0f, 0.2f);
|
||||||
}else{
|
} else {
|
||||||
request.scale = Mathf.lerpDelta(request.scale, 0.5f, 0.1f);
|
request.scale = Mathf.lerpDelta(request.scale, 0.5f, 0.1f);
|
||||||
request.redness = Mathf.lerpDelta(request.redness, 1f, 0.2f);
|
request.redness = Mathf.lerpDelta(request.redness, 1f, 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
drawRequest(request);
|
drawRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,30 +261,57 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
Tile tile = tileAt(control.gdxInput().getX(), control.gdxInput().getY());
|
Tile tile = tileAt(control.gdxInput().getX(), control.gdxInput().getY());
|
||||||
|
|
||||||
if(tile != null){
|
if(tile != null){
|
||||||
NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tile.x, tile.y, true, maxLength, lineScale);
|
|
||||||
|
|
||||||
Lines.rect(dresult.x, dresult.y, dresult.x2 - dresult.x, dresult.y2 - dresult.y);
|
//draw placing
|
||||||
|
if(mode == placing) {
|
||||||
|
NormalizeDrawResult dresult = PlaceUtils.normalizeDrawArea(recipe.result, lineStartX, lineStartY, tile.x, tile.y, true, maxLength, lineScale);
|
||||||
|
|
||||||
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, maxLength);
|
Lines.rect(dresult.x, dresult.y, dresult.x2 - dresult.x, dresult.y2 - dresult.y);
|
||||||
|
|
||||||
//go through each cell and draw the block to place if valid
|
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, maxLength);
|
||||||
for(int i = 0; i <= result.getLength(); i += recipe.result.size){
|
|
||||||
int x = lineStartX + i * Mathf.sign(tile.x - lineStartX) * Mathf.bool(result.isX());
|
|
||||||
int y = lineStartY + i * Mathf.sign(tile.y - lineStartY) * Mathf.bool(!result.isX());
|
|
||||||
|
|
||||||
if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){
|
//go through each cell and draw the block to place if valid
|
||||||
Draw.color();
|
for (int i = 0; i <= result.getLength(); i += recipe.result.size) {
|
||||||
|
int x = lineStartX + i * Mathf.sign(tile.x - lineStartX) * Mathf.bool(result.isX());
|
||||||
|
int y = lineStartY + i * Mathf.sign(tile.y - lineStartY) * Mathf.bool(!result.isX());
|
||||||
|
|
||||||
TextureRegion[] regions = recipe.result.getBlockIcon();
|
if (!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)) {
|
||||||
|
Draw.color();
|
||||||
|
|
||||||
for(TextureRegion region : regions){
|
TextureRegion[] regions = recipe.result.getBlockIcon();
|
||||||
Draw.rect(region, x *tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(),
|
|
||||||
region.getRegionWidth() * lineScale, region.getRegionHeight() * lineScale, recipe.result.rotate ? result.rotation * 90 : 0);
|
for (TextureRegion region : regions) {
|
||||||
|
Draw.rect(region, x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(),
|
||||||
|
region.getRegionWidth() * lineScale, region.getRegionHeight() * lineScale, recipe.result.rotate ? result.rotation * 90 : 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Draw.color(Palette.breakInvalid);
|
||||||
|
Lines.square(x * tilesize + recipe.result.offset(), y * tilesize + recipe.result.offset(), recipe.result.size * tilesize / 2f);
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
Draw.color(Palette.breakInvalid);
|
|
||||||
Lines.square(x*tilesize + recipe.result.offset(), y*tilesize + recipe.result.offset(), recipe.result.size * tilesize/2f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}else if(mode == breaking){
|
||||||
|
//draw breaking
|
||||||
|
NormalizeDrawResult result = PlaceUtils.normalizeDrawArea(Blocks.air, lineStartX, lineStartY, tile.x, tile.y, false, maxLength, 1f);
|
||||||
|
NormalizeResult dresult = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, false, maxLength);
|
||||||
|
|
||||||
|
Draw.color(Palette.remove);
|
||||||
|
|
||||||
|
Draw.alpha(0.6f);
|
||||||
|
Draw.alpha(1f);
|
||||||
|
|
||||||
|
for(int x = dresult.x; x <= dresult.x2; x ++){
|
||||||
|
for(int y = dresult.y; y <= dresult.y2; y ++){
|
||||||
|
Tile other = world.tile(x, y);
|
||||||
|
if(other == null || !validBreak(other.x, other.y)) continue;
|
||||||
|
other = other.target();
|
||||||
|
|
||||||
|
Lines.poly(other.drawx(), other.drawy(), 4, other.block().size * tilesize/2f, 45 + 15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Lines.rect(result.x, result.y, result.x2 - result.x, result.y2 - result.y);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,10 +330,10 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
if(cursor == null || ui.hasMouse(screenX, screenY)) return false;
|
if(cursor == null || ui.hasMouse(screenX, screenY)) return false;
|
||||||
|
|
||||||
//only begin selecting if the tapped block is a request
|
//only begin selecting if the tapped block is a request
|
||||||
selecting = hasRequest(cursor) && isPlacing();
|
selecting = hasRequest(cursor) && isPlacing() && mode == placing;
|
||||||
|
|
||||||
//call tap events
|
//call tap events
|
||||||
if(pointer == 0 && !selecting){
|
if(pointer == 0 && !selecting && mode == none){
|
||||||
tileTapped(cursor.target());
|
tileTapped(cursor.target());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,22 +347,49 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
if(lineMode) {
|
if(lineMode) {
|
||||||
Tile tile = tileAt(screenX, screenY);
|
Tile tile = tileAt(screenX, screenY);
|
||||||
|
|
||||||
if(tile == null) return false;
|
if (tile == null) return false;
|
||||||
|
|
||||||
//normalize area
|
if(mode == placing) {
|
||||||
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, 100);
|
|
||||||
|
|
||||||
rotation = result.rotation;
|
//normalize area
|
||||||
|
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, true, 100);
|
||||||
|
|
||||||
//place blocks on line
|
rotation = result.rotation;
|
||||||
for(int i = 0; i <= result.getLength(); i += recipe.result.size){
|
|
||||||
int x = lineStartX + i * Mathf.sign(tile.x - lineStartX) * Mathf.bool(result.isX());
|
|
||||||
int y = lineStartY + i * Mathf.sign(tile.y - lineStartY) * Mathf.bool(!result.isX());
|
|
||||||
|
|
||||||
if(!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)){
|
//place blocks on line
|
||||||
PlaceRequest request = new PlaceRequest(x * tilesize, y * tilesize, recipe, result.rotation);
|
for (int i = 0; i <= result.getLength(); i += recipe.result.size) {
|
||||||
request.scale = 1f;
|
int x = lineStartX + i * Mathf.sign(tile.x - lineStartX) * Mathf.bool(result.isX());
|
||||||
placement.add(request);
|
int y = lineStartY + i * Mathf.sign(tile.y - lineStartY) * Mathf.bool(!result.isX());
|
||||||
|
|
||||||
|
if (!checkOverlapPlacement(x, y, recipe.result) && validPlace(x, y, recipe.result, result.rotation)) {
|
||||||
|
PlaceRequest request = new PlaceRequest(x * tilesize, y * tilesize, recipe, result.rotation);
|
||||||
|
request.scale = 1f;
|
||||||
|
selection.add(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else if(mode == breaking){
|
||||||
|
//normalize area
|
||||||
|
NormalizeResult result = PlaceUtils.normalizeArea(lineStartX, lineStartY, tile.x, tile.y, rotation, false, maxLength);
|
||||||
|
|
||||||
|
//break everything in area
|
||||||
|
for(int x = 0; x <= Math.abs(result.x2 - result.x); x ++ ){
|
||||||
|
for(int y = 0; y <= Math.abs(result.y2 - result.y); y ++){
|
||||||
|
int wx = lineStartX + x * Mathf.sign(tile.x - lineStartX);
|
||||||
|
int wy = lineStartY + y * Mathf.sign(tile.y - lineStartY);
|
||||||
|
|
||||||
|
Tile tar = world.tile(wx, wy);
|
||||||
|
|
||||||
|
if(tar == null) continue;
|
||||||
|
|
||||||
|
tar = tar.target();
|
||||||
|
|
||||||
|
if (!hasRequest(world.tile(tar.x, tar.y)) && validBreak(tar.x, tar.y)) {
|
||||||
|
PlaceRequest request = new PlaceRequest(tar.worldx(), tar.worldy());
|
||||||
|
request.scale = 1f;
|
||||||
|
selection.add(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +400,7 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean longPress(float x, float y) {
|
public boolean longPress(float x, float y) {
|
||||||
if(state.is(State.menu) || !isPlacing()) return false;
|
if(state.is(State.menu) || mode == none) return false;
|
||||||
|
|
||||||
//get tile on cursor
|
//get tile on cursor
|
||||||
Tile cursor = tileAt(x, y);
|
Tile cursor = tileAt(x, y);
|
||||||
@ -320,7 +414,11 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
lineStartY = cursor.y;
|
lineStartY = cursor.y;
|
||||||
lineMode = true;
|
lineMode = true;
|
||||||
|
|
||||||
Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size);
|
if(mode == breaking){
|
||||||
|
Effects.effect(Fx.tapBlock, cursor.worldx(), cursor.worldy(), 1f);
|
||||||
|
}else{
|
||||||
|
Effects.effect(Fx.tapBlock, cursor.worldx() + recipe.result.offset(), cursor.worldy() + recipe.result.offset(), recipe.result.size);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -338,9 +436,12 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
//remove if request present
|
//remove if request present
|
||||||
if(hasRequest(cursor)) {
|
if(hasRequest(cursor)) {
|
||||||
removeRequest(getRequest(cursor));
|
removeRequest(getRequest(cursor));
|
||||||
}else if(isPlacing() && validPlace(cursor.x, cursor.y, recipe.result, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, recipe.result)){
|
}else if(mode == placing && isPlacing() && validPlace(cursor.x, cursor.y, recipe.result, rotation) && !checkOverlapPlacement(cursor.x, cursor.y, recipe.result)){
|
||||||
//add to placement queue if it's a valid place position
|
//add to selection queue if it's a valid place position
|
||||||
placement.add(new PlaceRequest(cursor.worldx(), cursor.worldy(), recipe, rotation));
|
selection.add(new PlaceRequest(cursor.worldx(), cursor.worldy(), recipe, rotation));
|
||||||
|
}else if(mode == breaking && validBreak(cursor.x, cursor.y) && !hasRequest(cursor)){
|
||||||
|
//add to selection queue if it's a valid BREAK position
|
||||||
|
selection.add(new PlaceRequest(cursor.worldx(), cursor.worldy()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -350,11 +451,22 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
public void update(){
|
public void update(){
|
||||||
|
|
||||||
//reset state when not placing
|
//reset state when not placing
|
||||||
if(!isPlacing()){
|
if(mode == none){
|
||||||
selecting = false;
|
selecting = false;
|
||||||
lineMode = false;
|
lineMode = false;
|
||||||
removals.addAll(placement);
|
removals.addAll(selection);
|
||||||
placement.clear();
|
selection.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//if there is no mode and there's a recipe, switch to placing
|
||||||
|
if(recipe != null && mode == none){
|
||||||
|
mode = placing;
|
||||||
|
}
|
||||||
|
|
||||||
|
//automatically switch to placing after a new recipe is selected
|
||||||
|
if(lastRecipe != recipe && mode == breaking && recipe != null){
|
||||||
|
mode = placing;
|
||||||
|
lastRecipe = recipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lineMode){
|
if(lineMode){
|
||||||
@ -413,12 +525,14 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
|
|
||||||
float dx = deltaX * Core.camera.zoom / Core.cameraScale, dy = deltaY * Core.camera.zoom / Core.cameraScale;
|
float dx = deltaX * Core.camera.zoom / Core.cameraScale, dy = deltaY * Core.camera.zoom / Core.cameraScale;
|
||||||
|
|
||||||
if(selecting){
|
if(selecting){ //pan all requests
|
||||||
for(PlaceRequest req : placement){
|
for(PlaceRequest req : selection){
|
||||||
|
if(req.remove) continue; //don't shift removal requests
|
||||||
req.x += dx;
|
req.x += dx;
|
||||||
req.y -= dy;
|
req.y -= dy;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
//pan player
|
||||||
player.x -= dx;
|
player.x -= dx;
|
||||||
player.y += dy;
|
player.y += dy;
|
||||||
player.targetAngle = Mathf.atan2(dx, -dy) + 180f;
|
player.targetAngle = Mathf.atan2(dx, -dy) + 180f;
|
||||||
@ -481,6 +595,7 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
float x, y;
|
float x, y;
|
||||||
Recipe recipe;
|
Recipe recipe;
|
||||||
int rotation;
|
int rotation;
|
||||||
|
boolean remove;
|
||||||
|
|
||||||
//animation variables
|
//animation variables
|
||||||
float scale;
|
float scale;
|
||||||
@ -491,10 +606,17 @@ public class AndroidInput extends InputHandler implements GestureListener{
|
|||||||
this.y = y;
|
this.y = y;
|
||||||
this.recipe = recipe;
|
this.recipe = recipe;
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
|
this.remove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaceRequest(float x, float y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.remove = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile tile(){
|
Tile tile(){
|
||||||
return world.tileWorld(x - recipe.result.offset(), y - recipe.result.offset());
|
return world.tileWorld(x - (recipe == null ? 0 : recipe.result.offset()), y - (recipe == null ? 0 : recipe.result.offset()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class Item implements Comparable<Item>, Content{
|
|||||||
items.add(this);
|
items.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(){
|
public void load(){
|
||||||
this.region = Draw.region("item-" + name);
|
this.region = Draw.region("item-" + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,10 @@ public class BlocksFragment implements Fragment{
|
|||||||
visible(() -> !state.is(State.menu) && shown);
|
visible(() -> !state.is(State.menu) && shown);
|
||||||
|
|
||||||
}}.end().get();
|
}}.end().get();
|
||||||
|
|
||||||
}}.end();
|
}}.end();
|
||||||
|
|
||||||
|
rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Rebuilds the whole placement menu, attempting to preserve previous state.*/
|
/**Rebuilds the whole placement menu, attempting to preserve previous state.*/
|
||||||
|
Loading…
Reference in New Issue
Block a user