/******************************************************************************* * 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 com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.ParticleEffect; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Polygon; import com.badlogic.gdx.utils.Align; import com.badlogic.gdx.utils.Json; import com.badlogic.gdx.utils.JsonValue; import com.bladecoder.engine.assets.EngineAssetManager; import com.bladecoder.engine.serialization.BladeJson; import com.bladecoder.engine.serialization.BladeJson.Mode; import com.bladecoder.engine.util.RectangleRenderer; public class ParticleRenderer implements ActorRenderer { private final static float DEFAULT_DIM = 100; private final ParticleEffect effect = new ParticleEffect(); private float lastAnimationTime = 0; private Polygon bbox; private String particleName; private String atlasName; private TextureAtlas atlasTex; private float tmpPosX = 0; private float tmpPosY = 0; private static final Matrix4 tmp = new Matrix4(); private int orgAlign = Align.bottom; public ParticleRenderer() { } public void reset() { tmpPosX = tmpPosY = 0; effect.reset(); } @Override public int getOrgAlign() { return orgAlign; } @Override public void setOrgAlign(int align) { orgAlign = align; } @Override public void update(float delta) { try { effect.update(delta); } catch (Exception e) { // avoid crashing if atlas is not found } } @Override public void draw(SpriteBatch batch, float x, float y, float scaleX, float scaleY, float rotation, Color tint) { float finalScaleX = EngineAssetManager.getInstance().getScale() * scaleX; float finalScaleY = EngineAssetManager.getInstance().getScale() * scaleY; if (effect.getEmitters().size > 0) { Matrix4 tm = batch.getTransformMatrix(); tmp.set(tm); if (tmpPosX != x / finalScaleX || tmpPosY != y / finalScaleY) { tmpPosX = x / finalScaleX; tmpPosY = y / finalScaleY; effect.setPosition(tmpPosX, tmpPosY); } tm.rotate(0, 0, 1, rotation).scale(finalScaleX, finalScaleY, 1); batch.setTransformMatrix(tm); if (tint != null) batch.setColor(tint); effect.draw(batch); if (tint != null) batch.setColor(Color.WHITE); batch.setTransformMatrix(tmp); } else { x = x - getWidth() / 2 * finalScaleX; RectangleRenderer.draw(batch, x, y, getWidth() * finalScaleX, getHeight() * finalScaleY, Color.RED); } } @Override public float getWidth() { return DEFAULT_DIM; } @Override public float getHeight() { return DEFAULT_DIM; } public String getParticleName() { return particleName; } public void setParticleName(String particleName) { this.particleName = particleName; } public String getAtlasName() { return atlasName; } public void setAtlasName(String atlasName) { this.atlasName = atlasName; } @Override public void updateBboxFromRenderer(Polygon bbox) { this.bbox = bbox; computeBbox(); } private void computeBbox() { if (bbox == null) return; if (bbox.getVertices() == null || bbox.getVertices().length != 8) { bbox.setVertices(new float[8]); } float[] verts = bbox.getVertices(); verts[0] = -getWidth() / 2; verts[1] = 0f; verts[2] = -getWidth() / 2; verts[3] = getHeight(); verts[4] = getWidth() / 2; verts[5] = getHeight(); verts[6] = getWidth() / 2; verts[7] = 0f; bbox.dirty(); } @Override public void loadAssets() { EngineAssetManager.getInstance().loadAtlas(getAtlasName()); } @Override public void retrieveAssets() { if (!EngineAssetManager.getInstance().isAtlasLoaded(atlasName)) { loadAssets(); EngineAssetManager.getInstance().finishLoading(); } atlasTex = EngineAssetManager.getInstance().getTextureAtlas(getAtlasName()); effect.load(EngineAssetManager.getInstance().getParticle(getParticleName()), atlasTex); effect.start(); // reset tmp to force repositioning tmpPosX = Float.MAX_VALUE; effect.update(lastAnimationTime); computeBbox(); } @Override public void dispose() { EngineAssetManager.getInstance().disposeAtlas(getAtlasName()); } @Override public void write(Json json) { BladeJson bjson = (BladeJson) json; if (bjson.getMode() == Mode.MODEL) { json.writeValue("atlasName", getAtlasName()); json.writeValue("particleName", getParticleName()); json.writeValue("orgAlign", orgAlign); } else { json.writeValue("lastAnimationTime", lastAnimationTime); } } @Override public void read(Json json, JsonValue jsonData) { BladeJson bjson = (BladeJson) json; if (bjson.getMode() == Mode.MODEL) { setAtlasName(json.readValue("atlasName", String.class, jsonData)); setParticleName(json.readValue("particleName", String.class, jsonData)); orgAlign = json.readValue("orgAlign", int.class, Align.bottom, jsonData); } else { lastAnimationTime = json.readValue("lastAnimationTime", Float.class, jsonData); } } @Override public void setWorld(World world) { // TODO Auto-generated method stub } }