com.bladecoder.engine.ui.TextManagerUI Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of blade-engine Show documentation
Show all versions of blade-engine Show documentation
Classic point and click adventure game engine
/*******************************************************************************
* Copyright 2014 Rafael Garcia Moreno.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.bladecoder.engine.ui;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.ObjectMap;
import com.bladecoder.engine.assets.EngineAssetManager;
import com.bladecoder.engine.model.Text;
import com.bladecoder.engine.model.TextManager;
import com.bladecoder.engine.model.World;
import com.bladecoder.engine.util.Config;
import com.bladecoder.engine.util.DPIUtils;
/**
* TextManagerUI draws texts and dialogs on screen.
*
* For now, only one subtitle is displayed in the screen.
*
* @author rgarcia
*
*/
public class TextManagerUI extends Actor {
private static final float PADDING = DPIUtils.getMarginSize();
private final Vector3 unprojectTmp = new Vector3();
private ObjectMap styles;
private Text subtitle;
private final GlyphLayout layout = new GlyphLayout();
private float fontX = 0;
private AtlasRegion charIcon = null;
public TextManagerUI(Skin skin) {
setTouchable(Touchable.disabled);
styles = skin.getAll(TextManagerUIStyle.class);
for (TextManagerUIStyle style : styles.values()) {
style.font.getData().markupEnabled = true;
}
setVisible(false);
}
@Override
public void act(float delta) {
super.act(delta);
Text currentSubtitle = World.getInstance().getTextManager().getCurrentText();
if (subtitle != currentSubtitle) {
subtitle = currentSubtitle;
if (currentSubtitle == null && isVisible()) {
setVisible(false);
} else if (currentSubtitle != null && !isVisible()) {
setVisible(true);
}
if (isVisible()) {
float posx = currentSubtitle.x;
float posy = currentSubtitle.y;
unprojectTmp.set(posx, posy, 0);
World.getInstance().getSceneCamera().scene2screen(getStage().getViewport(), unprojectTmp);
final TextManagerUIStyle style = getStyle(currentSubtitle);
float maxWidth = Math.min(getStage().getViewport().getScreenWidth() - DPIUtils.getMarginSize() * 2,
style.font.getXHeight() * (currentSubtitle.type == Text.Type.TALK ? style.maxTalkCharWidth : style.maxCharWidth));
Color color = currentSubtitle.color != null ? currentSubtitle.color : style.defaultColor;
if (color == null)
color = Color.BLACK;
layout.setText(style.font, currentSubtitle.str, color, maxWidth, Align.center, true);
if (posx == TextManager.POS_CENTER || posx == TextManager.POS_SUBTITLE) {
posx = getStage().getViewport().getScreenWidth() / 2;
fontX = getStage().getViewport().getScreenWidth() / 2;
} else {
posx = unprojectTmp.x;
fontX = posx + (layout.width - maxWidth) / 2;
}
if (posy == TextManager.POS_CENTER) {
posy = (getStage().getViewport().getScreenHeight() - layout.height) / 2;
} else if (posy == TextManager.POS_SUBTITLE) {
posy = getStage().getViewport().getScreenHeight() * style.subtitlePosPercent - layout.height;
if (posy < 0) {
posy = PADDING;
}
} else {
posy = unprojectTmp.y;
if (subtitle.type != Text.Type.TALK) {
posy -= layout.height;
}
}
// CHAR ICON CALCS
if (subtitle.type == Text.Type.SUBTITLE && !Config.getProperty(Config.CHARACTER_ICON_ATLAS, "").equals("") && subtitle.actorId != null) {
charIcon = EngineAssetManager.getInstance()
.getRegion(Config.getProperty(Config.CHARACTER_ICON_ATLAS, null), subtitle.actorId);
if(charIcon != null) {
float scale = getStage().getViewport().getScreenHeight() / (float)World.getInstance().getHeight();
float iconPosY = getStage().getViewport().getScreenHeight() - charIcon.getRegionHeight() * scale - DPIUtils.getMarginSize();
posy = Math.min(posy, iconPosY);
}
} else {
charIcon = null;
}
setPosition(posx - PADDING, posy - PADDING);
setSize(layout.width + PADDING * 2, layout.height + PADDING * 2);
if (currentSubtitle.type == Text.Type.TALK) {
if (style.talkBubble != null) {
setY(getY() + DPIUtils.getTouchMinSize() / 3 + PADDING);
} else {
setY(getY() + PADDING);
}
}
setX(getX() - layout.width / 2);
fontX = posx - maxWidth / 2;
// check if the text exits the screen
if (getX() < 0 && getX() > -getWidth()) {
setX(0 + PADDING);
fontX = getX() + PADDING + (layout.width - maxWidth) / 2;
} else if (getX() + getWidth() > getStage().getViewport().getScreenWidth()
&& getX() + getWidth() < getStage().getViewport().getScreenWidth() + getWidth()) {
setX(getStage().getViewport().getScreenWidth() - getWidth() - PADDING);
fontX = getStage().getViewport().getScreenWidth() - layout.width / 2 - PADDING * 2 - maxWidth / 2;
}
if (getY() + getHeight() > getStage().getViewport().getScreenHeight()) {
setY(getStage().getViewport().getScreenHeight() - getHeight() - PADDING);
}
}
}
}
@Override
public void draw(Batch batch, float alpha) {
batch.setColor(Color.WHITE);
final TextManagerUIStyle style = getStyle(subtitle);
if (subtitle.type == Text.Type.TALK) {
if (getX() < 0 || getX() > getStage().getViewport().getScreenWidth())
return;
if (style.talkBubble != null) {
float scale = DPIUtils.getTouchMinSize() * style.bubbleSize / 4 / style.talkBubble.getMinHeight();
float bubbleX = unprojectTmp.x - style.talkBubble.getMinWidth() * scale / 2;
bubbleX = Math.max(bubbleX, getX() + PADDING);
bubbleX = Math.min(bubbleX, getStage().getViewport().getScreenWidth() - PADDING);
float bubbleY = getY() - style.talkBubble.getMinHeight() * scale + 2;
style.talkBubble.draw(batch, bubbleX, bubbleY, style.talkBubble.getMinWidth() * scale,
style.talkBubble.getMinHeight() * scale);
}
if (style.talkBackground != null) {
style.talkBackground.draw(batch, getX(), getY(), getWidth(), getHeight());
}
} else if (subtitle.type == Text.Type.SUBTITLE) {
if (style.rectBackground != null) {
style.rectBackground.draw(batch, getX(), getY(), getWidth(), getHeight());
}
if (charIcon != null) {
float scale = getStage().getViewport().getScreenHeight() / (float)World.getInstance().getHeight();
batch.draw(charIcon, getX() - charIcon.getRegionWidth() * scale, getY(),
charIcon.getRegionWidth() * scale, charIcon.getRegionHeight() * scale);
}
}
style.font.draw(batch, layout, fontX, getY() + PADDING + layout.height);
}
private TextManagerUIStyle getStyle(Text text) {
String key = "default";
if (text != null) {
key = text.style;
}
if (key == null || key.isEmpty()) {
key = "default";
}
return styles.get(key);
}
/** The style for the TextManagerUI */
static public class TextManagerUIStyle {
/** Optional. */
public Drawable rectBackground;
public Drawable talkBackground;
public Drawable talkBubble;
public BitmapFont font;
public Color defaultColor;
public float subtitlePosPercent = 0.90f;
public float bubbleSize = 1f;
public int maxCharWidth = 80;
public int maxTalkCharWidth = 35;
public TextManagerUIStyle() {
}
public TextManagerUIStyle(TextManagerUIStyle style) {
rectBackground = style.rectBackground;
talkBackground = style.talkBackground;
talkBubble = style.talkBubble;
font = style.font;
defaultColor = style.defaultColor;
subtitlePosPercent = style.subtitlePosPercent;
bubbleSize = style.bubbleSize;
maxCharWidth = style.maxCharWidth;
maxTalkCharWidth = style.maxTalkCharWidth;
}
}
}