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

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

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

首先对于《赛贝尔曲线》不是很了解的童鞋,请自觉白度百科、google等等…

为了方便偷懒的童鞋,这里给个《贝赛尔曲线》百科地址,以及一段话简述《贝赛尔曲线》:

《贝赛尔曲线》白度百科快速地址:http://baike.baidu.com/view/4019466.htm

贝塞尔曲线又称贝兹曲线或贝济埃曲线,一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋;

上面这一段话其实就“线段像可伸缩的皮筋”这一句比较重要,也很容易理解;

至于贝赛尔曲线的实现,在Android中极其的简单,因为它是Android封装的一个方法,这个能不简单么。。。。。。只不过它隐藏的比较深,它隐藏于Path类中,方法如下:

android.graphics.Path.quadTo(float x1, float y1, float x2, float y2)

Since: API Level 1

此方参数解释:

第一个参数:操作点的x坐标

第二个参数:操作点的y坐标

第三个参数:结束点的x坐标

第四个参数:结束点的y坐标

从API中看出,赛贝尔曲线从API-1就开始支持了;

熟悉方法后,下面就来实现:

SurfaceView框架不多讲,看过我博客的都应该知道的;

直接看MySurfaceView类,此类继承SurfaceView ,是游戏的主视图

这里为了更清晰的讲解:这里部分代码先不贴出来了,最后会整体贴出,当然源码也是免费在最后提供~

首先是定义相关的成员变量:

1

2

3

4

5

6

7

8

// 贝赛尔曲线成员变量(起始点,控制(操作点),终止点,3点坐标)

private int startX, startY, controlX, controlY, endX, endY;

// Path

private Path path;

// 为了不影响主画笔,这里绘制贝赛尔曲线单独用一个新画笔

private Paint paintQ;

// 随机库(让贝赛尔曲线更明显)

private Random random;

本类构造函数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

* SurfaceView初始化函数

*/

public MySurfaceView(Context context) {

    super(context);

    ...

        //贝赛尔曲线相关初始化

        path = new Path();

        paintQ = new Paint();

        paintQ.setAntiAlias(true);

        paintQ.setStyle(Style.STROKE);

        paintQ.setStrokeWidth(5);

        paintQ.setColor(Color.WHITE);

        random = new Random();

    ...

}

接着我把绘制贝赛尔曲线封装一个方法了,函数如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

/**

* 绘制贝赛尔曲线

*

* @param canvas 主画布

*/

public void drawQpath(Canvas canvas) {

    path.reset();// 重置path

    // 贝赛尔曲线的起始点

    path.moveTo(startX, startY);

    // 设置贝赛尔曲线的操作点以及终止点

    path.quadTo(controlX, controlY, endX, endY);

    // 绘制贝赛尔曲线(Path)

    canvas.drawPath(path, paintQ);

}

最后是用户触屏监听函数以及逻辑函数:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

/**

* 触屏事件监听

*/

@Override

public boolean onTouchEvent(MotionEvent event) {

    endX = (int) event.getX();

    endY = (int) event.getY();

    return true;

}

/**

* 游戏逻辑

*/

private void logic() {

    if (endX != 0 && endY != 0) {

        // 设置操作点为线段x/y的一半

        controlX = random.nextInt((endX - startX) / 2);

        controlY = random.nextInt((endY - startY) / 2);

    }

}

整个代码很easy~主要是贝赛尔函数的参数,尤其是操作点,操作点的各种不同可以实现不同的效果,这里我简单的统一的讲操作点设置成用户触屏点的x,y的一半,呵呵偷懒了~嘻嘻~

我把贝赛尔的操作点写在了逻辑logic()函数中,不断的执行,并且每次利用nextInt函数得到随机的操作点,主要为了让其曲线不断的变化从而形成一个震动的曲线运动轨迹;

ok,效果接图如下:

这里可能由于图片是静止的效果看起来不是很明显,大家可以运行源码来观察 ,好了~本节就这样吧;下面贴出整个MySurfaceView的源码:(最后有本项目的源码下载地址)

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

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

package com.qpath;

import java.util.Random;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.graphics.Path;

import android.view.KeyEvent;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceHolder.Callback;

import android.view.SurfaceView;

/**

* 赛贝尔曲线

* @author Himi

*

*/

public class MySurfaceView extends SurfaceView implements Callback, Runnable {

    private SurfaceHolder sfh;

    private Paint paint;

    private Thread th;

    private boolean flag;

    private Canvas canvas;

    public static int screenW, screenH;

    // -----------以上是SurfaceView游戏框架

    // 贝赛尔曲线成员变量(起始点,控制(操作点),终止点,3点坐标)

    private int startX, startY, controlX, controlY, endX, endY;

    // Path

    private Path path;

    // 为了不影响主画笔,这里绘制贝赛尔曲线单独用一个新画笔

    private Paint paintQ;

    // 随机库(让贝赛尔曲线更明显)

    private Random random;

    /**

     * SurfaceView初始化函数

     */

    public MySurfaceView(Context context) {

        super(context);

        sfh = this.getHolder();

        sfh.addCallback(this);

        paint = new Paint();

        paint.setColor(Color.WHITE);

        paint.setAntiAlias(true);

        setFocusable(true);

        // -----------以上是SurfaceView游戏框架

        //贝赛尔曲线相关初始化

        path = new Path();

        paintQ = new Paint();

        paintQ.setAntiAlias(true);

        paintQ.setStyle(Style.STROKE);

        paintQ.setStrokeWidth(5);

        paintQ.setColor(Color.WHITE);

        random = new Random();

    }

    /**

     * SurfaceView视图创建,响应此函数

     */

    public void surfaceCreated(SurfaceHolder holder) {

        screenW = this.getWidth();

        screenH = this.getHeight();

        flag = true;

        // 实例线程

        th = new Thread(this);

        // 启动线程

        th.start();

        // -----------以上是SurfaceView游戏框架

    }

    /**

     * 游戏绘图

     */

    public void myDraw() {

        try {

            canvas = sfh.lockCanvas();

            if (canvas != null) {

                canvas.drawColor(Color.BLACK);

                // -----------以上是SurfaceView游戏框架

                drawQpath(canvas);

            }

        } catch (Exception e) {

            // TODO: handle exception

        } finally {

            if (canvas != null)

                sfh.unlockCanvasAndPost(canvas);

        }

    }

    /**

     * 绘制贝赛尔曲线

     *

     * @param canvas 主画布

     */

    public void drawQpath(Canvas canvas) {

        path.reset();// 重置path

        // 贝赛尔曲线的起始点

        path.moveTo(startX, startY);

        // 设置贝赛尔曲线的操作点以及终止点

        path.quadTo(controlX, controlY, endX, endY);

        // 绘制贝赛尔曲线(Path)

        canvas.drawPath(path, paintQ);

    }

    /**

     * 触屏事件监听

     */

    @Override

    public boolean onTouchEvent(MotionEvent event) {

        endX = (int) event.getX();

        endY = (int) event.getY();

        return true;

    }

    /**

     * 游戏逻辑

     */

    private void logic() {

        if (endX != 0 && endY != 0) {

            // 设置操作点为线段x/y的一半

            controlX = random.nextInt((endX - startX) / 2);

            controlY = random.nextInt((endY - startY) / 2);

        }

    }

    /**

     * 按键事件监听

     */

    @Override

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        return super.onKeyDown(keyCode, event);

    }

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

            }

        }

    }

    /**

     * SurfaceView视图状态发生改变,响应此函数

     */

    public void surfaceChanged(SurfaceHolder holder, int format, int width,

            int height) {

    }

    /**

     * SurfaceView视图消亡时,响应此函数

     */

    public void surfaceDestroyed(SurfaceHolder holder) {

        flag = false;

    }

}

本章源码下载: “贝赛尔曲线.zip”           下载地址:  http://vdisk.weibo.com/s/hq3e9

时间: 2024-10-29 20:15:54

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

【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游戏开发二十四】360°平滑游戏摇杆(触屏方向导航)

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

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

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/354.html 今天群里一哥哥说急需关于物理游戏方面的资料,so~下午就随手写了一个简单的圆形自由落体Demo,正好一起分享给大家学习下吧: 先大概说一下,之前的文章中,给大家介绍过重力传感器,那么和今天要说的重力系统,其实是一样的! 在重力传感器中,虽然我也实现了一个圆形会根据手机反转的角度而拥有不同的速度,但是

【ANDROID游戏开发二十七】讲解游戏开发与项目下的HDPI 、MDPI与LDPI资源文件夹以及游戏高清版本的设置

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/389.html 今天一个开发者问到我为什么游戏开发要删除项目下的hdpi.mdpi和ldpi文件夹:下面详细给大家解答一下: 首先童鞋们如果看过我写的<[Android游戏开发二十一]Android os设备谎言分辨率的解决方案!>这一节的话都应该知道Android从1.6和更高,Google为了方便开发者对于各

【IOS-COCOS2D-X 游戏开发之十五】COCOS2DX中响应ANDROID的BACK(返回)与MENU(小房子)事件&amp;&amp;COCOS2DX自动释放粒子内存函数!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2dx/792.html 本篇介绍两个常用知识,一个是粒子的自动释放机制函数,因为不少童鞋说cocos2dx为什么没有? 其实是没找到,这里特意拿出来说下!另外一个是如何响应Android的Menu菜单和Back返回事件的方法: 首先对于Cocos2dx中对于粒子自动释放的函数Himi这里给出,不少童鞋都在群里或者论坛

【ANDROID游戏开发之十】(优化处理)详细剖析ANDROID TRACEVIEW效率检视工具,分析程序运行速度!并讲解两种创建SDCARD方式!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/316.html ----------------------- 『很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块:请点击下面联系进入阅读:

【ANDROID游戏开发二十一】ANDROID OS设备谎言分辨率的解决方案!以及简单阐述游戏引擎如何使用!

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/356.html 刚才一群里的兄弟问的一问题,稍微研究下,这里一起分享:新建的Emulator -配置为:WAGA800  其分辨率是 800*480 的设备模拟器,当我们程序中在取得其 Height和 Width的时候发现,总是 320*533 ,明显是系统对我们撒了谎!如下图:   下面是官方文档原文: http

【ANDROID游戏开发之四】基础的ANDROID 游戏框架(一个游戏角色在屏幕行走的DEMO)

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/android-game/298.html ----------------------- 『很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块:请点击下面联系进入阅读: