start of server-client decoupling, unfinished

v5stable
Ondřej Hruška 10 years ago
parent 9835cd0023
commit e14be3ec1b
  1. 4
      src/mightypork/rogue/App.java
  2. 6
      src/mightypork/rogue/world/LocalWorldAccess.java
  3. 6
      src/mightypork/rogue/world/MapGenerator.java
  4. 45
      src/mightypork/rogue/world/Player.java
  5. 6
      src/mightypork/rogue/world/WorldAccess.java
  6. 92
      src/mightypork/rogue/world/WorldClient.java
  7. 93
      src/mightypork/rogue/world/WorldServer.java
  8. 21
      src/mightypork/rogue/world/map/Level.java
  9. 5
      src/mightypork/rogue/world/tile/DroppedItemRenderer.java
  10. 15
      src/mightypork/rogue/world/tile/Tile.java
  11. 13
      src/mightypork/rogue/world/tile/TileModel.java
  12. 2
      src/mightypork/rogue/world/tile/models/AbstractNullTile.java
  13. 2
      src/mightypork/rogue/world/tile/models/SimpleTile.java

@ -22,6 +22,7 @@ import mightypork.rogue.screens.main_menu.ScreenMainMenu;
import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy; import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy;
import mightypork.rogue.screens.test_cat_sound.ScreenTestCat; import mightypork.rogue.screens.test_cat_sound.ScreenTestCat;
import mightypork.rogue.screens.test_render.ScreenTestRender; import mightypork.rogue.screens.test_render.ScreenTestRender;
import mightypork.rogue.world.Player;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.map.Level; import mightypork.rogue.world.map.Level;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
@ -106,9 +107,10 @@ public final class App extends BaseApp {
@Override @Override
protected void preInit() protected void preInit()
{ {
Ion.registerBinary(Tile.ION_MARK, Tile.class);
Ion.registerBinary(Item.ION_MARK, Item.class); Ion.registerBinary(Item.ION_MARK, Item.class);
Ion.registerBinary(Level.ION_MARK, Level.class); Ion.registerBinary(Level.ION_MARK, Level.class);
Ion.registerBinary(Tile.ION_MARK, Tile.class); Ion.registerBinary(Level.ION_MARK, Player.class);
} }

@ -0,0 +1,6 @@
package mightypork.rogue.world;
public class LocalWorldAccess implements WorldAccess {
}

@ -13,19 +13,19 @@ public class MapGenerator {
public static final Random rand = new Random(); public static final Random rand = new Random();
public static World createWorld(long seed) public static WorldServer createWorld(long seed)
{ {
synchronized (rand) { synchronized (rand) {
rand.setSeed(seed); rand.setSeed(seed);
final World w = new World(); final WorldServer w = new WorldServer();
w.setSeed(seed); w.setSeed(seed);
w.addLevel(createLevel(rand.nextLong(), Tiles.CRYSTAL_FLOOR, Tiles.CRYSTAL_WALL)); w.addLevel(createLevel(rand.nextLong(), Tiles.CRYSTAL_FLOOR, Tiles.CRYSTAL_WALL));
w.addLevel(createLevel(rand.nextLong(), Tiles.BRCOBBLE_FLOOR, Tiles.BRCOBBLE_WALL)); w.addLevel(createLevel(rand.nextLong(), Tiles.BRCOBBLE_FLOOR, Tiles.BRCOBBLE_WALL));
// TODO place on start position // TODO place on start position
w.getPlayer().teleport(new WorldPos(10, 10, 0)); w.addPlayer("local", new Player(10, 10, 0));
return w; return w;
} }
} }

@ -3,12 +3,10 @@ package mightypork.rogue.world;
import java.io.IOException; import java.io.IOException;
import mightypork.util.constraints.vect.Vect; import mightypork.util.ion.IonBinary;
import mightypork.util.constraints.vect.mutable.VectAnimated;
import mightypork.util.control.timing.Updateable;
import mightypork.util.ion.IonBundle; import mightypork.util.ion.IonBundle;
import mightypork.util.ion.IonBundled; import mightypork.util.ion.IonInput;
import mightypork.util.math.Easing; import mightypork.util.ion.IonOutput;
/** /**
@ -16,7 +14,9 @@ import mightypork.util.math.Easing;
* *
* @author MightyPork * @author MightyPork
*/ */
public class Player implements IonBundled, MapObserver, Updateable { public class Player implements IonBinary, MapObserver {
public static final short ION_MARK = 0;
private final double walktime = 0.3; // possibly make changeable for speed potion private final double walktime = 0.3; // possibly make changeable for speed potion
@ -71,18 +71,26 @@ public class Player implements IonBundled, MapObserver, Updateable {
@Override @Override
public void load(IonBundle in) throws IOException public void load(IonInput in) throws IOException
{
IonBundle ib = in.readBundle();
ib.loadBundled("pos", position);
}
@Override
public void save(IonOutput out) throws IOException
{ {
in.loadBundled("pos", position); IonBundle ib = new IonBundle();
in.loadBundled("target", target); ib.putBundled("target", target);
out.writeBundle(ib);
} }
@Override @Override
public void save(IonBundle out) throws IOException public short getIonMark()
{ {
out.putBundled("pos", position); return ION_MARK;
out.putBundled("target", target);
} }
@ -113,15 +121,20 @@ public class Player implements IonBundled, MapObserver, Updateable {
} }
@Override public void setMoveListener(Runnable r)
public void update(double delta) {
this.moveListenerCustom = r;
}
public void updateVisual(double delta)
{ {
position.update(delta); position.update(delta);
} }
public void setMoveListener(Runnable r) public void updateLogic(double delta)
{ {
this.moveListenerCustom = r; // server stuffs (sleep timer etc)
} }
} }

@ -0,0 +1,6 @@
package mightypork.rogue.world;
public interface WorldAccess {
}

@ -1,11 +1,6 @@
package mightypork.rogue.world; package mightypork.rogue.world;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import mightypork.rogue.world.map.Level; import mightypork.rogue.world.map.Level;
import mightypork.rogue.world.map.TileRenderContext; import mightypork.rogue.world.map.TileRenderContext;
import mightypork.util.constraints.rect.Rect; import mightypork.util.constraints.rect.Rect;
@ -13,76 +8,21 @@ import mightypork.util.constraints.rect.RectConst;
import mightypork.util.constraints.rect.proxy.RectBound; import mightypork.util.constraints.rect.proxy.RectBound;
import mightypork.util.constraints.vect.VectConst; import mightypork.util.constraints.vect.VectConst;
import mightypork.util.control.timing.Updateable; import mightypork.util.control.timing.Updateable;
import mightypork.util.ion.IonBundle;
import mightypork.util.ion.IonBundled;
public class World implements IonBundled, Updateable {
private final ArrayList<Level> levels = new ArrayList<>();
private final Player player = new Player(); public class WorldClient implements Updateable {
private transient final Set<MapObserver> observers = new HashSet<>(); private Level level = null;
/** This seed can be used to re-create identical world. */ private final Player player = null;
private long seed;
@Override
public void load(IonBundle in) throws IOException
{
in.loadBundled("player", player);
seed = in.get("seed", 0L);
in.loadSequence("levels", levels);
}
@Override
public void save(IonBundle out) throws IOException
{
out.putBundled("player", player);
out.put("seed", seed);
out.putSequence("levels", levels);
}
public void removeObserver(MapObserver observer)
{
observers.remove(observer);
}
public void addObserver(MapObserver observer)
{
observers.add(observer);
}
public void addLevel(Level level)
{
levels.add(level);
}
@Override @Override
public void update(double delta) public void update(double delta)
{ {
player.update(delta); player.updateVisual(delta);
for (int level = 0; level < levels.size(); level++) {
for (final MapObserver observer : observers) {
if (observer.getPosition().floor == level) {
levels.get(level).update(observer, delta);
}
}
}
}
public Level getLevelForObserver(MapObserver observer) level.updateVisual(player, delta);
{
return levels.get(observer.getPosition().floor);
} }
@ -96,8 +36,6 @@ public class World implements IonBundled, Updateable {
*/ */
public void render(final RectBound viewport, final int yTiles, final int xTiles, final int minSize) public void render(final RectBound viewport, final int yTiles, final int xTiles, final int minSize)
{ {
final Level floor = getLevelForObserver(player); // TODO fractional movement
final Rect r = viewport.getRect(); final Rect r = viewport.getRect();
final double vpH = r.height().value(); final double vpH = r.height().value();
final double vpW = r.width().value(); final double vpW = r.width().value();
@ -119,14 +57,14 @@ public class World implements IonBundled, Updateable {
//@formatter:off //@formatter:off
final RectConst mapRect = vpCenter.startRect().grow( final RectConst mapRect = vpCenter.startRect().grow(
playerX*tileSize, playerX*tileSize,
(floor.getWidth() - playerX) * tileSize, (level.getWidth() - playerX) * tileSize,
playerY*tileSize, playerY*tileSize,
(floor.getHeight() - playerY) * tileSize (level.getHeight() - playerY) * tileSize
).freeze(); ).freeze();
//@formatter:on //@formatter:on
System.out.println(playerX + "," + playerY + " : " + mapRect); System.out.println(playerX + "," + playerY + " : " + mapRect);
System.out.println(floor.getWidth() + "," + floor.getHeight()); System.out.println(level.getWidth() + "," + level.getHeight());
// tiles to render // tiles to render
final int x1 = (int) Math.floor(playerX - (vpW / tileSize)); final int x1 = (int) Math.floor(playerX - (vpW / tileSize));
@ -134,7 +72,7 @@ public class World implements IonBundled, Updateable {
final int x2 = (int) Math.ceil(playerX + (vpW / tileSize)); final int x2 = (int) Math.ceil(playerX + (vpW / tileSize));
final int y2 = (int) Math.ceil(playerY + (vpH / tileSize)); final int y2 = (int) Math.ceil(playerY + (vpH / tileSize));
final TileRenderContext trc = new TileRenderContext(floor, mapRect); //-tileSize*0.5 final TileRenderContext trc = new TileRenderContext(level, mapRect); //-tileSize*0.5
for (trc.y = y1; trc.y <= y2; trc.y++) { for (trc.y = y1; trc.y <= y2; trc.y++) {
for (trc.x = x1; trc.x <= x2; trc.x++) { for (trc.x = x1; trc.x <= x2; trc.x++) {
trc.render(); trc.render();
@ -143,18 +81,6 @@ public class World implements IonBundled, Updateable {
} }
public void setSeed(long seed)
{
this.seed = seed;
}
public long getSeed()
{
return seed;
}
public Player getPlayer() public Player getPlayer()
{ {
return player; return player;

@ -0,0 +1,93 @@
package mightypork.rogue.world;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import mightypork.rogue.world.map.Level;
import mightypork.util.control.timing.Updateable;
import mightypork.util.ion.IonBundle;
import mightypork.util.ion.IonBundled;
/**
* World server. To a server, all players and levels are equal.
*
* @author MightyPork
*/
public class WorldServer implements IonBundled, Updateable {
private final ArrayList<Level> levels = new ArrayList<>();
private final Map<String, Player> players = new HashMap<>();
/** This seed can be used to re-create identical world. */
private long seed;
@Override
public void load(IonBundle in) throws IOException
{
seed = in.get("seed", 0L);
in.loadSequence("levels", levels);
in.loadMap("players", players);
}
@Override
public void save(IonBundle out) throws IOException
{
out.put("seed", seed);
out.putSequence("levels", levels);
out.putMap("players", players);
}
public void addLevel(Level level)
{
levels.add(level);
}
public void addPlayer(String name, Player player)
{
players.put(name, player);
}
public void removePlayer(String name)
{
players.remove(name);
}
@Override
public void update(double delta)
{
// food meters and such
for (final Player pl : players.values()) {
pl.updateLogic(delta);
}
for (int level = 0; level < levels.size(); level++) {
// more than 1 player can be on floor, update for all of them
for (final Player pl : players.values()) {
if (pl.getPosition().floor == level) {
levels.get(level).updateLogic(pl, delta);
}
}
}
}
public void setSeed(long seed)
{
this.seed = seed;
}
public long getSeed()
{
return seed;
}
}

@ -4,6 +4,7 @@ package mightypork.rogue.world.map;
import java.io.IOException; import java.io.IOException;
import mightypork.rogue.world.MapObserver; import mightypork.rogue.world.MapObserver;
import mightypork.rogue.world.Player;
import mightypork.rogue.world.WorldPos; import mightypork.rogue.world.WorldPos;
import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileModel; import mightypork.rogue.world.tile.TileModel;
@ -22,7 +23,7 @@ import mightypork.util.math.noise.NoiseGen;
*/ */
public class Level implements MapAccess, IonBinary { public class Level implements MapAccess, IonBinary {
public static final int ION_MARK = 52; public static final int ION_MARK = 53;
private int width, height; private int width, height;
@ -177,7 +178,19 @@ public class Level implements MapAccess, IonBinary {
} }
public void update(MapObserver observer, double delta) public void updateLogic(MapObserver observer, double delta)
{
updateForObserver(observer, delta, true, false);
}
public void updateVisual(Player player, double delta)
{
updateForObserver(player, delta, false, true);
}
private void updateForObserver(MapObserver observer, double delta, boolean logic, boolean visual)
{ {
final int viewRange = observer.getViewRange(); final int viewRange = observer.getViewRange();
final WorldPos position = observer.getPosition(); final WorldPos position = observer.getPosition();
@ -195,7 +208,8 @@ public class Level implements MapAccess, IonBinary {
for (int y = y1; y <= y2; y++) { for (int y = y1; y <= y2; y++) {
for (int x = x1; x <= x2; x++) { for (int x = x1; x <= x2; x++) {
getTile(x, y).update(delta); if (logic) getTile(x, y).updateLogic(delta);
if (visual) getTile(x, y).updateVisual(delta);
} }
} }
} }
@ -210,4 +224,5 @@ public class Level implements MapAccess, IonBinary {
return noiseGen; return noiseGen;
} }
} }

@ -11,7 +11,7 @@ import mightypork.util.control.timing.Updateable;
import mightypork.util.math.Easing; import mightypork.util.math.Easing;
public class DroppedItemRenderer implements Updateable { public class DroppedItemRenderer {
private Animator itemAnim = new AnimatorBounce(2, Easing.SINE_BOTH); private Animator itemAnim = new AnimatorBounce(2, Easing.SINE_BOTH);
@ -37,8 +37,7 @@ public class DroppedItemRenderer implements Updateable {
} }
@Override public void updateVisual(double delta)
public void update(double delta)
{ {
itemAnim.update(delta); itemAnim.update(delta);
} }

@ -14,7 +14,7 @@ import mightypork.util.ion.IonInput;
import mightypork.util.ion.IonOutput; import mightypork.util.ion.IonOutput;
public final class Tile implements IonBinary, Updateable { public final class Tile implements IonBinary {
public static final short ION_MARK = 50; public static final short ION_MARK = 50;
@ -99,16 +99,19 @@ public final class Tile implements IonBinary, Updateable {
} }
@Override public void updateLogic(double delta)
public void update(double delta)
{ {
model.update(this, delta); model.updateLogic(this, delta);
}
public void updateVisual(double delta)
{
model.updateVisual(this, delta);
if (hasItems()) { if (hasItems()) {
getItemRenderer().update(delta); getItemRenderer().updateVisual(delta);
} }
} }
private DroppedItemRenderer getItemRenderer() private DroppedItemRenderer getItemRenderer()
{ {
if (itemRenderer == null) { if (itemRenderer == null) {

@ -70,12 +70,21 @@ public abstract class TileModel {
/** /**
* Update a tile * Update tile state etc
* *
* @param tile tile * @param tile tile
* @param delta delta time * @param delta delta time
*/ */
public abstract void update(Tile tile, double delta); public abstract void updateLogic(Tile tile, double delta);
/**
* Update tile effects
*
* @param tile tile
* @param delta delta time
*/
public abstract void updateVisual(Tile tile, double delta);
/** /**

@ -30,7 +30,7 @@ public abstract class AbstractNullTile extends TileModel {
@Override @Override
public void update(Tile tile, double delta) public void updateLogic(Tile tile, double delta)
{ {
} }

@ -37,7 +37,7 @@ public abstract class SimpleTile extends TileModel {
@Override @Override
@DefaultImpl @DefaultImpl
public void update(Tile tile, double delta) public void updateLogic(Tile tile, double delta)
{ {
} }

Loading…
Cancel
Save