本站文章均为 李华明Himi 原创,转载务必在明显处注明:

转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/android-game/298.html

    各位童鞋请你们注意:surfaceview中确实有 onDraw这个方法,但是surfaceview不会自己去调用!!!

    而我代码中的ondraw 也好 draw 也好,都是我自己定义的一个方法。。。放在线程中不断调用的,一定要注意!!

其实上一篇分析surfaceview的文章就是一个简单的游戏框架了,当然这里再强调一下,简单的游戏框架,所以不要高手们不要乱喷~

这个Demo是给群里一童鞋写的一个对图片操作以及按键处理,游戏简单框架的一个demo,这里放出给大家分享~

  1. package com.himi;
  2. import android.content.Context;
  3. import android.content.res.Resources;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Color;
  8. import android.graphics.Paint;
  9. import android.util.Log;
  10. import android.view.KeyEvent;
  11. import android.view.SurfaceHolder;
  12. import android.view.SurfaceView;
  13. import android.view.SurfaceHolder.Callback;
  14. public class MySurfaceView extends SurfaceView implements Callback, Runnable {
  15. private Thread th = new Thread(this);
  16. private SurfaceHolder sfh;
  17. private int SH, SW;
  18. private Canvas canvas;
  19. private Paint p;
  20. private Paint p2;
  21. private Resources res;
  22. private Bitmap bmp;
  23. private int bmp_x = 100, bmp_y = 100;
  24. private boolean UP, DOWN, LEFT, RIGHT;
  25. private int animation_up[] = { 3, 4, 5 };
  26. private int animation_down[] = { 0, 1, 2 };
  27. private int animation_left[] = { 6, 7, 8 };
  28. private int animation_right[] = { 9, 10, 11 };
  29. private int animation_init[] = animation_down;
  30. private int frame_count;
  31. public MySurfaceView(Context context) {
  32. super(context);
  33. this.setKeepScreenOn(true);
  34. res = this.getResources();
  35. bmp = BitmapFactory.decodeResource(res, R.drawable.enemy1);
  36. sfh = this.getHolder();
  37. sfh.addCallback(this);
  38. p = new Paint();
  39. p.setColor(Color.YELLOW);
  40. p2 = new Paint();
  41. p2.setColor(Color.RED);
  42. p.setAntiAlias(true);
  43. setFocusable(true);  //备注1
  44. }
  45. public void surfaceCreated(SurfaceHolder holder) {
  46. SH = this.getHeight();
  47. SW = this.getWidth();
  48. th.start();
  49. }
  50. public void draw() {
  51. canvas = sfh.lockCanvas();
  52. canvas.drawRect(0, 0, SW, SH, p);   //备注2
  53. canvas.save();   //备注3
  54. canvas.drawText("Himi", bmp_x-2, bmp_y-10, p2);
  55. canvas.clipRect(bmp_x, bmp_y, bmp_x + bmp.getWidth() / 13, bmp_y+bmp.getHeight());
  56. if (animation_init == animation_up) {
  57. canvas.drawBitmap(bmp, bmp_x - animation_up[frame_count] * (bmp.getWidth() / 13), bmp_y, p);
  58. } else if (animation_init == animation_down) {
  59. canvas.drawBitmap(bmp, bmp_x - animation_down[frame_count] * (bmp.getWidth() / 13), bmp_y, p);
  60. } else if (animation_init == animation_left) {
  61. canvas.drawBitmap(bmp, bmp_x - animation_left[frame_count] * (bmp.getWidth() / 13), bmp_y, p);
  62. } else if (animation_init == animation_right) {
  63. canvas.drawBitmap(bmp, bmp_x - animation_right[frame_count] * (bmp.getWidth() / 13), bmp_y, p);
  64. }
  65. canvas.restore();  //备注3
  66. sfh.unlockCanvasAndPost(canvas);
  67. }
  68. public void cycle() {
  69. if (DOWN) {
  70. bmp_y += 5;
  71. } else if (UP) {
  72. bmp_y -= 5;
  73. } else if (LEFT) {
  74. bmp_x -= 5;
  75. } else if (RIGHT) {
  76. bmp_x += 5;
  77. }
  78. if (DOWN || UP || LEFT || RIGHT) {
  79. if (frame_count < 2) {
  80. frame_count++;
  81. } else {
  82. frame_count = 0;
  83. }
  84. }
  85. if (DOWN == false && UP == false && LEFT == false && RIGHT == false) {
  86. frame_count = 0;
  87. }
  88. }
  89. @Override
  90. public boolean onKeyDown(int key, KeyEvent event) {
  91. if (key == KeyEvent.KEYCODE_DPAD_UP) {
  92. if (UP == false) {
  93. animation_init = animation_up;
  94. }
  95. UP = true;
  96. } else if (key == KeyEvent.KEYCODE_DPAD_DOWN) {
  97. if (DOWN == false) {
  98. animation_init = animation_down;
  99. }
  100. DOWN = true;
  101. } else if (key == KeyEvent.KEYCODE_DPAD_LEFT) {
  102. if (LEFT == false) {
  103. animation_init = animation_left;
  104. }
  105. LEFT = true;
  106. } else if (key == KeyEvent.KEYCODE_DPAD_RIGHT) {
  107. if (RIGHT == false) {
  108. animation_init = animation_right;
  109. }
  110. RIGHT = true;
  111. }
  112. return super.onKeyDown(key, event);
  113. }
  114. /* (non-Javadoc)
  115. * @see android.view.View#onKeyUp(int, android.view.KeyEvent)
  116. */
  117. @Override
  118. public boolean onKeyUp(int keyCode, KeyEvent event) {
  119. if (DOWN) {
  120. DOWN = false;
  121. } else if (UP) {
  122. UP = false;
  123. } else if (LEFT) {
  124. LEFT = false;
  125. } else if (RIGHT) {
  126. RIGHT = false;
  127. }
  128. return super.onKeyUp(keyCode, event);
  129. }
  130. @Override
  131. public void run() {
  132. // TODO Auto-generated method stub
  133. while (true) {
  134. draw();
  135. cycle();
  136. try {
  137. Thread.sleep(100);
  138. } catch (Exception ex) {
  139. }
  140. }
  141. }
  142. @Override
  143. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  144. // TODO Auto-generated method stub
  145. }
  146. @Override
  147. public void surfaceDestroyed(SurfaceHolder holder) {
  148. // TODO Auto-generated method stub
  149. }
  150. }

备注1

此方法是用来响应按键!如果是自己定义一个继承自View的类,重新实现onKeyDown方法后,只有当该View获得焦点时才会调用onKeyDown方法,Actvity中的onKeyDown方法是当所有控件均没有处理该按键事件时,才会调用.

备注2

这里也是对屏幕进行刷屏操作,其实这也只是一种,之前文章里我也用到drawRGB的方法同样实现,当然也可以用fillRect等来刷屏。

那么这里我想说下,在继承view中,因为onDraw方法是系统自动调用的,不像在surfaceview这里这样去在run里面自己去不断调用,在view中我们可以抵用 invalidate()/postInvalidate() 这两种方法实现让系统调用onDraw方法,这里也是和surfaceview中的不同之一!

备注3

这里canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。这里稍微解释一下,当我们对画布进行旋转,缩放,平移等操作的时候其实我们是想对特定的元素进行操作,比如图片,一个矩形等,但是当你用canvas的方法来进行这些操作的时候,其实是对整个画布进行了操作,那么之后在画布上的元素都会受到影响,所以我们在操作之前调用canvas.save()来保存画布当前的状态,当操作之后取出之前保存过的状态,这样就不会对其他的元素进行影响。

对于 canvas.save();和canvas.restore(); 还有不少童鞋不懂,OK、我再补充点:

代码段1:

  1. public void draw() {
  2. Canvas canvas = sfh.lockCanvas();
  3. canvas.drawColor(Color.BLACK);
  4. canvas.drawBitmap(bmp1, 0,0,paint);
  5. canvas.save();
  6. canvas.scale(1.5f, 1.5f);
  7. canvas.restore();
  8. canvas.drawBitmap(bmp2, 0,0,paint);
  9. sfh.unlockCanvasAndPost(canvas);
  10. }

代码段2:

  1. public void draw() {
  2. Canvas canvas = sfh.lockCanvas();
  3. canvas.drawColor(Color.BLACK);
  4. canvas.drawBitmap(bmp1, 0,0,paint);
  5. canvas.scale(1.5f, 1.5f);
  6. canvas.drawBitmap(bmp2, 0,0,paint);
  7. sfh.unlockCanvasAndPost(canvas);
  8. }

上面这两个代码片段中我们都假设有两张图片 bmp1和bmp2,并且都画在画布上!

那么代码段1和代码段2的不同:

    代码段1中我们进行画布缩放的之前保存了画布状态,做了缩放操作之后又取出之前保存的状态,这样做是为了保证bmp2正常画出来不受到缩放的影响!

    代码段2里,画了bmp1后就执行了缩放操作,并且没有保存状态!紧接着画了bmp2,那么bmp2也会一样受到缩放的影响!!

所以我们如果单独处理一张图片的时候,而且不想影响其他部分的绘制,那么应该如下来做:

  1. public void draw() {
  2. Canvas canvas = sfh.lockCanvas();
  3. canvas.drawColor(Color.BLACK);
  4. canvas.drawBitmap(bmp1, 0,0,paint);
  5. canvas.save();
  6. canvas.scale(1.5f, 1.5f);
  7. canvas.drawBitmap(bmp2, 0,0,paint);
  8. canvas.restore();
  9. sfh.unlockCanvasAndPost(canvas);
  10. }

(推荐大家订阅本博客,因为咱的更新速度可是很快的~娃哈哈)

×××地址: http://www.himigame.com/android-game/298.html

转载于:https://blog.51cto.com/xiaominghimi/605690

【Android游戏开发之四】Android 游戏框架(一个游戏角色在屏幕行走的demo)相关推荐

  1. Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)

    懒骨头(http://blog.csdn.net/iamlazybone  QQ124774397 青岛 ) 或许有天 我们羡慕和崇拜的人 因为我们的努力 也会来了解我们 说不定 还会成为好友 骨头喜 ...

  2. Cocos2dx游戏开发系列笔记7:一个简单的跑酷游戏《萝莉快跑》的消化(附下载)...

    2019独角兽企业重金招聘Python工程师标准>>> 或许有天 我们羡慕和崇拜的人 因为我们的努力 也会来了解我们 说不定 还会成为好友 骨头喜欢这样与哲哲共勉 多少个夜晚 一张长 ...

  3. Cocos2dx游戏开发系列笔记3:牛刀小试-忍者飞镖射幽灵的Demo

    2019独角兽企业重金招聘Python工程师标准>>> 就是这个例子,应该很简单,主要用到的有:精灵的移动,触摸,碰撞检测. 赶紧搞定,待会还要陪哲哲来几局爱消除. 首先在Scene ...

  4. Android小游戏开发:简单的合金弹头游戏(一)游戏框架

    本篇博客适合给初学安卓,熟悉基本的JAVA语法,并希望用安卓写个小游戏的初学者参考,因为博主也因大学课程需要,是在2个星期内自学的JAVA和安卓开发,可能会有一些错误和需要优化的地方,望指出 我在这2 ...

  5. android手机游戏开发从入门到精通_unity3d游戏开发如何从入门到精通?

    对于游戏爱好者来说,unity3d想必大家都不陌生,unity3d和虚幻4算是现在最主流的游戏开发引擎,当然,Unity 3D 游戏开发引擎目前之所以炙手可热,与其完善的技术以及丰富的个性化功能密不可 ...

  6. DirectX游戏开发之代码的框架简析

    DirectX游戏开发之代码的框架简析 此次学习过程中,主要参考的是大神"毛星云"的博客和DirectX 官方SDK,不少代码是在前两者的基础上略做修改. 在这两个上面你能够学得更 ...

  7. ​Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机

    ​Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机 Unity中制作一个望远镜 本节制作的望远镜,在鼠标左键按下时,看到的视图会变大:当不再按下的时候,会慢慢缩小成原来的视图.游戏中时常出现 ...

  8. Unity游戏开发——新发教你做游戏(三):3种资源加载方式

    文章目录 一.前言 二.Unity的目录结构规范 1.Resources(不是很推荐把资源放这个目录) 2.RawAssets(存放生资源) 3.GameRes(存放熟资源) 4.StreamingA ...

  9. 2023游戏开发制作如何选择合适的游戏引擎?看完本文就知道

    在游戏开发方面,为您的游戏选择合适的游戏引擎可以决定整个体验的成败.还有很多因素需要考虑: 你想制作什么样的游戏? 你的游戏是 2D 还是 3D? 你有多少经验? 引擎或框架的社区有多活跃? 引擎可以 ...

  10. Unity 2D游戏开发教程之使用脚本实现游戏逻辑

    Unity 2D游戏开发教程之使用脚本实现游戏逻辑 使用脚本实现游戏逻辑 通过上一节的操作,我们不仅创建了精灵的动画,还设置了动画的过渡条件,最终使得精灵得以按照我们的意愿,进入我们所指定的动画状态. ...

最新文章

  1. 利用牛顿法求平方根-Go语言实现
  2. 【硬件基础】制作直流电源
  3. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1051:分段函数
  4. Liunx 重新mount
  5. 电脑QQ能登上,网页打不开的解决办法
  6. 小程序 bindtouchmove 使用拖动按钮 页面跟着滑动并拖动卡顿感 问题
  7. 罗永浩:6亿债务,已还了4个亿;Python 3.9指日可待|极客头条
  8. Android 生成分享长图并且添加全图水印
  9. vue 解决控制台Prop being mutated: “placement“报错
  10. 明辰智航发布流量分析审计系统
  11. 学习笔记10--多传感器融合定位技术
  12. 如何将ppt压缩到最小?
  13. Flink 统计页面点击量
  14. 如何使用计算机自带的刻录软件,Win10电脑如何刻录光盘?利用win10自带刻录工具来刻录DVD光盘教程...
  15. matlab subs命令,Matlab中subs函数
  16. noip题库 —— 4.7反质数
  17. java 文件内容查找_java 查找一个TXT文件内容。
  18. 计算机外存是ram硬盘还是,都是存储器,但RAM、ROM、闪存、硬盘怎么分?
  19. VUE常用指令v-xxx
  20. 银行案例启示:莫把客户投诉当小事

热门文章

  1. 自动化测试介入的时机
  2. Android系统源码分析--Context
  3. 003_ElasticSearch详解与优化设计
  4. 一个cp命令引发的mongodb大量慢查询
  5. js中,还真不了解 console
  6. HttpContext.Current
  7. Windows7中被大家忽略的实用七大功能
  8. 最详细的wine配置
  9. Vmware vSphere5.0网络连接服务器配置常见问题
  10. 365Key今天不能用了,感觉不爽