【ANDROID游戏开发二十】物理游戏之重力系统开发,让你的游戏变得有质有量!

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

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

今天群里一哥哥说急需关于物理游戏方面的资料,so~下午就随手写了一个简单的圆形自由落体Demo,正好一起分享给大家学习下吧;

先大概说一下,之前的文章中,给大家介绍过重力传感器,那么和今天要说的重力系统,其实是一样的!

在重力传感器中,虽然我也实现了一个圆形会根据手机反转的角度而拥有不同的速度,但是其内置加速度算法都是Android os封装好的,而今天我们要讲的重力系统就是去模拟这个加速度,从而让一个自由落体的圆形,感觉跟现实中的皮球一样有质有量!下落的时候速度加快,反弹起来以后速度慢慢减下来~

OK,先上两张截图,然后简单介绍之后进行讲解:

Demo:简介:(咳咳、玩的有点H,狂点按钮搞的满屏都是 – -)

当你点击模拟器任意按键的时候会随机在屏幕上生成一个随机大小、随即颜色、随即位置、不停闪烁的一个圆形,并且圆形都拥有重力,在做自由落体,当圆形触到屏幕底部的时候会反弹,并且反弹的高度一次比一次低!

这个实例中,为了好看,我没有让圆形最终慢到停下来,会一直在一个高度进行的反弹,下落;

还有一点:对于圆形当从一个高度自由落体的时候可能它在X坐标系上没有发生改变,当然这是在我们代码中,属于理想状态,因为现实生活中,一般X/Y坐标系都会有变动,在此Demo中,我主要把垂直下落并且反弹的功能做出来了,关于水平的加速度我没做,第一是因为和垂直的处理思路基本一致,第二点我没时间 – -…

好了 不废话!先介绍一下我自定义的圆形类:

MyArc.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

package com.himi;

import java.util.Random;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.RectF;

/**

* @author Himi

* @自定义圆形类

*/

public class MyArc {

    private int arc_x, arc_y, arc_r;//圆形的X,Y坐标和半径

    private float speed_x = 1.2f, speed_y = 1.2f;//小球的x、y的速度

    private float vertical_speed;//加速度

    private float horizontal_speed;//水平加速度,大家自己试着添加吧

    private final float ACC = 0.135f;//为了模拟加速度的偏移值

    private final float RECESSION = 0.2f;//每次弹起的衰退系数

    private boolean isDown = true;//是否处于下落  状态

    private Random ran;//随即数库

    /**

     * @定义圆形的构造函数

     * @param x 圆形X坐标

     * @param y 圆形Y坐标

     * @param r 圆形半径

     */

    public MyArc(int x, int y, int r) {

        ran = new Random();

        this.arc_x = x;

        this.arc_y = y;

        this.arc_r = r;

    }

    public void drawMyArc(Canvas canvas, Paint paint) {//每个圆形都应该拥有一套绘画方法

        paint.setColor(getRandomColor());//不断的获取随即颜色,对圆形进行填充(实现圆形闪烁效果)

        canvas.drawArc(new RectF(arc_x + speed_x, arc_y + speed_y, arc_x + 2 *

                arc_r + speed_x, arc_y + 2 * arc_r + speed_y), 0, 360, true, paint);

    }

    /**

     * @return

     * @返回一个随即颜色

     */

    public int getRandomColor() {

        int ran_color = ran.nextInt(8);

        int temp_color = 0;

        switch (ran_color) {

        case 0:

            temp_color = Color.WHITE;

            break;

        case 1:

            temp_color = Color.BLUE;

            break;

        case 2:

            temp_color = Color.CYAN;

            break;

        case 3:

            temp_color = Color.DKGRAY;

            break;

        case 4:

            temp_color = Color.RED;

            break;

        case 6:

            temp_color = Color.GREEN;

        case 7:

            temp_color = Color.GRAY;

        case 8:

            temp_color = Color.YELLOW;

            break;

        }

        return temp_color;

    }

    /**

     * 圆形的逻辑

     */

    public void logic() {//每个圆形都应该拥有一套逻辑

        if (isDown) {//圆形下落逻辑

/*--备注1-*/speed_y += vertical_speed;//圆形的Y轴速度加上加速度

            int count = (int) vertical_speed++;

            //这里拿另外一个变量记下当前速度偏移量

            //如果下面的for (int i = 0; i < vertical_speed++; i++) {}这样就就死循环了 - -

            for (int i = 0; i < count; i++) {//备注1

/*--备注2-*/  vertical_speed += ACC;

            }

        } else {//圆形反弹逻辑

            speed_y -= vertical_speed;

            int count = (int) vertical_speed--;

            for (int i = 0; i < count; i++) {

                vertical_speed -= ACC;

            }

        }

        if (isCollision()) {

            isDown = !isDown;//当发生碰撞说明圆形的方向要改变一下了!

            vertical_speed -= vertical_speed * RECESSION;//每次碰撞都会衰减反弹的加速度

        }

    }

    /**

     * 圆形与屏幕底部的碰撞

     * @return

     * @返回true 发生碰撞

     */

    public boolean isCollision() {

        return arc_y + 2 * arc_r + speed_y >= MySurfaceViee.screenH;

    }

}

代码比较简单主要讲解下几个备注:

备注1:

       估计有些同学看到这里有点小晕,我解释下,大家都知道自由落体的时候,速度是越来越快的,这是受到加速度的影响,所以这里我们对原有的圆形y速度基础上再加上加速度!

备注2:

       虽然加速度影响了圆形原有的速度,但是我们的加速度也不是恒定的,为了模拟真实球体的自由下落,这里我们不仅对加速度增加了偏移量ACC,而且我们还要对其变化的规律进行模拟,让下次的加速度偏移量成倍增加!所以为什么要for循环的时候把加速度的值当成for循环的一个判定条件!

好了,下面来看我们SurfaceView!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

package com.himi;

import java.util.Random;

import java.util.Vector;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.util.Log;

import android.view.KeyEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.SurfaceHolder.Callback;

public class MySurfaceViee extends SurfaceView implements Callback, Runnable {

    private Thread th;

    private SurfaceHolder sfh;

    private Canvas canvas;

    private Paint paint;

    private boolean flag;

    public static int screenW, screenH;

    private Vector<MyArc> vc;//这里定义装我们自定义圆形的容器

    private Random ran;//随即库

    public MySurfaceViee(Context context) {

        super(context);

        this.setKeepScreenOn(true);

        vc = new Vector<MyArc>();

        ran = new Random();//备注1

        sfh = this.getHolder();

        sfh.addCallback(this);

        paint = new Paint();

        paint.setAntiAlias(true);

        setFocusable(true);

    }

    public void surfaceCreated(SurfaceHolder holder) {

        flag = true;//这里都是上一篇刚讲过的。。。

        th = new Thread(this);

        screenW = this.getWidth();

        screenH = this.getHeight();

        th.start();

    }

    public void draw() {

        try {

            canvas = sfh.lockCanvas();

            canvas.drawColor(Color.BLACK);

            if (vc != null) {//当容器不为空,遍历容器中所有圆形画方法

                for (int i = 0; i < vc.size(); i++) {

                    vc.elementAt(i).drawMyArc(canvas, paint);

                }

            }

        } catch (Exception e) {

            // TODO: handle exception

        } finally {

            try {

                if (canvas != null)

                    sfh.unlockCanvasAndPost(canvas);

            } catch (Exception e2) {

            }

        }

    }

    private void logic() {//主逻辑

        if (vc != null) {//当容器不为空,遍历容器中所有圆形逻辑

            for (int i = 0; i < vc.size(); i++) {

                vc.elementAt(i).logic();

            }

        }

    }

    @Override

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        //当按键事件响应,我们往容器中仍个我们的圆形实例

        vc.addElement(new MyArc(ran.nextInt(this.getWidth()), ran.nextInt(100), ran.nextInt(50)));

        return true;

    }

    public void run() {

        // TODO Auto-generated method stub

        while (flag) {

            logic();

            draw();

            try {

                Thread.sleep(100);

            } catch (Exception ex) {

            }

        }

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        Log.v("Himi", "surfaceChanged");

    }

    public void surfaceDestroyed(SurfaceHolder holder) {

        flag = false;

    }

}

OK,代码都很简单,也很清晰! 稍微说一句:像MyArc里面也有类似MysurfaceView中一样的方法 logic() 以及draw()这样是更好的管理我们的代码结构,清晰思路,让该干什么的就去干什么,这样省的乱~

补充下://备注1 这里!有的童鞋说for循环可以简写:这我就要提示各位童鞋了~

for (int i = 0; i < count; i++) { 

         vertical_speed += ACC;

}

以上代码确实可以用一句来表示:

               vertical_speed +=ACC*count;     或者    vertical_speed  =vertical_speed + ACC*count;

但是要注意:因为我这里变量都是浮点数,大家都知道对于浮点数有位数的限制,那么我这里用for来写可以避免乘积,如果简写的形式会有造成得到的结果有差异!!!!所以要注意;

               还有千万不要简写成 vertical_speed =(vertical_speed +ACC)*count; 这是错误的!

 

源码下载:    “重力系统源码.rar”            下载地址:  http://vdisk.weibo.com/s/hq4Fw

时间: 2024-08-30 07:39:53

【ANDROID游戏开发二十】物理游戏之重力系统开发,让你的游戏变得有质有量!的相关文章

Android 物理游戏之重力系统开发示例代码

本节为大家提供有关物理游戏的知识,讲解了一个简单的圆形自由落体Demo的编写.本文要介绍的重力系统实际上是类似的. 在重力传感器中,虽然我也实现了一个圆形会根据手机反转的角度而拥有不同的速度,但是其内置加速度算法都是Android os封装好的,而今天我们要讲的重力系统就是去模拟这个加速度,从而让一个自由落体的圆形,感觉跟现实中的皮球一样有质有量!下落的时候速度加快,反弹起来以后速度慢慢减下来. 先贴上两张效果截图,让大家有一个直观的了解,之后再详加讲解: 圆形自由落体Demo简介 当你点击模拟

【ANDROID游戏开发二十四】360°平滑游戏摇杆(触屏方向导航)

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/384.html 此章节为正在创作的游戏开发书籍书稿中的一部分,由于写书的缘故很久没有更新了,挺对不起大家的:那么今天放出书稿中的一部分,让大家先睹为快吧: 在Android系统的手机,有的根本没有实体的上下左右导航按键,所以很多游戏都会有利用Android手机都具有触屏的特性,制作360度摇杆来取代游戏方向键,这样

【ANDROID游戏开发二十二】(图文详解)游戏中灵活实现动画播放!简述J2ME的游戏类库与ANDROID游戏开发!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/361.html 由于写书的缘故,博文更新缓慢,大家体谅,今天针对群内常提出动画实现的问题来进行一个详细讲述: 此章节适合没有做过游戏开发的同学学习! 做过Android软件的童鞋们,在学习游戏开发的时候,思维总是被固定在了Android系统组件上!比如动画实现总想着利用BitmapDrawable.Animatio

【ANDROID游戏开发二十六】追加简述SURFACEVIEW 与 GLSURFACEVIEW效率!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/388.html 今天在这里大概说下现在为什么游戏引擎都趋向与openGL进行的,这里大概说下: 当今基本所有的国外游戏都是质量很好,不管是从视觉上还是操作还是流畅度上,那么今天我们关注的是其流畅度: 首先有经验的游戏开发者,尤其是一直做2D游戏开发的童鞋门,从J2me到Android,很多做Android的都是从J

【ANDROID游戏开发二十五】在ANDROID上的使用《贝赛尔曲线》!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/386.html 首先对于<赛贝尔曲线>不是很了解的童鞋,请自觉白度百科.google等等- 为了方便偷懒的童鞋,这里给个<贝赛尔曲线>百科地址,以及一段话简述<贝赛尔曲线>: <贝赛尔曲线>白度百科快速地址:http://baike.baidu.com/view/4019466

kvm虚拟化学习笔记(二十)之convirt安装linux系统

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://koumm.blog.51cto.com/703525/1306526 情况说明: (1)本文接前文kvm虚拟化学习笔记(十九)之convirt集中管理平台搭建,采用convirt虚拟化平台安装linux操作系统的过程,这个过程中需要对convirt进行一系列的配置才能真正的使用convirt来实现管理.(2)convirt2.1.1是一套kvm/xen虚拟机管理工具,该管理工具

【IOS-COCOS2D-X 游戏开发之十二】自定义COCOS2DX摇杆(增强JOYSTICK),增加摇杆跟随用户触点作为摇杆坐标,让摇杆不再死板!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2dx/721.html 对于虚拟摇杆在游戏开发中必不可少,Android方面的是由Himi自己实现封装的,大家可以移步到这里查看详细实现机制: [Android游戏开发二十四]360°平滑游戏摇杆(触屏方向导航)  那么在Cocos2d引擎已提供此摇杆类(Joystick),所以Himi也就懒得重写了,但是Cocos

在设计师的角度讲系统开发

中介交易 SEO诊断 淘宝客 云主机 技术大厅 公司开发某系统已经有一段时间了,功能已经得到一些客户的肯定,但界面不好看一直是个大问题,所以前两三周专门做这方面的改善.面对着N个界面的设计,N++个杂.碎.乱的页面整理,着实是件头疼的事情.还好这一切已经完成,为那两三周的忙碌总结几点吧. 先简单概述一下系统界面美化的工作流程 1.准备阶段:熟悉,看系统相关的文档,对系统有个大概把握,不至于设计时钻牛角尖;估量,大概总结需要改善细化的页面问题;估时,计划工作时间;定人,明确参与修改的人员,设计师和

Python在实时嵌入式系统开发中扮演的五个主要角色

Python已经成为相当热门的程序语言.它以着名的Monty Python喜剧组命名,属于面向对象和解释型语言(非编译型).该属性使得Python具有良好的跨平台性,比如Linux和Windows,或是诸如Raspberry Pi等单板计算机.随着Python的日益普及,人们可能会问,在实时嵌入式系统中是否也有Python的一席之地. 答案是肯定的.下面是开发人员发现Python在实时嵌入式系统开发中有可能扮演的五个主要角色. 作用# 1设备调试和控制 在嵌入式软件开发过程中,开发人员常常需要分