mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-11 00:07:46 +07:00
Basic android support
This commit is contained in:
@ -1,24 +1,39 @@
|
||||
package io.anuke.mindustry;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import com.badlogic.gdx.backends.android.AndroidApplication;
|
||||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.TelephonyManager;
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.backends.android.AndroidApplication;
|
||||
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
|
||||
import com.badlogic.gdx.utils.IntArray;
|
||||
import com.esotericsoftware.kryonet.*;
|
||||
import com.esotericsoftware.kryonet.util.InputStreamSender;
|
||||
import io.anuke.mindustry.io.PlatformFunction;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.Net.ClientProvider;
|
||||
import io.anuke.mindustry.net.Net.SendMode;
|
||||
import io.anuke.mindustry.net.Net.ServerProvider;
|
||||
import io.anuke.mindustry.net.Packets.Connect;
|
||||
import io.anuke.mindustry.net.Packets.Disconnect;
|
||||
import io.anuke.mindustry.net.Registrator;
|
||||
import io.anuke.mindustry.net.Streamable;
|
||||
import io.anuke.mindustry.net.Streamable.StreamBegin;
|
||||
import io.anuke.mindustry.net.Streamable.StreamChunk;
|
||||
import io.anuke.ucore.UCore;
|
||||
import io.anuke.ucore.function.Callable;
|
||||
import io.anuke.ucore.scene.ui.TextField;
|
||||
import io.anuke.ucore.scene.ui.layout.Unit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
public class AndroidLauncher extends AndroidApplication{
|
||||
boolean doubleScaleTablets = true;
|
||||
|
||||
@ -62,6 +77,213 @@ public class AndroidLauncher extends AndroidApplication{
|
||||
}
|
||||
|
||||
config.hideStatusBar = true;
|
||||
|
||||
Net.setClientProvider(new ClientProvider() {
|
||||
Client client;
|
||||
|
||||
{
|
||||
client = new Client();
|
||||
client.start();
|
||||
client.addListener(new Listener(){
|
||||
@Override
|
||||
public void connected (Connection connection) {
|
||||
Connect c = new Connect();
|
||||
c.id = connection.getID();
|
||||
c.addressTCP = connection.getRemoteAddressTCP().toString();
|
||||
Net.handleClientReceived(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected (Connection connection) {
|
||||
Disconnect c = new Disconnect();
|
||||
Net.handleClientReceived(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void received (Connection connection, Object object) {
|
||||
if(object instanceof FrameworkMessage) return;
|
||||
|
||||
try{
|
||||
Net.handleClientReceived(object);
|
||||
}catch (Exception e){
|
||||
Gdx.app.exit();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
register(Registrator.getClasses());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(String ip, int port) throws IOException {
|
||||
client.connect(5000, ip, port, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object object, SendMode mode) {
|
||||
if(mode == SendMode.tcp){
|
||||
client.sendTCP(object);
|
||||
}else{
|
||||
client.sendUDP(object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePing() {
|
||||
client.updateReturnTripTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPing() {
|
||||
return client.getReturnTripTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Class<?>... types) {
|
||||
for(Class<?> c : types){
|
||||
client.getKryo().register(c);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Net.setServerProvider(new ServerProvider() {
|
||||
Server server;
|
||||
IntArray connections = new IntArray();
|
||||
|
||||
{
|
||||
server = new Server();
|
||||
Thread thread = new Thread(server, "Kryonet Server");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
server.addListener(new Listener(){
|
||||
@Override
|
||||
public void connected (Connection connection) {
|
||||
Connect c = new Connect();
|
||||
c.id = connection.getID();
|
||||
c.addressTCP = connection.getRemoteAddressTCP().toString();
|
||||
Net.handleServerReceived(c, c.id);
|
||||
connections.add(c.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected (Connection connection) {
|
||||
Disconnect c = new Disconnect();
|
||||
c.id = connection.getID();
|
||||
Net.handleServerReceived(c, c.id);
|
||||
connections.removeValue(c.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void received (Connection connection, Object object) {
|
||||
if(object instanceof FrameworkMessage) return;
|
||||
|
||||
try{
|
||||
Net.handleServerReceived(object, connection.getID());
|
||||
}catch (Exception e){
|
||||
Gdx.app.exit();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
register(Registrator.getClasses());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntArray getConnections() {
|
||||
return connections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void host(int port) throws IOException {
|
||||
server.bind(port, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
server.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendStream(int id, Streamable stream) {
|
||||
Connection connection = getByID(id);
|
||||
|
||||
connection.addListener(new InputStreamSender(stream.stream, 512) {
|
||||
int id;
|
||||
|
||||
protected void start () {
|
||||
//send an object so the receiving side knows how to handle the following chunks
|
||||
StreamBegin begin = new StreamBegin();
|
||||
begin.total = stream.stream.available();
|
||||
begin.type = stream.getClass();
|
||||
connection.sendTCP(begin);
|
||||
id = begin.id;
|
||||
UCore.log("Sending begin packet: " + begin);
|
||||
}
|
||||
|
||||
protected Object next (byte[] bytes) {
|
||||
StreamChunk chunk = new StreamChunk();
|
||||
chunk.id = id;
|
||||
chunk.data = bytes;
|
||||
UCore.log("Sending chunk of size " + chunk.data.length);
|
||||
return chunk; //wrap the byte[] with an object so the receiving side knows how to handle it.
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Object object, SendMode mode) {
|
||||
if(mode == SendMode.tcp){
|
||||
server.sendToAllTCP(object);
|
||||
}else{
|
||||
server.sendToAllUDP(object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTo(int id, Object object, SendMode mode) {
|
||||
if(mode == SendMode.tcp){
|
||||
server.sendToTCP(id, object);
|
||||
}else{
|
||||
server.sendToUDP(id, object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendExcept(int id, Object object, SendMode mode) {
|
||||
if(mode == SendMode.tcp){
|
||||
server.sendToAllExceptTCP(id, object);
|
||||
}else{
|
||||
server.sendToAllExceptUDP(id, object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Class<?>... types) {
|
||||
for(Class<?> c : types){
|
||||
server.getKryo().register(c);
|
||||
}
|
||||
}
|
||||
|
||||
Connection getByID(int id){
|
||||
for(Connection con : server.getConnections()){
|
||||
if(con.getID() == id){
|
||||
return con;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unable to find connection with ID " + id + "! Current connections: "
|
||||
+ Arrays.toString(server.getConnections()));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
initialize(new Mindustry(), config);
|
||||
}
|
||||
|
BIN
core/assets-raw/sprites/mechs/ship-standard.png
Normal file
BIN
core/assets-raw/sprites/mechs/ship-standard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 309 B |
@ -20,7 +20,7 @@ public class Vars{
|
||||
//respawn time in frames
|
||||
public static final float respawnduration = 60*4;
|
||||
//time between waves in frames (on normal mode)
|
||||
public static final float wavespace = 10*60*(android ? 1 : 1); //TODO revert
|
||||
public static final float wavespace = 60*60*(android ? 1 : 1); //TODO revert
|
||||
//waves can last no longer than 3 minutes, otherwise the next one spawns
|
||||
public static final float maxwavespace = 60*60*4f;
|
||||
//advance time the pathfinding starts at
|
||||
|
@ -26,6 +26,8 @@ import io.anuke.ucore.entities.BaseBulletType;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.modules.Module;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class NetClient extends Module {
|
||||
@ -193,6 +195,25 @@ public class NetClient extends Module {
|
||||
|
||||
Net.handle(BlockSyncPacket.class, packet -> {
|
||||
//TODO implementation, load data...
|
||||
DataInputStream stream = new DataInputStream(packet.stream);
|
||||
|
||||
try{
|
||||
while(stream.available() > 0){
|
||||
int pos = stream.readInt();
|
||||
|
||||
Tile tile = Vars.world.tile(pos % Vars.world.width(), pos / Vars.world.width());
|
||||
|
||||
byte times = stream.readByte();
|
||||
|
||||
for(int i = 0; i < times; i ++){
|
||||
tile.entity.timer.getTimes()[i] = stream.readFloat();
|
||||
}
|
||||
|
||||
tile.entity.read(stream);
|
||||
}
|
||||
}catch (IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class NetServer extends Module{
|
||||
/**Maps connection IDs to players.*/
|
||||
IntMap<Player> connections = new IntMap<>();
|
||||
float serverSyncTime = 4, itemSyncTime = 10, blockSyncTime = 120;
|
||||
|
||||
@ -241,8 +242,12 @@ public class NetServer extends Module{
|
||||
for(int i = 0; i < connections.size; i ++){
|
||||
int id = connections.get(i);
|
||||
Player player = this.connections.get(i);
|
||||
if(player == null) continue;
|
||||
int x = Mathf.scl2(player.x, Vars.tilesize);
|
||||
int y = Mathf.scl2(player.y, Vars.tilesize);
|
||||
int w = 14;
|
||||
int h = 10;
|
||||
sendBlockSync(id, x, y, w, h);
|
||||
}
|
||||
|
||||
//TODO sync to each player entity
|
||||
|
@ -1,9 +1,6 @@
|
||||
package io.anuke.mindustry.ui.fragments;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
|
||||
import io.anuke.mindustry.Mindustry;
|
||||
import io.anuke.mindustry.core.GameState;
|
||||
import io.anuke.mindustry.core.GameState.State;
|
||||
@ -12,6 +9,8 @@ import io.anuke.mindustry.ui.PressGroup;
|
||||
import io.anuke.ucore.scene.builders.imagebutton;
|
||||
import io.anuke.ucore.scene.builders.table;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class MenuFragment implements Fragment{
|
||||
|
||||
public void build(){
|
||||
@ -72,6 +71,8 @@ public class MenuFragment implements Fragment{
|
||||
new imagebutton("icon-editor", isize, () -> ui.showEditor()).text("$text.editor").padTop(4f);
|
||||
|
||||
new imagebutton("icon-tools", isize, () -> ui.showPrefs()).text("$text.settings").padTop(4f);
|
||||
|
||||
new imagebutton("icon-tools", isize, () -> ui.showJoinGame()).text("$text.joingame").padTop(4f);
|
||||
|
||||
if(Mindustry.donationsCallable != null){
|
||||
new imagebutton("icon-donate", isize, () -> {
|
||||
|
Reference in New Issue
Block a user