/** * Copyright 2008 - 2011 * * 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. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.1 */ package loon.action.sprite; import loon.LSystem; import loon.action.ActionBind; import loon.action.collision.CollisionHelper; import loon.action.map.Field2D; import loon.core.LObject; import loon.core.geom.Point; import loon.core.geom.RectBox; import loon.core.geom.Vector2f; import loon.core.graphics.device.LColor; import loon.core.graphics.device.LGraphics; import loon.core.graphics.device.LTrans; import loon.core.graphics.opengl.GLEx; import loon.core.graphics.opengl.LTexture; import loon.core.graphics.opengl.TextureUtils; public class Sprite extends LObject implements ActionBind, ISprite, LTrans { /** * */ private static final long serialVersionUID = -1982110847888726016L; // 默认每帧刷新时间 final static private long defaultTimer = 150; // 是否可见 private boolean visible = true; // 精灵名称 private String spriteName; // 精灵图片 private LTexture image; // 动画 private Animation animation = new Animation(); private int transform; private float scaleX = 1, scaleY = 1; /** * 默认构造函数 * */ public Sprite() { this(0, 0); } /** * 以下参数分别为 坐标x,坐标y * * @param x * @param y */ public Sprite(float x, float y) { this("Sprite" + System.currentTimeMillis(), x, y); } /** * 以下参数分别为 精灵名,坐标x,坐标y * * @param spriteName * @param x * @param y */ private Sprite(String spriteName, float x, float y) { this.setLocation(x, y); this.spriteName = spriteName; this.visible = true; this.transform = LTrans.TRANS_NONE; } /** * 以下参数分别为 取材文件,每行取材宽度,每列取材长度 * * @param fileName * @param row * @param col */ public Sprite(String fileName, int row, int col) { this(fileName, -1, 0, 0, row, col, defaultTimer); } /** * 以下参数分别为 取材文件,每行取材宽度,每列取材长度,平均每桢显示时间 * * @param fileName * @param row * @param col * @param timer */ public Sprite(String fileName, int row, int col, long timer) { this(fileName, -1, 0, 0, row, col, timer); } /** * 以下参数分别为 取材文件,坐标x,坐标y,每行取材宽度,每列取材长度 * * @param fileName * @param x * @param y * @param row * @param col */ public Sprite(String fileName, float x, float y, int row, int col) { this(fileName, x, y, row, col, defaultTimer); } /** * 以下参数分别为 取材文件,坐标x,坐标y,每行取材宽度,每列取材长度,平均每桢显示时间 * * @param fileName * @param x * @param y * @param row * @param col * @param timer */ private Sprite(String fileName, float x, float y, int row, int col, long timer) { this(fileName, -1, x, y, row, col, timer); } /** * 以下参数分别为 取材文件,最大分解桢数,坐标x,坐标y,每行取材宽度,每列取材长度 * * @param fileName * @param maxFrame * @param x * @param y * @param row * @param col */ public Sprite(String fileName, int maxFrame, float x, float y, int row, int col) { this(fileName, maxFrame, x, y, row, col, defaultTimer); } /** * 以下参数分别为 取材文件,最大分解桢数,坐标x,坐标y,每行取材宽度,每列取材长度,平均每桢显示时间 * * @param fileName * @param maxFrame * @param x * @param y * @param row * @param col * @param timer */ public Sprite(String fileName, int maxFrame, float x, float y, int row, int col, long timer) { this("Sprite" + System.currentTimeMillis(), fileName, maxFrame, x, y, row, col, timer); } /** * 以下参数分别为 精灵名,取材文件,最大分解桢数,坐标x,坐标y,每行取材宽度,每列取材长度,平均每桢显示时间 * * @param spriteName * @param fileName * @param maxFrame * @param x * @param y * @param row * @param col * @param timer */ public Sprite(String spriteName, String fileName, int maxFrame, float x, float y, int row, int col, long timer) { this(spriteName, TextureUtils.getSplitTextures(fileName, row, col), maxFrame, x, y, timer); } /** * 注入指定图片 * * @param fileName */ public Sprite(String fileName) { this(new LTexture(fileName)); } /** * 注入指定图片 * * @param images */ public Sprite(final LTexture img) { this(new LTexture[] { img }, 0, 0); } /** * 以下参数分别为 图像数组 * * @param images */ public Sprite(LTexture[] images) { this(images, 0, 0); } /** * 以下参数分别为 图像数组,坐标x,坐标y * * @param images * @param x * @param y */ public Sprite(LTexture[] images, float x, float y) { this(images, x, y, defaultTimer); } /** * 以下参数分别为 图像数组,平均每桢显示时间 * * @param images * @param timer */ public Sprite(LTexture[] images, long timer) { this(images, -1, 0, 0, defaultTimer); } /** * 以下参数分别为 图像数组,坐标x,坐标y,平均每桢显示时间 * * @param images * @param x * @param y * @param timer */ public Sprite(LTexture[] images, float x, float y, long timer) { this(images, -1, x, y, timer); } /** * 以下参数分别为 图像数组,最大分解桢数,坐标x,坐标y,平均每桢显示时间 * * @param spriteName * @param images * @param maxFrame * @param x * @param y * @param timer */ public Sprite(LTexture[] images, int maxFrame, float x, float y, long timer) { this("Sprite" + System.currentTimeMillis(), images, maxFrame, x, y, timer); } /** * 以下参数分别为 精灵名,图像数组,最大分解桢数,坐标x,坐标y,平均每桢显示时间 * * @param spriteName * @param images * @param maxFrame * @param x * @param y * @param timer */ public Sprite(String spriteName, LTexture[] images, int maxFrame, float x, float y, long timer) { this.setLocation(x, y); this.spriteName = spriteName; this.setAnimation(animation, images, maxFrame, timer); this.visible = true; this.transform = LTrans.TRANS_NONE; } /** * 是否在播放动画 * * @param running */ public void setRunning(boolean running) { animation.setRunning(running); } /** * 返回当前总桢数 * * @return */ public int getTotalFrames() { return animation.getTotalFrames(); } /** * 设定当前帧 * * @param index */ public void setCurrentFrameIndex(int index) { animation.setCurrentFrameIndex(index); } /** * 返回当前桢索引 * * @return */ public int getCurrentFrameIndex() { return animation.getCurrentFrameIndex(); } /** * 获得当前精灵的窗体居中横坐标 * * @param x * @return */ public int centerX(int x) { return centerX(this, x); } /** * 获得指定精灵的窗体居中横坐标 * * @param sprite * @param x * @return */ public static int centerX(Sprite sprite, int x) { int newX = x - (sprite.getWidth() / 2); if (newX + sprite.getWidth() >= LSystem.screenRect.width) { return (LSystem.screenRect.width - sprite.getWidth() - 1); } if (newX < 0) { return x; } else { return newX; } } /** * 获得当前精灵的窗体居中纵坐标 * * @param y * @return */ public int centerY(int y) { return centerY(this, y); } /** * 获得指定精灵的窗体居中纵坐标 * * @param sprite * @param y * @return */ public static int centerY(Sprite sprite, int y) { int newY = y - (sprite.getHeight() / 2); if (newY + sprite.getHeight() >= LSystem.screenRect.height) { return (LSystem.screenRect.height - sprite.getHeight() - 1); } if (newY < 0) { return y; } else { return newY; } } /** * 插入指定动画 * * @param myAnimation * @param images * @param maxFrame * @param timer */ private void setAnimation(Animation myAnimation, LTexture[] images, int maxFrame, long timer) { if (maxFrame != -1) { for (int i = 0; i < maxFrame; i++) { myAnimation.addFrame(images[i], timer); } } else { for (int i = 0; i < images.length; i++) { myAnimation.addFrame(images[i], timer); } } } /** * 插入指定动画 * * @param fileName * @param maxFrame * @param row * @param col * @param timer */ public void setAnimation(String fileName, int maxFrame, int row, int col, long timer) { setAnimation(new Animation(), TextureUtils.getSplitTextures(fileName, row, col), maxFrame, timer); } /** * 插入指定动画 * * @param fileName * @param row * @param col * @param timer */ public void setAnimation(String fileName, int row, int col, long timer) { setAnimation(fileName, -1, row, col, timer); } /** * 插入指定动画 * * @param images * @param maxFrame * @param timer */ public void setAnimation(LTexture[] images, int maxFrame, long timer) { setAnimation(new Animation(), images, maxFrame, timer); } /** * 插入指定动画 * * @param images * @param timer */ public void setAnimation(LTexture[] images, long timer) { setAnimation(new Animation(), images, -1, timer); } /** * 插入指定动画 * * @param animation */ public void setAnimation(Animation animation) { this.animation = animation; } public Animation getAnimation() { return animation; } /** * 变更动画 */ public void update(long timer) { if (visible) { animation.update(timer); } } /** * 变更定位器坐标 * * @param vector */ public void updateLocation(Vector2f vector) { this.setX(Math.round(vector.getX())); this.setY(Math.round(vector.getY())); } public LTexture getImage() { return animation.getSpriteImage(); } public int getWidth() { LTexture si = animation.getSpriteImage(); if (si == null) { return -1; } return (int) (si.getWidth() * scaleX); } public int getHeight() { LTexture si = animation.getSpriteImage(); if (si == null) { return -1; } return (int) (si.getHeight() * scaleY); } /** * 获得精灵的中间位置 * * @return */ public Point getMiddlePoint() { return new Point(getLocation().x() + getWidth() / 2, getLocation().y() + getHeight() / 2); } /** * 获得两个精灵的中间距离 * * @param second * @return */ public float getDistance(Sprite second) { return (float) this.getMiddlePoint() .distanceTo(second.getMiddlePoint()); } /** * 返回碰撞盒 * * @return */ public RectBox getCollisionBox() { return getRect(getLocation().x(), getLocation().y(), getWidth(), getHeight()); } /** * 检查是否与指定精灵位置发生了矩形碰撞 * * @param sprite * @return */ public boolean isRectToRect(Sprite sprite) { return CollisionHelper.isRectToRect(this.getCollisionBox(), sprite.getCollisionBox()); } /** * 检查是否与指定精灵位置发生了圆形碰撞 * * @param sprite * @return */ public boolean isCircToCirc(Sprite sprite) { return CollisionHelper.isCircToCirc(this.getCollisionBox(), sprite.getCollisionBox()); } /** * 检查是否与指定精灵位置发生了方形与圆形碰撞 * * @param sprite * @return */ public boolean isRectToCirc(Sprite sprite) { return CollisionHelper.isRectToCirc(this.getCollisionBox(), sprite.getCollisionBox()); } private LColor filterColor; public void createUI(GLEx g) { if (!visible) { return; } image = animation.getSpriteImage(); if (image == null) { return; } float width = (image.getWidth() * scaleX); float height = (image.getHeight() * scaleY); if (filterColor == null) { if (alpha > 0 && alpha < 1) { g.setAlpha(alpha); } if (LTrans.TRANS_NONE == transform) { g.drawTexture(image, x(), y(), width, height, rotation); } else { g.drawRegion(image, 0, 0, getWidth(), getHeight(), transform, x(), y(), LGraphics.TOP | LGraphics.LEFT); } if (alpha > 0 && alpha < 1) { g.setAlpha(1); } return; } else { if (alpha > 0 && alpha < 1) { g.setAlpha(alpha); } if (LTrans.TRANS_NONE == transform) { g.drawTexture(image, x(), y(), width, height, rotation, filterColor); } else { g.drawRegion(image, 0, 0, getWidth(), getHeight(), transform, x(), y(), LGraphics.TOP | LGraphics.LEFT, filterColor); } if (alpha > 0 && alpha < 1) { g.setAlpha(1); } return; } } public boolean isVisible() { return visible; } public void setVisible(boolean visible) { this.visible = visible; } public String getSpriteName() { return spriteName; } public void setSpriteName(String spriteName) { this.spriteName = spriteName; } public int getTransform() { return transform; } public void setTransform(int transform) { this.transform = transform; } public LColor getFilterColor() { return filterColor; } public void setFilterColor(LColor filterColor) { this.filterColor = filterColor; } public LTexture getBitmap() { return this.image; } public float getScaleX() { return scaleX; } public void setScaleX(float scaleX) { this.scaleX = scaleX; } public float getScaleY() { return scaleY; } public void setScaleY(float scaleY) { this.scaleY = scaleY; } public void dispose() { this.visible = false; if (image != null) { image.dispose(); image = null; } if (animation != null) { animation.dispose(); animation = null; } } public Field2D getField2D() { return null; } public boolean isBounded() { return false; } public boolean isContainer() { return false; } public boolean inContains(int x, int y, int w, int h) { return false; } public RectBox getRectBox() { return getCollisionBox(); } public int getContainerWidth() { return 0; } public int getContainerHeight() { return 0; } public void setScale(float sx, float sy) { this.scaleX = sx; this.scaleY = sy; } }