Java tutorial
/******************************************************************************* * 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.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.model.Text; import com.bladecoder.engine.model.TextManager; import com.bladecoder.engine.model.World; 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 float maxRectangleWidth; private float maxTalkWidth; private final Vector3 unprojectTmp = new Vector3(); private ObjectMap<String, TextManagerUIStyle> styles; private Text subtitle; private final GlyphLayout layout = new GlyphLayout(); private float fontX = 0; 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); float maxWidth = currentSubtitle.type == Text.Type.TALK ? maxTalkWidth : maxRectangleWidth; final TextManagerUIStyle style = getStyle(currentSubtitle); 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() - layout.width) / 2; fontX = (getStage().getViewport().getScreenWidth() - maxWidth) / 2; } else { posx = unprojectTmp.x; fontX = unprojectTmp.x; } if (posy == TextManager.POS_CENTER) { posy = (getStage().getViewport().getScreenHeight() - layout.height) / 2; } else if (posy == TextManager.POS_SUBTITLE) { posy = getStage().getViewport().getScreenHeight() - layout.height - DPIUtils.getMarginSize() * 4; } else { posy = unprojectTmp.y; } 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); } 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()); fontX = getStage().getViewport().getScreenWidth() - layout.width / 2 - PADDING - 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() / 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()); } } style.font.draw(batch, layout, fontX, getY() + PADDING + layout.height); } public void resize() { final Text currentSubtitle = subtitle != null ? subtitle : World.getInstance().getTextManager().getCurrentText(); final TextManagerUIStyle style = getStyle(currentSubtitle); maxRectangleWidth = Math.min(getStage().getViewport().getScreenWidth() - DPIUtils.getMarginSize() * 2, style.font.getSpaceWidth() * 80); maxTalkWidth = Math.min(getStage().getViewport().getScreenWidth() - DPIUtils.getMarginSize() * 2, style.font.getSpaceWidth() * 35); } 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 TextManagerUIStyle() { } public TextManagerUIStyle(TextManagerUIStyle style) { rectBackground = style.rectBackground; talkBackground = style.talkBackground; talkBubble = style.talkBubble; font = style.font; defaultColor = style.defaultColor; } } }