android上使用贝塞尔曲线.docx
- 文档编号:9525214
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:14
- 大小:66.30KB
android上使用贝塞尔曲线.docx
《android上使用贝塞尔曲线.docx》由会员分享,可在线阅读,更多相关《android上使用贝塞尔曲线.docx(14页珍藏版)》请在冰豆网上搜索。
android上使用贝塞尔曲线
李华明Himi 原创,转载务必在明显处注明:
转载自【黑米GameDev街区】 原文链接:
很多童鞋说我的代码运行后,点击home或者back后会程序异常,如果你也这样遇到过,那么你肯定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的原因和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块;请点击下面联系进入阅读:
【Android游戏开发十九】(必看篇)SurfaceView运行机制详解—剖析Back与Home按键及切入后台等异常处理!
首先对于《赛贝尔曲线》不是很了解的童鞋,请自觉白度百科、google等等...
为了方便偷懒的童鞋,这里给个《贝赛尔曲线》百科地址,以及一段话简述《贝赛尔曲线》:
《贝赛尔曲线》白度百科快速地址:
贝塞尔曲线又称贝兹曲线或贝济埃曲线,一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋;
上面这一段话其实就“线段像可伸缩的皮筋”这一句比较重要,也很容易理解;
至于贝赛尔曲线的实现,在Android中极其的简单,因为它是Android封装的一个方法,这个能不简单么。
。
。
。
。
。
只不过它隐藏的比较深,它隐藏于Path类中,方法如下:
android.graphics.Path.quadTo(floatx1,floaty1,floatx2,floaty2)
Since:
APILevel1
此方参数解释:
第一个参数:
操作点的x坐标
第二个参数:
操作点的y坐标
第三个参数:
结束点的x坐标
第四个参数:
结束点的y坐标
从API中看出,赛贝尔曲线从API-1就开始支持了;
熟悉方法后,下面就来实现:
SurfaceView框架不多讲,看过我博客的都应该知道的;
直接看MySurfaceView类,此类继承SurfaceView,是游戏的主视图
这里为了更清晰的讲解:
这里部分代码先不贴出来了,最后会整体贴出,当然源码也是免费在最后提供~
首先是定义相关的成员变量:
[java:
showcolumns] viewplaincopy
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
1.// 贝赛尔曲线成员变量(起始点,控制(操作点),终止点,3点坐标)
2.private int startX, startY, controlX, controlY, endX, endY;
3.// Path
4.private Path path;
5.// 为了不影响主画笔,这里绘制贝赛尔曲线单独用一个新画笔
6.private Paint paintQ;
7.// 随机库(让贝赛尔曲线更明显)
8.private Random random;
本类构造函数:
[java:
showcolumns] viewplaincopy
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
1./**
2. * SurfaceView初始化函数
3. */
4.public MySurfaceView(Context context) {
5. super(context);
6. ...
7. //贝赛尔曲线相关初始化
8. path = new Path();
9. paintQ = new Paint();
10. paintQ.setAntiAlias(true);
11. paintQ.setStyle(Style.STROKE);
12. paintQ.setStrokeWidth(5);
13. paintQ.setColor(Color.WHITE);
14. random = new Random();
15. ...
16.}
接着我把绘制贝赛尔曲线封装一个方法了,函数如下:
[java:
showcolumns] viewplaincopy
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
1./**
2. * 绘制贝赛尔曲线
3. *
4. * @param canvas 主画布
5. */
6.public void drawQpath(Canvas canvas) {
7. path.reset();// 重置path
8. // 贝赛尔曲线的起始点
9. path.moveTo(startX, startY);
10. // 设置贝赛尔曲线的操作点以及终止点
11. path.quadTo(controlX, controlY, endX, endY);
12. // 绘制贝赛尔曲线(Path)
13. canvas.drawPath(path, paintQ);
14.}
最后是用户触屏监听函数以及逻辑函数:
[c-sharp:
showcolumns] viewplaincopy
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
1./**
2. * 触屏事件监听
3. */
4.@Override
5.public boolean onTouchEvent(MotionEvent event) {
6. endX = (int) event.getX();
7. endY = (int) event.getY();
8. return true;
9.}
10./**
11. * 游戏逻辑
12. */
13.private void logic() {
14. if (endX !
= 0 && endY !
= 0) {
15. // 设置操作点为线段x/y的一半
16. controlX = random.nextInt((endX - startX) / 2);
17. controlY = random.nextInt((endY - startY) / 2);
18. }
19.}
整个代码很easy~主要是贝赛尔函数的参数,尤其是操作点,操作点的各种不同可以实现不同的效果,这里我简单的统一的讲操作点设置成用户触屏点的x,y的一半,呵呵偷懒了~嘻嘻~
我把贝赛尔的操作点写在了逻辑logic()函数中,不断的执行,并且每次利用nextInt函数得到随机的操作点,主要为了让其曲线不断的变化从而形成一个震动的曲线运动轨迹;
ok,效果接图如下:
这里可能由于图片是静止的效果看起来不是很明显,大家可以运行源码来观察,好了~本节就这样吧;下面贴出整个MySurfaceView的源码:
(最后有本项目的源码下载地址)
[java:
showcolumns] viewplaincopy
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
1.package com.qpath;
2.import java.util.Random;
3.import android.content.Context;
4.import android.graphics.Canvas;
5.import android.graphics.Color;
6.import android.graphics.Paint;
7.import android.graphics.Paint.Style;
8.import android.graphics.Path;
9.import android.view.KeyEvent;
10.import android.view.MotionEvent;
11.import android.view.SurfaceHolder;
12.import android.view.SurfaceHolder.Callback;
13.import android.view.SurfaceView;
14./**
15. * 赛贝尔曲线
16. * @author Himi
17. *
18. */
19.public class MySurfaceView extends SurfaceView implements Callback, Runnable {
20. private SurfaceHolder sfh;
21. private Paint paint;
22. private Thread th;
23. private boolean flag;
24. private Canvas canvas;
25. public static int screenW, screenH;
26. // -----------以上是SurfaceView游戏框架
27. // 贝赛尔曲线成员变量(起始点,控制(操作点),终止点,3点坐标)
28. private int startX, startY, controlX, controlY, endX, endY;
29. // Path
30. private Path path;
31. // 为了不影响主画笔,这里绘制贝赛尔曲线单独用一个新画笔
32. private Paint paintQ;
33. // 随机库(让贝赛尔曲线更明显)
34. private Random random;
35. /**
36. * SurfaceView初始化函数
37. */
38. public MySurfaceView(Context context) {
39. super(context);
40. sfh = this.getHolder();
41. sfh.addCallback(this);
42. paint = new Paint();
43. paint.setColor(Color.WHITE);
44. paint.setAntiAlias(true);
45. setFocusable(true);
46. // -----------以上是SurfaceView游戏框架
47. //贝赛尔曲线相关初始化
48. path = new Path();
49. paintQ = new Paint();
50. paintQ.setAntiAlias(true);
51. paintQ.setStyle(Style.STROKE);
52. paintQ.setStrokeWidth(5);
53. paintQ.setColor(Color.WHITE);
54. random = new Random();
55. }
56. /**
57. * SurfaceView视图创建,响应此函数
58. */
59. public void surfaceCreated(SurfaceHolder holder) {
60. screenW = this.getWidth();
61. screenH = this.getHeight();
62. flag = true;
63. // 实例线程
64. th = new Thread(this);
65. // 启动线程
66. th.start();
67. // -----------以上是SurfaceView游戏框架
68. }
69. /**
70. * 游戏绘图
71. */
72. public void myDraw() {
73. try {
74. canvas = sfh.lockCanvas();
75. if (canvas !
= null) {
76. canvas.drawColor(Color.BLACK);
77. // -----------以上是SurfaceView游戏框架
78. drawQpath(canvas);
79. }
80. } catch (Exception e) {
81. // TODO:
handle exception
82. } finally {
83. if (canvas !
= null)
84. sfh.unlockCanvasAndPost(canvas);
85. }
86. }
87. /**
88. * 绘制贝赛尔曲线
89. *
90. * @param canvas 主画布
91. */
92. public void drawQpath(Canvas canvas) {
93. path.reset();// 重置path
94. // 贝赛尔曲线的起始点
95. path.moveTo(startX, startY);
96. // 设置贝赛尔曲线的操作点以及终止点
97. path.quadTo(controlX, controlY, endX, endY);
98. // 绘制贝赛尔曲线(Path)
99. canvas.drawPath(path, paintQ);
100. }
101. /**
102. * 触屏事件监听
103. */
104. @Override
105. public boolean onTouchEvent(MotionEvent event) {
106. endX = (int) event.getX();
107. endY = (int) event.getY();
108. return true;
109. }
110. /**
111. * 游戏逻辑
112. */
113. private void logic() {
114. if (endX !
= 0 && endY !
= 0) {
115. // 设置操作点为线段x/y的一半
116. controlX = random.nextInt((endX - startX) / 2);
117. controlY = random.nextInt((endY - startY) / 2);
118. }
119. }
120. /**
121. * 按键事件监听
122. */
123. @Override
124. public boolean onKeyDown(int keyCode, KeyEvent event) {
125. return super.onKeyDown(keyCode, event);
126. }
127. public void run() {
128. while (flag) {
129. long start = System.currentTimeMillis();
130. myDraw();
131. logic();
132. long end = System.currentTimeMillis();
133. try {
134. if (end - start < 50) {
135. Thread.sleep(50 - (end - start));
136. }
137. } catch (InterruptedException e) {
138. e.printStackTrace();
139. }
140. }
141. }
142. /**
143. * SurfaceView视图状态发生改变,响应此函数
144. */
145. public void surfaceChanged(SurfaceHolder holder, int format, int width,
146. int height) {
147. }
148. /**
149. * SurfaceView视图消亡时,响应此函数
150. */
151. public void surfaceDestroyed(SurfaceHolder holder) {
152. flag = false;
153. }
154.}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android 使用 贝塞尔 曲线
![提示](https://static.bdocx.com/images/bang_tan.gif)