⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sprite.java

📁 一个 JAVA 写的 J2ME 开源模拟器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 *  MicroEmulator
 *  Copyright (C) 2005 Andres Navarro
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package javax.microedition.lcdui.game;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 *
 * @author Andres Navarro
 *
 */

// TODO add more synchronization

public class Sprite extends Layer {
    // transform constants
    public static final int TRANS_NONE = 0;
    public static final int TRANS_ROT90 = 5;
    public static final int TRANS_ROT180 = 3;
    public static final int TRANS_ROT270 = 6;
    public static final int TRANS_MIRROR = 2;
    public static final int TRANS_MIRROR_ROT90 = 7;
    public static final int TRANS_MIRROR_ROT180 = 1;
    public static final int TRANS_MIRROR_ROT270 = 4;

    // current frame index (within the sequence, not the absolut index)
    private int frame;
    
    // the frame sequence
    // null if the default is used
    private int [] sequence;
    
    // coordinate of the reference pixel
    private int refX;
    private int refY;
    
    // number of cols and rows within the image
    private int cols;
    private int rows;
    
    // the transform aplied to this sprite
    private int transform;
            
    // the image containg the frames
    private Image img;
    
    // the collision rectangle
    private int collX;
    private int collY;
    private int collWidth;
    private int collHeight;
    
    // arrays for the collision detection at pixel level
    private int []rgbData;
    private int []rgbDataAux;
    
    public Sprite(Image img) {
        this(img, img.getWidth(), img.getHeight());
    }
    
    public Sprite(Image img, int frameWidth, int frameHeight) {
        // initial state is visible, positioned at 0, 0
        // with a bound rectangle the same as the frame
        super(0, 0, frameWidth, frameHeight, true);
        
        // implicit check for null img
        if (img.getWidth() % frameWidth != 0 ||
                img.getHeight() % frameHeight != 0)
            throw new IllegalArgumentException();
        this.img = img;
        cols = img.getWidth() / frameWidth;
        rows = img.getHeight() / frameHeight;
        collX = collY = 0;
        collWidth = frameWidth;
        collHeight = frameHeight;
    }
    
    public Sprite(Sprite otherSprite) {
        // copy the otherSprite
        super(otherSprite.getX(), otherSprite.getY(), 
                otherSprite.getWidth(), otherSprite.getHeight(),
                otherSprite.isVisible());
        this.frame = otherSprite.frame;
        this.sequence = otherSprite.sequence;
        this.refX = otherSprite.refX;
        this.refY = otherSprite.refY;
        this.cols = otherSprite.cols;
        this.rows = otherSprite.rows;
        this.transform = otherSprite.transform;
        this.img = otherSprite.img;
        this.collX = otherSprite.collX;
        this.collY = otherSprite.collY;
        this.collWidth = otherSprite.collWidth;
        this.collHeight = otherSprite.collHeight;
    }
    
    public final boolean collidesWith(Image image, int iX, int iY, boolean pixelLevel) {
        if (image == null)
            throw new IllegalArgumentException();
        
        // only check collision if visible
        if (!this.isVisible())
                return false;

        if (pixelLevel)
            return collidesWithPixelLevel(image, iX, iY);
        else
            return collidesWith(image, iX, iY);
    }


    
    public final boolean collidesWith(TiledLayer layer, boolean pixelLevel) {
        int sX, sY;
        int sW, sH;

        if (layer == null) {
            throw new NullPointerException();
        }
        
        // only check collision if visible
        if (!this.isVisible())
                return false;

        // only check collision if both are visible
        if (!layer.isVisible() || !this.isVisible())
            return false;
            
        if (pixelLevel) // second and third parameters are dont care
            return collidesWithPixelLevel(layer, 0, 0);
        else 
            return collidesWith(layer, 0, 0);
    }

    public final boolean collidesWith(Sprite otherSprite, boolean pixelLevel) {
        int sX, sY;
        int sW, sH;

        if (otherSprite == null) {
            throw new NullPointerException();
        }
        
        // only check collision if both are visible
        if (!otherSprite.isVisible() || !this.isVisible())
            return false;
        
        if (pixelLevel) // second and third parameters are dont care
            return collidesWithPixelLevel(otherSprite, 0, 0);
        else 
            return collidesWith(otherSprite, 0, 0);
    }
    
    public void defineReferencePixel(int x, int y) {
        refX = x;
        refY = y;
    }
    
    public int getRefPixelX() {
        return getX() + refX;
    }
    
    public int getRefPixelY() {
        return getY() + refY;
    }

    public void setRefPixelPosition(int x, int y) {
        int curRefX, curRefY;
        int width = getWidth();
        int height = getHeight();

        switch(transform) {
            case TRANS_NONE:
                curRefX = refX;
                curRefY = refY;
                break;
            case TRANS_MIRROR_ROT180:
                curRefX = width - refX;
                curRefY = height - refY;
                break;
            case TRANS_MIRROR:
                curRefX = width - refX;
                curRefY = refY;
                break;
            case TRANS_ROT180:
                curRefX = refX;
                curRefY = height - refY;
                break;
            case TRANS_MIRROR_ROT270:
                curRefX = height - refY;
                curRefY = refX;
                break;
            case TRANS_ROT90:
                curRefX = height - refY;
                curRefY = width - refX;
                break;
            case TRANS_ROT270:
                curRefX = refY;
                curRefY = refX;
                break;
            case TRANS_MIRROR_ROT90:
                curRefX = refY;
                curRefY = width - refX;
                break;
            default: // cant really happen, but the return keeps the
                    // compiler happy (otherwise it'll report variable
                    // may not be initialized)
                return;
        }

        setPosition(x - curRefX, y - curRefY);
    }
   
    public void defineCollisionRectangle(int x, int y, int width, int height) {
        if (width < 0 || height < 0)
            throw new IllegalArgumentException();
        collX = x;
        collY = y;
        collWidth = width;
        collHeight = height;
    }
    
    public void setFrameSequence(int []sequence) {
        if (sequence == null) {
            // return to default sequence
            this.sequence = null;
            return;
        }

        int max = (rows*cols)-1;

        int l = sequence.length;
        
        if (l == 0)
            throw new IllegalArgumentException();
        
        for (int i = 0; i < l; i++) {
            int value = sequence[i];
            if (value > max || value < 0)
                throw new ArrayIndexOutOfBoundsException();
        }
            
        this.sequence = sequence;
        // the frame number has to be reseted
        this.frame = 0;
    }
    
    public final int getFrame() {
		return frame;
    }
    
    public int getFrameSequenceLength() {
    	return (sequence == null) ? rows*cols : sequence.length; 
    }
    
    public void setFrame(int frame) {
        int l = (sequence == null)? rows*cols : sequence.length; 
        if (frame < 0 || frame >= l) {
            throw new IndexOutOfBoundsException();
        }
        this.frame = frame;
    }
    
    public void nextFrame() {
        if (frame == ((sequence == null)? rows*cols : sequence.length) - 1)
            frame = 0;
        else
            frame++;
    }
    
    public void prevFrame() {
        if (frame == 0)
            frame = ((sequence == null)? rows*cols : sequence.length) - 1;
        else
            frame--;
    }
 
    public void setImage(Image img, int frameWidth, int frameHeight) {
    	synchronized (this) {
	        int oldW = getWidth();
	        int oldH = getHeight();
	        int newW = img.getWidth();
	        int newH = img.getHeight();
	        
	        // implicit size check
	        setSize(frameWidth, frameHeight);
	
	        if (img.getWidth() % frameWidth != 0 ||
	                img.getHeight() % frameHeight != 0)
	            throw new IllegalArgumentException();
	        this.img = img;
	        
	        int oldFrames = cols*rows;
	        cols = img.getWidth() / frameWidth;
	        rows = img.getHeight() / frameHeight;
	        
	        if (rows*cols < oldFrames) {
	            // there are fewer frames
	            // reset frame number and sequence
	            sequence = null;
	            frame = 0;
	        }
	        
	        if (frameWidth != getWidth() || frameHeight != getHeight()) {
	            // size changed
	            // reset collision rectangle and collision detection array
	            defineCollisionRectangle(0, 0, frameWidth, frameHeight);
	            rgbData = rgbDataAux = null;
	            
	            // if necessary change position to keep the reference pixel in place
	            
	            if (transform != TRANS_NONE) {
	                int dx, dy;
	                switch(transform) {
	                    case TRANS_MIRROR_ROT180:
	                        dx = newW - oldW;
	                        dy = newH - oldH;
	                        break;
	                    case TRANS_MIRROR:
	                        dx = newW - oldW;
	                        dy = 0;
	                        break;
	                    case TRANS_ROT180:
	                        dx = 0;
	                        dy = newH - oldH;
	                        break;
	                    case TRANS_MIRROR_ROT270:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -