diff options
| author | ilotterytea <iltsu@alright.party> | 2024-06-01 00:51:20 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2024-06-01 00:51:20 +0500 |
| commit | e49f8b310d6032c99406baf04b5ec3eba0fd111f (patch) | |
| tree | 5120a1fbbf923da5ee8bc8561ed1545855aa5547 /core/src/kz/ilotterytea/maxon/screens | |
| parent | 10e9df6190ddc3f9c8dd7c86482449bec4651e0c (diff) | |
upd: moved the whole project under kz.ilotterytea.maxon name
Diffstat (limited to 'core/src/kz/ilotterytea/maxon/screens')
6 files changed, 1357 insertions, 0 deletions
diff --git a/core/src/kz/ilotterytea/maxon/screens/GameScreen.java b/core/src/kz/ilotterytea/maxon/screens/GameScreen.java new file mode 100644 index 0000000..a6dcace --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/screens/GameScreen.java @@ -0,0 +1,603 @@ +package kz.ilotterytea.maxon.screens; + +import com.badlogic.gdx.*; +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.graphics.*; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g3d.decals.CameraGroupStrategy; +import com.badlogic.gdx.graphics.g3d.decals.Decal; +import com.badlogic.gdx.graphics.g3d.decals.DecalBatch; +import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.math.Vector3; +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.utils.Align; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import kz.ilotterytea.maxon.MaxonConstants; +import kz.ilotterytea.maxon.MaxonGame; +import kz.ilotterytea.maxon.anim.SpriteUtils; +import kz.ilotterytea.maxon.audio.Playlist; +import kz.ilotterytea.maxon.inputprocessors.CrossProcessor; +import kz.ilotterytea.maxon.player.DecalPlayer; +import kz.ilotterytea.maxon.player.MaxonItem; +import kz.ilotterytea.maxon.player.MaxonItemRegister; +import kz.ilotterytea.maxon.player.MaxonSavegame; +import kz.ilotterytea.maxon.screens.game.shop.ShopUI; +import kz.ilotterytea.maxon.ui.*; +import kz.ilotterytea.maxon.utils.math.Math; +import kz.ilotterytea.maxon.utils.serialization.GameDataSystem; +import com.rafaskoberg.gdx.typinglabel.TypingLabel; +import net.mgsx.gltf.scene3d.attributes.PBRCubemapAttribute; +import net.mgsx.gltf.scene3d.attributes.PBRTextureAttribute; +import net.mgsx.gltf.scene3d.lights.DirectionalShadowLight; +import net.mgsx.gltf.scene3d.lights.PointLightEx; +import net.mgsx.gltf.scene3d.scene.Scene; +import net.mgsx.gltf.scene3d.scene.SceneAsset; +import net.mgsx.gltf.scene3d.scene.SceneManager; +import net.mgsx.gltf.scene3d.scene.SceneSkybox; +import net.mgsx.gltf.scene3d.utils.IBLBuilder; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Map; + +public class GameScreen implements Screen, InputProcessor { + final MaxonGame game; + final int slotId; + final long playTimestamp; + boolean isShopping = false, isInventoryEnabled = false; + + MaxonSavegame player; + + Stage stage; + Skin skin; + + TextureAtlas mainAtlas; + + Label pointsLabel, multiplierLabel; + AnimatedImage cat; + AnimatedImageButton maxon; + + Table boardTable, quickTable; + + Dialog notEnoughPointsDialog; + + ArrayList<MaxonItem> items; + Map<Integer, Integer> invItems; + + MovingChessBackground bg; + Playlist playlist; + + private ShopUI shopUI; + + private SceneManager sceneManager; + private PerspectiveCamera camera; + + private DecalBatch decalBatch; + private ArrayList<Decal> decals; + private DecalPlayer decalPlayer; + + private final MaxonSavegame savegame; + + public GameScreen(MaxonGame game, MaxonSavegame sav, int slotId) throws IOException, ClassNotFoundException { + this.savegame = sav; + + this.game = game; + this.slotId = slotId; + this.playTimestamp = System.currentTimeMillis(); + + create3D(); + + decalBatch = new DecalBatch(new CameraGroupStrategy(camera)); + decals = new ArrayList<>(); + + TextureRegion[] playerTextureRegions = SpriteUtils.splitToTextureRegions(game.assetManager.get("sprites/sheet/loadingCircle.png", Texture.class), 112, 112, 10, 5); + decalPlayer = new DecalPlayer(sav, playerTextureRegions); + decals.add(decalPlayer.getDecal()); + + playlist = new Playlist( + game.assetManager.get("mus/game/onwards.wav", Music.class), + game.assetManager.get("mus/game/paris.wav", Music.class), + game.assetManager.get("mus/game/adieu.wav", Music.class), + game.assetManager.get("mus/game/shopping_spree.wav", Music.class) + ); + playlist.setShuffleMode(true); + if (game.prefs.getBoolean("music", true)) playlist.next(); + + player = sav; + items = new ArrayList<>(); + + createStageUI(); + + Gdx.input.setInputProcessor(new InputMultiplexer(this, new CrossProcessor(), stage)); + } + + @Override + public void show() { + Timer.schedule(new Timer.Task() { + @Override + public void run() { + GameDataSystem.save(player, "latest.sav"); + } + }, 10, 10); + + Timer.schedule(new Timer.Task() { + @Override + public void run() { + float multiplier = 0; + + for (MaxonItem item : items) { + multiplier += item.multiplier; + } + + player.points += multiplier; + + final TypingLabel label = new TypingLabel(game.locale.FormattedText("game.newPoint", MaxonConstants.DECIMAL_FORMAT.format(player.multiplier)), skin, "default"); + + label.setPosition( + maxon.getX(), + maxon.getY() + maxon.getHeight() + ); + + label.setWidth(maxon.getWidth()); + + label.setAlignment(Align.center); + + label.addAction(Actions.parallel( + Actions.fadeOut(5f), + Actions.moveTo( + label.getX(), label.getY() + Math.getRandomNumber(10, 156), 5f, Interpolation.exp5Out) + )); + + Timer.schedule(new Timer.Task() { + @Override + public void run() { + label.remove(); + } + }, 10f); + + stage.addActor(label); + } + }, 5, 5); + + // Random gifts: + Timer.schedule(new Timer.Task() { + @Override + public void run() { + final ImageButton gift = new ImageButton(skin, "gift"); + gift.setPosition(stage.getWidth() + gift.getWidth(), Math.getRandomNumber((int) gift.getHeight(), (int) stage.getHeight() - (int) gift.getHeight())); + gift.addAction( + Actions.repeat( + 3, + Actions.sequence( + Actions.moveTo(-gift.getWidth(), gift.getY(), 15f, Interpolation.linear), + Actions.moveTo(stage.getWidth() + gift.getWidth(), Math.getRandomNumber((int) gift.getHeight(), (int) stage.getHeight() - (int) gift.getHeight()), 15f, Interpolation.linear) + ) + ) + ); + + + gift.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + int giftId = Math.getRandomNumber(0, 25); + final TypingLabel label = new TypingLabel(game.locale.TranslatableText("gifts.empty"), skin); + + switch (giftId) { + // Points + case 0: + int randPoints = Math.getRandomNumber(150, 3000); + label.setText(game.locale.FormattedText("gifts.points", String.valueOf(randPoints))); + player.points += randPoints; + break; + + // Multiplier + case 1: + int randMp = Math.getRandomNumber(1, 10); + label.setText(game.locale.FormattedText("gifts.multiplier", String.valueOf(randMp))); + player.multiplier += randMp; + break; + + + // Random pet + case 2: + int randPet = Math.getRandomNumber(0, 1); + assert MaxonItemRegister.get(randPet) != null; + String name = MaxonItemRegister.get(randPet).name; + label.setText(game.locale.FormattedText("gifts.new_pet", name)); + player.inv.add(randPet); + if (invItems.containsKey(randPet)) { + invItems.put(randPet, invItems.get(randPet) + 1); + } else { + invItems.put(randPet, 1); + } + break; + // Default + default: + break; + } + + label.setPosition( + gift.getX(), + gift.getY() + ); + + label.addAction(Actions.sequence( + Actions.delay(3f), + Actions.fadeOut(2f) + )); + + stage.addActor(label); + gift.remove(); + + Timer.schedule(new Timer.Task() { + @Override + public void run() { + label.remove(); + } + }, 5f); + } + }); + + stage.addActor(gift); + } + }, 600, 600); + + camera.update(); + render(Gdx.graphics.getDeltaTime()); + } + + @Override + public void render(float delta) { + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); + + if (game.prefs.getBoolean("music", true) && !playlist.getPlayingNow().isPlaying()) { + playlist.next(); + } + + // i've temporarily commented it all out while i set up 3d + //game.batch.begin(); + + //bg.draw(game.batch); + + //game.batch.end(); + + // Update the points label: + //pointsLabel.setText(game.locale.FormattedText("game.points", + // MaxonConstants.DECIMAL_FORMAT.format(player.points) + //)); + + // Update the multiplier label: + //multiplierLabel.setText(game.locale.FormattedText("game.multiplier", + // MaxonConstants.DECIMAL_FORMAT.format(player.multiplier) + //)); + + // Render 3D + sceneManager.update(Gdx.graphics.getDeltaTime()); + sceneManager.render(); + + this.decalPlayer.render(this.camera); + + for (Decal decal : this.decals) { + decal.lookAt(this.camera.position, this.camera.up); + this.decalBatch.add(decal); + } + + this.decalBatch.flush(); + + stage.act(delta); + stage.draw(); + + shopUI.render(); + } + + @Override + public void resize(int width, int height) { + this.stage.getViewport().update(width, height, true); + sceneManager.updateViewport(width, height); + this.shopUI.update(); + } + + private void showShop() { + // - - - - - - S H O P T A B L E - - - - - - : + final Table shopTable = new Table(skin); + shopTable.setBackground("bg"); + shopTable.setSize(stage.getWidth() - 20f, stage.getHeight() - (boardTable.getHeight() + quickTable.getHeight() + 20f)); + shopTable.setPosition(10f, quickTable.getHeight() + 10f); + shopTable.align(Align.top | Align.center); + + stage.addActor(shopTable); + + // Header table: + Table headShopTable = new Table(); + shopTable.add(headShopTable).width(shopTable.getWidth()).row(); + + // - - - S H O P T I T L E - - -: + Label shopTitle = new Label(game.locale.TranslatableText("game.petShop"), skin); + headShopTable.add(shopTitle).expandX(); + + // - - - C L O S E B U T T O N - - - : + TextButton closeButton = new TextButton("X", skin); + + closeButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + shopTable.remove(); + isShopping = !isShopping; + } + }); + + headShopTable.add(closeButton).row(); + + // - - - S H O P C O N T E N T - - - : + Table contentTable = new Table(); + + // Adding items to shop: + for (final MaxonItem item : MaxonItemRegister.getItems()) { + PurchaseItem p_item = new PurchaseItem( + skin, + item + ); + + p_item.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (player.points < item.price) { + notEnoughPointsDialog.show(stage); + + Timer.schedule(new Timer.Task() { + @Override + public void run() { + notEnoughPointsDialog.hide(Actions.fadeOut(2f, Interpolation.smoother)); + } + }, 2); + + return; + } + + player.points -= item.price; + player.multiplier += item.multiplier; + player.inv.add(item.id); + + if (invItems.containsKey(item.id)) { + invItems.put(item.id, invItems.get(item.id) + 1); + } else { + invItems.put(item.id, 1); + } + } + }); + + contentTable.add(p_item).pad(6f).width(shopTable.getWidth()).row(); + } + + // Scroll panel for content table: + ScrollPane contentPane = new ScrollPane(contentTable); + contentPane.setScrollingDisabled(true, false); + shopTable.add(contentPane); + } + + private void showInventory() { + // - - - - - - I N V E N T O R Y T A B L E - - - - - - : + final Table inventoryTable = new Table(skin); + inventoryTable.setBackground("bg"); + inventoryTable.setSize(stage.getWidth() - 20f, stage.getHeight() - (boardTable.getHeight() + quickTable.getHeight() + 20f)); + inventoryTable.setPosition(10f, quickTable.getHeight() + 10f); + inventoryTable.align(Align.top | Align.center); + + stage.addActor(inventoryTable); + + // Header table: + Table headInventoryTable = new Table(); + inventoryTable.add(headInventoryTable).width(inventoryTable.getWidth()).row(); + + // - - - S H O P T I T L E - - -: + Label inventoryTitle = new Label(game.locale.TranslatableText("game.inventory.title"), skin); + headInventoryTable.add(inventoryTitle).expandX(); + + // - - - C L O S E B U T T O N - - - : + TextButton closeButton = new TextButton("X", skin); + + closeButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + inventoryTable.remove(); + isInventoryEnabled = !isInventoryEnabled; + } + }); + + headInventoryTable.add(closeButton).row(); + + // - - - I N V E N T O R Y C O N T E N T - - - : + Table contentTable = new Table(); + contentTable.align(Align.left); + + // Adding items to inventory: + for (int i = 0; i < invItems.keySet().size(); i++) { + MaxonItem item = MaxonItemRegister.get(i); + + if (item != null) { + InventoryAnimatedItem invItem = new InventoryAnimatedItem(item, skin, invItems.get(i)); + Cell<InventoryAnimatedItem> cell = contentTable.add(invItem).size(64, 64).pad(5f); + + if (i != 0 && i % (inventoryTable.getWidth() / 69f) == 0) { + cell.row(); + } + } + }; + + // Scroll panel for content table: + ScrollPane contentPane = new ScrollPane(contentTable); + contentPane.setScrollingDisabled(true, false); + inventoryTable.add(contentPane); + } + + @Override public void pause() {} + + @Override public void resume() {} + + @Override public void hide() { + playlist.getPlayingNow().stop(); + dispose(); + } + + @Override + public void dispose() { + stage.clear(); + } + + @Override + public boolean keyDown(int keycode) { + if (Gdx.input.isKeyPressed(Input.Keys.ESCAPE)) { + 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(); + } + //if (Gdx.input.isKeyPressed(Input.Keys.SPACE) || Gdx.input.isKeyPressed(Input.Keys.UP)) { + // displayPointIncrease(); + //} + return false; + } + + private void displayPointIncrease() { + cat.nextFrame(); + maxon.setDrawable(cat.getDrawable()); + + player.points += player.multiplier; + + final TypingLabel label = new TypingLabel(game.locale.FormattedText("game.newPoint", MaxonConstants.DECIMAL_FORMAT.format(player.multiplier)), skin, "default"); + + label.setPosition( + maxon.getX(), + maxon.getY() + maxon.getHeight() + ); + + label.setWidth(maxon.getWidth()); + + label.setAlignment(Align.center); + + label.addAction(Actions.parallel( + Actions.fadeOut(5f), + Actions.moveTo( + label.getX(), label.getY() + Math.getRandomNumber(10, 156), 5f, Interpolation.exp5Out) + )); + + Timer.schedule(new Timer.Task() { + @Override + public void run() { + label.remove(); + } + }, 10f); + + stage.addActor(label); + } + + private void create3D() { + SceneAsset sceneAsset = game.assetManager.get("models/scenes/living_room.glb", SceneAsset.class); + Scene scene = new Scene(sceneAsset.scene); + + sceneManager = new SceneManager(); + sceneManager.addScene(scene); + + camera = new PerspectiveCamera(60f, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + camera.near = 1f; + camera.far = 300f; + camera.position.set(-3f, 2f, -0.3f); + camera.rotate(256f, 0f, 1f, 0f); + + camera.update(); + + sceneManager.setCamera(camera); + + DirectionalShadowLight light = new DirectionalShadowLight(1024, 1024, 60f, 60f, 1f, 300f); + light.set(new Color(0xdcccffff), -1f, -0.8f, -0.2f); + light.intensity = 5f; + sceneManager.environment.add(light); + sceneManager.environment.shadowMap = light; + + PointLightEx signLight = new PointLightEx(); + signLight.set(Color.PINK, new Vector3(2f, 6f, 2f), 80f, 100f); + + PointLightEx windowLight = new PointLightEx(); + windowLight.set(Color.BLUE, new Vector3(-1.1f, 7.3f, 0.5f), 80f, 100f); + + sceneManager.environment.add(windowLight, signLight); + + // setup quick IBL (image based lighting) + IBLBuilder iblBuilder = IBLBuilder.createOutdoor(light); + Cubemap environmentCubemap = iblBuilder.buildEnvMap(1024); + Cubemap diffuseCubemap = iblBuilder.buildIrradianceMap(256); + Cubemap specularCubemap = iblBuilder.buildRadianceMap(10); + iblBuilder.dispose(); + + Texture brdfLUT = new Texture(Gdx.files.classpath("net/mgsx/gltf/shaders/brdfLUT.png")); + + sceneManager.setAmbientLight(1f); + sceneManager.environment.set(new PBRTextureAttribute(PBRTextureAttribute.BRDFLUTTexture, brdfLUT)); + sceneManager.environment.set(PBRCubemapAttribute.createSpecularEnv(specularCubemap)); + sceneManager.environment.set(PBRCubemapAttribute.createDiffuseEnv(diffuseCubemap)); + + SceneSkybox skybox = new SceneSkybox(environmentCubemap); + sceneManager.setSkyBox(skybox); + } + + private void createStageUI() { + this.stage = new Stage(new ScreenViewport()); + this.skin = this.game.assetManager.get("MainSpritesheet.skin", Skin.class); + this.mainAtlas = this.game.assetManager.get("MainSpritesheet.atlas", TextureAtlas.class); + + this.shopUI = new ShopUI(savegame, this.stage, this.skin, this.mainAtlas); + + shopUI.createShopTitleUI(); + shopUI.createShopControlUI(); + shopUI.createShopListUI(); + shopUI.createSavegameUI(); + } + + @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 touchCancelled(int i, int i1, int i2, int i3) { + 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/kz/ilotterytea/maxon/screens/MenuScreen.java b/core/src/kz/ilotterytea/maxon/screens/MenuScreen.java new file mode 100644 index 0000000..ef75046 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/screens/MenuScreen.java @@ -0,0 +1,380 @@ +package kz.ilotterytea.maxon.screens; + +import com.badlogic.gdx.*; +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.graphics.*; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Action; +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.actions.RepeatAction; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.Timer; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import kz.ilotterytea.maxon.MaxonConstants; +import kz.ilotterytea.maxon.MaxonGame; +import kz.ilotterytea.maxon.player.MaxonSavegame; +import kz.ilotterytea.maxon.ui.*; +import kz.ilotterytea.maxon.utils.I18N; +import kz.ilotterytea.maxon.utils.serialization.GameDataSystem; +import net.mgsx.gltf.scene3d.attributes.PBRCubemapAttribute; +import net.mgsx.gltf.scene3d.attributes.PBRTextureAttribute; +import net.mgsx.gltf.scene3d.lights.DirectionalShadowLight; +import net.mgsx.gltf.scene3d.lights.PointLightEx; +import net.mgsx.gltf.scene3d.scene.Scene; +import net.mgsx.gltf.scene3d.scene.SceneAsset; +import net.mgsx.gltf.scene3d.scene.SceneManager; +import net.mgsx.gltf.scene3d.utils.IBLBuilder; + +import java.util.ArrayList; + +public class MenuScreen implements Screen { + private final MaxonGame game; + + private final Stage stage; + private final Music menuMusic; + + MaxonSavegame sav; + + private SceneManager sceneManager; + private PerspectiveCamera camera; + + public MenuScreen(final MaxonGame game) { + this.game = game; + + // Stage and skin: + this.stage = new Stage(new ScreenViewport()); + this.stage.addAction(Actions.sequence(Actions.alpha(0.0f), Actions.alpha(1.0f, 1f))); + + Skin skin = game.assetManager.get("MainSpritesheet.skin", Skin.class); + Skin widgetSkin = game.assetManager.get("sprites/gui/widgets.skin", Skin.class); + TextureAtlas brandAtlas = game.assetManager.get("sprites/gui/brand.atlas", TextureAtlas.class); + TextureAtlas widgetAtlas = game.assetManager.get("sprites/gui/widgets.atlas", TextureAtlas.class); + + Skin friendsSkin = game.assetManager.get("sprites/gui/friends.skin", Skin.class); + + sav = GameDataSystem.load("00.maxon"); + + // Main Menu music: + this.menuMusic = game.assetManager.get("mus/menu/mus_menu_loop.ogg", Music.class); + menuMusic.setLooping(true); + + // Tint the background + Image tintImage = new Image(skin, "tint"); + tintImage.setFillParent(true); + this.stage.addActor(tintImage); + + // - - - - - - U I - - - - - - + Table menuTable = new Table(); + menuTable.setFillParent(true); + + // - - - Brand - - - + Table brandTable = new Table(); + + Image logo = new Image(brandAtlas.findRegion("brand")); + + logo.setOrigin( + logo.getWidth() / 2f, + logo.getHeight() / 2f + ); + + logo.addAction( + 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) + ) + ) + ) + ); + + brandTable.add(logo); + + // - - - Menu control (quit, options, etc.) - - - + Table controlTable = new Table(skin); + controlTable.align(Align.top | Align.center); + controlTable.pad(6f); + + // Left part of menu control + Table leftGameControlTable = new Table(); + leftGameControlTable.align(Align.left); + + ImageButton quitButton = new ImageButton(widgetSkin, "quit"); + + quitButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + Gdx.app.exit(); + } + }); + + leftGameControlTable.add(quitButton).padRight(12f); + + // Right part of menu control + Table rightGameControlTable = new Table(); + rightGameControlTable.align(Align.right); + + // - - - D E V E L O P E R S H O W C A S E - - - + Image developerImage = new Image(); + final int[] developerIndex = {MaxonConstants.GAME_DEVELOPERS.length}; + developerImage.setSize(64, 64); + + Timer.schedule(new Timer.Task() { + @Override + public void run() { + developerIndex[0]++; + + if (developerIndex[0] >= MaxonConstants.GAME_DEVELOPERS.length) { + developerIndex[0] = 0; + } + + String[] dev = MaxonConstants.GAME_DEVELOPERS[developerIndex[0]]; + + developerImage.clearActions(); + developerImage.addAction( + Actions.sequence( + Actions.alpha(0.0f, 1f), + new Action() { + @Override + public boolean act(float delta) { + developerImage.setDrawable(friendsSkin, dev[0]); + return true; + } + }, + Actions.alpha(1.0f, 1f) + ) + ); + + developerImage.clearListeners(); + developerImage.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + Gdx.net.openURI(dev[1]); + } + }); + } + }, 0, 5); + + rightGameControlTable.add(developerImage).padRight(16f); + + // Localization + String[] fh4Locale = game.locale.getFileHandle().nameWithoutExtension().split("_"); + String localeButtonStyleName = "locale_" + fh4Locale[0]; + ImageButton localeButton = new ImageButton(widgetSkin, localeButtonStyleName); + + localeButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + + int index = 0; + ArrayList<FileHandle> fhArray = new ArrayList<>(); + fhArray.add(MaxonConstants.FILE_RU_RU); + fhArray.add(MaxonConstants.FILE_EN_US); + + if (fhArray.indexOf(game.locale.getFileHandle()) + 1 < fhArray.size()) { + index = fhArray.indexOf(game.locale.getFileHandle()) + 1; + } + + FileHandle fhNext = fhArray.get(index); + + game.locale = new I18N(fhNext); + game.prefs.putString("lang", fhNext.nameWithoutExtension()); + game.prefs.flush(); + + game.setScreen(new SplashScreen(game)); + menuMusic.stop(); + } + }); + + + rightGameControlTable.add(localeButton).padRight(16f); + + // Music button + String musicButtonStyleName; + + if (game.prefs.getBoolean("music")) { + musicButtonStyleName = "music_on"; + menuMusic.play(); + } else { + musicButtonStyleName = "music_off"; + } + + ImageButton musicButton = new ImageButton(widgetSkin, musicButtonStyleName); + musicButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + + Button.ButtonStyle style; + + if (game.prefs.getBoolean("music")) { + style = widgetSkin.get("music_off", ImageButton.ImageButtonStyle.class); + menuMusic.pause(); + } else { + style = widgetSkin.get("music_on", ImageButton.ImageButtonStyle.class); + menuMusic.play(); + } + + game.prefs.putBoolean("music", !game.prefs.getBoolean("music")); + game.prefs.flush(); + + musicButton.setStyle(style); + } + }); + rightGameControlTable.add(musicButton).padRight(16f); + + // Resolution button + String resolutionButtonStyleName; + + if (game.prefs.getBoolean("fullscreen")) { + resolutionButtonStyleName = "windowed"; + } else { + resolutionButtonStyleName = "fullscreen"; + } + + ImageButton resolutionButton = new ImageButton(widgetSkin, resolutionButtonStyleName); + resolutionButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + + Button.ButtonStyle style; + + if (game.prefs.getBoolean("fullscreen")) { + style = widgetSkin.get("fullscreen", ImageButton.ImageButtonStyle.class); + Gdx.graphics.setWindowedMode(game.prefs.getInteger("width", 800), game.prefs.getInteger("height", 600)); + } else { + style = widgetSkin.get("windowed", ImageButton.ImageButtonStyle.class); + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } + + game.prefs.putBoolean("fullscreen", !game.prefs.getBoolean("fullscreen")); + game.prefs.flush(); + + resolutionButton.setStyle(style); + } + }); + rightGameControlTable.add(resolutionButton); + + controlTable.add(leftGameControlTable).grow(); + controlTable.add(rightGameControlTable).grow(); + + // - - - Savegame - - - + Table savegameTable = new Table(); + SavegameWidget info = new SavegameWidget(this.game, skin, stage, sav); + + savegameTable.add(info).minSize(640f, 240f); + + // Adding tables into the main UI table + menuTable.add(brandTable).grow().row(); + menuTable.add(savegameTable).grow().row(); + menuTable.add(controlTable).growX(); + + this.stage.addActor(menuTable); + + create3D(); + Gdx.input.setInputProcessor(stage); + } + + @Override public void show() { + if (game.prefs.getBoolean("music", true)) menuMusic.play(); + + // Start to render: + render(Gdx.graphics.getDeltaTime()); + } + + @Override + public void render(float delta) { + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); + + sceneManager.update(delta); + sceneManager.render(); + + camera.rotate(2 * delta, 0, 1, 0); + camera.update(); + + stage.act(delta); + stage.draw(); + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + sceneManager.updateViewport(width, height); + } + + @Override public void pause() {} + @Override public void resume() {} + @Override public void hide() { + menuMusic.stop(); + dispose(); + } + @Override public void dispose() { + stage.dispose(); + } + + private void create3D() { + SceneAsset sceneAsset = game.assetManager.get("models/scenes/living_room.glb", SceneAsset.class); + Scene scene = new Scene(sceneAsset.scene); + + sceneManager = new SceneManager(); + sceneManager.addScene(scene); + + camera = new PerspectiveCamera(60f, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + camera.near = 1f; + camera.far = 300f; + camera.position.set(0f, 5f, 0f); + + camera.update(); + + sceneManager.setCamera(camera); + + DirectionalShadowLight light = new DirectionalShadowLight(1024, 1024, 60f, 60f, 1f, 300f); + light.set(new Color(0xdcccffff), -1f, -0.8f, -0.2f); + light.intensity = 5f; + sceneManager.environment.add(light); + sceneManager.environment.shadowMap = light; + + PointLightEx signLight = new PointLightEx(); + + if (sav != null) { + signLight.set(Color.PINK, new Vector3(2f, 6f, 2f), 80f, 100f); + } + + PointLightEx windowLight = new PointLightEx(); + windowLight.set(Color.BLUE, new Vector3(-1.1f, 7.3f, 0.5f), 80f, 100f); + + sceneManager.environment.add(windowLight, signLight); + + // setup quick IBL (image based lighting) + IBLBuilder iblBuilder = IBLBuilder.createOutdoor(light); + Cubemap environmentCubemap = iblBuilder.buildEnvMap(1024); + Cubemap diffuseCubemap = iblBuilder.buildIrradianceMap(256); + Cubemap specularCubemap = iblBuilder.buildRadianceMap(10); + iblBuilder.dispose(); + + Texture brdfLUT = new Texture(Gdx.files.classpath("net/mgsx/gltf/shaders/brdfLUT.png")); + + sceneManager.setAmbientLight(1f); + sceneManager.environment.set(new PBRTextureAttribute(PBRTextureAttribute.BRDFLUTTexture, brdfLUT)); + sceneManager.environment.set(PBRCubemapAttribute.createSpecularEnv(specularCubemap)); + sceneManager.environment.set(PBRCubemapAttribute.createDiffuseEnv(diffuseCubemap)); + } +} diff --git a/core/src/kz/ilotterytea/maxon/screens/SplashScreen.java b/core/src/kz/ilotterytea/maxon/screens/SplashScreen.java new file mode 100644 index 0000000..f381bb8 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/screens/SplashScreen.java @@ -0,0 +1,102 @@ +package kz.ilotterytea.maxon.screens; + +import com.badlogic.gdx.*; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.scenes.scene2d.Action; +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.ProgressBar; +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.viewport.ScreenViewport; +import kz.ilotterytea.maxon.utils.AssetLoading; +import kz.ilotterytea.maxon.MaxonGame; + +public class SplashScreen implements Screen { + final MaxonGame game; + + final Stage stage; + final Skin skin; + + TextureAtlas brandAtlas; + Image dev; + ProgressBar bar; + + private boolean assetsLoaded = false; + + public SplashScreen(MaxonGame game) { + this.game = game; + + this.stage = new Stage(new ScreenViewport()); + this.skin = new Skin(Gdx.files.internal("MainSpritesheet.skin")); + + Table logoTable = new Table(); + logoTable.setFillParent(true); + logoTable.align(Align.center); + + brandAtlas = new TextureAtlas(Gdx.files.internal("sprites/gui/ilotterytea.atlas")); + + dev = new Image(brandAtlas.findRegion("devOld")); + dev.setSize(dev.getWidth() * 5f, dev.getHeight() * 5f); + logoTable.add(dev).size(dev.getWidth(), dev.getHeight()).padBottom(60f).row(); + + bar = new ProgressBar(0f, 100f, 1f, false, skin); + logoTable.add(bar).width(dev.getWidth()); + + stage.addActor(logoTable); + + AssetLoading.setup(game.assetManager); + AssetLoading.queue(game.assetManager); + } + + @Override public void show() { + render(Gdx.graphics.getDeltaTime()); + } + + private void update() { + if (game.assetManager.update() && !assetsLoaded) { + stage.addAction( + Actions.sequence( + Actions.alpha(0.0f, 1f), + new Action() { + @Override + public boolean act(float v) { + AssetLoading.registerItems(game.assetManager, game.locale); + game.setScreen(new MenuScreen(game)); + dispose(); + return false; + } + } + ) + ); + assetsLoaded = true; + } + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(1, 1, 1, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + + stage.draw(); + stage.act(delta); + + update(); + bar.setValue(100f / (game.assetManager.getQueuedAssets() + 1)); + } + + @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() { + brandAtlas.dispose(); + } +} diff --git a/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopMode.java b/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopMode.java new file mode 100644 index 0000000..d81e925 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopMode.java @@ -0,0 +1,6 @@ +package kz.ilotterytea.maxon.screens.game.shop; + +public enum ShopMode { + BUY, + SELL +} diff --git a/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopMultiplier.java b/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopMultiplier.java new file mode 100644 index 0000000..361290a --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopMultiplier.java @@ -0,0 +1,17 @@ +package kz.ilotterytea.maxon.screens.game.shop; + +public enum ShopMultiplier { + X1(1), + X10(10), + ; + + private final int multiplier; + + ShopMultiplier(int multiplier) { + this.multiplier = multiplier; + } + + public int getMultiplier() { + return multiplier; + } +} diff --git a/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopUI.java b/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopUI.java new file mode 100644 index 0000000..0282ea6 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/screens/game/shop/ShopUI.java @@ -0,0 +1,249 @@ +package kz.ilotterytea.maxon.screens.game.shop; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Align; +import kz.ilotterytea.maxon.player.MaxonItem; +import kz.ilotterytea.maxon.player.MaxonItemRegister; +import kz.ilotterytea.maxon.player.MaxonSavegame; +import kz.ilotterytea.maxon.ui.PurchaseItem; +import kz.ilotterytea.maxon.utils.math.Math; + +import java.util.ArrayList; + +public class ShopUI { + private final Table table, mainTable; + private final Skin skin; + private final TextureAtlas atlas; + private final ArrayList<MaxonItem> items; + + private ShopMode mode; + private ShopMultiplier multiplier; + + private final MaxonSavegame savegame; + private Label pointsLabel, multiplierLabel; + + private final ArrayList<PurchaseItem> purchaseItems = new ArrayList<>(); + + public ShopUI(final MaxonSavegame savegame, Stage stage, Skin skin, TextureAtlas atlas) { + this.savegame = savegame; + + this.skin = skin; + this.atlas = atlas; + this.mode = ShopMode.BUY; + this.multiplier = ShopMultiplier.X1; + this.items = MaxonItemRegister.getItems(); + + this.table = new Table(skin); + this.table.setBackground("board"); + + this.mainTable = new Table(this.skin); + mainTable.setFillParent(true); + mainTable.align(Align.center | Align.left); + + mainTable.add(this.table).growY().width(Math.percentFromValue(25f, Gdx.graphics.getWidth())); + stage.addActor(mainTable); + } + + public void createSavegameUI() { + Table table = new Table(this.skin); + + table.align(Align.center | Align.left); + table.pad(10f); + + // Setting up the points + Table pointsTable = new Table(); + + Image pointsImage = new Image(this.atlas.findRegion("points")); + this.pointsLabel = new Label(String.valueOf(savegame.points), this.skin); + + pointsTable.add(pointsImage); + pointsTable.add(pointsLabel).padLeft(15f); + + table.add(pointsTable).padBottom(10f).row(); + + // Setting up the multiplier + Table multiplierTable = new Table(); + + Image multiplierImage = new Image(this.atlas.findRegion("multiplier")); + this.multiplierLabel = new Label(String.format("%s/s", savegame.multiplier), this.skin); + + multiplierTable.add(multiplierImage); + multiplierTable.add(multiplierLabel).padLeft(15f); + + table.add(multiplierTable); + + this.table.add(table).grow(); + } + + public void createShopTitleUI() { + Table table = new Table(this.skin); + + table.align(Align.center); + table.pad(10f); + + Label label = new Label("Store", skin); + table.add(label); + + this.table.add(table).grow().row(); + } + + public void createShopControlUI() { + Table table = new Table(this.skin); + + table.align(Align.center); + table.pad(10f); + + // Mode changer + Table modeTable = new Table(); + + TextButton buyButton = new TextButton("Buy", this.skin); + buyButton.setDisabled(true); + modeTable.add(buyButton).growX().row(); + + TextButton sellButton = new TextButton("Sell", this.skin); + modeTable.add(sellButton).growX(); + + sellButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + mode = ShopMode.SELL; + sellButton.setDisabled(true); + buyButton.setDisabled(false); + } + }); + + buyButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + mode = ShopMode.BUY; + sellButton.setDisabled(false); + buyButton.setDisabled(true); + } + }); + + table.add(modeTable).grow(); + + // Multiplier changer + Table multiplierTable = new Table(); + + TextButton x1Button = new TextButton("1x", this.skin); + x1Button.setDisabled(true); + multiplierTable.add(x1Button).width(64f).height(64f).padRight(10f); + + TextButton x10Button = new TextButton("10x", this.skin); + multiplierTable.add(x10Button).width(64f).height(64f); + + x1Button.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + multiplier = ShopMultiplier.X1; + x1Button.setDisabled(true); + x10Button.setDisabled(false); + } + }); + + x10Button.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + multiplier = ShopMultiplier.X10; + x1Button.setDisabled(false); + x10Button.setDisabled(true); + } + }); + + table.add(multiplierTable).grow(); + + this.table.add(table).grow().row(); + } + + public void createShopListUI() { + Table table = new Table(this.skin); + table.setBackground("shop_list"); + + for (final MaxonItem item : this.items) { + PurchaseItem purchaseItem = new PurchaseItem(this.skin, item); + purchaseItem.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + + if (purchaseItem.isDisabled()) { + return; + } + + if (mode == ShopMode.BUY) { + savegame.points -= (long) purchaseItem.getPrice(); + for (int i = 0; i < multiplier.getMultiplier(); i++) { + savegame.inv.add(purchaseItem.getItem().id); + } + } else { + savegame.points += (long) purchaseItem.getPrice(); + for (int i = 0; i < multiplier.getMultiplier(); i++) { + savegame.inv.remove(Integer.valueOf(purchaseItem.getItem().id)); + } + } + } + }); + + purchaseItems.add(purchaseItem); + table.add(purchaseItem).growX().padBottom(5f).row(); + } + + ScrollPane scrollPane = new ScrollPane(table); + scrollPane.setScrollingDisabled(true, false); + + Table scrollPaneTable = new Table(this.skin); + scrollPaneTable.setBackground("shop_list"); + scrollPaneTable.pad(1f, 5f, 1f, 5f); + scrollPaneTable.add(scrollPane).grow(); + + this.table.add(scrollPaneTable).grow().row(); + } + + private void updatePurchaseItems() { + for (final PurchaseItem item : this.purchaseItems) { + int amount = (int) savegame.inv.stream().filter(c -> c == item.getItem().id).count(); + double price = item.getItem().price * java.lang.Math.pow(1.15f, amount + multiplier.getMultiplier()); + + if (mode == ShopMode.SELL) { + price /= 4; + } + + item.setPrice(price); + + if (mode == ShopMode.BUY) { + if (price > savegame.points || savegame.points - price < 0) { + item.setDisabled(true); + } else if (item.isDisabled()) { + item.setDisabled(false); + } + } else { + if (amount - multiplier.getMultiplier() < 0) { + item.setDisabled(true); + } else if (item.isDisabled()) { + item.setDisabled(false); + } + } + } + } + + public void render() { + this.pointsLabel.setText(String.valueOf(savegame.points)); + this.multiplierLabel.setText(String.format("%s/s", savegame.multiplier)); + updatePurchaseItems(); + } + + public void update() { + this.mainTable.clear(); + this.mainTable.add(this.table).growY().width(Math.percentFromValue(30f, Gdx.graphics.getWidth())); + } +} |
