Add custom Theme system using external files
This commit is contained in:
parent
eb9b6ee5f1
commit
219e229bb9
7 changed files with 135 additions and 93 deletions
19
android/assets/themes/default.theme
Normal file
19
android/assets/themes/default.theme
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "Default",
|
||||
"price": 0,
|
||||
"colors": {
|
||||
"background": "e6e6e6ff",
|
||||
"buttons": [
|
||||
"00ff33ff",
|
||||
"ffd700ff",
|
||||
"2389fcff",
|
||||
"d94848ff"
|
||||
],
|
||||
"cells": [
|
||||
"7988bfff", "98dc53ff", "4cd4aeff",
|
||||
"fec63dff", "ec9548ff", "e66a82ff", "da6554ff",
|
||||
"57cb84ff", "5abee2ff"
|
||||
]
|
||||
},
|
||||
"cell_texture": "basic.png"
|
||||
}
|
|
@ -11,12 +11,17 @@ import io.github.lonamiwebs.klooni.screens.MainMenuScreen;
|
|||
|
||||
public class Klooni extends Game {
|
||||
|
||||
// TODO Not sure whether the theme should be static or not since it might load textures
|
||||
public static Theme theme;
|
||||
public Skin skin;
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
prefs = Gdx.app.getPreferences("io.github.lonamiwebs.klooni.game");
|
||||
|
||||
// Use only one instance for the theme, so anyone using it uses the most up-to-date
|
||||
theme = Theme.getTheme(prefs.getString("themeName", "default"));
|
||||
|
||||
// TODO Better way to have this skin somewhere
|
||||
// Gotta create that darn .json…!
|
||||
skin = new Skin(Gdx.files.internal("skin/uiskin.json"));
|
||||
|
@ -54,6 +59,7 @@ public class Klooni extends Game {
|
|||
public void dispose() {
|
||||
super.dispose();
|
||||
skin.dispose();
|
||||
theme.dispose();
|
||||
}
|
||||
|
||||
//region Settings
|
||||
|
|
87
core/src/io/github/lonamiwebs/klooni/Theme.java
Normal file
87
core/src/io/github/lonamiwebs/klooni/Theme.java
Normal file
|
@ -0,0 +1,87 @@
|
|||
package io.github.lonamiwebs.klooni;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
import com.badlogic.gdx.utils.JsonReader;
|
||||
import com.badlogic.gdx.utils.JsonValue;
|
||||
|
||||
public class Theme {
|
||||
|
||||
private String displayName;
|
||||
private String name;
|
||||
private int price;
|
||||
private Color background;
|
||||
private Color[] cells;
|
||||
private Color[] buttons;
|
||||
|
||||
private Theme() { }
|
||||
|
||||
public static Theme[] getThemes() {
|
||||
FileHandle[] handles = Gdx.files.internal("themes").list();
|
||||
|
||||
Theme[] result = new Theme[handles.length];
|
||||
for (int i = 0; i < handles.length; i++) {
|
||||
result[i] = Theme.fromFile(handles[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Theme getTheme(final String name) {
|
||||
return new Theme().update(name);
|
||||
}
|
||||
|
||||
private static Theme fromFile(FileHandle handle) {
|
||||
return new Theme().update(handle);
|
||||
}
|
||||
|
||||
public Theme update(final String name) {
|
||||
return update(Gdx.files.internal("themes/"+name+".theme"));
|
||||
}
|
||||
|
||||
private Theme update(final FileHandle handle) {
|
||||
final JsonValue json = new JsonReader().parse(handle.readString());
|
||||
|
||||
name = handle.nameWithoutExtension();
|
||||
displayName = json.getString("name");
|
||||
price = json.getInt("price");
|
||||
|
||||
JsonValue colors = json.get("colors");
|
||||
background = new Color( // Java won't allow unsigned integers, we need to use Long
|
||||
(int)Long.parseLong(colors.getString("background"), 16));
|
||||
|
||||
JsonValue buttonColors = colors.get("buttons");
|
||||
buttons = new Color[buttonColors.size];
|
||||
for (int i = 0; i < buttons.length; i++) {
|
||||
buttons[i] = new Color((int)Long.parseLong(buttonColors.getString(i), 16));
|
||||
}
|
||||
|
||||
JsonValue cellColors = colors.get("cells");
|
||||
cells = new Color[cellColors.size];
|
||||
for (int i = 0; i < cells.length; i++) {
|
||||
cells[i] = new Color((int)Long.parseLong(cellColors.getString(i), 16));
|
||||
}
|
||||
|
||||
String cellTextureFile = json.getString("cell_texture");
|
||||
return this;
|
||||
}
|
||||
|
||||
// TODO Avoid creating game.skin.newDrawable all the time without disposing…
|
||||
public ImageButton.ImageButtonStyle getStyle(final Skin skin, int button, final String imageName) {
|
||||
return new ImageButton.ImageButtonStyle(
|
||||
skin.newDrawable("button_up", buttons[button]),
|
||||
skin.newDrawable("button_down", buttons[button]),
|
||||
null, skin.getDrawable(imageName), null, null);
|
||||
}
|
||||
|
||||
public Color getCellColor(int colorIndex) {
|
||||
return cells[colorIndex];
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
|
||||
}
|
||||
}
|
|
@ -7,16 +7,12 @@ import com.badlogic.gdx.math.MathUtils;
|
|||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
|
||||
import io.github.lonamiwebs.klooni.Klooni;
|
||||
|
||||
// Pieces can be L shaped and be rotated 0 to 3 times to make it random
|
||||
// Maximum cellSize = 4
|
||||
public class Piece {
|
||||
|
||||
private final static int[] colors = {
|
||||
0x7988bfff, 0x98dc53ff, 0x4cd4aeff, // Squares
|
||||
0xfec63dff, 0xec9548ff, 0xe66a82ff, 0xda6554ff, // Lines
|
||||
0x57cb84ff, 0x5abee2ff // L's
|
||||
};
|
||||
|
||||
final Vector2 pos;
|
||||
float cellSize = 10f; // Default
|
||||
|
||||
|
@ -26,7 +22,7 @@ public class Piece {
|
|||
final Color color;
|
||||
|
||||
private Piece(int cols, int rows, boolean swapSize, int colorIndex) {
|
||||
color = new Color(colors[colorIndex]);
|
||||
color = Klooni.theme.getCellColor(colorIndex);
|
||||
|
||||
pos = new Vector2();
|
||||
cellCols = swapSize ? rows : cols;
|
||||
|
@ -40,7 +36,7 @@ public class Piece {
|
|||
}
|
||||
|
||||
private Piece(int lSize, int rotateCount, int colorIndex) {
|
||||
color = new Color(colors[colorIndex]);
|
||||
color = Klooni.theme.getCellColor(colorIndex);
|
||||
|
||||
pos = new Vector2();
|
||||
cellCols = cellRows = lSize;
|
||||
|
|
|
@ -4,7 +4,6 @@ package io.github.lonamiwebs.klooni.screens;
|
|||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
import com.badlogic.gdx.scenes.scene2d.Stage;
|
||||
|
@ -14,7 +13,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
|
|||
import com.badlogic.gdx.scenes.scene2d.ui.Table;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
|
||||
|
||||
import io.github.lonamiwebs.klooni.Klooni;
|
||||
|
||||
|
@ -35,13 +33,7 @@ public class CustomizeScreen implements Screen {
|
|||
optionsGroup.space(12);
|
||||
|
||||
// Back to the previous screen
|
||||
ImageButton.ImageButtonStyle backStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.GOLD),
|
||||
game.skin.newDrawable("button_down", Color.GOLD),
|
||||
null, game.skin.getDrawable("back_texture"), null, null);
|
||||
|
||||
final ImageButton backButton = new ImageButton(backStyle);
|
||||
optionsGroup.addActor(backButton);
|
||||
final ImageButton backButton = new ImageButton(Klooni.theme.getStyle(game.skin, 1, "back_texture"));
|
||||
backButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
|
@ -49,18 +41,12 @@ public class CustomizeScreen implements Screen {
|
|||
dispose();
|
||||
}
|
||||
});
|
||||
optionsGroup.addActor(backButton);
|
||||
|
||||
// Turn sound on/off
|
||||
Drawable soundDrawable = game.skin.getDrawable(
|
||||
Klooni.soundsEnabled() ? "sound_on_texture" : "sound_off_texture");
|
||||
final ImageButton soundButton = new ImageButton(Klooni.theme.getStyle(
|
||||
game.skin, 0, Klooni.soundsEnabled() ? "sound_on_texture" : "sound_off_texture"));
|
||||
|
||||
ImageButton.ImageButtonStyle soundStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.LIME),
|
||||
game.skin.newDrawable("button_down", Color.LIME),
|
||||
null, soundDrawable, null, null);
|
||||
|
||||
final ImageButton soundButton = new ImageButton(soundStyle);
|
||||
optionsGroup.addActor(soundButton);
|
||||
soundButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
|
@ -69,36 +55,27 @@ public class CustomizeScreen implements Screen {
|
|||
Klooni.soundsEnabled() ? "sound_on_texture" : "sound_off_texture");
|
||||
}
|
||||
});
|
||||
optionsGroup.addActor(soundButton);
|
||||
|
||||
// Issues
|
||||
ImageButton.ImageButtonStyle issuesStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.FIREBRICK),
|
||||
game.skin.newDrawable("button_down", Color.FIREBRICK),
|
||||
null, game.skin.getDrawable("issues_texture"), null, null);
|
||||
|
||||
final ImageButton issuesButton = new ImageButton(issuesStyle);
|
||||
optionsGroup.addActor(issuesButton);
|
||||
final ImageButton issuesButton = new ImageButton(Klooni.theme.getStyle(game.skin, 3, "issues_texture"));
|
||||
issuesButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Gdx.net.openURI("https://github.com/LonamiWeb/Klooni1010/issues");
|
||||
}
|
||||
});
|
||||
optionsGroup.addActor(issuesButton);
|
||||
|
||||
// Website
|
||||
ImageButton.ImageButtonStyle webStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", new Color(0x6E99FFFF)),
|
||||
game.skin.newDrawable("button_down", new Color(0x6E99FFFF)),
|
||||
null, game.skin.getDrawable("web_texture"), null, null);
|
||||
|
||||
final ImageButton webButton = new ImageButton(webStyle);
|
||||
optionsGroup.addActor(webButton);
|
||||
final ImageButton webButton = new ImageButton(Klooni.theme.getStyle(game.skin, 2, "web_texture"));
|
||||
webButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
Gdx.net.openURI("https://lonamiwebs.github.io");
|
||||
}
|
||||
});
|
||||
optionsGroup.addActor(webButton);
|
||||
|
||||
table.add(new ScrollPane(optionsGroup)).pad(20, 4, 12, 4);
|
||||
table.row();
|
||||
|
|
|
@ -3,7 +3,6 @@ package io.github.lonamiwebs.klooni.screens;
|
|||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Input;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.GL20;
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
|
@ -32,56 +31,34 @@ public class MainMenuScreen extends InputListener implements Screen {
|
|||
stage.addActor(table);
|
||||
|
||||
// Play button
|
||||
ImageButton.ImageButtonStyle playStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.GREEN),
|
||||
game.skin.newDrawable("button_down", Color.GREEN),
|
||||
null, game.skin.getDrawable("play_texture"), null, null);
|
||||
|
||||
final ImageButton playButton = new ImageButton(playStyle);
|
||||
table.add(playButton).colspan(3).fill().space(16);
|
||||
|
||||
final ImageButton playButton = new ImageButton(Klooni.theme.getStyle(game.skin, 0, "play_texture"));
|
||||
playButton.addListener(new ChangeListener() {
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
game.setScreen(new GameScreen(game));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
table.add(playButton).colspan(3).fill().space(16);
|
||||
|
||||
table.row();
|
||||
|
||||
// Star button (on GitHub)
|
||||
ImageButton.ImageButtonStyle starStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.YELLOW),
|
||||
game.skin.newDrawable("button_down", Color.YELLOW),
|
||||
null, game.skin.getDrawable("star_texture"), null, null);
|
||||
|
||||
final ImageButton starButton = new ImageButton(starStyle);
|
||||
final ImageButton starButton = new ImageButton(Klooni.theme.getStyle(game.skin, 1, "star_texture"));
|
||||
table.add(starButton).space(16);
|
||||
|
||||
// Stats button (high scores)
|
||||
ImageButton.ImageButtonStyle statsStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.BLUE),
|
||||
game.skin.newDrawable("button_down", Color.BLUE),
|
||||
null, game.skin.getDrawable("stats_texture"), null, null);
|
||||
|
||||
final ImageButton statsButton = new ImageButton(statsStyle);
|
||||
final ImageButton statsButton = new ImageButton(Klooni.theme.getStyle(game.skin, 2, "stats_texture"));
|
||||
table.add(statsButton).space(16);
|
||||
|
||||
// Palette button (buy colors)
|
||||
ImageButton.ImageButtonStyle paletteStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.FIREBRICK),
|
||||
game.skin.newDrawable("button_down", Color.FIREBRICK),
|
||||
null, game.skin.getDrawable("palette_texture"), null, null);
|
||||
|
||||
final ImageButton paletteButton = new ImageButton(paletteStyle);
|
||||
table.add(paletteButton).space(16);
|
||||
|
||||
final ImageButton paletteButton = new ImageButton(Klooni.theme.getStyle(game.skin, 3, "palette_texture"));
|
||||
paletteButton.addListener(new ChangeListener() {
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
game.setScreen(new CustomizeScreen(game, game.getScreen()));
|
||||
// Don't dispose because then it needs to take us to the previous screen
|
||||
}
|
||||
});
|
||||
table.add(paletteButton).space(16);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,12 +42,7 @@ public class PauseMenuStage extends Stage {
|
|||
addActor(band);
|
||||
|
||||
// Home screen button
|
||||
ImageButton.ImageButtonStyle homeStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.FIREBRICK),
|
||||
game.skin.newDrawable("button_down", Color.FIREBRICK),
|
||||
null, game.skin.getDrawable("home_texture"), null, null);
|
||||
|
||||
final ImageButton homeButton = new ImageButton(homeStyle);
|
||||
final ImageButton homeButton = new ImageButton(Klooni.theme.getStyle(game.skin, 3, "home_texture"));
|
||||
table.add(homeButton).space(16);
|
||||
|
||||
homeButton.addListener(new ChangeListener() {
|
||||
|
@ -58,12 +53,7 @@ public class PauseMenuStage extends Stage {
|
|||
});
|
||||
|
||||
// Replay button
|
||||
ImageButton.ImageButtonStyle replayStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.GREEN),
|
||||
game.skin.newDrawable("button_down", Color.GREEN),
|
||||
null, game.skin.getDrawable("replay_texture"), null, null);
|
||||
|
||||
final ImageButton replayButton = new ImageButton(replayStyle);
|
||||
final ImageButton replayButton = new ImageButton(Klooni.theme.getStyle(game.skin, 0, "replay_texture"));
|
||||
table.add(replayButton).space(16);
|
||||
|
||||
replayButton.addListener(new ChangeListener() {
|
||||
|
@ -77,12 +67,7 @@ public class PauseMenuStage extends Stage {
|
|||
table.row();
|
||||
|
||||
// Palette button (buy colors)
|
||||
ImageButton.ImageButtonStyle paletteStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.YELLOW),
|
||||
game.skin.newDrawable("button_down", Color.YELLOW),
|
||||
null, game.skin.getDrawable("palette_texture"), null, null);
|
||||
|
||||
final ImageButton paletteButton = new ImageButton(paletteStyle);
|
||||
final ImageButton paletteButton = new ImageButton(Klooni.theme.getStyle(game.skin, 1, "palette_texture"));
|
||||
table.add(paletteButton).space(16);
|
||||
|
||||
paletteButton.addListener(new ChangeListener() {
|
||||
|
@ -95,12 +80,7 @@ public class PauseMenuStage extends Stage {
|
|||
|
||||
// Continue playing OR share (if game over) button
|
||||
// TODO Enable both actions for this button
|
||||
ImageButton.ImageButtonStyle playStyle = new ImageButton.ImageButtonStyle(
|
||||
game.skin.newDrawable("button_up", Color.BLUE),
|
||||
game.skin.newDrawable("button_down", Color.BLUE),
|
||||
null, game.skin.getDrawable("play_texture"), null, null);
|
||||
|
||||
final ImageButton playButton = new ImageButton(playStyle);
|
||||
final ImageButton playButton = new ImageButton(Klooni.theme.getStyle(game.skin, 2, "play_texture"));
|
||||
table.add(playButton).space(16);
|
||||
|
||||
playButton.addListener(new ChangeListener() {
|
||||
|
|
Loading…
Reference in a new issue