最近在尝试使用Android做一些小的游戏,游戏中需要使用到画地图的功能,在本篇文章中着重讲解经典“火星登陆”的游戏中随机画地图的相关功能。
其他功能大家可以参考谷歌官方给的例子,地址为:https://android.googlesource.com/platform/development/+/master/samples/LunarLander
好了,接下来直接上代码,总共有两个类(第一个类LandingSceneProvider为创建地面场景的提供者,第二个类LandingScene用于创建地面场景到画布中):
/** * LandingSceneProvider类主要用于创建或获取地面场景/地图对象(包括 随机创建地图以及预先设置好的地图) * * @version 1.1 */ public class LandingSceneProvider { // 定义Resources对象 Resources resources; public LandingSceneProvider(Resources resources) { this.resources = resources; } /** * 获取随机地图 * * @return * @parm */ public LandingScene getScene(Bundle params) { // int displayHeight = params.getInt("SCREEN_HEIGHT"); int displayWidth = params.getInt("SCREEN_WIDTH"); int displayLeft = params.getInt("SCREEN_LEFT"); int displayTop = params.getInt("SCREEN_TOP"); // 是否随机创建场景 boolean randomScene = params.getBoolean("SCENE_RANDOM"); String sceneTitle = params.getString("SCENE_Name"); // 创建落地场景 LandingScene landingScene = new LandingScene(); if (randomScene) { // 初始化10个X,Y坐标 landingScene.pathX = new int[10]; landingScene.pathY = new int[10]; Random random = new Random(SystemClock.currentThreadTimeMillis()); for (int i = 0; i < 10; i++) { if (i == 3) {//创建一个平行线用于着陆 // 第四个X坐标点需要与第三个相等 landingScene.pathX[i] = landingScene.pathX[2] + displayWidth / 11; // 落地的空间稍微大一些 landingScene.pathY[i] = landingScene.pathY[2]; } else if (i == 6) {//创建一个平行线用于着陆 // 第七个X轴坐标点需与第六个相等 landingScene.pathX[i] = landingScene.pathX[5] + displayWidth / 11; // 落地的空间稍大一些 landingScene.pathY[i] = landingScene.pathY[5]; } else if (i == 0) { // 第一个坐标显示在左下角 landingScene.pathX[i] = 0; landingScene.pathY[i] = displayHeight; } else if (i == 9) { // 在右下角显示坐标终点 landingScene.pathX[i] = displayWidth; landingScene.pathY[i] = displayHeight; } else { // 创建随机坐标点 landingScene.pathX[i] = landingScene.pathX[i - 1] + displayWidth / 10; landingScene.pathY[i] = displayHeight - random.nextInt(displayHeight / 2); } } } else { // 创建预设(第一次启动时)的场景 landingScene.pathX = new int[]{ 0, displayWidth / 10, 2 * displayWidth / 10, 3 * displayWidth / 10, 4 * displayWidth / 10 , 5 * displayWidth / 10, 6 * displayWidth / 10, 7 * displayWidth / 10, 8 * displayWidth / 10, displayWidth}; landingScene.pathY = new int[]{ displayHeight, displayHeight - 100, displayHeight - 205, displayHeight - 205, displayHeight - 10, displayHeight - 88, displayHeight - 88, displayHeight - 70, displayHeight - 80, displayHeight}; } // 设置背景颜色为黑色 landingScene.windowBackgroundColor = Color.BLACK; // 设置地图背景图 landingScene.obstacleBackground = BitmapFactory.decodeResource(resources, R.drawable.mars); landingScene.obstacleBackground = Bitmap.createScaledBitmap(landingScene.obstacleBackground, displayWidth, displayHeight, true); // 设置合理的场景(地图)宽度 landingScene.displayHeight = displayHeight; landingScene.displayWidth = displayWidth; landingScene.displayLeft = displayLeft; landingScene.displayTop = displayTop; return landingScene; } }
/** * LandingScene.class 用于定义在屏幕下方的地面障碍物及其背景 */ public class LandingScene { Paint paint = new Paint(); // 填充到地面的颜色填充器 BitmapShader shader; // Surface View 的高度 public int displayHeight; // Surface View 的宽度 public int displayWidth; // Surface View 的左侧 public int displayLeft; // Surface View 的顶部 public int displayTop; // 定义X,Y轴 public int[] pathX; public int[] pathY; // 整个窗口的背景色 public int windowBackgroundColor; // 地面障碍物的背景图 public Bitmap obstacleBackground; public LandingScene() { paint.setColor(Color.GREEN); } public void postValidate(Canvas canvas) { if (shader == null) { // 初始化着色板 shader = new BitmapShader(obstacleBackground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); } // 设置画笔的颜色 canvas.drawColor(windowBackgroundColor, PorterDuff.Mode.CLEAR); Path path = new Path(); path.moveTo(0, displayHeight); for (int i = 0; i < pathX.length; i++) { path.lineTo(pathX[i], pathY[i]); } paint.setShader(shader); canvas.drawPath(path, paint); paint.setShader(null); // 在可以落地的上方画一条绿色的线 canvas.drawLine(pathX[5], pathY[5], pathX[6], pathY[6], paint); canvas.drawLine(pathX[2], pathY[2], pathX[3], pathY[3], paint); } public boolean releaseRes() { obstacleBackground.recycle(); return true; } }