【读书笔记《Android游戏编程之从零开始》】17.游戏开发基础(游戏适屏的简述和作用、让游戏主角动起来)

简介:

1.游戏适屏的简述和作用

由于市面上安装 Android 系统的手机不断增多,出现了各种分辨率、各种屏幕尺寸的Android 系统手机。为了保证一个游戏或者一个软件能在所有的 Android 手机上正常显示,常用的适屏做法有:利用屏幕宽高、位图宽高来设置一些游戏元素的位置;字体的适屏做法最好的使用字体图,这样文字不会因为手机分辨率不同而不同,毕竟图片大小是固定不变的。

2.让游戏主角动起来
实例演示将一张由多行多列的动作帧组成的图片实现动态效果。

 

新建项目,游戏框架为SurfaceView 框架,准备图片robot.png如下:

修改MySurfaceView 类,代码如下:

 

复制代码
package com.example.ex4_13;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView implements Callback,Runnable {
    private SurfaceHolder sfh;
    private Canvas canvas;
    private Paint paint;
    private boolean flag;
    private Thread th;
    //机器人位图
    private Bitmap bmpRobot ;
    //机器人的方向常量
    private final int DIR_LEFT =0;
    private final int DIR_RIGHT=1;
    //机器人当前的方向
    private int dir = DIR_RIGHT;
    //动作帧下标
    private int currentFrame;
    //机器人的X,Y位置
    private int robot_x,robot_y;
    //处理按键卡现象
    private boolean isUp, isDown, isLeft, isRight;
    public MySurfaceView(Context context) {
        super(context);
        sfh = this.getHolder();
        sfh.addCallback(this);
        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        setFocusable(true);
        bmpRobot = BitmapFactory.decodeResource(this.getResources(), R.drawable.robot);
    }
    /**
     * SurfaceView视图创建,响应此函数
     */
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        flag = true;
        //实例线程
        th = new Thread(this);
        //启动线程
        th.start();
    }
    
    /**
     * SurfaceView视图状态发生改变,响应此函数
     */
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        
    }
    /**
     * SurfaceView视图消亡时,响应此函数
     */
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        flag = false;
    }

    /**
     * 绘制函数
     */
    private void myDraw()
    {
        try {
            canvas = sfh.lockCanvas();
            if(canvas!=null)
            {
                canvas.drawColor(Color.BLACK);
                drawFrame(currentFrame,canvas,paint);
            }
        } catch (Exception e) {
            // TODO: handle exception
        }finally{
            if(canvas!=null)
            {
                sfh.unlockCanvasAndPost(canvas);
            }
        }
    }
    /**
     * 
     * @param currentFrame 绘制帧
     * @param frameW  
     *             每帧的高
     * @param frameH 
     *             每帧的高
     * @param canvas  
     *             画布实例
     * @param paint         
     *              画笔实例
     */
    private void drawFrame(int currentFrame,Canvas canvas,Paint paint)
    {
        //每帧的宽
        int frameW = bmpRobot.getWidth() / 6;
        //每帧的高
        int frameH = bmpRobot.getHeight() / 2;
        //得到位图的列数
        int col = bmpRobot.getWidth() / frameW;
        //得到当前帧相对于位图的X坐标
        int x = currentFrame % col * frameW;
        //得到当前帧相对于位图的Y坐标
        int y = currentFrame / col * frameH;
        canvas.save();
        //设置一个宽高与机器人每帧相同大小的可视区域
        canvas.clipRect(robot_x, robot_y, robot_x + bmpRobot.getWidth() / 6, robot_y + bmpRobot.getHeight() / 2);
        if (dir == DIR_LEFT) {//如果是向左侧移动
            //镜像操作 - 反转 - 改变机器人动画的朝向
            canvas.scale(-1, 1, robot_x - x + bmpRobot.getWidth() / 2, robot_y - y + bmpRobot.getHeight() / 2);
        }
        canvas.drawBitmap(bmpRobot, robot_x - x, robot_y - y, paint);
        canvas.restore();
    }
    /**
     * 游戏逻辑
     */
    private void logic() {
        //控制机器人位移方向
        if (isUp) {
            robot_y -= 5;
        }
        if (isDown) {
            robot_y += 5;
        }
        if (isLeft) {
            robot_x -= 5;
        }
        if (isRight) {
            robot_x += 5;
        }
        //动作帧数的循环控制,让其动作帧不断重复播放
        currentFrame++;
        if (currentFrame >= 12) {
            currentFrame = 0;
        }
    }
    
    @Override
    public void run() {
        while (flag) {
            long start = System.currentTimeMillis();
            myDraw();
            logic();
            long end = System.currentTimeMillis();
            try {
                if (end - start < 50) {
                    Thread.sleep(50 - (end - start));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 按键事件监听
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
            isUp = true;
        }
        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
            isDown = true;
        }
        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
            isLeft = true;
            dir = DIR_LEFT;
        }
        if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
            isRight = true;
            dir = DIR_RIGHT;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
            isUp = false;
        }
        if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
            isDown = false;
        }
        if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
            isLeft = false;
        }
        if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
            isRight = false;
        }
        return super.onKeyUp(keyCode, event);
    }
    
    
}
复制代码





本文转自秋楓博客园博客,原文链接:http://www.cnblogs.com/yc-755909659/p/4179436.html,如需转载请自行联系原作者
目录
相关文章
|
8月前
|
缓存 图形学
《unity游戏优化》第一章读书笔记
《unity游戏优化》第一章读书笔记
|
8月前
|
缓存 算法 API
《unity游戏优化》第六章读书笔记
《unity游戏优化》第六章读书笔记
|
搜索推荐 Java Linux
Android基础入门教程
Android是一种基于Linux的自由及开放源代码的操作系统,Android 分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层。
204 0
|
XML 存储 移动开发
Android基础 | 关于Activity你应该明白的一切
Activity 作为一个老生常谈的话题,它是我们刚接触Android开发就遇到,虽然已有一段时间开发经验,但谈起完全搞懂Activity相关,不敢妄言,故结合个人理解及书籍参考,简单总结一下 Activity基础相关知识,其中也留出了一些有意思的问题。
141 0
|
XML 存储 安全
Android四大组件全面解析,夯实基础。(下)
Android四大组件 lay a solid foundation 夯实基础
167 0
|
Android开发
Android四大组件全面解析,夯实基础。(中)
Android四大组件 lay a solid foundation 夯实基础
179 0
Android四大组件全面解析,夯实基础。(中)
|
存储 设计模式 前端开发
Android四大组件全面解析,夯实基础。(上)
Android四大组件 lay a solid foundation 夯实基础
108 0
|
安全 Java 调度
Android多线程编程——线程基础
Android沿用了Java的线程模型,一个Android应用在创建的时候会开启一个线程,我们叫它主线程或者UI线程。
208 0
Android多线程编程——线程基础
|
Java Android开发
移动应用程序设计基础——Android环境构建与Activity生命周期
安装智能手机开发相关软件平台,并在此基础上测试Activity的生命周期过程。 5、 完成智能手机开发平台安装、以及相关配置; 6、 并实现Hello World; 7、 添加Log日志,通过Log日志验证Ac 1、 安装JAVA JDK 2、 安装Android Studio,熟悉AS的基本操作,改变AS的字体,显示方式;截图和文字说明。 3、 建立新项目,实现Hello World。说明各个文件的作用,以及各个关键语句的作用或含义,给出程序的运行结果。 4、 设置生命周期的Log日志,分别执行相关操作
231 0
移动应用程序设计基础——Android环境构建与Activity生命周期
|
XML 存储 Java
Android动画基础详析 | 概述、逐帧动画、视图动画(附诸多实际运行效果动图)
Android动画基础详析 | 概述、逐帧动画、视图动画(附诸多实际运行效果动图)