當我們點擊play運行遊戲是最討厭的就是遊戲卡住,這就是我們通常所說的遊戲不夠流暢問題。這種問題出現的一個原因是在遊戲運行過程中執行的代碼太占記憶體,比如一直建立對象,一直重複載入遊戲的圖片或者聲音資源等等。比如你的主戰機需要發子彈,我們會想當然的認為建立一個子彈類,然後在使用者點擊發子彈按鈕後一直去建立不用方向、不同移動速度的對象,然後將子彈對象的圖片畫到螢幕上。例如下面這個類:
package org.loon.test.barrage;
import java.util.List;
import org.loon.framework.android.game.action.map.shapes.RectBox;
import org.loon.framework.android.game.core.LSystem;
import org.loon.framework.android.game.core.graphics.device.LGraphics;
import org.loon.framework.android.game.core.timer.LTimer;
import org.loon.framework.android.game.utils.GraphicsUtils;
import android.graphics.Bitmap;
import android.graphics.Matrix;
public class Ball extends Barrage {
// 所畫主戰機子彈的位元影像對象
Bitmap image;
// 設定發子彈的類型
int type;
double v;
int index;
LTimer timer;
private RectBox rect;
Matrix matrix;
public Ball(int type, double direction) {
this.x = MyBarrage.spr.getMiddlePoint().getX();
this.y = MyBarrage.spr.getMiddlePoint().getY();
this.v = direction;
this.type = type;
timer = new LTimer(300);
matrix = new Matrix();
switch(type){
case 0:
image = GraphicsUtils.loadImage("res/main_bullets/common_bullet.jpg",false).getBitmap();
// image = LoadImages.ball_type_0;
this.life = 2;
this.power = 1;
break;
case 1:
image = GraphicsUtils.loadImage("res/main_bullets/skill_bullet.jpg", false).getBitmap();
// image = LoadImages.ball_type_1;
this.life = 5;
this.power = 4;
break;
}
matrix.postRotate((float)direction);
image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, false);
this.width = image.getWidth();
this.height = image.getHeight();
}
public boolean isKilled() {
if(this.remove){
return true;
}
if(this.life <= 0){
this.remove = true;
return true;
}
else if((x < 0)||(x >= LSystem.getSystemHandler().getWidth())){
this.remove = true;
return true;
}
else if((y < 0)||(y > LSystem.getSystemHandler().getHeight())){
this.remove = true;
return true;
}
return false;
}
//將子彈畫到螢幕上
public void draw(LGraphics g) {
switch(type){
case 0:
g.drawBitmap(image, (int)x - image.getWidth()/2, (int)y - image.getHeight()/2);
break;
case 1:
g.drawBitmap(image, (int)x - image.getWidth()/2, (int)y - image.getHeight()/2);
break;
}
}
//隨時更新子彈的座標
public void update(List<Barrage> attacks, int px, int py) {
double rad = (Math.PI/180)*v;
switch(type){
case 0:
x = Math.cos(rad)*10 + x;
y = Math.sin(rad)*10 + y;
break;
case 1:
if (timer.action(30)) {
if (index < 7) {
index++;
} else {
index = 0;
}
}
x = Math.cos(rad)*5 + x;
y = Math.sin(rad)*5 + y;
break;
}
}
//碰撞檢測方法
public boolean checkCollision(double tx, double ty, int w, int h) {
if (rect == null) {
rect = new RectBox((int) x - this.width/2, (int) y - this.height/2, this.width, this.height);
} else {
rect.setBounds((int) x - this.width/2, (int) y - this.height/2, this.width, this.height);
}
return rect.intersects((int) tx - w/2, (int) ty - h/2, w, h)|| rect.contains((int) tx, (int) ty);
}
}
在這個類中有兩行紅色的代碼,如果在發子彈的時候一直用new去建立對象,那麼紅色的載入圖片資源的這兩行代碼將會一直執行,這樣是相當耗費android手機的記憶體資源的,這樣在遊戲主戰區將會表現得非常卡。
我們觀察一下當紅色代碼中image對象一旦建立,它是不會發生變化的,所以我們可以建立一個類去儲存載入圖片的這個對象,然後當用到這種對象時直接調用早已產生的對象就可以了,所以我們建立下面這個類來建立圖片資源的對象:
package org.loon.test.barrage;
import org.loon.framework.android.game.core.graphics.LImage;
import org.loon.framework.android.game.utils.GraphicsUtils;
import android.graphics.Bitmap;
public class LoadImages {
static Bitmap ball_type_0;
static Bitmap ball_type_1;
static Bitmap enemyBall_type_0;
static Bitmap enemyBall_type_1;
static Bitmap enemyBall_type_2;
static Bitmap enemyBall_type_3;
static Bitmap tracker;
static LImage enemyA_type_0;
static LImage enemyA_type_1;
static LImage stones[];
public void initialize(){
ball_type_0 = this.loadBalls(0);
ball_type_1 = this.loadBalls(1);
enemyBall_type_0 = this.loadEnemyBalls(0);
enemyBall_type_1 = this.loadEnemyBalls(1);
enemyBall_type_2 = this.loadEnemyBalls(2);
enemyBall_type_3 = this.loadEnemyBalls(3);
tracker = this.loadTrackers();
enemyA_type_0 = this.loadEnemyA(0);
enemyA_type_1 = this.loadEnemyA(1);
stones = this.loadStones();
}
private Bitmap loadBalls(int type){
Bitmap bitmap = null;
if(type == 0){
bitmap = GraphicsUtils.loadImage("res/main_bullets/common_bullet.jpg",false).getBitmap();
}
else if(type == 1){
bitmap = GraphicsUtils.loadImage("res/main_bullets/skill_bullet.jpg",false).getBitmap();
}
return bitmap;
}
private Bitmap loadEnemyBalls(int type){
Bitmap bitmap = null;
switch (type) {
case 0://普通小敵機追蹤子彈
bitmap = GraphicsUtils.loadImage("res/enemy_balls/common_bullet.png",false).getBitmap();
break;
case 1://boss追蹤子彈
bitmap = GraphicsUtils.loadImage("res/enemy_balls/tracker_bullet.png",false).getBitmap();
break;
case 2://boss圍繞子彈
bitmap = GraphicsUtils.loadImage("res/enemy_balls/boss_bullet_1.png", false).getBitmap();
break;
case 3:bitmap = GraphicsUtils.loadImage("res/enemy_balls/boss_bullet_2.jpg", false).getBitmap();
break;
}
return bitmap;
}
private Bitmap loadTrackers(){
Bitmap bitmap = null;
bitmap = GraphicsUtils.loadImage("res/enemys/tracker.png", false).getBitmap();
return bitmap;
}
private LImage loadEnemyA(int type){
LImage image = null;
switch(type){
case 0:
image = GraphicsUtils.loadImage("res/enemys/common_plane.png", false);
break;
case 1:
image = GraphicsUtils.loadImage("res/enemys/bigger_plane.png",false);
break;
}
return image;
}
private LImage[] loadStones(){
LImage image[] = null;
image = GraphicsUtils.getSplitImages("res/enemys/stones.png", 32, 32, false);
return image;
}
}