123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- package me.hammerle.supersnuvi.gamelogic;
- import java.io.File;
- import java.util.Arrays;
- import java.util.HashMap;
- import javafx.scene.input.KeyCode;
- import javafx.scene.paint.Color;
- import me.hammerle.supersnuvi.input.IKeyHandler;
- import me.hammerle.supersnuvi.rendering.IGameRenderer;
- import me.hammerle.supersnuvi.savegame.SimpleConfig;
- import me.hammerle.supersnuvi.tiles.*;
- import me.hammerle.supersnuvi.util.SoundUtils;
- public class StateRenderer
- {
- // constants
- public static final ColoredBaseTile FALLBACK_TILE = new ColoredBaseTile(Color.TRANSPARENT);
-
- // rendering
- private final IGameRenderer renderer;
-
- // tiles
- private final HashMap<Integer, Tile> registeredTiles;
-
- // levels
- private Level currentLevel;
- private final Level[] levels;
- private int levelIndex;
- private final SimpleConfig config;
-
- public static boolean noSound;
-
- public StateRenderer(IGameRenderer renderer)
- {
- this.renderer = renderer;
- this.registeredTiles = new HashMap<>();
-
- File[] files = new File("./levels").listFiles();
- Arrays.sort(files, (o1, o2) -> o1.compareTo(o2));
- levels = new Level[files.length];
- for(int i = 0; i < levels.length; i++)
- {
- levels[i] = new Level(this, files[i]);
- }
- currentLevel = null;
- levelIndex = 0;
- config = new SimpleConfig("savegame.txt");
- config.load();
-
- noSound = !config.getBoolean("sound", false);
- SoundUtils.loadSounds();
-
- registerTiles();
- }
- // -------------------------------------------------------------------------
- // tile stuff
- // -------------------------------------------------------------------------
-
- private void registerTiles()
- {
- // dirt
- for(int i = 0; i < 16; i++)
- {
- registeredTiles.put(i, new BaseBoxTile("dirt/dirt" + i));
- }
-
- // grass
- registeredTiles.put(20, new BaseBoxTile("grass/grass4"));
- registeredTiles.put(21, new BaseBoxTile("grass/grass7"));
- registeredTiles.put(22, new BaseBoxTile("grass/grass8"));
- registeredTiles.put(23, new BaseBoxTile("grass/grass9"));
- registeredTiles.put(28, new BaseBoxTile("grass/grass10"));
- registeredTiles.put(29, new BaseBoxTile("grass/grass14"));
- registeredTiles.put(30, new BaseBoxTile("grass/grass15"));
- registeredTiles.put(31, new BaseBoxTile("grass/grass16"));
-
- // bottled soul
- registeredTiles.put(BottledSoulTile.ID, new BottledSoulTile());
-
- // bounce shroom
- registeredTiles.put(48, new TrampolinTile());
-
- // crumbling stones
- registeredTiles.put(64, new CrumblingStoneTile());
-
- // spike trap
- registeredTiles.put(80, new SpikeTile());
-
- // water
- registeredTiles.put(96, new WaterTile(true));
- registeredTiles.put(97, new WaterTile(false));
-
- // snuvi start block
- registeredTiles.put(StartTile.ID, new StartTile());
-
- // sky
- registeredTiles.put(128, new SkyTile());
-
- // ice
- registeredTiles.put(144, new SlipperyTile("ice/ice"));
-
- // slippery slime
- registeredTiles.put(148, new SlipperyTile("slippery_slime/slippery_slime148"));
- registeredTiles.put(149, new SlipperyTile("slippery_slime/slippery_slime149"));
- registeredTiles.put(150, new SlipperyTile("slippery_slime/slippery_slime150"));
- registeredTiles.put(151, new SlipperyTile("slippery_slime/slippery_slime151"));
- registeredTiles.put(156, new SlipperyTile("slippery_slime/slippery_slime156"));
- registeredTiles.put(157, new SlipperyTile("slippery_slime/slippery_slime157"));
- registeredTiles.put(158, new SlipperyTile("slippery_slime/slippery_slime158"));
- registeredTiles.put(159, new SlipperyTile("slippery_slime/slippery_slime159"));
-
- // end level
- registeredTiles.put(160, new GoalTile("end/end"));
- registeredTiles.put(161, new GoalTile("end/end2"));
-
- // thorns
- registeredTiles.put(176, new KillTile("thorns/thorns_bottom", 2));
- registeredTiles.put(177, new KillTile("thorns/thorns_mid", 2));
- registeredTiles.put(178, new KillTile("thorns/thorns_top", 2));
- registeredTiles.put(179, new KillTile("thorns/thorns_bottom", -3));
- registeredTiles.put(180, new KillTile("thorns/thorns_mid", -3));
- registeredTiles.put(181, new KillTile("thorns/thorns_top", -3));
-
- // decoration shrooms
- registeredTiles.put(208, new DecoShroomTile("shrooms/shroom"));
- registeredTiles.put(209, new DecoShroomTile("shrooms/shroom2"));
- registeredTiles.put(210, new DecoShroomTile("shrooms/shroom3"));
- registeredTiles.put(211, new DecoShroomTile("shrooms/shroom4"));
- }
-
- public Tile getTile(int id)
- {
- Tile tile = registeredTiles.get(id);
- if(tile == null)
- {
- return FALLBACK_TILE;
- }
- return tile;
- }
-
- public Tile getInteractionTile(int id)
- {
- return registeredTiles.getOrDefault(id, FALLBACK_TILE);
- }
-
- public void resetTiles()
- {
- registeredTiles.values().forEach(v -> v.reset());
- }
-
- // -------------------------------------------------------------------------
- // tick, rendering
- // -------------------------------------------------------------------------
- public IGameRenderer getRenderer()
- {
- return renderer;
- }
-
- private static final int MENU_WIDTH = 26;
- private static final int MENU_X = 12;
- private static final int MENU_Y = 5;
- private static final int MENU_MAX = 11;
- private static final char[] TABLE_TOP = getCharLine((char) 131, (char) 136, (char) 133, (char) 136);
- private static final char[] TABLE_HEADING = getCharLine((char) 134, "Wähle ein Level ...", (char) 134, ' ');
- private static final char[] TABLE_MID = getCharLine((char) 130, (char) 136, (char) 132, (char) 129);
- private static final char[] TABLE_BOTTOM = getCharLine((char) 137, (char) 136, (char) 138, (char) 135);
- private static final char[] TABLE_MORE = getCharLine((char) 134, "...", (char) 134, (char) 134);
-
- private static char[] getCharLine(char start, char mid, char end, char spacer)
- {
- char[] c = new char[MENU_WIDTH];
- Arrays.fill(c, 1, c.length - 1, mid);
- c[0] = start;
- c[c.length - 1] = end;
- c[c.length - 3] = spacer;
- return c;
- }
-
- private static char[] getCharLine(char start, String s, char end, char spacer)
- {
- char[] chars = new char[MENU_WIDTH];
- chars[0] = start;
- chars[chars.length - 1] = end;
- int border = Math.min(MENU_WIDTH - 2, s.length());
- for(int i = 0; i < border; i++)
- {
- chars[i + 1] = s.charAt(i);
- }
- chars[chars.length - 3] = spacer;
- return chars;
- }
-
- public void tick(IKeyHandler keys)
- {
- if(currentLevel != null)
- {
- SoundUtils.playSound(SoundUtils.SONG_1, false);
- SoundUtils.stopSound(SoundUtils.MENU_MUSIC);
-
- currentLevel.tick(keys);
-
- // doing that here to prevent concurent modification
- if(currentLevel.shouldFinish())
- {
- currentLevel.resetLevel();
- config.set("level." + currentLevel.getName(), true);
- currentLevel = null;
- config.save();
- return;
- }
-
- if(currentLevel.shouldReset())
- {
- currentLevel.resetLevel();
- }
-
- if(keys.isKeyJustReleased(KeyCode.ESCAPE) > 0)
- {
- currentLevel = null;
- }
- }
- else
- {
- SoundUtils.playSound(SoundUtils.MENU_MUSIC, false);
- SoundUtils.stopSound(SoundUtils.SONG_1);
-
- if(keys.isKeyJustReleased(KeyCode.ENTER) > 0)
- {
- currentLevel = levels[levelIndex];
- return;
- }
- if(keys.getKeyDownTime(KeyCode.DOWN) > 12)
- {
- keys.resetKeyTime(KeyCode.DOWN);
- levelIndex++;
- }
- else if(keys.getKeyDownTime(KeyCode.UP) > 12)
- {
- keys.resetKeyTime(KeyCode.UP);
- levelIndex--;
- }
- else if(keys.isKeyJustReleased(KeyCode.DOWN) > 0)
- {
- levelIndex++;
- }
- else if(keys.isKeyJustReleased(KeyCode.UP) > 0)
- {
- levelIndex--;
- }
- if(levelIndex < 0)
- {
- levelIndex = 0;
- }
- else if(levelIndex >= levels.length)
- {
- levelIndex = levels.length - 1;
- }
- renderer.prepareStringDrawing(Color.WHITE);
- double lineHeight = renderer.getLineHeight();
- double x = renderer.getStringOffsetX(MENU_X);
- double y = renderer.getStringOffsetY(MENU_Y);
- renderer.drawChars(TABLE_TOP, x, y);
- y += lineHeight;
- renderer.drawChars(TABLE_HEADING, x, y);
- y += lineHeight;
- renderer.drawChars(TABLE_MID, x, y);
- y += lineHeight;
- if(levels.length > MENU_MAX)
- {
- int upperHalf = MENU_MAX / 2;
- int downHalf = levels.length - upperHalf;
- if(levelIndex < upperHalf)
- {
- paintStringMarking(lineHeight, x, y, levelIndex);
- y = paintLevelName(x, y, 0, MENU_MAX - 1);
- renderer.drawChars(TABLE_MORE, x, y);
- y += lineHeight;
- }
- else if(levelIndex >= downHalf)
- {
- paintStringMarking(lineHeight, x, y, levelIndex - downHalf + upperHalf + ((MENU_MAX & 1) != 0 ? 1 : 0));
- renderer.drawChars(TABLE_MORE, x, y);
- y += lineHeight;
- y = paintLevelName(x, y, levels.length - MENU_MAX + 1, MENU_MAX - 1);
- }
- else
- {
- paintStringMarking(lineHeight, x, y, upperHalf);
- renderer.drawChars(TABLE_MORE, x, y);
- y += lineHeight;
- y = paintLevelName(x, y, levelIndex - upperHalf + 1, MENU_MAX - 2);
- renderer.drawChars(TABLE_MORE, x, y);
- y += lineHeight;
- }
- }
- else
- {
- paintStringMarking(lineHeight, x, y, levelIndex);
- y = paintLevelName(x, y, 0, levels.length);
- }
- renderer.drawChars(TABLE_BOTTOM, x, y);
- renderer.stopStringDrawing();
- }
- }
-
- private double paintLevelName(double x, double y, int from, int length)
- {
- double lineHeight = renderer.getLineHeight();
-
- char[] chars = new char[MENU_WIDTH];
- chars[0] = 134;
- chars[MENU_WIDTH - 1] = 134;
- String s;
- int border;
- length += from;
- length = Math.min(length, levels.length);
- for(int j = from; j < length; j++)
- {
- s = levels[j].getName();
- border = Math.min(MENU_WIDTH - 4, s.length());
- for(int i = 0; i < border; i++)
- {
- chars[i + 1] = s.charAt(i);
- }
- Arrays.fill(chars, border + 1, MENU_WIDTH - 1, (char) 0);
- chars[chars.length - 3] = 134;
- if(config.getBoolean("level." + s, false))
- {
- chars[chars.length - 2] = 'x';
- }
- else
- {
- chars[chars.length - 2] = 'o';
- }
- renderer.drawChars(chars, x, y);
- y += lineHeight;
- }
- return y;
- }
-
- private void paintStringMarking(double lineHeight, double x, double y, int pos)
- {
- renderer.fillRec(
- x + renderer.getStringWidth(1),
- y + pos * lineHeight - 1,
- renderer.getStringWidth(MENU_WIDTH - 4),
- lineHeight + 1,
- Color.GRAY);
-
- renderer.fillRec(
- x + renderer.getStringWidth(MENU_WIDTH - 2),
- y + pos * lineHeight - 1,
- renderer.getStringWidth(1),
- lineHeight + 1,
- Color.GRAY);
- }
-
- public void tick()
- {
- registeredTiles.values().forEach(tile -> tile.tick());
- }
- }
|