diff options
| author | ilotterytea <iltsu@alright.party> | 2024-11-10 20:45:32 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2024-11-10 20:45:32 +0500 |
| commit | 0a29485586012ae00548997c262ea16f3820a823 (patch) | |
| tree | c1abed64ee34a53e8e119219a6278a03733b0754 /core/src | |
| parent | c5493df746e8f3915d86d8ebe85346dc1690ee4f (diff) | |
upd: kotlin has been a disaster for maxon source code
Diffstat (limited to 'core/src')
9 files changed, 697 insertions, 611 deletions
diff --git a/core/src/kz/ilotterytea/javaextra/tuples/Pair.java b/core/src/kz/ilotterytea/javaextra/tuples/Pair.java new file mode 100644 index 0000000..e312bad --- /dev/null +++ b/core/src/kz/ilotterytea/javaextra/tuples/Pair.java @@ -0,0 +1,19 @@ +package kz.ilotterytea.javaextra.tuples; + +public class Pair<A, B> { + private A first; + private B second; + + public Pair(A first, B second) { + this.first = first; + this.second = second; + } + + public A getFirst() { + return first; + } + + public B getSecond() { + return second; + } +} diff --git a/core/src/kz/ilotterytea/maxon/audio/Playlist.java b/core/src/kz/ilotterytea/maxon/audio/Playlist.java new file mode 100644 index 0000000..62e8d14 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/audio/Playlist.java @@ -0,0 +1,57 @@ +package kz.ilotterytea.maxon.audio; + +import com.badlogic.gdx.audio.Music; +import kz.ilotterytea.maxon.utils.math.Math; + +import java.util.Arrays; +import java.util.List; + +public class Playlist { + private List<Music> music; + private Music playingNow; + private int index; + + private boolean shuffleMode; + private float volume; + + public Playlist(Music... music) { + this.music = Arrays.asList(music); + + this.playingNow = this.music.get(0); + this.index = 0; + this.shuffleMode = false; + this.volume = 1f; + + this.playingNow.setVolume(this.volume); + } + + public void next() { + if (playingNow.isPlaying()) playingNow.stop(); + + if (shuffleMode) { + index = Math.getRandomNumber(0, music.size() - 1); + playingNow = music.get(index); + } else { + index++; + if (index > music.size() - 1) index = 0; + + playingNow = music.get(index); + } + + playingNow.setVolume(volume); + playingNow.play(); + } + + public void setVolume(float volume) { + this.volume = volume; + playingNow.setVolume(volume); + } + + public void setShuffleMode(boolean shuffleMode) { + this.shuffleMode = shuffleMode; + } + + public Music getPlayingNow() { + return playingNow; + } +} diff --git a/core/src/kz/ilotterytea/maxon/audio/Playlist.kt b/core/src/kz/ilotterytea/maxon/audio/Playlist.kt deleted file mode 100644 index 2e79f37..0000000 --- a/core/src/kz/ilotterytea/maxon/audio/Playlist.kt +++ /dev/null @@ -1,40 +0,0 @@ -package kz.ilotterytea.maxon.audio - -import com.badlogic.gdx.audio.Music -import kz.ilotterytea.maxon.utils.math.Math - -/** - * Playlist. - */ -class Playlist(vararg musics: Music) { - private val playlist: Array<out Music> = musics - var playingNow: Music = playlist[0] - private var index = 0 - - var shuffleMode = false - var volume = 1f - set(value) { - playingNow.volume = value - field = value - } - - /** - * Play next music. - */ - fun next() { - if (playingNow.isPlaying) playingNow.stop() - - if (shuffleMode) { - index = Math.getRandomNumber(0, playlist.size - 1) - playingNow = playlist[index] - } else { - index++ - if (index > playlist.size - 1) index = 0 - - playingNow = playlist[index] - } - - playingNow.volume = volume - playingNow.play() - } -}
\ No newline at end of file diff --git a/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.java b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.java new file mode 100644 index 0000000..ce564e5 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.java @@ -0,0 +1,508 @@ +package kz.ilotterytea.maxon.screens; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.assets.AssetManager; +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.scenes.scene2d.Actor; +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.ChangeListener; +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.FitViewport; +import com.badlogic.gdx.utils.viewport.ScreenViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import kz.ilotterytea.javaextra.tuples.Pair; +import kz.ilotterytea.maxon.MaxonGame; +import kz.ilotterytea.maxon.constants.SettingsConstants; +import kz.ilotterytea.maxon.localization.LineId; +import kz.ilotterytea.maxon.player.Savegame; +import kz.ilotterytea.maxon.screens.game.GameScreen; +import kz.ilotterytea.maxon.tasks.MultiplierTask; +import kz.ilotterytea.maxon.utils.OsUtils; +import kz.ilotterytea.maxon.utils.formatters.NumberFormatter; +import kz.ilotterytea.maxon.utils.math.Math; + +import java.util.ArrayList; + +public class SlotsMinigameScreen implements Screen { + private enum Slot { + Arbuz(5), + Icecream(30), + Kochan(80), + Buter(120), + Corn(200), + Kebab(500), + Onions(1000), + Treat(2500) + ; + + private final int multiplier; + + Slot(int multiplier) { + this.multiplier = multiplier; + } + + public int getMultiplier() { + return multiplier; + } + } + + private static class SlotImage extends Image { + public SlotImage(Slot slot, AssetManager assetManager) { + super(assetManager.get( + String.format("sprites/minigames/slots/%s.png", slot.name().toLowerCase()), + Texture.class + )); + } + } + + private Savegame savegame; + private MaxonGame game; + + private Stage stage; + private TextButton spinButton, exitButton; + private Label prizeLabel, moneyLabel; + private TextField stakeField; + private Table columns; + + private double prize, stake; + private int loseStreak, maxLoseStreak, lockedColumns; + private boolean disabled; + + private Slot loseSlot; + + private ArrayList<Slot> columnSlots; + private ArrayList<Pair<Timer.Task, Float>> tasks; + + private MultiplierTask multiplierTask; + + private Music audioLoop; + private float soundVolume; + + @Override + public void show() { + this.savegame = Savegame.getInstance(); + this.game = MaxonGame.getInstance(); + this.columnSlots = new ArrayList<>(); + this.tasks = new ArrayList<>(); + this.multiplierTask = new MultiplierTask(savegame); + this.loseSlot = Slot.values()[0]; + + Viewport viewport; + + if (OsUtils.isMobile) { + viewport = new ScreenViewport(); + } else { + viewport = new FitViewport(800f, 600f); + } + + this.stage = new Stage(viewport); + + Skin skin = game.assetManager.get("sprites/gui/ui.skin"); + + Table table = new Table(); + table.setFillParent(true); + table.align(Align.center); + + if (OsUtils.isMobile) table.pad(64f); + + stage.addActor(table); + + // Background + if (OsUtils.isPC) { + Image background = new Image(game.assetManager.get("sprites/minigames/slots/background.png", Texture.class)); + background.setZIndex(2); + + table.add(background); + } + + String styleName = OsUtils.isMobile ? "defaultMobile" : "default"; + + // Buttons + spinButton = new TextButton(game.getLocale().getLine(LineId.MinigameSlotsSpinbutton), skin, styleName); + spinButton.setDisabled(true); + spinButton.setWidth(420f); + spinButton.setPosition(62f, 60f); + spinButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (spinButton.isDisabled()) return; + super.clicked(event, x, y); + restart(); + } + }); + + exitButton = new TextButton(game.getLocale().getLine(LineId.MinigameSlotsExitbutton), skin, styleName); + exitButton.setPosition(62f, stage.getHeight() / 2f - 150f); + exitButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + if (exitButton.isDisabled()) return; + super.clicked(event, x, y); + game.setScreen(new GameScreen()); + } + }); + + // Labels + styleName = OsUtils.isMobile ? "slotsMobile" : "slots"; + + prizeLabel = new Label("", skin, styleName); + prizeLabel.setAlignment(Align.center); + prizeLabel.setPosition(stage.getWidth() / 2f - 180f, stage.getHeight() / 2f + 80f); + + Image moneyIcon = new Image(game.assetManager.get("sprites/gui/player_icons.atlas", TextureAtlas.class).findRegion("points")); + moneyIcon.setSize(20f, 20f); + moneyIcon.setPosition(stage.getWidth() / 2f + 60f, stage.getHeight() / 2f - 180f); + + moneyLabel = new Label(NumberFormatter.format(savegame.getMoney()), skin, styleName); + moneyLabel.setAlignment(Align.right); + moneyLabel.setPosition(stage.getWidth() / 2f, stage.getHeight() / 2f - 180f); + + Label stakeLabel = new Label(game.getLocale().getLine(LineId.MinigameSlotsBet), skin, styleName); + stakeLabel.setAlignment(Align.center); + stakeLabel.setPosition(stage.getWidth() / 2f - 40f, stage.getHeight() / 2f - 100f); + + stakeField = new TextField("", skin, OsUtils.isMobile ? "defaultMobile" : "default"); + stakeField.setMessageText("---"); + stakeField.setTextFieldFilter((x, c) -> String.valueOf(c).matches("^[0-9]*$")); + stakeField.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + if (actor instanceof TextField tf) { + if (tf.isDisabled()) return; + + String value = tf.getText(); + + try { + long v = Long.parseLong(value); + + if (v > savegame.getMoney()) { + v = Double.valueOf(savegame.getMoney()).longValue(); + } + + tf.setText(Long.toString(v)); + stake = (double) v; + + spinButton.setDisabled(stake <= 0.0); + } catch (Exception ignored) {} + } + } + }); + stakeField.setPosition(stage.getWidth() / 2f - 70f, stage.getHeight() / 2f - 150f); + + // Slot columns + columns = new Table(); + + if (OsUtils.isPC) { + columns.setX(62f); + columns.setY(stage.getHeight() / 2f); + columns.setWidth(424f); + } + + for (int i = 0; i < 3; i++) { + columnSlots.add(Slot.values()[Math.getRandomNumber(0, Slot.values().length)]); + } + + reRoll(); + + Timer.Task updateTask = new Timer.Task() { + @Override + public void run() { + reRoll(); + } + }; + + tasks.add(new Pair<>(updateTask, 0.1f)); + + Timer.Task lockColumnTask = new Timer.Task() { + @Override + public void run() { + Sound sound = game.assetManager.get("sfx/minigames/slots/slots_lock.ogg", Sound.class); + sound.play(soundVolume); + + lockedColumns += 1; + + if (lockedColumns > 1) { + finish(); + } + } + }; + + tasks.add(new Pair<>(lockColumnTask, 2f)); + + disableSlotMachineIfNoStake(); + + audioLoop = game.assetManager.get("mus/minigames/slots/slots_loop.mp3"); + audioLoop.setLooping(true); + audioLoop.setVolume(game.prefs.getInteger("music", 10) / 10f); + soundVolume = game.prefs.getInteger("sfx", 10) / 10f; + + Timer.schedule(multiplierTask, 0.1f, 0.1f); + + if (OsUtils.isMobile) { + Image title = new Image(game.assetManager.get("sprites/minigames/slots/title.png", Texture.class)); + table.add(title).growX().height( + title.getHeight() * (this.stage.getWidth() - 64f) / title.getWidth() + ).padBottom(64f).row(); + + table.add(prizeLabel).expandX().padBottom(64f).row(); + + table.add(columns).growX().padBottom(64f).row(); + columns.align(Align.center); + + table.add(stakeLabel).growX().padBottom(32f).row(); + stakeLabel.setAlignment(Align.right); + + Table table2 = new Table(); + table2.add(exitButton).align(Align.left).expandX(); + table2.add(stakeField).align(Align.right).minWidth(300f); + table.add(table2).growX().padBottom(32f).row(); + + Table table3 = new Table(); + table3.align(Align.right); + table3.add(moneyLabel).padRight(16f); + table3.add(moneyIcon); + table.add(table3).growX().padBottom(64f).row(); + + table.add(spinButton).growX(); + } else { + stage.addActor(spinButton); + stage.addActor(exitButton); + stage.addActor(prizeLabel); + stage.addActor(moneyIcon); + stage.addActor(moneyLabel); + stage.addActor(stakeLabel); + stage.addActor(stakeField); + stage.addActor(columns); + } + + Gdx.input.setInputProcessor(stage); + } + + @Override + public void render(float delta) { + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); + if (OsUtils.isMobile) { + Gdx.gl.glClearColor(0.12f, 0.12f, 0.15f, 1f); + } else { + Gdx.gl.glClearColor(0f, 0f, 0f, 1f); + } + + stage.act(delta); + stage.draw(); + + moneyLabel.setText(NumberFormatter.format(savegame.getMoney(), false)); + } + + + private void finish() { + if (audioLoop.isPlaying()) audioLoop.stop(); + + stakeField.setDisabled(false); + exitButton.setDisabled(false); + spinButton.setDisabled(false); + + for (Pair<Timer.Task, Float> x : tasks) { + x.getFirst().cancel(); + } + + giveReward(); + updateLabels(); + disableSlotMachineIfNoStake(); + } + + private void restart() { + audioLoop.play(); + + Sound sound = game.assetManager.get("sfx/minigames/slots/slots_start.ogg"); + sound.play(soundVolume); + + prizeLabel.setText(""); + + exitButton.setDisabled(true); + spinButton.setDisabled(true); + stakeField.setDisabled(true); + + loseSlot = Slot.values()[Math.getRandomNumber(0,3)]; + lockedColumns = -1; + loseStreak = 0; + prize = 0.0; + maxLoseStreak = Math.getRandomNumber(20, 50); + + reRoll(); + + for (Pair<Timer.Task, Float> task : tasks) { + Timer.schedule(task.getFirst(), task.getSecond(), task.getSecond()); + } + } + + private void reRoll() { + ArrayList<Slot> array = new ArrayList<>(); + + for (int i = 0; i < columnSlots.size(); i++) { + while (true) { + Slot x = columnSlots.get(i); + + if (i <= lockedColumns) { + if (loseStreak >= maxLoseStreak) { + x = loseSlot; + } + + array.add(x); + break; + } + + Slot slot = Slot.values()[Math.getRandomNumber(0, Slot.values().length)]; + + if (x.ordinal() != slot.ordinal()) { + array.add(slot); + break; + } + } + } + + columnSlots.clear(); + columns.clear(); + + float size = (OsUtils.isMobile ? 300f : 100f) * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE); + + for (Slot x : array) { + columnSlots.add(x); + columns.add(new SlotImage(x, game.assetManager)) + .size(size, size) + .expandX(); + } + } + + private void disableSlotMachineIfNoStake() { + if ((long) savegame.getMoney() > 0) { + return; + } + + disabled = true; + + stakeField.setMessageText("---"); + stakeField.setText("---"); + stakeField.setDisabled(disabled); + spinButton.setDisabled(disabled); + + for (Pair<Timer.Task, Float> x : tasks) { + x.getFirst().cancel(); + } + } + + private void giveReward() { + Slot first = columnSlots.get(0); + boolean same = false; + + for (Slot x : columnSlots) { + same = x.ordinal() == first.ordinal(); + + if (!same) { + break; + } + } + + playRewardSound(same, first); + + savegame.setSlotsTotalSpins(savegame.getSlotsTotalSpins() + 1); + + if (!same) { + loseStreak++; + savegame.decreaseMoney(stake); + return; + } + + prize = stake * first.multiplier; + savegame.increaseMoney(prize); + savegame.setSlotsWins(savegame.getSlotsWins() + 1); + } + + private void updateLabels() { + String prizeText; + + if (prize == 0.0) { + prizeText = game.getLocale().getLine(LineId.MinigameSlotsNothing); + } else { + prizeText = game.getLocale().getFormattedLine(LineId.MinigameSlotsPrize, NumberFormatter.format(prize, false)); + } + + prizeLabel.setText(prizeText); + + if (stake > savegame.getMoney()) { + stake = savegame.getMoney(); + + long money = (long) savegame.getMoney(); + String stakeText; + if (money <= 0) { + stakeText = "---"; + } else { + stakeText = String.valueOf(money); + } + + stakeField.setText(stakeText); + } + + moneyLabel.setText(NumberFormatter.format(savegame.getMoney(), false)); + } + + private void playRewardSound(boolean same, Slot slot) { + String path; + if (!same) { + path = "fail"; + } else { + path = switch (slot.ordinal()) { + case 0, 1 -> "small_win"; + case 2, 3, 4 -> "medium_win"; + default -> "big_win"; + }; + } + + Sound sound = game.assetManager.get(String.format("sfx/minigames/slots/slots_%s.ogg", path)); + sound.play(soundVolume); + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + @Override + public void pause() { + dispose(); + } + + @Override + public void resume() { + show(); + } + + @Override + public void hide() { + savegame.save(); + dispose(); + } + + @Override + public void dispose() { + for (Pair<Timer.Task, Float> x : tasks) { + x.getFirst().cancel(); + } + + tasks.clear(); + multiplierTask.cancel(); + stage.dispose(); + audioLoop.stop(); + + Gdx.input.setOnscreenKeyboardVisible(false); + Gdx.input.setInputProcessor(null); + } +} diff --git a/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt b/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt deleted file mode 100644 index 6a03025..0000000 --- a/core/src/kz/ilotterytea/maxon/screens/SlotsMinigameScreen.kt +++ /dev/null @@ -1,468 +0,0 @@ -@file:Suppress("unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", - "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused" -) - -package kz.ilotterytea.maxon.screens - -import com.badlogic.gdx.Gdx -import com.badlogic.gdx.Screen -import com.badlogic.gdx.assets.AssetManager -import com.badlogic.gdx.audio.Music -import com.badlogic.gdx.audio.Sound -import com.badlogic.gdx.graphics.GL20 -import com.badlogic.gdx.graphics.Texture -import com.badlogic.gdx.graphics.g2d.TextureAtlas -import com.badlogic.gdx.scenes.scene2d.Actor -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.ChangeListener -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.Timer.Task -import com.badlogic.gdx.utils.viewport.FitViewport -import com.badlogic.gdx.utils.viewport.ScreenViewport -import kz.ilotterytea.maxon.MaxonGame -import kz.ilotterytea.maxon.constants.SettingsConstants -import kz.ilotterytea.maxon.localization.LineId -import kz.ilotterytea.maxon.player.Savegame -import kz.ilotterytea.maxon.screens.game.GameScreen -import kz.ilotterytea.maxon.tasks.MultiplierTask -import kz.ilotterytea.maxon.utils.OsUtils -import kz.ilotterytea.maxon.utils.formatters.NumberFormatter -import kotlin.math.roundToInt -import kotlin.math.roundToLong -import kotlin.random.Random - -private enum class Slot(val multiplier: Int) { - Arbuz(5), - Icecream(30), - Kochan(80), - Buter(120), - Corn(200), - Kebab(500), - Onions(1000), - Treat(2500), -} - -private class SlotImage(slot: Slot, assetManager: AssetManager) : Image(assetManager.get("sprites/minigames/slots/${slot.name.lowercase()}.png", Texture::class.java)) - -@Suppress("unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", "unused", - "unused", "unused", "unused", "unused", "unused", "unused", "unused" -) -class SlotsMinigameScreen : Screen { - private val savegame = Savegame.getInstance() - - private val game = MaxonGame.getInstance() - private val stage = Stage(if (OsUtils.isMobile) { - ScreenViewport() - } else { - FitViewport(800f, 600f) - }) - - private var spinButton: TextButton? = null - private var exitButton: TextButton? = null - - private var prize = 0.0 - private var prizeLabel: Label? = null - private var moneyLabel: Label? = null - - private var stake = 0.0 - private var stakeField: TextField? = null - - private var loseSlot = Slot.values()[0] - private var loseStreak = 0 - private var maxLoseStreak = Random.nextInt(20, 50) - - private var disabled = false - private var lockedColumns = -1 - private val columnSlots = arrayListOf<Slot>() - private val columns = Table() - - private val tasks = arrayListOf<Pair<Task, Float>>() - - private val audioLoop: Music = game.assetManager.get("mus/minigames/slots/slots_loop.mp3") - - private val soundVolume = game.prefs.getInteger("sfx", 10) / 10f - - private val multiplierTask = MultiplierTask(savegame) - - override fun show() { - // Skins - val skin = game.assetManager.get("sprites/gui/ui.skin", Skin::class.java) - - // Main table - val table = Table() - table.setFillParent(true) - table.align(Align.center) - - if (OsUtils.isMobile) table.pad(64f) - - stage.addActor(table) - - // Background - if (OsUtils.isPC) { - val background = Image(game.assetManager.get("sprites/minigames/slots/background.png", Texture::class.java)) - background.zIndex = 2 - - table.add(background) - } - - var styleName = if (OsUtils.isMobile) "defaultMobile" else "default" - - // Buttons - spinButton = TextButton(game.locale.getLine(LineId.MinigameSlotsSpinbutton), skin, styleName) - spinButton?.isDisabled = true - spinButton?.width = 420f - spinButton?.setPosition(62f, 60f) - spinButton?.addListener(object : ClickListener() { - override fun clicked(event: InputEvent?, x: Float, y: Float) { - if (spinButton?.isDisabled == true) return - super.clicked(event, x, y) - restart() - } - }) - - exitButton = TextButton(game.locale.getLine(LineId.MinigameSlotsExitbutton), skin, styleName) - exitButton?.setPosition(62f, stage.height / 2f - 150f) - exitButton?.addListener(object : ClickListener() { - override fun clicked(event: InputEvent?, x: Float, y: Float) { - if (exitButton?.isDisabled == true) return - super.clicked(event, x, y) - game.screen = GameScreen() - } - }) - - // Labels - styleName = if (OsUtils.isMobile) "slotsMobile" else "slots" - - prizeLabel = Label("", skin, styleName) - prizeLabel?.setAlignment(Align.center) - prizeLabel?.setPosition(stage.width / 2f - 180f, stage.height / 2f + 80f) - - val moneyIcon = Image(game.assetManager.get("sprites/gui/player_icons.atlas", TextureAtlas::class.java).findRegion("points")) - moneyIcon.setSize(20f, 20f) - moneyIcon.setPosition(stage.width / 2f + 60f, stage.height / 2f - 180f) - - moneyLabel = Label(NumberFormatter.format(savegame.money), skin, styleName) - moneyLabel?.setAlignment(Align.right) - moneyLabel?.setPosition(stage.width / 2f, stage.height / 2f - 180f) - - val stakeLabel = Label(game.locale.getLine(LineId.MinigameSlotsBet), skin, styleName) - stakeLabel.setAlignment(Align.center) - stakeLabel.setPosition(stage.width / 2f - 40f, stage.height / 2f - 100f) - - stakeField = TextField("", skin, if (OsUtils.isMobile) "defaultMobile" else "default") - stakeField?.messageText = "---" - stakeField?.setTextFieldFilter { _, c -> c.toString().matches(Regex("^[0-9]*\$")) } - stakeField?.addListener(object : ChangeListener() { - override fun changed(event: ChangeEvent?, actor: Actor?) { - val textField = actor as TextField - if (textField.isDisabled) return - - var value = textField.text?.toLongOrNull() - - if (value != null) { - if (value > savegame.money.toLong()) { - value = savegame.money.roundToLong() - } - - textField.text = value.toString() - stake = value.toDouble() - - spinButton?.isDisabled = stake <= 0.0 - } - } - }) - stakeField?.setPosition(stage.width / 2f - 70f, stage.height / 2f - 150f) - - // Slot columns - if (OsUtils.isPC) { - columns.x = 62f - columns.y = stage.height / 2f - columns.width = 424f - } - - for (i in 0..2) { - columnSlots.add(Slot.values()[Random.nextInt(0, Slot.values().size)]) - } - - reRoll() - - val updateTask = object : Task() { - override fun run() { - reRoll() - } - } - - tasks.add(Pair(updateTask, 0.1f)) - - val lockColumnTask = object : Task() { - override fun run() { - val sound = game.assetManager.get("sfx/minigames/slots/slots_lock.ogg", Sound::class.java) - sound.play(soundVolume) - - lockedColumns += 1 - - if (lockedColumns > 1) { - finish() - } - } - } - - tasks.add(Pair(lockColumnTask, 2f)) - - disableSlotMachineIfNoStake() - - audioLoop.isLooping = true - audioLoop.volume = game.prefs.getInteger("music", 10) / 10f - - Timer.schedule(multiplierTask, 0.1f, 0.1f) - - if (OsUtils.isMobile) { - val title = Image(game.assetManager.get("sprites/minigames/slots/title.png", Texture::class.java)) - table.add(title).growX().height(title.height * (this.stage.width - 64f) / title.width).padBottom(64f).row() - - table.add(prizeLabel).expandX().padBottom(64f).row() - - table.add(columns).growX().padBottom(64f).row() - columns.align(Align.center) - - table.add(stakeLabel).growX().padBottom(32f).row() - stakeLabel.setAlignment(Align.right) - - val table2 = Table() - table2.add(exitButton).align(Align.left).expandX() - table2.add(stakeField).align(Align.right).minWidth(300f) - table.add(table2).growX().padBottom(32f).row() - - val table3 = Table() - table3.align(Align.right) - table3.add(moneyLabel).padRight(16f) - table3.add(moneyIcon) - table.add(table3).growX().padBottom(64f).row() - - table.add(spinButton).growX() - } else { - stage.addActor(spinButton) - stage.addActor(exitButton) - stage.addActor(prizeLabel) - stage.addActor(moneyIcon) - stage.addActor(moneyLabel) - stage.addActor(stakeLabel) - stage.addActor(stakeField) - stage.addActor(columns) - } - - Gdx.input.inputProcessor = stage - } - - override fun render(delta: Float) { - Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT or GL20.GL_DEPTH_BUFFER_BIT) - if (OsUtils.isMobile) { - Gdx.gl.glClearColor(0.12f, 0.12f, 0.15f, 1f) - } else { - Gdx.gl.glClearColor(0f, 0f, 0f, 1f) - } - - stage.act(delta) - stage.draw() - - moneyLabel?.setText(NumberFormatter.format(savegame.money, false)) - } - - private fun reRoll() { - val array = arrayListOf<Slot>() - - for (i in 0 until columnSlots.size) { - while (true) { - var x = columnSlots[i] - - if (i <= lockedColumns) { - if (loseStreak >= maxLoseStreak) { - x = loseSlot - } - - array.add(x) - break - } - - val slot = Slot.values()[Random.nextInt(0, Slot.values().size)] - - if (x.ordinal != slot.ordinal) { - array.add(slot) - break - } - } - } - - columnSlots.clear() - columns.clear() - - val size = (if (OsUtils.isMobile) 300f else 100f) * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE) - - for (x in array) { - columnSlots.add(x) - columns.add(SlotImage(x, game.assetManager)) - .size(size, size) - .expandX() - } - } - - - private fun finish() { - if (audioLoop.isPlaying) audioLoop.stop() - - stakeField?.isDisabled = false - exitButton?.isDisabled = false - spinButton?.isDisabled = false - - for (x in tasks) { - x.first.cancel() - } - - giveReward() - updateLabels() - disableSlotMachineIfNoStake() - } - - private fun restart() { - audioLoop.play() - - val sound = game.assetManager.get<Sound>("sfx/minigames/slots/slots_start.ogg") - sound.play(soundVolume) - - prizeLabel?.setText("") - - exitButton?.isDisabled = true - spinButton?.isDisabled = true - stakeField?.isDisabled = true - - loseSlot = Slot.values()[Random.nextInt(0,3)] - lockedColumns = -1 - loseStreak = 0 - prize = 0.0 - maxLoseStreak = Random.nextInt(20, 50) - - reRoll() - - for (task in tasks) { - Timer.schedule(task.first, task.second, task.second) - } - } - - private fun giveReward() { - val first = columnSlots[0] - var same = false - - for (x in columnSlots) { - same = x.ordinal == first.ordinal - - if (!same) { - break - } - } - - playRewardSound(same, first) - - savegame.slotsTotalSpins++ - - if (!same) { - loseStreak++ - savegame.money -= stake - return - } - - prize = stake * first.multiplier - savegame.money += prize - savegame.slotsWins++ - } - - private fun updateLabels() { - val prizeText = if (prize == 0.0) { - game.locale.getLine(LineId.MinigameSlotsNothing) - } else { - game.locale.getFormattedLine(LineId.MinigameSlotsPrize, NumberFormatter.format(prize, false)) - } - - prizeLabel?.setText(prizeText) - - if (stake.toLong() > savegame.money.toLong()) { - stake = savegame.money - - val stakeText = if (savegame.money.roundToInt() <= 0) { - "---" - } else { - savegame.money.roundToInt().toString() - } - - stakeField?.text = stakeText - } - - moneyLabel?.setText(NumberFormatter.format(savegame.money, false)) - } - - private fun disableSlotMachineIfNoStake() { - if (savegame.money.toLong() > 0) { - return - } - - disabled = true - - stakeField?.messageText = "---" - stakeField?.text = "---" - stakeField?.isDisabled = disabled - spinButton?.isDisabled = disabled - - for (x in tasks) { - x.first.cancel() - } - } - - private fun playRewardSound(same: Boolean, slot: Slot) { - val path = if (!same) { - "fail" - } else { - when (slot.ordinal) { - in 0..1 -> "small_win" - in 2..4 -> "medium_win" - else -> "big_win" - } - } - - val sound = game.assetManager.get("sfx/minigames/slots/slots_$path.ogg", Sound::class.java) - sound.play(soundVolume) - } - - override fun resize(width: Int, height: Int) { - stage.viewport.update(width, height, true) - } - - override fun pause() { - dispose() - } - - override fun resume() { - show() - } - - override fun hide() { - savegame.save() - dispose() - } - - override fun dispose() { - for (x in tasks) { - x.first.cancel() - } - - tasks.clear() - multiplierTask.cancel() - stage.dispose() - audioLoop.stop() - - Gdx.input.setOnscreenKeyboardVisible(false) - Gdx.input.inputProcessor = null - } -}
\ No newline at end of file diff --git a/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.java b/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.java new file mode 100644 index 0000000..2a28586 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.java @@ -0,0 +1,42 @@ +package kz.ilotterytea.maxon.ui; + +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.actions.Actions; +import com.badlogic.gdx.scenes.scene2d.actions.RepeatAction; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; + +public class ShakingImageButton extends Image { + public ShakingImageButton(Skin skin, String style) { + super(skin.getRegion(style)); + + this.setOrigin(getWidth() / 2f, getHeight() / 2f); + + this.addListener(new ClickListener() { + @Override + public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) { + super.enter(event, x, y, pointer, fromActor); + + addAction( + Actions.repeat( + RepeatAction.FOREVER, + Actions.sequence( + Actions.rotateTo(-2f, 0.1f), + Actions.rotateTo(2f, 0.1f) + ) + ) + ); + } + + @Override + public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) { + super.exit(event, x, y, pointer, toActor); + + clearActions(); + addAction(Actions.rotateTo(0f, 0.1f)); + } + }); + } +} diff --git a/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.kt b/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.kt deleted file mode 100644 index eb8c51c..0000000 --- a/core/src/kz/ilotterytea/maxon/ui/ShakingImageButton.kt +++ /dev/null @@ -1,37 +0,0 @@ -package kz.ilotterytea.maxon.ui - -import com.badlogic.gdx.scenes.scene2d.Actor -import com.badlogic.gdx.scenes.scene2d.InputEvent -import com.badlogic.gdx.scenes.scene2d.actions.Actions -import com.badlogic.gdx.scenes.scene2d.actions.RepeatAction -import com.badlogic.gdx.scenes.scene2d.ui.Image -import com.badlogic.gdx.scenes.scene2d.ui.Skin -import com.badlogic.gdx.scenes.scene2d.utils.ClickListener - -class ShakingImageButton(skin: Skin, style: String) : Image(skin.getRegion(style)) { - init { - setOrigin(width / 2f, height / 2f) - - addListener(object : ClickListener() { - override fun enter(event: InputEvent?, x: Float, y: Float, pointer: Int, fromActor: Actor?) { - super.enter(event, x, y, pointer, fromActor) - - addAction( - Actions.repeat( - RepeatAction.FOREVER, - Actions.sequence( - Actions.rotateTo(-2f, 0.1f), - Actions.rotateTo(2f, 0.1f) - ) - ) - ) - } - - override fun exit(event: InputEvent?, x: Float, y: Float, pointer: Int, toActor: Actor?) { - super.exit(event, x, y, pointer, toActor) - clearActions() - addAction(Actions.rotateTo(0f, 0.1f)) - } - }) - } -}
\ No newline at end of file diff --git a/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.java b/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.java new file mode 100644 index 0000000..1940d65 --- /dev/null +++ b/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.java @@ -0,0 +1,71 @@ +package kz.ilotterytea.maxon.ui.game; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.ui.Cell; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.Align; +import kz.ilotterytea.maxon.MaxonGame; +import kz.ilotterytea.maxon.constants.SettingsConstants; +import kz.ilotterytea.maxon.screens.MenuScreen; +import kz.ilotterytea.maxon.screens.SlotsMinigameScreen; +import kz.ilotterytea.maxon.ui.ShakingImageButton; +import kz.ilotterytea.maxon.utils.OsUtils; + +public class QuickActionsTable extends Table { + public QuickActionsTable(Skin widgetSkin, Skin uiSkin) { + super(uiSkin); + + MaxonGame game = MaxonGame.getInstance(); + + Sound clickSound = game.assetManager.get("sfx/ui/click.ogg"); + float soundVolume = game.prefs.getInteger("sfx", 10) / 10f; + + float iconSize = (OsUtils.isMobile ? 256f : 64f) + * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE); + + ShakingImageButton slotsButton = new ShakingImageButton(widgetSkin, "slots"); + slotsButton.setOrigin(iconSize / 2f, iconSize / 2f); + slotsButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + clickSound.play(soundVolume); + game.setScreen(new SlotsMinigameScreen()); + } + }); + Cell<ShakingImageButton> slotsCell = add(slotsButton).size(iconSize).padRight(8f); + + ShakingImageButton quitButton = new ShakingImageButton(widgetSkin, "exit"); + quitButton.setOrigin(iconSize / 2f, iconSize / 2f); + quitButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + super.clicked(event, x, y); + clickSound.play(soundVolume); + game.setScreen(new MenuScreen()); + } + }); + Cell<ShakingImageButton> quitCell = add(quitButton).size(iconSize); + + if (OsUtils.isMobile) { + slotsCell.expandX(); + quitCell.expandX(); + } + } + + @Override + public void draw(Batch batch, float parentAlpha) { + super.draw(batch, parentAlpha); + + if (OsUtils.isMobile) return; + + // i'm not sure how much does it affect on performance + setX(Gdx.graphics.getWidth() - 36f * 2f, Align.left); + setY(Gdx.graphics.getHeight() - 36f, Align.top); + } +} diff --git a/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.kt b/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.kt deleted file mode 100644 index 08b4bb7..0000000 --- a/core/src/kz/ilotterytea/maxon/ui/game/QuickActionsTable.kt +++ /dev/null @@ -1,66 +0,0 @@ -package kz.ilotterytea.maxon.ui.game - -import com.badlogic.gdx.Gdx -import com.badlogic.gdx.audio.Sound -import com.badlogic.gdx.graphics.g2d.Batch -import com.badlogic.gdx.scenes.scene2d.InputEvent -import com.badlogic.gdx.scenes.scene2d.ui.Skin -import com.badlogic.gdx.scenes.scene2d.ui.Table -import com.badlogic.gdx.scenes.scene2d.utils.ClickListener -import com.badlogic.gdx.utils.Align -import kz.ilotterytea.maxon.MaxonGame -import kz.ilotterytea.maxon.constants.SettingsConstants -import kz.ilotterytea.maxon.screens.MenuScreen -import kz.ilotterytea.maxon.screens.SlotsMinigameScreen -import kz.ilotterytea.maxon.ui.ShakingImageButton -import kz.ilotterytea.maxon.utils.OsUtils - -class QuickActionsTable(widgetSkin: Skin, uiSkin: Skin) : Table(uiSkin) { - init { - val game = MaxonGame.getInstance() - val clickSound = game.assetManager.get("sfx/ui/click.ogg", Sound::class.java) - val soundVolume = game.prefs.getInteger("sfx", 10) / 10f - val iconSize = if (OsUtils.isMobile) { - 256f - } else { - 64f - } * game.prefs.getFloat("guiScale", SettingsConstants.UI_DEFAULT_SCALE) - - val slotsButton = ShakingImageButton(widgetSkin, "slots") - slotsButton.setOrigin(iconSize / 2f, iconSize / 2f) - slotsButton.addListener(object : ClickListener() { - override fun clicked(event: InputEvent, x: Float, y: Float) { - super.clicked(event, x, y) - clickSound.play(soundVolume) - game.screen = SlotsMinigameScreen() - } - }) - val slotsCell = add(slotsButton).size(iconSize).padRight(8f) - - val quitButton = ShakingImageButton(widgetSkin, "exit") - quitButton.setOrigin(iconSize / 2f, iconSize / 2f) - quitButton.addListener(object : ClickListener() { - override fun clicked(event: InputEvent, x: Float, y: Float) { - super.clicked(event, x, y) - clickSound.play(soundVolume) - game.screen = MenuScreen() - } - }) - val quitCell = add(quitButton).size(iconSize) - - if (OsUtils.isMobile) { - slotsCell.expandX() - quitCell.expandX() - } - } - - override fun draw(batch: Batch?, parentAlpha: Float) { - super.draw(batch, parentAlpha) - - if (OsUtils.isMobile) return - - // i'm not sure how much does it affect on performance - setX(Gdx.graphics.width - 36f * 2f, Align.left) - setY(Gdx.graphics.height - 36f, Align.top) - } -}
\ No newline at end of file |
