LibGdx练习-像素鸟(二)

游戏资源管理

像素鸟ios 像素鸟2_ATLAS


res包下创建接口Res对于资源路径和变量进行统一管理使项目零散,便于调试。

public interface Res {

    /** 固定世界宽度为 480, 高度根据实际屏幕比例换算 */
    public static final float FIX_WORLD_WIDTH = 600;
    public static final float FIX_WORLD_HEIGHT = 900;

    /** 帧率显示所需要的位图字体 文件路径 */
    public static final String FPS_BITMAP_FONT_PATH = "fps/fps24px.fnt";

    /**
     * 相关物理参数(调节物理参数可改变游戏难度)
     */
    public static interface Physics {

        /** 水管和地板的移动速度, 单位: px/s */
        public static final float MOVE_VELOCITY = -150.0F;

        /** 点击屏幕时给小鸟的竖直方向上的速度, 单位: px/s */
        public static final float JUMP_VELOCITY = 150.0F;

        /** 小鸟竖直方向上的重力加速度, 单位: px/(s*s) */
        public static final float GRAVITY = -200.0F;

        /** 撞入深度, 小鸟撞入水管或地板该深度后才算碰撞 */
        public static final float DEPTH = 0.0F;

        /** 生成水管时间间隔, 单位: s */
        public static final float GENERATE_BAR_TIME_INTERVAL = 2.2F;

        /** 上下水管之间的间隔 */
        public static final float BAR_INTERVAL = 180.0F;
    }

    /**
     * 纹理图集
     */
    public static interface Atlas {

        /** 纹理图集 文件路径 */
        public static final String ATLAS_PATH = "atlas/images.atlas";

        /* 纹理图集中的小图名称 */
        public static final String IMAGE_GAME_BG = "game_bg";
        public static final String IMAGE_GAME_FLOOR = "game_floor";
        public static final String IMAGE_GAME_RESULT_BG = "game_result_bg";
        public static final String IMAGE_BAR_DOWN = "bar_down";
        public static final String IMAGE_BAR_UP = "bar_up";
        public static final String IMAGE_GAME_TAP_TIP = "game_tap_tip";
        public static final String IMAGE_GAME_READY = "game_ready";
        public static final String IMAGE_GAME_OVER = "game_over";

        public static final String IMAGE_GAME_START_01_TO_02 = "game_start";
        public static final String IMAGE_GAME_MEDAL_01_TO_04 = "game_medal";
        public static final String IMAGE_NUM_BIG_00_TO_09 = "num_big";
        public static final String IMAGE_NUM_SCORE_00_TO_09 = "num_score";
        public static final String IMAGE_BIRD_YELLOW_01_TO_03 = "bird_yellow";
    }

    /**
     * 音效
     */
    public static interface Audios {

        /** 音效资源文件夹路径 */
        public static final String AUDIO_BASE_DIR	= "audio/";

        // 音效资源路径
        public static final String AUDIO_DIE = AUDIO_BASE_DIR + "die.ogg";
        public static final String AUDIO_HIT = AUDIO_BASE_DIR + "hit.ogg";
        public static final String AUDIO_TOUCH = AUDIO_BASE_DIR + "touch.ogg";
        public static final String AUDIO_RESTART = AUDIO_BASE_DIR + "restart.ogg";
        public static final String AUDIO_SCORE = AUDIO_BASE_DIR + "score.ogg";
    }
}

资源中主要包括

  • 资源常量
  • 图集和文字集
  • 音频

三个部分来进行统一管理。

像素鸟ios 像素鸟2_像素鸟ios_02


与此同时,在util包下对于游戏进行状态进行了枚举类型的封装。

public enum GameState {

    /** 准备状态 */
    ready,

    /** 游戏状态(小鸟处于飞翔状态) */
    fly,

    /** 小鸟死亡状态(撞到水管, 掉落到地板前) */
    die,

    /** 游戏结束(撞到地板或撞到水管后掉落到地板) */
    gameOver,

//    暂停状态
    pause,
//    恢复状态
    resume;
}

工具包

像素鸟ios 像素鸟2_像素鸟ios_02


工具包下Assets主要完成了对于资源管理器的封装,配合Res接口完成资源的调用。

public class AssetsUtil {
    private static AssetManager assetManager;

    public static TextureAtlas atlas;
    public static BitmapFont bitmapFont;
    public static void init(){
        assetManager = new AssetManager();
    }
    public static void load(){
        //		加载资源
        assetManager.load(Res.Atlas.ATLAS_PATH, TextureAtlas.class);
        assetManager.load(Res.Audios.AUDIO_DIE, Sound.class);
        assetManager.load(Res.Audios.AUDIO_HIT, Sound.class);
        assetManager.load(Res.Audios.AUDIO_TOUCH, Sound.class);
        assetManager.load(Res.Audios.AUDIO_RESTART, Sound.class);
        assetManager.load(Res.Audios.AUDIO_SCORE, Sound.class);
        assetManager.load(Res.FPS_BITMAP_FONT_PATH, BitmapFont.class);
    }

    public static boolean loadFinished(){
//        加载图集和文字集
        atlas = assetManager.get(Res.Atlas.ATLAS_PATH);
        bitmapFont = assetManager.get(Res.FPS_BITMAP_FONT_PATH);
        return true;
    }

    /**
     * 等待资源加载完毕
     * @return
     */
    public static boolean update(){
        return assetManager.update();
    }

    public static AssetManager getAssetManager() {
        return assetManager;
    }

//    资源管理器需要手动释放
    public static void dispose(){
        assetManager.dispose();
        assetManager = null;
        atlas = null;
        bitmapFont = null;
    }
}

CollisionUtils类主要负责碰撞检测操作,调用其中的isCollision方法可以直接判断两个actor的碰撞情况,发生碰撞返回true,否则返回false。

public class CollisionUtils {
	
	private static final Rectangle rect1 = new Rectangle();
	private static final Rectangle rect2 = new Rectangle();
	private static final Rectangle tempRect = new Rectangle();

	/**
	 * 判断两个演员是否碰撞
	 * 
	 * @param actor1
	 * @param actor2
	 * @param depth 碰撞深度, 两个演员的包围矩阵重叠部分的矩形宽高均超过 depth 才算碰撞
	 * @return
	 */
	public static synchronized boolean isCollision(Actor actor1, Actor actor2, float depth) {
        if (actor1 == null || actor2 == null) {
            return false;
        }
        
        // 获取 演员1 缩放后的包围矩阵
        rect1.setSize(
                actor1.getWidth() * actor1.getScaleX(),
                actor1.getHeight() * actor1.getScaleY()
        );
        rect1.setPosition(
                actor1.getX() - (actor1.getOriginX() * actor1.getScaleX() - actor1.getOriginX()),
                actor1.getY() - (actor1.getOriginY() * actor1.getScaleY() - actor1.getOriginY())
        );

        // 获取 演员2 缩放后的包围矩阵
        rect2.setSize(
                actor2.getWidth() * actor2.getScaleX(),
                actor2.getHeight() * actor2.getScaleY()
        );
        rect2.setPosition(
                actor2.getX() - (actor2.getOriginX() * actor2.getScaleX() - actor2.getOriginX()),
                actor2.getY() - (actor2.getOriginY() * actor2.getScaleY() - actor2.getOriginY())
        );
        return rect1.overlaps(rect2);
	}
}

SoundPlayer类负责银盆播放。

public class SoundPlayer {
    private boolean sound = true;

    public SoundPlayer(boolean sound){
        this.sound = sound;
    }

    public void playSound(String soundName){
        if(!AssetsUtil.getAssetManager().isLoaded(soundName)) return;
        if (!sound){
            Gdx.app.error("myk","未获取音频权限");
            return;
        }

        Sound sound = AssetsUtil.getAssetManager().get(soundName);
        sound.play();
    }
}

本处当没有获得音频播放权限的时候给出日志提示,实际操作时可以考虑弹出异常,对于异常进行捕获处理,弹窗提示等。