com.bladecoder.engine.model.ImageRenderer 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.model;
import java.util.HashMap;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonValue;
import com.bladecoder.engine.actions.ActionCallback;
import com.bladecoder.engine.actions.ActionCallbackQueue;
import com.bladecoder.engine.anim.AnimationDesc;
import com.bladecoder.engine.anim.Tween;
import com.bladecoder.engine.assets.EngineAssetManager;
import com.bladecoder.engine.i18n.I18N;
import com.bladecoder.engine.util.EngineLogger;
import com.bladecoder.engine.util.RectangleRenderer;
import com.bladecoder.engine.util.SerializationHelper;
import com.bladecoder.engine.util.SerializationHelper.Mode;
public class ImageRenderer extends AnimationRenderer {
class ImageCacheEntry extends CacheEntry {
Texture tex;
}
public ImageRenderer() {
}
@Override
public String[] getInternalAnimations(AnimationDesc anim) {
return new String[] { anim.source.substring(0, anim.source.lastIndexOf('.')) };
}
@Override
public void update(float delta) {
}
@Override
public void draw(SpriteBatch batch, float x, float y, float scale, float rotation, Color tint) {
float dx = getAlignDx(getWidth(), orgAlign);
float dy = getAlignDy(getHeight(), orgAlign);
ImageCacheEntry source = (ImageCacheEntry)currentSource;
if (source == null || source.tex == null) {
RectangleRenderer.draw(batch, x + dx * scale , y + dy * scale, getWidth() * scale, getHeight() * scale, Color.RED);
return;
}
if(tint != null)
batch.setColor(tint);
x = x + dx;
y = y + dy;
batch.draw(source.tex, x, y, -dx, -dy, getWidth(), getHeight(), scale, scale, rotation,
0, 0, source.tex.getWidth(), source.tex.getHeight(), flipX, false);
if(tint != null)
batch.setColor(Color.WHITE);
}
@Override
public float getWidth() {
ImageCacheEntry source = (ImageCacheEntry)currentSource;
if (source == null || source.tex == null)
return super.getWidth();
return source.tex.getWidth();
}
@Override
public float getHeight() {
ImageCacheEntry source = (ImageCacheEntry)currentSource;
if (source == null || source.tex == null)
return super.getHeight();
return source.tex.getHeight();
}
@Override
public void startAnimation(String id, Tween.Type repeatType, int count, ActionCallback cb) {
AnimationDesc fa = getAnimation(id);
if (fa == null) {
EngineLogger.error("AnimationDesc not found: " + id);
return;
}
if (cb != null)
ActionCallbackQueue.add(cb);
if (currentAnimation != null && currentAnimation.disposeWhenPlayed)
disposeSource(currentAnimation.source);
currentAnimation = fa;
currentSource = (ImageCacheEntry)sourceCache.get(fa.source);
// If the source is not loaded. Load it.
if (currentSource == null || currentSource.refCounter < 1) {
loadSource(fa.source);
EngineAssetManager.getInstance().finishLoading();
retrieveSource(fa.source);
currentSource = (ImageCacheEntry)sourceCache.get(fa.source);
if (currentSource == null) {
EngineLogger.error("Could not load AnimationDesc: " + id);
currentAnimation = null;
computeBbox();
return;
}
}
computeBbox();
}
private AnimationDesc getAnimation(String id) {
AnimationDesc fa = fanims.get(id);
flipX = false;
if (fa == null) {
// Search for flipped
String flipId = AnimationDesc.getFlipId(id);
fa = fanims.get(flipId);
if (fa != null)
flipX = true;
else {
// search for .left if .frontleft not found and viceversa
StringBuilder sb = new StringBuilder();
if (id.endsWith(AnimationDesc.FRONTLEFT)) {
sb.append(id.substring(0, id.lastIndexOf('.') + 1));
sb.append(AnimationDesc.LEFT);
} else if (id.endsWith(AnimationDesc.FRONTRIGHT)) {
sb.append(id.substring(0, id.lastIndexOf('.') + 1));
sb.append(AnimationDesc.RIGHT);
} else if (id.endsWith(AnimationDesc.BACKLEFT) || id.endsWith(AnimationDesc.BACKRIGHT)) {
sb.append(id.substring(0, id.lastIndexOf('.') + 1));
sb.append(AnimationDesc.BACK);
} else if (id.endsWith(AnimationDesc.LEFT)) {
sb.append(id.substring(0, id.lastIndexOf('.') + 1));
sb.append(AnimationDesc.FRONTLEFT);
} else if (id.endsWith(AnimationDesc.RIGHT)) {
sb.append(id.substring(0, id.lastIndexOf('.') + 1));
sb.append(AnimationDesc.FRONTRIGHT);
}
String s = sb.toString();
fa = fanims.get(s);
if (fa == null) {
// Search for flipped
flipId = AnimationDesc.getFlipId(s);
fa = fanims.get(flipId);
if (fa != null)
flipX = true;
}
}
}
return fa;
}
@Override
public void startAnimation(String id, Tween.Type repeatType, int count, ActionCallback cb, String direction) {
StringBuilder sb = new StringBuilder(id);
// if dir==null gets the current animation direction
if (direction == null) {
int idx = getCurrentAnimationId().indexOf('.');
if (idx != -1) {
String dir = getCurrentAnimationId().substring(idx);
sb.append(dir);
}
} else {
sb.append('.');
sb.append(direction);
}
String anim = sb.toString();
if (getAnimation(anim) == null) {
anim = id;
}
startAnimation(anim, repeatType, count, null);
}
@Override
public void startAnimation(String id, Tween.Type repeatType, int count, ActionCallback cb, Vector2 p0, Vector2 pf) {
startAnimation(id, repeatType, count, cb, AnimationDesc.getDirectionString(p0, pf, AnimationDesc.getDirs(id, fanims)));
}
private void loadSource(String source) {
CacheEntry entry = sourceCache.get(source);
if (entry == null) {
entry = new ImageCacheEntry();
sourceCache.put(source, entry);
}
if (entry.refCounter == 0) {
// I18N for images
if (source.charAt(0) == I18N.PREFIX) {
source = getI18NSource(source.substring(1));
}
EngineAssetManager.getInstance().loadTexture(EngineAssetManager.IMAGE_DIR + source);
}
entry.refCounter++;
}
private void retrieveSource(String source) {
CacheEntry entry = sourceCache.get(source);
if (entry == null || entry.refCounter < 1) {
loadSource(source);
EngineAssetManager.getInstance().finishLoading();
entry = sourceCache.get(source);
}
if (((ImageCacheEntry)entry).tex == null) {
// I18N for images
if (source.charAt(0) == I18N.PREFIX) {
source = getI18NSource(source.substring(1));
}
((ImageCacheEntry)entry).tex = EngineAssetManager.getInstance().getTexture(EngineAssetManager.IMAGE_DIR + source);
}
}
private String getI18NSource(String source) {
String lang = I18N.getCurrentLocale().getLanguage();
int pointIdx = source.lastIndexOf('.');
String ext = source.substring(pointIdx);
String name = source.substring(0, pointIdx);
String localName = name + "_" + lang + ext;
if(EngineAssetManager.getInstance().assetExists(EngineAssetManager.IMAGE_DIR + localName))
return localName;
return source;
}
private void disposeSource(String source) {
ImageCacheEntry entry = (ImageCacheEntry)sourceCache.get(source);
if (entry.refCounter == 1) {
EngineAssetManager.getInstance().disposeTexture(entry.tex);
entry.tex = null;
}
entry.refCounter--;
}
@Override
public void loadAssets() {
for (AnimationDesc fa : fanims.values()) {
if (fa.preload)
loadSource(fa.source);
}
if (currentAnimation != null && !currentAnimation.preload) {
loadSource(currentAnimation.source);
} else if (currentAnimation == null && initAnimation != null) {
AnimationDesc fa = fanims.get(initAnimation);
if (fa != null && !fa.preload)
loadSource(fa.source);
}
}
@Override
public void retrieveAssets() {
for (String key : sourceCache.keySet()) {
if (sourceCache.get(key).refCounter > 0)
retrieveSource(key);
}
if (currentAnimation != null) {
CacheEntry entry = sourceCache.get(currentAnimation.source);
currentSource = entry;
} else if (initAnimation != null) {
startAnimation(initAnimation, Tween.Type.SPRITE_DEFINED, 1, null);
}
computeBbox();
}
@Override
public void dispose() {
for (CacheEntry entry : sourceCache.values()) {
if(entry.refCounter > 0)
EngineAssetManager.getInstance().disposeTexture(((ImageCacheEntry)entry).tex);
}
sourceCache.clear();
currentSource = null;
}
@SuppressWarnings("unchecked")
@Override
public void read(Json json, JsonValue jsonData) {
super.read(json, jsonData);
if (SerializationHelper.getInstance().getMode() == Mode.MODEL) {
fanims = json.readValue("fanims", HashMap.class, AnimationDesc.class, jsonData);
} else {
}
}
}