2011-09-15 36 views
1

私はスプライトを含むゲームを開発しています。Androidでスプライトを作成する方法

現在、私はビットマップをロードしていて、ビットマップから正しいフレームを取得するためにRectangleを使用しています。

問題はロードされていますが、ビットマップはあまりにも多くのメモリを必要とし、同時に複数のスプライトを読み込むことはできません。

Androidでスプライトを行うための代替手段は何ですか?

答えて

0

この方法を試してください。

import org.cocos2d.layers.CCLayer; 
public class GameLayer extends CCLayer{ 

    CCSprite mSprite;  

protected GameLayer() { 
    super(); 
    CGSize winSize = CCDirector.sharedDirector().winSize();  
    mSprite = new CCSprite("image.png"); 
    mSprite.setPosition(CGPoint.ccp(mSprite.getContentSize().width/2.0f, mSprite.getContentSize().height/2.0f)); 
    addChild(mSprite); 
} 
0
/* It is Sprite class */ 
import android.graphics.*; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.graphics.Rect; 

public class Sprite { 

int x; 
private int y; 
private boolean visibility = true; 
private Bitmap sprite; 
private int verticalFrame,horizontalFrame; 
private int frameWidth,frameHeight; 
private int sequence[] = new int[1]; 
private int maxFrame = 0; 
private int currentFrame; 
private int color; 
private Rect src; 
private Rect dest; 
private int frameCount; 
private Paint p = new Paint(); 
private int spInitX,spInitY; 
private int rotate = 0; 
private float currentRotateAngle = 0; 
//private Graphics g; 
public float velocityY; 
public float velocityX; 
public int height; 

public Sprite(Bitmap sprite){ 

    this.sprite = sprite; 
    this.frameWidth = sprite.getWidth(); 
    this.frameHeight = sprite.getHeight(); 
    setFrameCount(); 
} 
public Sprite(Bitmap sprite,int frameWidth,int frameHeight){ 

    this.sprite = sprite; 
    this.frameWidth = frameWidth; 
    this.frameHeight = frameHeight; 
    setFrameCount();   
} 

public void rotate(float angle){ 
    currentRotateAngle = angle;  
} 

public void setImage(Bitmap bm,int frameWidth,int frameHeight){ 
    this.sprite = bm; 
    this.frameWidth = frameWidth; 
    this.frameHeight = frameHeight; 
} 

public Bitmap getBitmap(){ 
    return sprite; 
} 
public void paint(Canvas canvas){ 
    dest.offsetTo(getX(), getY()); 
// g.drawImage(sprite, x, y,src.left,src.top,frameWidth,frameHeight); 
    canvas.drawBitmap(sprite, src, dest, null); 

} 


public int getMaxFrame(){ 
    return maxFrame; 
} 
public int getFrameSequenceLength(){ 
    return sequence.length; 
} 
public void setFrameSequence(int seq[]){ 
    sequence = seq; 
} 

public void previousFrame(){ 
    if(sequence.length > 1){ 
      if(frameCount > 0){ 
      setFrame(sequence[frameCount]); 
     frameCount--; 
     }else{ 
     frameCount = sequence.length - 1; 
     setFrame(sequence[frameCount]); 
     } 

    }else{ 

     setFrame(frameCount); 

     if(frameCount > 0){ 
      frameCount++; 
     }else{ 
      frameCount = maxFrame - 1; 
     } 
    } 
} 

public void setPixel(int x,int y){ 
    spInitX = x; 
    spInitY = y; 
    } 



public void nextFrame(){ 
    if(sequence.length > 1){ 
      if(frameCount < sequence.length){ 
      setFrame(sequence[frameCount]); 
      frameCount++; 
      }else{ 
      frameCount = 0; 
      setFrame(sequence[frameCount]); 
      } 

    }else{ 

     setFrame(frameCount); 

     if(frameCount < maxFrame){ 
      frameCount++; 
     }else{ 
      frameCount = 0; 
     } 
    } 
} 

public int getFrame(){ 
    return currentFrame; 
} 
public void setPosition(int x,int y){ 
    this.x = x; 
    this.y = y; 

} 
public void setFrameCount(){ 
    verticalFrame = sprite.getHeight()/frameHeight; 
    horizontalFrame = sprite.getWidth()/frameWidth; 
    src = new Rect(0,0,frameWidth,frameHeight); 
    dest = new Rect(0,0,frameWidth,frameHeight); 
    maxFrame = verticalFrame * horizontalFrame; 
} 

public void setFrame(int frame){ 

     if(frame < maxFrame){ 
      currentFrame = frame; 
     } 
     int hf = currentFrame % horizontalFrame; 
     int vf = currentFrame/horizontalFrame; 
     src.left = hf * frameWidth; 
     src.right = src.left + frameWidth; 
     src.top = vf * frameHeight; 
     src.bottom = src.top + frameHeight; 
    } 

    public boolean collidesWith(Sprite sp,boolean cl){ 

    int maxHGap = (getWidth() + sp.getWidth())/2; 
    int maxVGap = (getHeight() + sp.getHeight())/2; 

    int x = getX() + getWidth()/2; 
    int y = getY() + getHeight()/2; 

    int x1 = sp.getX() + sp.getWidth()/2; 
    int y1 = sp.getY() + sp.getHeight()/2; 


    if(Math.abs(x - x1) < maxHGap && Math.abs(y - y1) < maxVGap){ 
     return true; 
    } 

    return false; 
} 


public void setVisible(boolean v){ 
    visibility = v; 
} 
public final boolean isVisible(){ 
    return visibility; 
} 
public int getX(){ 
    return x; 

} 
public int getY(){ 
    return y; 

} 


public void setX(int x) { 
    this.x = x; 
} 
public void setY(int y) { 
    this.y = y; 
} 
public void move(int moveX,int moveY){ 
    setX(getX()+moveX); 
    setY(getY()+moveY); 
    //this.y+=y; 
    //this.x+=x; 
} 

    public final int getWidth(){ 
    return frameWidth; 
} 
public final int getHeight(){ 
    return frameHeight; 
} 
public void setEventY(int i) { 
    // TODO Auto-generated method stub 

} 
public int getEventY() { 
    // TODO Auto-generated method stub 
    return 0; 
} 


} 

/*Create Main Thread Class Also */ 

import java.text.DecimalFormat; 
import android.graphics.Canvas; 
import android.util.Log; 
import android.view.SurfaceHolder; 

public class MainThread extends Thread { 
boolean isPaused; 

private static final String TAG = MainThread.class.getSimpleName(); 

// desired fps 
private final static int MAX_FPS = 50; 
// maximum number of frames to be skipped 
private final static int MAX_FRAME_SKIPS = 5; 
// the frame period 
private final static int FRAME_PERIOD = 1000/MAX_FPS; 

/* Stuff for stats */ 
private DecimalFormat df = new DecimalFormat("0.##"); // 2 dp 
// we'll be reading the stats every second 
private final static int STAT_INTERVAL = 1000; // ms 
// the average will be calculated by storing 
// the last n FPSs 
private final static int FPS_HISTORY_NR = 10; 
// last time the status was stored 
private long lastStatusStore = 0; 
// the status time counter 
private long statusIntervalTimer = 0l; 
// number of frames skipped since the game started 
private long totalFramesSkipped = 0l; 
// number of frames skipped in a store cycle (1 sec) 
private long framesSkippedPerStatCycle = 0l; 

// number of rendered frames in an interval 
private int frameCountPerStatCycle = 0; 
private long totalFrameCount = 0l; 
// the last FPS values 
private double fpsStore[]; 
// the number of times the stat has been read 
private long statsCount = 0; 
// the average FPS since the game started 
private double averageFps = 0.0; 

// Surface holder that can access the physical surface 
private SurfaceHolder surfaceHolder; 
// The actual view that handles inputs 
// and draws to the surface 
private GameView gv; 

// flag to hold game state 
private boolean running; 

public void setRunning(boolean running) { 
    this.running = running; 
} 

public MainThread(SurfaceHolder surfaceHolder, GameView gv) { 
    super(); 
    this.surfaceHolder = surfaceHolder; 
    this.gv = gv; 
} 

public MainThread(Setting setting) { 
    // TODO Auto-generated constructor stub 
} 

public void setPause(int i) { 
    synchronized (gv.getHolder()) { 

     if (i == 0) { 
      isPaused = false; 
     } 
     if (i == 1) { 
      isPaused = true; 
     } 
    } 
} 

@Override 
public void run() { 
    Canvas canvas; 
    Log.d(TAG, "Starting game loop"); 

    initTimingElements(); 

    long beginTime; // the time when the cycle begun 
    long timeDiff; // the time it took for the cycle to execute 
    int sleepTime; // ms to sleep (<0 if we're behind) 
    int framesSkipped; // number of frames being skipped 

    sleepTime = 0; 

    while (running) { 
     canvas = null; 
     // try locking the canvas for exclusive pixel editing 
     // in the surface 
     try { 
      canvas = this.surfaceHolder.lockCanvas(); 
      synchronized (surfaceHolder) { 
       beginTime = System.currentTimeMillis(); 
       framesSkipped = 0; // resetting the frames skipped 
       // update game state 
       this.gv.update(); 
       // render state to the screen 
       // draws the canvas on the panel 
       this.gv.render(canvas); 
       // calculate how long did the cycle take 
       timeDiff = System.currentTimeMillis() - beginTime; 
       // calculate sleep time 
       sleepTime = (int) (FRAME_PERIOD - timeDiff); 

       if (sleepTime > 0) { 
        // if sleepTime > 0 we're OK 
        try { 
         // send the thread to sleep for a short period 
         // very useful for battery saving 
         Thread.sleep(sleepTime); 
        } catch (InterruptedException e) { 
        } 
       } 

       while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) { 
        // we need to catch up 
        this.gv.update(); // update without rendering 
        sleepTime += FRAME_PERIOD; // add frame period to check 
               // if in next frame 
        framesSkipped++; 
       } 

       if (framesSkipped > 0) { 
        Log.d(TAG, "Skipped:" + framesSkipped); 
       } 
       // for statistics 
       framesSkippedPerStatCycle += framesSkipped; 
       // calling the routine to store the gathered statistics 
       storeStats(); 
      } 
     } catch (InterruptedException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } finally { 
      // in case of an exception the surface is not left in 
      // an inconsistent state 
      if (canvas != null) { 
       surfaceHolder.unlockCanvasAndPost(canvas); 
      } 
     } // end finally 
    } 
    } 

private void storeStats() { 
    frameCountPerStatCycle++; 
    totalFrameCount++; 
    // assuming that the sleep works each call to storeStats 
    // happens at 1000/FPS so we just add it up 
    // statusIntervalTimer += FRAME_PERIOD; 

    // check the actual time 
    statusIntervalTimer += (System.currentTimeMillis() - statusIntervalTimer); 

    if (statusIntervalTimer >= lastStatusStore + STAT_INTERVAL) { 
     // calculate the actual frames pers status check interval 
     double actualFps = (double) (frameCountPerStatCycle/(STAT_INTERVAL/1000)); 

     // stores the latest fps in the array 
     fpsStore[(int) statsCount % FPS_HISTORY_NR] = actualFps; 

     // increase the number of times statistics was calculated 
     statsCount++; 

     double totalFps = 0.0; 
     // sum up the stored fps values 
     for (int i = 0; i < FPS_HISTORY_NR; i++) { 
      totalFps += fpsStore[i]; 
     } 

     // obtain the average 
     if (statsCount < FPS_HISTORY_NR) { 
      // in case of the first 10 triggers 
      averageFps = totalFps/statsCount; 
     } else { 
      averageFps = totalFps/FPS_HISTORY_NR; 
     } 
     // saving the number of total frames skipped 
     totalFramesSkipped += framesSkippedPerStatCycle; 
     // resetting the counters after a status record (1 sec) 
     framesSkippedPerStatCycle = 0; 
     statusIntervalTimer = 0; 
     frameCountPerStatCycle = 0; 

     statusIntervalTimer = System.currentTimeMillis(); 
     lastStatusStore = statusIntervalTimer; 
     // Log.d(TAG, "Average FPS:" + df.format(averageFps)); 
     gv.setAvgFps("FPS: " + df.format(averageFps)); 
    } 
    } 

    private void initTimingElements() { 
    // initialise timing elements 
    fpsStore = new double[FPS_HISTORY_NR]; 
    for (int i = 0; i < FPS_HISTORY_NR; i++) { 
     fpsStore[i] = 0.0; 
    } 
    Log.d(TAG + ".initTimingElements()", 
      "Timing elements for stats initialised"); 
    } 

} 
関連する問題