diff options
Diffstat (limited to 'core/src/com/ilotterytea/maxoning')
16 files changed, 690 insertions, 619 deletions
diff --git a/core/src/com/ilotterytea/maxoning/MaxonConstants.java b/core/src/com/ilotterytea/maxoning/MaxonConstants.java index b3f968a..42f2892 100644 --- a/core/src/com/ilotterytea/maxoning/MaxonConstants.java +++ b/core/src/com/ilotterytea/maxoning/MaxonConstants.java @@ -4,10 +4,13 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.ilotterytea.maxoning.utils.OsUtils; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; + public class MaxonConstants { public static final String GAME_NAME = "Maxon Petting Simulator"; - public static final String GAME_VERSION = "Alpha 1.1.2"; - public static final String GAME_GHTAG = "alpha-1.1.2"; + public static final String GAME_VERSION = "Alpha 1.2"; + public static final String GAME_GHTAG = "alpha-1.2"; public static final String GAME_PUBLISHER = "iLotterytea"; public static final String GAME_MAIN_FOLDER = OsUtils.getUserDataDirectory(".Maxoning"); @@ -16,4 +19,11 @@ public class MaxonConstants { public static final FileHandle FILE_EN_US = Gdx.files.internal("i18n/en_us.json"); public static final FileHandle FILE_RU_RU = Gdx.files.internal("i18n/ru_ru.json"); + + public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("###,###.##"); + public static final DecimalFormat DECIMAL_FORMAT2 = new DecimalFormat("###,###"); + @SuppressWarnings("SimpleDateFormat") + public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/M/yyyy hh:mm:ss"); + public static final long startTime = System.currentTimeMillis(); + } diff --git a/core/src/com/ilotterytea/maxoning/MaxonGame.java b/core/src/com/ilotterytea/maxoning/MaxonGame.java index 4ee3861..f361d20 100644 --- a/core/src/com/ilotterytea/maxoning/MaxonGame.java +++ b/core/src/com/ilotterytea/maxoning/MaxonGame.java @@ -6,12 +6,8 @@ import com.badlogic.gdx.Preferences; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; -import com.ilotterytea.maxoning.player.MaxonPlayer; -import com.ilotterytea.maxoning.screens.AssetLoadingScreen; +import com.ilotterytea.maxoning.screens.SplashScreen; import com.ilotterytea.maxoning.utils.I18N; -import com.ilotterytea.maxoning.utils.serialization.GameDataSystem; - -import java.io.IOException; public class MaxonGame extends Game { public SpriteBatch batch; @@ -36,14 +32,6 @@ public class MaxonGame extends Game { prefs = Gdx.app.getPreferences("Maxoning"); locale = new I18N(Gdx.files.internal("i18n/" + prefs.getString("lang", "en_us") + ".json")); - if (!GameDataSystem.exists()) { - try { - GameDataSystem.SaveData(new MaxonPlayer()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - prefs.putInteger("width", Gdx.graphics.getWidth()); prefs.putInteger("height", Gdx.graphics.getHeight()); prefs.flush(); @@ -53,7 +41,7 @@ public class MaxonGame extends Game { assetManager = new AssetManager(); - this.setScreen(new AssetLoadingScreen(this)); + this.setScreen(new SplashScreen(this)); } @Override diff --git a/core/src/com/ilotterytea/maxoning/player/MaxonSavegame.java b/core/src/com/ilotterytea/maxoning/player/MaxonSavegame.java new file mode 100644 index 0000000..301840b --- /dev/null +++ b/core/src/com/ilotterytea/maxoning/player/MaxonSavegame.java @@ -0,0 +1,40 @@ +package com.ilotterytea.maxoning.player; + +import java.io.Serializable; +import java.util.ArrayList; + +/** + * Save-game data class. + * @author NotDankEnough + * @since Alpha 1.2 (Oct 02, 2022) + */ +public class MaxonSavegame implements Serializable { + /** Earned Squish Points. */ + public int points; + /** Multiplier. */ + public short multiplier; + + /** Home inventory. */ + public ArrayList<Integer> inv; + /** Outside Inventory. */ + public ArrayList<Integer> outInv; + + /** Seed. */ + public long seed; + + /** Player name. */ + public String name; + /** Pet name. */ + public String petName; + /** Pet ID. */ + public byte petId; + + /** Elapsed time from game start. */ + public long elapsedTime; + + /** Last timestamp when save game was used. */ + public long lastTimestamp; + + /** Location. */ + public short roomId; +}
\ No newline at end of file diff --git a/core/src/com/ilotterytea/maxoning/screens/AssetLoadingScreen.java b/core/src/com/ilotterytea/maxoning/screens/AssetLoadingScreen.java deleted file mode 100644 index e61dc90..0000000 --- a/core/src/com/ilotterytea/maxoning/screens/AssetLoadingScreen.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.ilotterytea.maxoning.screens; - -import com.badlogic.gdx.*; -import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.math.MathUtils; -import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.ilotterytea.maxoning.MaxonGame; -import com.ilotterytea.maxoning.ui.AnimatedImage; -import com.ilotterytea.maxoning.anim.SpriteUtils; -import com.ilotterytea.maxoning.utils.AssetLoading; - -public class AssetLoadingScreen implements Screen { - final MaxonGame game; - - final Stage stage; - final Skin skin; - final AnimatedImage animatedMaxon; - final Label loadingLabel; - - final Texture M4x0nnes; - - public AssetLoadingScreen(MaxonGame game) { - this.game = game; - - this.M4x0nnes = new Texture("sprites/sheet/loadingCircle.png"); - - this.skin = new Skin(Gdx.files.internal("main.skin")); - this.stage = new Stage(new ScreenViewport()); - - this.loadingLabel = new Label("Loading...", skin); - - TextureRegion[] txrr = SpriteUtils.splitToTextureRegions(M4x0nnes, 112, 112, 10, 5); - this.animatedMaxon = new AnimatedImage(txrr); - - animatedMaxon.setPosition(8, 8); - animatedMaxon.setScale(0.25f); - - loadingLabel.setPosition(animatedMaxon.getWidth() * 0.25f + loadingLabel.getX() + 16, 8); - - stage.addActor(animatedMaxon); - //stage.addActor(loadingLabel); - - AssetLoading.queue(game.assetManager); - } - - @Override public void show() { render(Gdx.graphics.getDeltaTime()); } - - private void update() { - if (game.assetManager.update()) { - AssetLoading.registerItems(game.assetManager, game.locale); - game.setScreen(new SplashScreen(game)); - dispose(); - } - } - - @Override - public void render(float delta) { - Gdx.gl.glClearColor(0, 0, 0, 1); - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - - loadingLabel.setText(String.format("%s%% (Loaded %s assets)", MathUtils.floor(game.assetManager.getProgress() * 100), game.assetManager.getLoadedAssets())); - - stage.draw(); - stage.act(delta); - - update(); - } - - @Override - public void resize(int width, int height) { - stage.getViewport().update(width, height, true); - } - @Override public void pause() {} - @Override public void resume() {} - @Override public void hide() { dispose(); } - @Override public void dispose() {} -} diff --git a/core/src/com/ilotterytea/maxoning/screens/GameScreen.java b/core/src/com/ilotterytea/maxoning/screens/GameScreen.java index 263f282..8e4538d 100644 --- a/core/src/com/ilotterytea/maxoning/screens/GameScreen.java +++ b/core/src/com/ilotterytea/maxoning/screens/GameScreen.java @@ -3,24 +3,24 @@ package com.ilotterytea.maxoning.screens; import com.badlogic.gdx.*; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; -import com.badlogic.gdx.graphics.g2d.NinePatch; import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; -import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Timer; import com.badlogic.gdx.utils.viewport.FillViewport; +import com.ilotterytea.maxoning.MaxonConstants; import com.ilotterytea.maxoning.MaxonGame; import com.ilotterytea.maxoning.anim.SpriteUtils; import com.ilotterytea.maxoning.inputprocessors.CrossProcessor; import com.ilotterytea.maxoning.player.MaxonItem; import com.ilotterytea.maxoning.player.MaxonItemRegister; -import com.ilotterytea.maxoning.player.MaxonPlayer; +import com.ilotterytea.maxoning.player.MaxonSavegame; import com.ilotterytea.maxoning.ui.*; import com.ilotterytea.maxoning.utils.serialization.GameDataSystem; import com.rafaskoberg.gdx.typinglabel.TypingLabel; @@ -32,11 +32,15 @@ import java.util.Map; public class GameScreen implements Screen, InputProcessor { final MaxonGame game; + final int slotId; + final long playTimestamp; - MaxonPlayer player; + MaxonSavegame player; Stage stage; - Skin skin; + Skin skin, widgetSkin; + + TextureAtlas widgetAtlas, environmentAtlas; Label pointsLabel; Image blackBg, inventoryBg, shopBg, pointsBg; @@ -46,48 +50,40 @@ public class GameScreen implements Screen, InputProcessor { Table petTable, inventoryTable, mainTable; ScrollPane petScroll; - NinePatch btnUp, btnDown, btnOver, btnDisabled; - - Texture bgTile, bgTileAlt; - ArrayList<MaxonItem> items; Map<Integer, Integer> invItems; - boolean isShopping = true; - ArrayList<ArrayList<Sprite>> bgTiles; - public GameScreen(MaxonGame game) throws IOException, ClassNotFoundException { + public GameScreen(MaxonGame game, MaxonSavegame sav, int slotId) throws IOException, ClassNotFoundException { this.game = game; + this.slotId = slotId; + this.playTimestamp = System.currentTimeMillis(); - player = new MaxonPlayer(); - player.load(GameDataSystem.LoadData()); + player = sav; // Initializing the stage and skin: stage = new Stage(new FillViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); skin = new Skin(Gdx.files.internal("main.skin")); + widgetSkin = new Skin(Gdx.files.internal("sprites/gui/widgets.skin")); - // Ninepatch textures for buttons: - btnUp = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton.png", Texture.class), 8, 8, 8, 8); - btnDown = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton_down.png", Texture.class), 8, 8, 8, 8); - btnOver = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton_over.png", Texture.class), 8, 8, 8, 8); - btnDisabled = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton_disabled.png", Texture.class), 8, 8, 8, 8); - + widgetAtlas = game.assetManager.get("sprites/gui/widgets.atlas", TextureAtlas.class); + environmentAtlas = game.assetManager.get("sprites/env/environment.atlas", TextureAtlas.class); items = new ArrayList<>(); - for (int id : player.purchasedItems) { + for (int id : player.inv) { items.add(MaxonItemRegister.get(id)); } - // Make the background a little dimmed: - blackBg = new Image(game.assetManager.get("sprites/black.png", Texture.class)); + // Make the background a little darker: + blackBg = new Image(environmentAtlas.findRegion("tile")); + blackBg.setColor(0f, 0f, 0f, 0.5f); blackBg.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - blackBg.addAction(Actions.parallel(Actions.alpha(0.25f))); stage.addActor(blackBg); // Setting the background for inventory: - inventoryBg = new Image(btnDisabled); + inventoryBg = new Image(widgetSkin, "down"); inventoryBg.setSize((Gdx.graphics.getWidth() / 2.0f) - 512f, (Gdx.graphics.getHeight() / 2.0f) - 8f); inventoryBg.setPosition(8, 4); stage.addActor(inventoryBg); @@ -104,15 +100,9 @@ public class GameScreen implements Screen, InputProcessor { inventoryTable.setSize(inventoryBg.getWidth(), inventoryBg.getHeight() - inventoryLabel.getHeight()); inventoryTable.setPosition(inventoryBg.getX(), inventoryBg.getY()); - TextTooltip.TextTooltipStyle textTooltipStyle = new TextTooltip.TextTooltipStyle(); - textTooltipStyle.label = new Label.LabelStyle(); - textTooltipStyle.label.font = skin.getFont("default"); - textTooltipStyle.label.fontColor = skin.getColor("white"); - textTooltipStyle.background = new NinePatchDrawable(btnUp); - invItems = new HashMap<>(); - for (Integer id : player.purchasedItems) { + for (Integer id : player.inv) { if (invItems.containsKey(id)) { invItems.put(id, invItems.get(id) + 1); } else { @@ -121,21 +111,14 @@ public class GameScreen implements Screen, InputProcessor { } // Put the items in the inventory table: - for (Integer id : invItems.keySet()) { - MaxonItem item = MaxonItemRegister.get(id); - - if (item != null) { - InventoryAnimatedItem invItem = new InventoryAnimatedItem(item, skin, invItems.get(id)); - inventoryTable.add(invItem).size(64, 64).pad(5f); - } - } + reorderInvItems(); inventoryTable.align(Align.left|Align.top); stage.addActor(inventoryTable); // Setting the background for pet shop: - shopBg = new Image(btnDisabled); + shopBg = new Image(widgetSkin, "down"); shopBg.setSize((Gdx.graphics.getWidth() / 2.0f) - 512f, (Gdx.graphics.getHeight() / 2.0f) - 8f); shopBg.setPosition(8, inventoryBg.getY() + inventoryBg.getHeight() + 8f); stage.addActor(shopBg); @@ -153,7 +136,7 @@ public class GameScreen implements Screen, InputProcessor { // Adding the pet items in pet table: for (final MaxonItem item : MaxonItemRegister.getItems()) { PurchaseItem purchaseItem = new PurchaseItem( - skin, btnUp, item.icon, item.name, item.desc, item.price + skin, widgetSkin, item.icon, item.name, item.desc, MaxonConstants.DECIMAL_FORMAT2.format(item.price) ); purchaseItem.addListener(new ClickListener() { @@ -162,13 +145,13 @@ public class GameScreen implements Screen, InputProcessor { if (player.points > item.price) { player.points -= item.price; player.multiplier += item.multiplier; - player.purchasedItems.add(item.id); + player.inv.add(item.id); items.add(item); invItems.clear(); inventoryTable.clear(); - for (Integer id : player.purchasedItems) { + for (Integer id : player.inv) { if (invItems.containsKey(id)) { invItems.put(id, invItems.get(id) + 1); } else { @@ -177,14 +160,7 @@ public class GameScreen implements Screen, InputProcessor { } // Put the items in the inventory table: - for (Integer id : invItems.keySet()) { - MaxonItem item = MaxonItemRegister.get(id); - - if (item != null) { - InventoryAnimatedItem invItem = new InventoryAnimatedItem(item, skin, invItems.get(id)); - inventoryTable.add(invItem).size(64, 64).pad(5f); - } - } + reorderInvItems(); } } }); @@ -202,7 +178,7 @@ public class GameScreen implements Screen, InputProcessor { stage.addActor(petScroll); // Background for points label: - pointsBg = new Image(btnDisabled); + pointsBg = new Image(widgetSkin, "down"); pointsBg.setSize((Gdx.graphics.getWidth() - (shopBg.getX() + shopBg.getWidth()) - 8f), 64f); pointsBg.setPosition(shopBg.getX() + shopBg.getWidth() + 4f, Gdx.graphics.getHeight() - pointsBg.getHeight() - 4f); @@ -220,30 +196,10 @@ public class GameScreen implements Screen, InputProcessor { stage.addActor(pointsLabel); - bgTile = game.assetManager.get("sprites/menu/tile_1.png", Texture.class); - bgTileAlt = game.assetManager.get("sprites/menu/tile_2.png", Texture.class); - // Generate the background: bgTiles = new ArrayList<>(); - for (int i = 0; i < Gdx.graphics.getHeight() / bgTile.getHeight() + 1; i++) { - bgTiles.add(i, new ArrayList<Sprite>()); - - for (int j = -1; j < Gdx.graphics.getWidth() / bgTile.getWidth(); j++) { - Sprite spr = new Sprite(); - - if ((j + i) % 2 == 0) { - spr.setTexture(bgTile); - } else { - spr.setTexture(bgTileAlt); - } - - spr.setSize(bgTile.getWidth(), bgTile.getHeight()); - - spr.setPosition(bgTile.getWidth() * j, bgTile.getHeight() * i); - bgTiles.get(i).add(spr); - } - } + genNewBgTiles((int) stage.getWidth(), (int) stage.getHeight()); // Table for Maxon cat: mainTable = new Table(); @@ -294,7 +250,7 @@ public class GameScreen implements Screen, InputProcessor { player.points += multiplier; - final TypingLabel label = new TypingLabel(game.locale.FormattedText("game.newPoint", String.valueOf(1 * player.multiplier)), skin, "default"); + final TypingLabel label = new TypingLabel(game.locale.FormattedText("game.newPoint", MaxonConstants.DECIMAL_FORMAT.format(player.multiplier)), skin, "default"); label.setPosition( mainTable.getX() + actor.getActorX(), @@ -362,8 +318,8 @@ public class GameScreen implements Screen, InputProcessor { // Update the points label: pointsLabel.setText(game.locale.FormattedText("game.points", - String.valueOf(player.points), - String.valueOf(player.multiplier) + MaxonConstants.DECIMAL_FORMAT.format(player.points), + MaxonConstants.DECIMAL_FORMAT.format(player.multiplier) )); stage.draw(); @@ -374,26 +330,46 @@ public class GameScreen implements Screen, InputProcessor { public void resize(int width, int height) { bgTiles.clear(); - for (int i = 0; i < Gdx.graphics.getHeight() / bgTile.getHeight() + 1; i++) { - bgTiles.add(i, new ArrayList<Sprite>()); + genNewBgTiles(width, height); + + stage.getViewport().update(width, height, true); + } + + private void reorderInvItems() { + inventoryTable.clear(); + + for (int i = 0; i < invItems.keySet().size(); i++) { + MaxonItem item = MaxonItemRegister.get(i); - for (int j = -1; j < Gdx.graphics.getWidth() / bgTile.getWidth(); j++) { - Sprite spr = new Sprite(); + if (item != null) { + InventoryAnimatedItem invItem = new InventoryAnimatedItem(item, skin, invItems.get(i)); + Cell<InventoryAnimatedItem> cell = inventoryTable.add(invItem).size(64, 64).pad(5f); + + if (i != 0 && i % 5 == 0) { + cell.row(); + } + } + } + } + + private void genNewBgTiles(int width, int height) { + for (int i = 0; i < height / environmentAtlas.findRegion("tile").getRegionHeight() + 1; i++) { + bgTiles.add(i, new ArrayList<Sprite>()); + for (int j = -1; j < width / environmentAtlas.findRegion("tile").getRegionWidth(); j++) { + Sprite spr = new Sprite(environmentAtlas.findRegion("tile")); if ((j + i) % 2 == 0) { - spr.setTexture(bgTile); + spr.setColor(0.98f, 0.71f, 0.22f, 1f); } else { - spr.setTexture(bgTileAlt); + spr.setColor(0.84f, 0.61f, 0.20f, 1f); } - spr.setSize(bgTile.getWidth(), bgTile.getHeight()); + spr.setSize(64, 64); - spr.setPosition(bgTile.getWidth() * j, bgTile.getHeight() * i); + spr.setPosition(spr.getWidth() * j, spr.getHeight() * i); bgTiles.get(i).add(spr); } } - - stage.getViewport().update(width, height, true); } @Override public void pause() {} @@ -411,11 +387,9 @@ public class GameScreen implements Screen, InputProcessor { @Override public boolean keyDown(int keycode) { if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) { - try { - GameDataSystem.SaveData(player); - } catch (IOException e) { - throw new RuntimeException(e); - } + player.lastTimestamp = System.currentTimeMillis(); + player.elapsedTime = (System.currentTimeMillis() - playTimestamp) + player.elapsedTime; + GameDataSystem.save(player, String.format("0%s.maxon", (slotId >= 0) ? slotId : "latest")); game.setScreen(new MenuScreen(game)); dispose(); @@ -432,9 +406,9 @@ public class GameScreen implements Screen, InputProcessor { cat.nextFrame(); maxon.setDrawable(cat.getDrawable()); - player.points += 1 * player.multiplier; + player.points += player.multiplier; - final TypingLabel label = new TypingLabel(game.locale.FormattedText("game.newPoint", String.valueOf(1 * player.multiplier)), skin, "default"); + final TypingLabel label = new TypingLabel(game.locale.FormattedText("game.newPoint", MaxonConstants.DECIMAL_FORMAT.format(player.multiplier)), skin, "default"); label.setPosition( mainTable.getX() + actor.getActorX(), diff --git a/core/src/com/ilotterytea/maxoning/screens/MenuScreen.java b/core/src/com/ilotterytea/maxoning/screens/MenuScreen.java index 7acdf66..c796d22 100644 --- a/core/src/com/ilotterytea/maxoning/screens/MenuScreen.java +++ b/core/src/com/ilotterytea/maxoning/screens/MenuScreen.java @@ -3,8 +3,8 @@ package com.ilotterytea.maxoning.screens; import com.badlogic.gdx.*; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.*; -import com.badlogic.gdx.graphics.g2d.NinePatch; import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.Stage; @@ -14,109 +14,91 @@ import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.viewport.FillViewport; +import com.ilotterytea.maxoning.MaxonConstants; import com.ilotterytea.maxoning.MaxonGame; -import com.ilotterytea.maxoning.inputprocessors.CrossProcessor; +import com.ilotterytea.maxoning.player.MaxonSavegame; import com.ilotterytea.maxoning.ui.*; +import com.ilotterytea.maxoning.utils.math.Math; +import com.ilotterytea.maxoning.utils.serialization.GameDataSystem; +import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Calendar; -public class MenuScreen implements Screen, InputProcessor { +public class MenuScreen implements Screen { final MaxonGame game; final Stage stage; - final Skin skin; + final Skin skin, widgetSkin; - Image brandLogo, blackBg; - Label startLabel, infoLabel; + Image brandLogo, blackBg, menuBg; - NinepatchButton singlePlayerButton, optionsButton, quitButton; final Music menuMusic; - Table menuTable, optionsTable; + Table menuTable, savegameTable; - final Texture bgTile1, bgTile2; - - NinePatch buttonUp, buttonDown, buttonOver, buttonDisabled; + // Atlases: + TextureAtlas environmentAtlas, brandAtlas; private ArrayList<ArrayList<Sprite>> bgMenuTiles; + private ArrayList<LeafParticle> leafTiles, delLeafTiles; - private boolean anyKeyPressed = false, brandActionsSet = false; + private final boolean isAutumn = + // Autumn. + ((Calendar.getInstance().get(Calendar.MONTH) + 1 > 8) && (Calendar.getInstance().get(Calendar.MONTH) + 1 < 12)) || + // Spring. + ((Calendar.getInstance().get(Calendar.MONTH) + 1 < 6) && (Calendar.getInstance().get(Calendar.MONTH) + 1 > 2)); + private final boolean isSummer = (Calendar.getInstance().get(Calendar.MONTH) + 1 > 5 && Calendar.getInstance().get(Calendar.MONTH) + 1 < 9); public MenuScreen(final MaxonGame game) { this.game = game; - buttonUp = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton.png", Texture.class), 8, 8, 8, 8); - buttonDown = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton_down.png", Texture.class), 8, 8, 8, 8); - buttonOver = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton_over.png", Texture.class), 8, 8, 8, 8); - buttonDisabled = new NinePatch(game.assetManager.get("sprites/ui/sqrbutton_disabled.png", Texture.class), 8, 8, 8, 8); - - bgTile1 = game.assetManager.get("sprites/menu/tile_1.png", Texture.class); - bgTile2 = game.assetManager.get("sprites/menu/tile_2.png", Texture.class); - - bgMenuTiles = new ArrayList<>(); + // Environment atlas for leafs, snowflakes and background tiles: + environmentAtlas = game.assetManager.get("sprites/env/environment.atlas", TextureAtlas.class); - for (int i = 0; i < Gdx.graphics.getHeight() / bgTile1.getHeight() + 1; i++) { - bgMenuTiles.add(i, new ArrayList<Sprite>()); - for (int j = -1; j < Gdx.graphics.getWidth() / bgTile1.getWidth(); j++) { - Sprite spr = new Sprite((j + i % 2 == 0) ? bgTile1 : bgTile2); - - spr.setPosition(bgTile1.getWidth() * j, bgTile1.getHeight() * i); - bgMenuTiles.get(i).add(spr); - } - } + // Brand atlas: + brandAtlas = game.assetManager.get("sprites/gui/brand.atlas", TextureAtlas.class); + // Stage and skin: this.stage = new Stage(new FillViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); this.skin = new Skin(Gdx.files.internal("main.skin")); + this.widgetSkin = new Skin(Gdx.files.internal("sprites/gui/widgets.skin")); + // Main Menu music: this.menuMusic = game.assetManager.get("mus/menu/mus_menu_loop.ogg", Music.class); - brandLogo = new Image(game.assetManager.get("sprites/brand.png", Texture.class)); - blackBg = new Image(game.assetManager.get("sprites/black.png", Texture.class)); + // Make the background a little darker: + brandLogo = new Image(brandAtlas.findRegion("brand")); + blackBg = new Image(environmentAtlas.findRegion("tile")); - this.startLabel = new Label(game.locale.TranslatableText("menu.pressStart"), skin, "press"); - this.infoLabel = new DebugLabel(skin); + blackBg.setColor(0f, 0f, 0f, 0.25f); + blackBg.setSize(stage.getWidth(), stage.getHeight()); - // Menu Buttons: - menuTable = new Table(); + stage.addActor(blackBg); - singlePlayerButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.TranslatableText("menu.playGame"), skin, "default"); - optionsButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.TranslatableText("menu.options"), skin, "default"); - quitButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.TranslatableText("menu.quit"), skin, "default"); + // Save game table: + savegameTable = new Table(); + loadSavegamesToTable(savegameTable); - singlePlayerButton.addListener(new ClickListener() { - @Override - public void clicked(InputEvent event, float x, float y) { - try { - game.setScreen(new GameScreen(game)); - } catch (IOException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - dispose(); - } - }); + // Quick buttons: + Table quickTable = new Table(); + quickTable.align(Align.right); - // Options: + // Options button: + TextButton optionsButton = new TextButton("Options", widgetSkin, "default"); optionsButton.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { - menuTable.clearActions(); - menuTable.addAction(Actions.moveTo(-Gdx.graphics.getWidth(), menuTable.getY(), 0.75f, Interpolation.sine)); - - optionsTable.clearActions(); - optionsTable.addAction(Actions.moveTo(0, optionsTable.getY(), 0.75f, Interpolation.sine)); - - blackBg.clearActions(); - blackBg.addAction(Actions.alpha(0.5f)); - - brandLogo.addAction( - Actions.moveTo(brandLogo.getX(), brandLogo.getY() + 512f, 0.5f, Interpolation.sine) - ); + super.clicked(event, x, y); } }); - // Exit the game when "quit button" is pressed: + quickTable.add(optionsButton).height(48f).minWidth(90f).pad(4f); + + // Quit button: + TextButton quitButton = new TextButton("Quit", widgetSkin, "default"); quitButton.addListener(new ClickListener() { @Override public void clicked(InputEvent event, float x, float y) { @@ -124,99 +106,71 @@ public class MenuScreen implements Screen, InputProcessor { } }); - // Set the width and position for menu table: - menuTable.setPosition(0, Gdx.graphics.getHeight()); - menuTable.setWidth(Gdx.graphics.getWidth()); - menuTable.align(Align.center); + quickTable.add(quitButton).height(48f).minWidth(90f).pad(4f); - menuTable.add(singlePlayerButton).width(512f).height(81f).padBottom(10f).row(); - menuTable.add(optionsButton).width(512f).height(81f).padBottom(91f).row(); - menuTable.add(quitButton).width(512f).height(81f).row(); + // Menu table: + menuTable = new Table(); + menuTable.setPosition(0, 0); + menuTable.setSize(stage.getWidth(), stage.getHeight()); + menuTable.align(Align.center); - blackBg.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - blackBg.addAction(Actions.alpha(0.25f)); + Label menuTitle = new Label("Please select a save slot", skin, "default"); + menuTitle.setAlignment(Align.left); - // Options table: - optionsTable = new OptionsTable(game, skin, buttonUp, buttonDown, buttonOver, menuMusic, menuTable, blackBg, brandLogo); + menuTable.add(menuTitle).width(512f).row(); + menuTable.add(savegameTable).width(512f).maxWidth(640f).row(); + menuTable.add(quickTable).width(512f); - stage.addActor(blackBg); - stage.addActor(infoLabel); - stage.addActor(brandLogo); - stage.addActor(startLabel); stage.addActor(menuTable); - stage.addActor(optionsTable); - - menuTable.addAction(Actions.sequence(Actions.alpha(0f), Actions.moveTo(0f, -Gdx.graphics.getHeight() - Gdx.graphics.getHeight(), 0f))); - optionsTable.addAction(Actions.moveTo(Gdx.graphics.getWidth(), 0, 0f)); - - Gdx.input.setInputProcessor(new InputMultiplexer(this, new CrossProcessor(), stage)); - - // Setting the music: - if (game.prefs.getBoolean("music", true)) { - menuMusic.setLooping(true); - menuMusic.setVolume((game.prefs.getBoolean("music", true)) ? 1f : 0f); - menuMusic.play(); - } - } - - @Override public void show() { - brandLogo.setScale(100f); + // // Logo: + brandLogo = new Image(brandAtlas.findRegion("brand")); brandLogo.setPosition( - (Gdx.graphics.getWidth() / 2.0f) - (brandLogo.getWidth() / 2.0f), - (Gdx.graphics.getHeight() / 2.0f) - (brandLogo.getHeight() / 2.0f) + (stage.getWidth() / 2f) - (brandLogo.getWidth() / 2f), + stage.getHeight() - brandLogo.getHeight() * 1.5f ); brandLogo.setOrigin( - brandLogo.getWidth() / 2.0f, - brandLogo.getHeight() / 2.0f + brandLogo.getWidth() / 2f, + brandLogo.getHeight() / 2f ); brandLogo.addAction( - Actions.sequence( - Actions.alpha(0), - Actions.parallel( - Actions.fadeIn(1f), - Actions.scaleTo(1f, 1f, 1f, Interpolation.pow2InInverse) - ), - Actions.repeat( - RepeatAction.FOREVER, - Actions.sequence( - Actions.parallel( - Actions.rotateTo(-10, 10f, Interpolation.sine), - Actions.scaleTo(0.85f, 0.85f, 10f, Interpolation.sine) - ), - Actions.parallel( - Actions.rotateTo(10, 10f, Interpolation.sine), - Actions.scaleTo(1.25f, 1.25f, 10f, Interpolation.sine) - ) - ) - )) - ); - - startLabel.setPosition( - (Gdx.graphics.getWidth() / 2.0f) - (startLabel.getWidth() / 2.0f), - 32 - ); - - startLabel.addAction( Actions.repeat( RepeatAction.FOREVER, Actions.sequence( - Actions.alpha(0f), - Actions.fadeIn(1f), - Actions.delay(5f), - Actions.fadeOut(1f) + Actions.parallel( + Actions.rotateTo(-5f, 5f, Interpolation.smoother), + Actions.scaleTo(0.9f, 0.9f, 5f, Interpolation.smoother) + ), + Actions.parallel( + Actions.rotateTo(5f, 5f, Interpolation.smoother), + Actions.scaleTo(1.1f, 1.1f, 5f, Interpolation.smoother) + ) ) ) ); - infoLabel.setPosition(8, (Gdx.graphics.getHeight() - infoLabel.getHeight() - 8)); + stage.addActor(brandLogo); + + // Debug label: + DebugLabel debug = new DebugLabel(skin); + debug.setPosition(4, stage.getHeight() - debug.getHeight() - 4); + stage.addActor(debug); - // Start to render: - render(Gdx.graphics.getDeltaTime()); + Gdx.input.setInputProcessor(new InputMultiplexer(stage)); + // Generate background tiles: + bgMenuTiles = new ArrayList<>(); + genNewBgTiles((int) stage.getWidth(), (int) stage.getHeight()); + leafTiles = new ArrayList<>(); + delLeafTiles = new ArrayList<>(); + } + + @Override public void show() { + // Start to render: + render(Gdx.graphics.getDeltaTime()); } @Override @@ -224,46 +178,32 @@ public class MenuScreen implements Screen, InputProcessor { Gdx.gl.glClearColor(0, 0, 0, 1f); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); - if (anyKeyPressed && !brandActionsSet) { - startLabel.clearActions(); - startLabel.addAction(Actions.fadeOut(0.5f)); - - brandLogo.clearActions(); - brandLogo.addAction( - Actions.sequence( - Actions.parallel( - Actions.alpha(1f), - Actions.rotateTo(0f, 2f), - Actions.scaleTo(1f, 1f, 2f), - Actions.moveTo( - (Gdx.graphics.getWidth() / 2f) - (brandLogo.getWidth() / 2f), - (Gdx.graphics.getHeight() - brandLogo.getHeight()) - 81, - 2f, - Interpolation.sine - ) - ), - Actions.repeat(RepeatAction.FOREVER, - Actions.sequence( - Actions.parallel( - Actions.rotateTo(-5f, 5f, Interpolation.smoother), - Actions.scaleTo(0.9f, 0.9f, 5f, Interpolation.smoother) - ), - Actions.parallel( - Actions.rotateTo(5f, 5f, Interpolation.smoother), - Actions.scaleTo(1.1f, 1.1f, 5f, Interpolation.smoother) - ) - ))) - ); - - menuTable.clearActions(); - menuTable.addAction( - Actions.parallel( - Actions.fadeIn(1.5f), - Actions.moveTo(0, (Gdx.graphics.getHeight() / 2f) - (menuTable.getHeight() / 2f) - 64f, 2.5f, Interpolation.smoother) - ) - ); - - brandActionsSet = true; + // Generate a new leaf: + if (!isSummer) { + LeafParticle _leaf = new LeafParticle( + (isAutumn) ? environmentAtlas.findRegion("leaf") : environmentAtlas.findRegion("snowflake"), + (float) java.lang.Math.floor(java.lang.Math.random() * Gdx.graphics.getWidth()), + Gdx.graphics.getHeight(), + (float) Math.getRandomNumber(-257, 256) + 1, + (float) Math.getRandomNumber(-257, 256) + 1, + (float) Math.getRandomNumber(5, 15)); + + _leaf.setScale(5f); + + if (isAutumn) { + switch (Math.getRandomNumber(0, 3)) { + case 0: _leaf.setColor(Color.CORAL); break; + case 1: _leaf.setColor(Color.YELLOW); break; + default: _leaf.setColor(Color.RED); break; + } + } else { + switch (Math.getRandomNumber(0, 1)) { + case 0: _leaf.setColor(Color.WHITE); break; + case 1: _leaf.setColor(Color.SKY); + } + } + + leafTiles.add(_leaf); } game.batch.begin(); @@ -275,6 +215,10 @@ public class MenuScreen implements Screen, InputProcessor { } } + for (LeafParticle spr : leafTiles) { + spr.draw(game.batch); + } + game.batch.end(); for (ArrayList<Sprite> array : bgMenuTiles) { @@ -296,6 +240,17 @@ public class MenuScreen implements Screen, InputProcessor { } } + if (!isSummer) { + for (LeafParticle spr : leafTiles) { + if (spr.getX() > Gdx.graphics.getWidth() || spr.getY() > Gdx.graphics.getHeight()) { + delLeafTiles.add(spr); + } + } + + for (LeafParticle spr : delLeafTiles) { leafTiles.remove(spr); } + delLeafTiles.clear(); + } + stage.draw(); stage.act(delta); } @@ -304,24 +259,87 @@ public class MenuScreen implements Screen, InputProcessor { public void resize(int width, int height) { bgMenuTiles.clear(); - for (int i = 0; i < height / bgTile1.getHeight() + 1; i++) { + genNewBgTiles(width, height); + + stage.getViewport().update(width, height, true); + } + + private void loadSavegamesToTable(Table table) { + for (int i = 0; i < 3; i++) { + if (new File(MaxonConstants.GAME_SAVEGAME_FOLDER + String.format("/0%s.maxon", i)).exists()) { + final MaxonSavegame sav = GameDataSystem.load("0" + i + ".maxon"); + SaveGameWidget widget = new SaveGameWidget( + skin, widgetSkin, sav + ); + final int finalI = i; + widget.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + try { + game.setScreen(new GameScreen(game, sav, finalI)); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + dispose(); + } + }); + table.add(widget).width(512f).padBottom(8f).row(); + } else { + + final MaxonSavegame sav = new MaxonSavegame(); + final SaveGameWidget widget = new SaveGameWidget( + skin, widgetSkin, null + ); + final int finalI = i; + widget.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + sav.petId = 0; + sav.inv = new ArrayList<>(); + sav.multiplier = 5; + sav.points = 0; + sav.roomId = 0; + sav.seed = System.currentTimeMillis(); + sav.name = "SAVE " + (finalI + 1); + sav.elapsedTime = 0; + sav.lastTimestamp = System.currentTimeMillis(); + sav.outInv = new ArrayList<>(); + + GameDataSystem.save(sav, "0" + finalI + ".maxon"); + + try { + game.setScreen(new GameScreen(game, sav, finalI)); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + dispose(); + } + }); + table.add(widget).width(512f).padBottom(8f).row(); + } + } + } + + private void genNewBgTiles(int width, int height) { + bgMenuTiles.clear(); + + for (int i = 0; i < height / environmentAtlas.findRegion("tile").getRegionHeight() + 1; i++) { bgMenuTiles.add(i, new ArrayList<Sprite>()); - for (int j = -1; j < width / bgTile1.getWidth(); j++) { - Sprite spr = new Sprite(); + for (int j = -1; j < width / environmentAtlas.findRegion("tile").getRegionWidth(); j++) { + Sprite spr = new Sprite(environmentAtlas.findRegion("tile")); if ((j + i) % 2 == 0) { - spr.setTexture(bgTile1); + spr.setColor(0.98f, 0.71f, 0.22f, 1f); } else { - spr.setTexture(bgTile2); + spr.setColor(0.84f, 0.61f, 0.20f, 1f); } - spr.setSize(bgTile1.getWidth(), bgTile1.getHeight()); - spr.setPosition(bgTile1.getWidth() * j, bgTile1.getHeight() * i); + spr.setSize(64, 64); + + spr.setPosition(spr.getWidth() * j, spr.getHeight() * i); bgMenuTiles.get(i).add(spr); } } - - stage.getViewport().update(width, height, true); } @Override public void pause() {} @@ -331,50 +349,4 @@ public class MenuScreen implements Screen, InputProcessor { stage.clear(); skin.dispose(); } - - @Override - public boolean keyDown(int keycode) { - if (Gdx.input.isKeyPressed(Input.Keys.ANY_KEY)) { - anyKeyPressed = true; - } - return false; - } - - @Override - public boolean keyUp(int keycode) { - return false; - } - - @Override - public boolean keyTyped(char character) { - return false; - } - - @Override - public boolean touchDown(int screenX, int screenY, int pointer, int button) { - if (!anyKeyPressed) { - anyKeyPressed = true; - } - return false; - } - - @Override - public boolean touchUp(int screenX, int screenY, int pointer, int button) { - return false; - } - - @Override - public boolean touchDragged(int screenX, int screenY, int pointer) { - return false; - } - - @Override - public boolean mouseMoved(int screenX, int screenY) { - return false; - } - - @Override - public boolean scrolled(float amountX, float amountY) { - return false; - } } diff --git a/core/src/com/ilotterytea/maxoning/screens/SplashScreen.java b/core/src/com/ilotterytea/maxoning/screens/SplashScreen.java index 9eac50d..ccae6b1 100644 --- a/core/src/com/ilotterytea/maxoning/screens/SplashScreen.java +++ b/core/src/com/ilotterytea/maxoning/screens/SplashScreen.java @@ -1,133 +1,133 @@ package com.ilotterytea.maxoning.screens; import com.badlogic.gdx.*; -import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.scenes.scene2d.Stage; -import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Timer; import com.badlogic.gdx.utils.viewport.FillViewport; import com.ilotterytea.maxoning.MaxonGame; -import com.ilotterytea.maxoning.inputprocessors.CrossProcessor; -import com.ilotterytea.maxoning.ui.DebugLabel; +import com.ilotterytea.maxoning.utils.AssetLoading; +import com.ilotterytea.maxoning.utils.OsUtils; +import com.ilotterytea.maxoning.utils.math.Math; +import com.ilotterytea.maxoning.utils.serialization.GameDataSystem; -public class SplashScreen implements InputProcessor, Screen { +import java.io.IOException; +import java.util.ArrayList; + +public class SplashScreen implements Screen { final MaxonGame game; final Stage stage; final Skin skin; - final Image whiteSquare, dev, org; - final Label infoLabel, disclaimer, legalLabel; - - final Music introMusic; + TextureAtlas brandAtlas, envAtlas; + ArrayList<Sprite> contribList; + Image dev, pub; public SplashScreen(MaxonGame game) { this.game = game; - this.introMusic = game.assetManager.get("mus/menu/mus_menu_intro.ogg", Music.class); - this.stage = new Stage(new FillViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); this.skin = new Skin(Gdx.files.internal("main.skin")); - this.infoLabel = new DebugLabel(skin); - this.disclaimer = new Label(game.locale.TranslatableText("splash.disclaimer"), skin, "disclaimer"); - this.legalLabel = new Label("", skin, "disclaimer"); - - this.dev = new Image(game.assetManager.get("sprites/ilotterytea.png", Texture.class)); - this.org = new Image(game.assetManager.get("sprites/supadank.png", Texture.class)); - this.whiteSquare = new Image(game.assetManager.get("sprites/white.png", Texture.class)); - - disclaimer.setBounds(0, 0, 800, 600); - - infoLabel.setPosition( - 8, - (Gdx.graphics.getHeight() - infoLabel.getHeight()) - 8 - ); - - dev.setScale(5f); - - dev.setPosition( - (Gdx.graphics.getWidth() / 2.0f) - (dev.getWidth() * 5f / 2.0f), - (Gdx.graphics.getHeight() / 2.0f) - (dev.getHeight() * 5f / 2.0f) - ); - - org.setPosition( - (Gdx.graphics.getWidth() / 2.0f) - (org.getWidth() / 2.0f), - (Gdx.graphics.getHeight() / 2.0f) - (org.getHeight() / 2.0f) - ); - - disclaimer.setPosition( - (Gdx.graphics.getWidth() / 2.0f) - (800 / 2.0f), - (Gdx.graphics.getHeight() / 2.0f) - (600 / 2.0f) - ); - - whiteSquare.setPosition(0, 0); - whiteSquare.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - - dev.addAction(Actions.sequence( - Actions.alpha(0), - Actions.fadeIn(1f), - Actions.delay(5f), - Actions.fadeOut(0.25f) - )); - - org.addAction(Actions.sequence( - Actions.alpha(0f), - Actions.delay(7.3f), - Actions.fadeIn(2.5f), - Actions.delay(5f), - Actions.fadeOut(5f) - )); - - disclaimer.addAction( - Actions.sequence( - Actions.alpha(0f), - Actions.delay(19.8f), - Actions.fadeIn(1f), - Actions.delay(3f), - Actions.fadeOut(1f) - ) - ); - - whiteSquare.addAction(Actions.sequence( - Actions.alpha(0), - Actions.fadeIn(0.5f), - Actions.delay(25f), - Actions.fadeOut(0.5f) - )); - disclaimer.setWrap(true); - - stage.addActor(whiteSquare); - stage.addActor(infoLabel); - stage.addActor(dev); - stage.addActor(org); - stage.addActor(disclaimer); - - Gdx.input.setInputProcessor(new InputMultiplexer(this, new CrossProcessor(), stage)); + Table logoTable = new Table(); + + logoTable.setSize(stage.getWidth(), stage.getHeight()); + logoTable.setPosition(0, 0); + logoTable.align(Align.center); + + brandAtlas = new TextureAtlas(Gdx.files.internal("sprites/gui/ilotterytea.atlas")); + envAtlas = new TextureAtlas(Gdx.files.internal("sprites/env/environment.atlas")); + contribList = new ArrayList<>(); + + pub = new Image(brandAtlas.findRegion("org")); + logoTable.add(pub).size(pub.getWidth() * 5f, pub.getHeight() * 5f).pad(16f).row(); + + dev = new Image(brandAtlas.findRegion("devOld")); + logoTable.add(dev).size(dev.getWidth() * 5f, dev.getHeight() * 5f); + + stage.addActor(logoTable); + + AssetLoading.queue(game.assetManager); } @Override public void show() { - introMusic.setVolume((game.prefs.getBoolean("music", true)) ? 1f : 0f); - introMusic.play(); + int size = 64; + for (int i = 0; i < stage.getHeight() / size; i++) { + for (int j = 0; j < stage.getWidth() / size; j++) { + Sprite spr = new Sprite(envAtlas.findRegion("tile")); + spr.setSize(size, size); + spr.setPosition(size * j, size * i); + switch (Math.getRandomNumber(0, 5)) { + case 0: spr.setColor(Color.SKY); break; + case 1: spr.setColor(Color.PURPLE); break; + case 2: spr.setColor(Color.PINK); break; + case 3: spr.setColor(Color.CHARTREUSE); break; + case 4: spr.setColor(Color.ORANGE); break; + } + spr.setAlpha(0.25f); + contribList.add(spr); + } + } + + Timer.schedule(new Timer.Task() { + @Override + public void run() { + for (Sprite spr : contribList) { + switch (Math.getRandomNumber(0, 5)) { + case 0: spr.setColor(Color.SKY); break; + case 1: spr.setColor(Color.PURPLE); break; + case 2: spr.setColor(Color.PINK); break; + case 3: spr.setColor(Color.CHARTREUSE); break; + case 4: spr.setColor(Color.ORANGE); break; + } + spr.setAlpha(0.25f); + } + } + }, 1f, 1f); + render(Gdx.graphics.getDeltaTime()); } + private void update() { + if (game.assetManager.update()) { + AssetLoading.registerItems(game.assetManager, game.locale); + if (OsUtils.isAndroid || OsUtils.isIos) { + try { + game.setScreen(new GameScreen(game, GameDataSystem.load("latest.sav"), -1)); + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } else { + game.setScreen(new MenuScreen(game)); + } + dispose(); + } + } + @Override public void render(float delta) { Gdx.gl.glClearColor(0, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + game.batch.begin(); + for (Sprite spr : contribList) { + spr.draw(game.batch); + } + game.batch.end(); + stage.draw(); stage.act(delta); - if (!introMusic.isPlaying()) { - game.setScreen(new MenuScreen(game)); - } + update(); } @Override @@ -138,53 +138,8 @@ public class SplashScreen implements InputProcessor, Screen { @Override public void pause() {} @Override public void resume() {} @Override public void hide() { dispose(); } - @Override public void dispose() {} - - @Override - public boolean keyDown(int keycode) { - if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) { - Gdx.app.exit(); - } - if (Gdx.input.isKeyPressed(Input.Keys.ANY_KEY)) { - introMusic.stop(); - game.setScreen(new MenuScreen(game)); - dispose(); - } - return false; - } - - @Override - public boolean keyUp(int keycode) { - return false; - } - - @Override - public boolean keyTyped(char character) { - return false; - } - - @Override - public boolean touchDown(int screenX, int screenY, int pointer, int button) { - return false; - } - - @Override - public boolean touchUp(int screenX, int screenY, int pointer, int button) { - return false; - } - - @Override - public boolean touchDragged(int screenX, int screenY, int pointer) { - return false; - } - - @Override - public boolean mouseMoved(int screenX, int screenY) { - return false; - } - - @Override - public boolean scrolled(float amountX, float amountY) { - return false; + @Override public void dispose() { + brandAtlas.dispose(); + envAtlas.dispose(); } } diff --git a/core/src/com/ilotterytea/maxoning/ui/DebugLabel.java b/core/src/com/ilotterytea/maxoning/ui/DebugLabel.java index 9300962..5335450 100644 --- a/core/src/com/ilotterytea/maxoning/ui/DebugLabel.java +++ b/core/src/com/ilotterytea/maxoning/ui/DebugLabel.java @@ -1,18 +1,19 @@ package com.ilotterytea.maxoning.ui; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.ilotterytea.maxoning.MaxonConstants; public class DebugLabel extends Label { - private static final String str_placeholder = "%s\n%s fps"; + private static final String str_placeholder = "%s fps"; public DebugLabel(Skin skin) { - super(String.format(str_placeholder, MaxonConstants.GAME_VERSION, Gdx.graphics.getFramesPerSecond()), skin); + super(String.format(str_placeholder, Gdx.graphics.getFramesPerSecond()), skin, "debug"); + super.setColor(Color.LIME); } @Override public void act(float delta) { - super.setText(String.format(str_placeholder, MaxonConstants.GAME_VERSION, Gdx.graphics.getFramesPerSecond())); + super.setText(String.format(str_placeholder, Gdx.graphics.getFramesPerSecond())); } } diff --git a/core/src/com/ilotterytea/maxoning/ui/LeafParticle.java b/core/src/com/ilotterytea/maxoning/ui/LeafParticle.java new file mode 100644 index 0000000..24df879 --- /dev/null +++ b/core/src/com/ilotterytea/maxoning/ui/LeafParticle.java @@ -0,0 +1,30 @@ +package com.ilotterytea.maxoning.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.TextureRegion; + +public class LeafParticle extends Sprite { + private float angle, x, y, vertAngle, rotation, time; + + public LeafParticle(TextureRegion region, float x, float y, float angle, float vertAngle, float rotation) { + super(region); + this.angle = angle; + this.vertAngle = vertAngle; + this.rotation = rotation; + this.x = x; + this.y = y; + } + + @Override + public void draw(Batch batch) { + this.time = Gdx.graphics.getDeltaTime(); + this.x -= (float) Math.sin(time) * this.angle; + this.y -= (float) Math.sin(time) * this.vertAngle; + + super.setPosition(x, y); + super.setRotation(super.getRotation() + this.rotation); + super.draw(batch); + } +} diff --git a/core/src/com/ilotterytea/maxoning/ui/OptionsTable.java b/core/src/com/ilotterytea/maxoning/ui/OptionsTable.java index 2dbe61f..0794e31 100644 --- a/core/src/com/ilotterytea/maxoning/ui/OptionsTable.java +++ b/core/src/com/ilotterytea/maxoning/ui/OptionsTable.java @@ -3,14 +3,10 @@ package com.ilotterytea.maxoning.ui; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.files.FileHandle; -import com.badlogic.gdx.graphics.g2d.NinePatch; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.actions.Actions; -import com.badlogic.gdx.scenes.scene2d.ui.Image; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.Skin; -import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.utils.Align; import com.ilotterytea.maxoning.MaxonConstants; @@ -25,9 +21,7 @@ public class OptionsTable extends Table { public OptionsTable( final MaxonGame game, Skin skin, - NinePatch buttonUp, - NinePatch buttonDown, - NinePatch buttonOver, + Skin widgetSkin, final Music music, final Table menuTable, final Image bgImage, @@ -42,7 +36,7 @@ public class OptionsTable extends Table { Table lidlOptionsTable = new Table(); // Music button: - final NinepatchButton musicButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.FormattedText("options.music", (game.prefs.getBoolean("music", true)) ? "ON" : "OFF"), skin, "default"); + final TextButton musicButton = new TextButton(game.locale.FormattedText("options.music", (game.prefs.getBoolean("music", true)) ? "ON" : "OFF"), widgetSkin, "default"); musicButton.addListener(new ClickListener() { @Override @@ -64,7 +58,7 @@ public class OptionsTable extends Table { lidlOptionsTable.add(musicButton).size(512f, 81f).pad(10f).left(); - final NinepatchButton soundButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.FormattedText("options.sound", (game.prefs.getBoolean("sound", true)) ? "ON" : "OFF"), skin, "default"); + final TextButton soundButton = new TextButton(game.locale.FormattedText("options.sound", (game.prefs.getBoolean("sound", true)) ? "ON" : "OFF"), widgetSkin, "default"); soundButton.addListener(new ClickListener() { @Override @@ -78,7 +72,7 @@ public class OptionsTable extends Table { lidlOptionsTable.add(soundButton).size(512f, 81f).pad(10f).right().row(); - final NinepatchButton vsyncButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.FormattedText("options.vsync", (game.prefs.getBoolean("vsync", true)) ? "ON" : "OFF"), skin, "default"); + final TextButton vsyncButton = new TextButton(game.locale.FormattedText("options.vsync", (game.prefs.getBoolean("vsync", true)) ? "ON" : "OFF"), widgetSkin, "default"); vsyncButton.addListener(new ClickListener() { @Override @@ -98,7 +92,7 @@ public class OptionsTable extends Table { lidlOptionsTable.add(vsyncButton).size(512f, 81f).pad(10f).left(); - final NinepatchButton fullscreenButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.FormattedText("options.fullscreen", (game.prefs.getBoolean("fullscreen", false)) ? "ON" : "OFF"), skin, "default"); + final TextButton fullscreenButton = new TextButton(game.locale.FormattedText("options.fullscreen", (game.prefs.getBoolean("fullscreen", false)) ? "ON" : "OFF"), widgetSkin, "default"); fullscreenButton.addListener(new ClickListener() { @Override @@ -123,7 +117,7 @@ public class OptionsTable extends Table { String[] fh4Locale = game.locale.getFileHandle().nameWithoutExtension().split("_"); Locale locale = new Locale(fh4Locale[0], fh4Locale[1]); - final NinepatchButton switchLangButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.FormattedText("options.language", locale.getDisplayLanguage(), locale.getDisplayCountry()), skin, "default"); + final TextButton switchLangButton = new TextButton(game.locale.FormattedText("options.language", locale.getDisplayLanguage(), locale.getDisplayCountry()), widgetSkin, "default"); switchLangButton.addListener(new ClickListener() { @Override @@ -154,7 +148,7 @@ public class OptionsTable extends Table { super.add(switchLangButton).size(1024f, 81f).padTop(91f).center().row(); - final NinepatchButton optionsCloseButton = new NinepatchButton(buttonUp, buttonDown, buttonOver, game.locale.TranslatableText("options.close"), skin, "default"); + final TextButton optionsCloseButton = new TextButton(game.locale.TranslatableText("options.close"), widgetSkin, "default"); optionsCloseButton.addListener(new ClickListener() { @Override diff --git a/core/src/com/ilotterytea/maxoning/ui/PurchaseItem.java b/core/src/com/ilotterytea/maxoning/ui/PurchaseItem.java index 97a78e7..b8c44f9 100644 --- a/core/src/com/ilotterytea/maxoning/ui/PurchaseItem.java +++ b/core/src/com/ilotterytea/maxoning/ui/PurchaseItem.java @@ -1,19 +1,18 @@ package com.ilotterytea.maxoning.ui; -import com.badlogic.gdx.graphics.g2d.NinePatch; import com.badlogic.gdx.scenes.scene2d.ui.*; import com.badlogic.gdx.utils.Align; public class PurchaseItem extends Stack { public PurchaseItem( Skin skin, - NinePatch ninepatch, + Skin widgetSkin, AnimatedImage icon, CharSequence name, CharSequence desc, - float price + String price ) { - super(new Image(ninepatch)); + super(new Image(widgetSkin, "up")); Table summary = new Table(); summary.setHeight(super.getHeight()); diff --git a/core/src/com/ilotterytea/maxoning/ui/SaveGameWidget.java b/core/src/com/ilotterytea/maxoning/ui/SaveGameWidget.java new file mode 100644 index 0000000..2bb4a81 --- /dev/null +++ b/core/src/com/ilotterytea/maxoning/ui/SaveGameWidget.java @@ -0,0 +1,90 @@ +package com.ilotterytea.maxoning.ui; + + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Null; +import com.ilotterytea.maxoning.player.MaxonSavegame; +import com.ilotterytea.maxoning.utils.formatters.NumberFormatter; + +public class SaveGameWidget extends Button { + public SaveGameWidget( + Skin skin, + Skin widgetSkin, + @Null MaxonSavegame sav + ) { + // Setting the stack: + super(widgetSkin, "slot"); + + // // // Save slot data: + // // Info row: + Table infoTable = new Table(); + + // Top left label (name): + Label topleftLabel = new Label((sav != null) ? sav.name : "[EMPTY]", skin); + topleftLabel.setAlignment(Align.left); + infoTable.add(topleftLabel).width(256f); + + // Top right label (elapsed time): + String time = "--:--"; + + if (sav != null) { + long h = sav.elapsedTime / 1000 / 60 / 60; + long m = sav.elapsedTime / 1000 / 60; + + time = String.format( + "%s:%s", + ((h < 10) ? "0" : "") + h, + ((m < 10) ? "0" : "") + m + ); + } + + Label toprightLabel = new Label( + time, + skin + ); + toprightLabel.setAlignment(Align.right); + infoTable.add(toprightLabel).width(256f); + + // // Description row: + Table descTable = new Table(); + + // Bottom left label (purchased items): + Label bottomleftLabel = new Label( + String.format( + "%s purchased items", + (sav != null) ? sav.inv.size() : "?" + ), + skin + ); + bottomleftLabel.setAlignment(Align.left); + descTable.add(bottomleftLabel).width(256f); + + // Bottom right label (points/multiplier): + Label pointsLabel = new Label( + String.format( + "%s$/x%s", + (sav != null) ? NumberFormatter.format(sav.points) : "---", + (sav != null) ? NumberFormatter.format(sav.multiplier) : "0" + ), + skin + ); + pointsLabel.setAlignment(Align.right); + descTable.add(pointsLabel).width(256f); + + // Adding the tables to main table: + Table summaryTable = new Table(); + summaryTable.add(infoTable).pad(5f).row(); + summaryTable.add(descTable).pad(5f).row(); + + if (sav == null) { + topleftLabel.setColor(Color.DARK_GRAY); + toprightLabel.setColor(Color.DARK_GRAY); + bottomleftLabel.setColor(Color.DARK_GRAY); + pointsLabel.setColor(Color.DARK_GRAY); + } + + super.add(summaryTable); + } +} diff --git a/core/src/com/ilotterytea/maxoning/utils/AssetLoading.java b/core/src/com/ilotterytea/maxoning/utils/AssetLoading.java index c8b76ba..aba31fa 100644 --- a/core/src/com/ilotterytea/maxoning/utils/AssetLoading.java +++ b/core/src/com/ilotterytea/maxoning/utils/AssetLoading.java @@ -3,6 +3,7 @@ package com.ilotterytea.maxoning.utils; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.audio.Music; import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.ilotterytea.maxoning.anim.SpriteUtils; import com.ilotterytea.maxoning.player.MaxonItemEnum; import com.ilotterytea.maxoning.player.MaxonItemRegister; @@ -10,10 +11,14 @@ import com.ilotterytea.maxoning.ui.AnimatedImage; public class AssetLoading { public static void queue(AssetManager am) { - - // Textures: - am.load("sprites/supadank.png", Texture.class); - + // Texture atlases: + am.load("sprites/env/environment.atlas", TextureAtlas.class); + am.load("sprites/gui/brand.atlas", TextureAtlas.class); + am.load("sprites/gui/icons.atlas", TextureAtlas.class); + am.load("sprites/gui/ilotterytea.atlas", TextureAtlas.class); + am.load("sprites/gui/widgets.atlas", TextureAtlas.class); + + // Cat item textures: am.load("sprites/sheet/loadingCircle.png", Texture.class); am.load("sprites/sheet/bror.png", Texture.class); am.load("sprites/sheet/manlooshka.png", Texture.class); @@ -31,20 +36,6 @@ public class AssetLoading { am.load("sprites/sheet/aeae.png", Texture.class); am.load("sprites/sheet/succat.png", Texture.class); - am.load("sprites/white.png", Texture.class); - am.load("sprites/black.png", Texture.class); - am.load("sprites/brand.png", Texture.class); - am.load("sprites/ilotterytea.png", Texture.class); - - am.load("sprites/menu/tile_1.png", Texture.class); - am.load("sprites/menu/tile_2.png", Texture.class); - - // // Ninepatches: - am.load("sprites/ui/sqrbutton.png", Texture.class); - am.load("sprites/ui/sqrbutton_down.png", Texture.class); - am.load("sprites/ui/sqrbutton_over.png", Texture.class); - am.load("sprites/ui/sqrbutton_disabled.png", Texture.class); - // Music: am.load("mus/menu/mus_menu_intro.ogg", Music.class); am.load("mus/menu/mus_menu_loop.ogg", Music.class); diff --git a/core/src/com/ilotterytea/maxoning/utils/formatters/NumberFormatter.java b/core/src/com/ilotterytea/maxoning/utils/formatters/NumberFormatter.java new file mode 100644 index 0000000..96c0258 --- /dev/null +++ b/core/src/com/ilotterytea/maxoning/utils/formatters/NumberFormatter.java @@ -0,0 +1,32 @@ +package com.ilotterytea.maxoning.utils.formatters; + +import java.util.Map; +import java.util.NavigableMap; +import java.util.TreeMap; + +public class NumberFormatter { + private static final NavigableMap<Long, String> suffixes = new TreeMap<>(); + static { + suffixes.put(1_000L, "k"); + suffixes.put(1_000_000L, "M"); + suffixes.put(1_000_000_000L, "G"); + suffixes.put(1_000_000_000_000L, "T"); + suffixes.put(1_000_000_000_000_000L, "P"); + suffixes.put(1_000_000_000_000_000_000L, "E"); + } + + public static String format(long value) { + //Long.MIN_VALUE == -Long.MIN_VALUE so we need an adjustment here + if (value == Long.MIN_VALUE) return format(Long.MIN_VALUE + 1); + if (value < 0) return "-" + format(-value); + if (value < 1000) return Long.toString(value); //deal with easy case + + Map.Entry<Long, String> e = suffixes.floorEntry(value); + Long divideBy = e.getKey(); + String suffix = e.getValue(); + + long truncated = value / (divideBy / 10); //the number part of the output times 10 + boolean hasDecimal = truncated < 100 && (truncated / 10d) != (truncated / 10); + return hasDecimal ? (truncated / 10d) + suffix : (truncated / 10) + suffix; + } +} diff --git a/core/src/com/ilotterytea/maxoning/utils/math/Math.java b/core/src/com/ilotterytea/maxoning/utils/math/Math.java new file mode 100644 index 0000000..0bb8aa8 --- /dev/null +++ b/core/src/com/ilotterytea/maxoning/utils/math/Math.java @@ -0,0 +1,13 @@ +package com.ilotterytea.maxoning.utils.math; + +public class Math { + /** + * Get random number from min value to max value + * @param min Minimal value + * @param max Maximum value + * @return Random number between minimal and maximum values + */ + public static int getRandomNumber(int min, int max) { + return (int) ((java.lang.Math.random() * (max - min)) + min); + } +} diff --git a/core/src/com/ilotterytea/maxoning/utils/serialization/GameDataSystem.java b/core/src/com/ilotterytea/maxoning/utils/serialization/GameDataSystem.java index a10d98a..3e64c45 100644 --- a/core/src/com/ilotterytea/maxoning/utils/serialization/GameDataSystem.java +++ b/core/src/com/ilotterytea/maxoning/utils/serialization/GameDataSystem.java @@ -1,35 +1,99 @@ package com.ilotterytea.maxoning.utils.serialization; +import com.badlogic.gdx.utils.Null; +import com.google.gson.Gson; import com.ilotterytea.maxoning.MaxonConstants; -import com.ilotterytea.maxoning.player.MaxonPlayer; +import com.ilotterytea.maxoning.player.MaxonSavegame; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.*; +import java.util.ArrayList; +/** + * External game data system control. + * @author NotDankEnough + * @since Alpha 1.0 + */ public class GameDataSystem { private static final File dir = new File(MaxonConstants.GAME_SAVEGAME_FOLDER); - private static final File file = new File(dir.getPath() + "/savegame.sav"); + private static final Gson gson = new Gson(); + private static final Logger log = LoggerFactory.getLogger(GameDataSystem.class.getSimpleName()); - public static boolean exists() { return file.exists(); } + /** + * Get all savefiles from savegame directory (/.Maxoning/savegames/) + * @return Array of MaxonSavegames + * @see MaxonSavegame + */ + public static ArrayList<MaxonSavegame> getSavegames() { + ArrayList<MaxonSavegame> saves = new ArrayList<>(); + File[] files = dir.listFiles(); - public static void SaveData(MaxonPlayer player) throws IOException { - if (!dir.exists()) { - dir.mkdirs(); + assert files != null; + for (File file : files) { + try { + + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + + MaxonSavegame sav = gson.fromJson(ois.readUTF(), MaxonSavegame.class); + saves.add(sav); + + ois.close(); + fis.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } } - FileOutputStream fo = new FileOutputStream(file); - ObjectOutputStream out = new ObjectOutputStream(fo); - out.writeObject(player); - out.close(); + return saves; + } + + /** + * Convert <b>MaxonSavegame</b> class to <b>JSON</b> string and write in UTF-8 encoding (I'm sorry, encryption enjoyers). + * @param savegame Save game object. + * @param file_name File name. + * @see MaxonSavegame + */ + public static void save(@NotNull MaxonSavegame savegame, @NotNull String file_name) { + try { + log.info("Saving the game..."); + FileOutputStream fos = new FileOutputStream(String.format("%s/%s", dir.getAbsolutePath(), file_name)); + ObjectOutputStream oos = new ObjectOutputStream(fos); + + oos.writeUTF(gson.toJson(savegame)); + oos.close(); + log.info(String.format("Success! Savegame located at %s/%s", dir.getAbsolutePath(), file_name)); + } catch (IOException e) { + throw new RuntimeException(e); + } } - public static MaxonPlayer LoadData() throws IOException, ClassNotFoundException { - FileInputStream fi = new FileInputStream(file); - ObjectInputStream oi = new ObjectInputStream(fi); + /** + * Reading a <b>JSON</b> string from the file and convert to <b>MaxonSavegame</b> class. + * @param file_name File name. If null - it will get the first file by last modified time. + * @return Filled <b>MaxonSavegame</b> class + * @see MaxonSavegame + */ + public static MaxonSavegame load(@Null String file_name) { + MaxonSavegame sav = new MaxonSavegame(); + + if (new File(dir.getAbsolutePath() + "/" + file_name).exists()) { + try { + log.info(String.format("Trying to get the savegame at %s/%s...", dir.getAbsolutePath(), file_name)); + FileInputStream fis = new FileInputStream(String.format("%s/%s", dir.getAbsolutePath(), file_name)); + ObjectInputStream oos = new ObjectInputStream(fis); - MaxonPlayer pl = (MaxonPlayer) oi.readObject(); + sav = gson.fromJson(oos.readUTF(), MaxonSavegame.class); + oos.close(); + + log.info(String.format("Successfully loaded the savegame from %s/%s!", dir.getAbsolutePath(), file_name)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } - oi.close(); - fi.close(); - return pl; + return sav; } } |
