博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【读书笔记《Android游戏编程之从零开始》】17.游戏开发基础(游戏适屏的简述和作用、让游戏主角动起来)...
阅读量:6966 次
发布时间:2019-06-27

本文共 5513 字,大约阅读时间需要 18 分钟。

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); } }

 

本文地址:

PS:本文由原创,如有转载请注明出处,谢谢!

 

你可能感兴趣的文章
网站服务器设置禁PING的方法步骤
查看>>
Linux基础命令---lpstat查看打印机状态
查看>>
新年福利 | 架构的“一小步”,业务的一大步
查看>>
Confluence 6 升级中的一些常见问题
查看>>
不可小看的数值类型—Python基础前传(5)
查看>>
集群中节点挂载数据盘的几种方式
查看>>
工作日志——基于k8s搭建spark集群
查看>>
3. 爬虫框架Clawler 爬取优酷电影名
查看>>
记维护旧项目遇到的问题
查看>>
Node v10.15.3 (LTS) 发布,服务器端的 JavaScript 运行环境
查看>>
如何让你的网站拥有网盘功能, 一分钟搞定
查看>>
行李箱品牌“July”完成数百万元天使轮融资
查看>>
group by,where,having之间的区别和用法
查看>>
HashMap VS Hashtable
查看>>
MySQL-To-JSON 的 Kafka 生产者
查看>>
[网络篇]ESP8266-SDK教程(五)之SmartConfig、Airkiss等多种配网方式
查看>>
C4C销售订单中业务伙伴的自动决定功能Partner determination procedure
查看>>
关于Java序列化你不知道的事
查看>>
使用 HTML5,通过创建 cache manifest 文件,可以轻松地创建 web 应用的离线版本。...
查看>>
项目管理助力组织赢在VUCA时代
查看>>