/* * Pixel Dungeon * Copyright (C) 2012-2015 Oleg Dolya * * Shattered Pixel Dungeon * Copyright (C) 2014-2019 Evan Debenham * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package com.shatteredpixel.shatteredpixeldungeon.effects; import com.shatteredpixel.shatteredpixeldungeon.scenes.GameScene; import com.shatteredpixel.shatteredpixeldungeon.scenes.PixelScene; import com.shatteredpixel.shatteredpixeldungeon.tiles.DungeonTilemap; import com.shatteredpixel.shatteredpixeldungeon.ui.RenderedTextBlock; import com.watabou.noosa.Camera; import com.watabou.noosa.Game; import com.watabou.noosa.RenderedText; import com.watabou.utils.Callback; import com.watabou.utils.SparseArray; import java.util.ArrayList; public class FloatingText extends RenderedTextBlock { private static final float LIFESPAN = 1f; private static final float DISTANCE = DungeonTilemap.SIZE; private float timeLeft; private int key = -1; private static final SparseArray<ArrayList<FloatingText>> stacks = new SparseArray<>(); public FloatingText() { super(9*PixelScene.defaultZoom); setHightlighting(false); } @Override public void update() { super.update(); if (timeLeft > 0) { if ((timeLeft -= Game.elapsed) <= 0) { kill(); } else { float p = timeLeft / LIFESPAN; alpha( p > 0.5f ? 1 : p * 2 ); float yMove = (DISTANCE / LIFESPAN) * Game.elapsed; y -= yMove; for (RenderedText t : words){ t.y -= yMove; } } } } @Override public void kill() { if (key != -1) { synchronized (stacks) { stacks.get(key).remove(this); } key = -1; } super.kill(); } @Override public void destroy() { kill(); super.destroy(); } public void reset( float x, float y, String text, int color ) { revive(); zoom( 1 / (float)PixelScene.defaultZoom ); text( text ); hardlight( color ); setPos( PixelScene.align( Camera.main, x - width() / 2), PixelScene.align( Camera.main, y - height()) ); timeLeft = LIFESPAN; } /* STATIC METHODS */ public static void show( float x, float y, String text, int color ) { Game.runOnRenderThread(new Callback() { @Override public void call() { FloatingText txt = GameScene.status(); if (txt != null){ txt.reset(x, y, text, color); } } }); } public static void show( float x, float y, int key, String text, int color ) { Game.runOnRenderThread(new Callback() { @Override public void call() { FloatingText txt = GameScene.status(); if (txt != null){ txt.reset(x, y, text, color); push(txt, key); } } }); } private static void push( FloatingText txt, int key ) { synchronized (stacks) { txt.key = key; ArrayList<FloatingText> stack = stacks.get(key); if (stack == null) { stack = new ArrayList<>(); stacks.put(key, stack); } if (stack.size() > 0) { FloatingText below = txt; int aboveIndex = stack.size() - 1; while (aboveIndex >= 0) { FloatingText above = stack.get(aboveIndex); if (above.bottom() + 4 > below.top()) { above.setPos(above.left(), below.top() - above.height() - 4); below = above; aboveIndex--; } else { break; } } } stack.add(txt); } } }