canvas应用之各种游戏转盘
canvas应用之各种游戏转盘
angle :角度
所以由角度变成弧度,再变成余弦值:
double radians = Math.toRadians(30 + startAngle);
float cos = (float) (Math.cos(radians) * r + r);
也就是:double cos = (Math.cos(Math.toRadians(startAngle);
注意:只有变为弧度后才能使用Math.cos(),求余弦值,切记,切记;
还有手机屏幕坐标系与数学坐标系是不同的哦:
0--------------------------->X轴| 1 2 3 4|1|| 坐标一区|2||3|VY轴
RectF rectF = new RectF(float left, float top, float right, float bottom);
rectF中的参数理解:左:左边线的X坐标值;上:上边线的Y坐标值;右:右边线的X坐标值;下:下边线的Y坐标值;
扇形圆弧的绘制:
canvas.drawArc(RectF rectF, float startAngle, float sweepAngle, boolean useCenter,Paint paint);
其会根据rectF中给的四个坐标,自动确定圆心点坐标,然后再根据 startAngle设置弧线的起始线位置, startAngle=0起点是x轴正方向,sweepAngle是绘制弧线的角度,若sweepAngle为正则逆时针绘制弧线,sweepAngle为负数则顺时针绘制弧线(注意使用数学极坐标方式),useCenter表示是否使用中心;
p.setTypeface( font );
而mCanvas.drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset,float vOffset, @NonNull Paint paint);文字会根据路径path的绘制方向,而随之改变文字的显示方向;hOffset表示"path的前端"处空出来的空间大小(值为正则增大间隙空间,负值则反向减小空间),vOffset表示"path垂直"方向偏移的大小(正值向内偏移,负值向外偏移);
对于旋转绘制问题,有两种方式:
方式一:
mCanvas.drawText(@NonNull String text, float x, float y, @NonNull Paint paint);
mCanvas.rotate(everyAngle ,r,r); //替换方式1:旋转的是带有文字的“纸——mCanvas”,此时笔(View的坐 标)是不动的
方式二:
for (int i = 0; i < size; i++) {
drawText(InitAngle + 3*halfAngle, strs[i],radius, textPaint, canvas, rectF);
InitAngle += everyAngle; //替换方式2:以改变绘制的角度来实现旋转绘制
}
两种方式的区别:
@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);final int paddingLeft = getPaddingLeft();final int paddingRight = getPaddingRight();final int paddingTop = getPaddingTop();final int paddingBottom = getPaddingBottom();int width = getWidth() - paddingLeft - paddingRight;int height = getHeight() - paddingTop - paddingBottom;int MinValue = Math.min(width, height);radius = MinValue / 2;RectF rectF = new RectF(getPaddingLeft(), getPaddingTop(), width, height);float angle = InitAngle; //这里的扇形背景与文字或图片需要相差30度,因为文字和图片要在30度角处(背景中间处)显示//扇形背景绘制for (int i = 0; i < size; i++) {if (i % 2 == 0) {canvas.drawArc(rectF, angle, everyAngle, true, dPaint);} else {canvas.drawArc(rectF, angle, everyAngle, true, sPaint);}angle += everyAngle;}//图片和文字绘制for (int i = 0; i < size; i++) {//在此处加3*halfAngle只是为了显示正确,这和直接给InitAngle赋值决定pos是不一样的
// drawIcon(width / 2, height / 2, radius, InitAngle + 3*halfAngle, i, canvas);drawText(InitAngle + everyAngle, strs[i], radius, textPaint, canvas, rectF);InitAngle += everyAngle; //方式1:以改变绘制的角度来实现旋转绘制,可用方式1替换}}
drawText代码:
private void drawText(float startAngle, String string, int r, Paint mTextPaint, Canvas mCanvas, RectF mRange) {/************************************* 1 文字圆弧状显示 *********************************/
//设计思路:沿着弧线方向对字符串进行绘制,注意textPaint.setTextAlign(Paint.Align.CENTER);设定的绘制的起始位置值,这里字间距没办法修改Path path = new Path();path.addArc(mRange, startAngle, everyAngle); //startAngle就决定了初始位置
// mTextPaint.setTextAlign(Paint.Align.LEFT);
// float textWidth = mTextPaint.measureText(string);
// //文字水平偏移量,偏移到扇形中间位置(作用与textPaint.setTextAlign(Paint.Align.CENTER)等同)
// float hOffset = (float) (r * Math.PI / size - textWidth / 2);float vOffset = r / 4;mTextPaint.setTypeface(Typeface.create(Typeface.MONOSPACE, Typeface.NORMAL)); //字体设置mCanvas.drawTextOnPath(string, path, 0, vOffset, mTextPaint);}
drawIcon代码:
private void drawIcon(int xx, int yy, int mRadius, float startAngle, int i, Canvas mCanvas) {int imgWidth = mRadius / 4;float angle = (float) Math.toRadians(startAngle);float x = (float) (xx + mRadius / 2 * Math.cos(angle));float y = (float) (yy + mRadius / 2 * Math.sin(angle));// 确定绘制图片的位置RectF rect = new RectF(x - imgWidth * 3 / 4, y - imgWidth * 3 / 4, x + imgWidth* 3 / 4, y + imgWidth * 3 / 4);Bitmap bitmap = bitmaps.get(i);mCanvas.drawBitmap(bitmap, null, rect, null);}
/********************************* 2 文字横扫同向模式 ********************************/
//设计思路:采用直线型路径path由中心向外绘制每个字符串,字符串首字符与圆心距离用转盘内部小同心圆的半径作为限定, path的两个点坐标可由两圆半径算得//使文字竖着摆放显示,(但文字方向有点问题)mTextPaint.setTextAlign(Paint.Align.CENTER);Rect bounds = new Rect();mTextPaint.getTextBounds(string,0,1,bounds);int wordHeight = bounds.height();Path path1 = new Path();//分别计算x,y初始的坐标double radians = Math.toRadians(startAngle + halfAngle); //startAngle的正负决定旋转方向,负为顺时针旋转 halfAngle为调整位置显示值float bigX = (float) (Math.cos(radians) * r + r);//大圆坐标,此固定值在开发时不需要放到循环中float bigY = r + (float) Math.sin(radians) * r;double cos = Math.cos(radians);double sin = Math.sin(radians);float smallR = r/3; //内圆半径,也是字符串与圆心的距离//内部小圆x,y坐标float smallX = (float)(cos * smallR + r); //小圆坐标float smallY = (float) (sin * smallR + r);//采用从圆心向外发射画法
// path1.moveTo(bigX,bigY); //采用直线路径法绘制文字,这里的hOffset1代表也可称为文字竖直偏移量
// path1.lineTo(smallX,smallY);path1.moveTo(smallX,smallY); //设置文字显示方向倒转path1.lineTo(bigX,bigY);mCanvas.drawTextOnPath(string, path1, 0, wordHeight/2, mTextPaint);
/********************************** 3 文字横扫多变模式或多状态显示 ******************************/
//设计思路:通过给转盘添加同心小圆的方式,确定一条字符串的首个字符位置(以具体坐标定位),其他字符则根据手字符进行适当偏移生成//该方式文字竖直显示1,但英文显示会有问题Rect bounds = new Rect();mTextPaint.getTextBounds(string.substring(0, 1), 0, 1, bounds);int wordHeight = bounds.height() + 20; //增大字间距mTextPaint.setTextAlign(Paint.Align.CENTER);if (isClicked) {du = halfAngle; //du决定整体文字朝向,就是以该角度处的文字样式为模板,然后偏移到别的地方,就像是在固定一个地方写字,人不动而纸动}double radians = Math.toRadians(startAngle + du); //startAngle的正负决定旋转方向,负为顺时针旋转double cos = Math.cos(radians);double sin = Math.sin(radians);float smallR = r/3;//内部小圆x,y坐标float x = (float)(cos * smallR + r);float y = (float) (sin * smallR + r);//采用从圆心向外发射画法for (int j = string.length()-1;j >=0 ;j--) { //从后往前取文字,文字汇聚式阅读mCanvas.drawText(string.substring(j, j + 1), (float) (x + wordHeight * cos * (string.length() - j)), (float) (y + wordHeight * sin * (string.length() - j)), textPaint);}
//方式2:旋转的是带有文字的“纸——mCanvas”,此时笔(View的坐标)是不动的,可替换换方式1处代码
// mCanvas.rotate(everyAngle ,r,r);
/************************************************* 4 文字发射状显示 ************************************************************/
//设计思路:采用每个字符串使用一个圆弧,并且每个圆弧都只放一个文字,该字符串的其他文字则根据该文字进行相对位置平移生成Path path = new Path();path.addArc(mRange, startAngle, everyAngle); //startAngle决定了绘制的初始位置,该位置的值可调整以适应扇形背景区域Rect bounds = new Rect();//此固定值在开发时不需要放到循环中mTextPaint.getTextBounds(string.substring(0, 1), 0, 1, bounds);//14是增加的字间距,因为中英文的文字高度不同,会导致显示效果不均一,这里可以用定值替代int wordHeight = bounds.height() + 14;//因绘制文字采用的是由中心向四周发射方式,此处指定vOffset相对path垂直向内偏移量(包括字间距)int i = 6;//为了使每串字符串都与圆心保持相同距离,此处采用倒序绘制文字for (int j = string.length() - 1; j >= 0; j--) {//若hOffset和vOffset都为0时,该方法会让文字沿着Path路径绘制文本,hOffset参数指定相对path水平偏移,hOffset值为正数则向path正方向偏移,vOffset指定相对path垂直偏移,若vOffset值为正则向下向内偏移;mCanvas.drawTextOnPath(string.substring(j, j + 1), path,0, wordHeight * i--, textPaint);}
// mCanvas.rotate(everyAngle ,r,r); //用于替代InitAngle += everyAngle;的第二种实现方式}
关键要看需求中文字的显示方向和方式都是什么样的,当然大家要是有好的实现和例子可以告诉我哦!
最后附上git上的项目地址:点 我!
canvas应用之各种游戏转盘相关推荐
- php 设计五子棋游戏,基于js+canvas实现五子棋小游戏
本文实例为大家分享了js+canvas实现五子棋小游戏的具体代码,供大家参考,具体内容如下 效果展示: 源码展示: 五子棋 * { margin: 0; padding: 0; } body { ma ...
- 使用jquery—Canvas实现html5小游戏——《坦克大战》
目录 1.项目背景 2.项目展示 3.设计思路 3.1.坦克移动 3.2.坦克开火 3.3.击中坦克 4.实现代码 5.总结 1.项目背景 2021年春节期间在家无聊,正好又学过一些前端的知识,因此就 ...
- canvas刮刮卡游戏开发
canvas刮刮卡游戏开发 先看效果: 一.基础知识-画布元素的使用 1 绘制线条 思路 在页面中添加画布元素 获取画布元素的上下文环境对象 使用上下文环境对象绘制图形,保存在内存中 绘制一个线条 / ...
- 用canvas整个打飞机游戏
之前在当耐特的DEMO里看到个打飞机的游戏,然后就把他的图片和音频扒了了下来....自己凭着玩的心情重新写了一个.仅供娱乐哈......我没有用框架,所有js都是自己写的......所以就可以来当个简 ...
- JavaScript+ Canvas开发趣味小游戏《贪吃蛇》
一.效果展示 二.<贪吃蛇>基本实现思路 蛇头部分+蛇身体部分:采用对象形式来存储坐标,并将每个坐标对象放到一个snake数组中,方便使用.设置每个方格宽度30px,高度30px,画布高度 ...
- canvas 绘制贪吃蛇游戏
效果如下 代码 <!DOCTYPE html> <html lang="zh_CN"> <head><meta charset=" ...
- HTML5 Canvas 射击类小游戏 平滑的移动 思路
这篇博客主要讲了如何处理HTML5 Canvas 游戏中的角色移动问题. 笔者这几天做了一个 HTML5 Canvas 的射击类小游戏,嗯,名字叫做<DroppingBalls>,大概就是 ...
- html打飞机游戏代码,利用HTML5 Canvas实现打飞机游戏
这篇文章主要介绍了利用HTML5 Canvas制作一个简单的打飞机游戏,作者也给出了相关的Javascript代码,需要的朋友可以参考下 之前在当耐特的DEMO里看到个打飞机的游戏,然后就把他的图片和 ...
- canvas + JavaScript实现幸运大转盘
HTML代码: <!doctype html> <html> <head> <meta charset="utf-8"> <t ...
- html中canvas动画游戏显示,【Fes】基于canvas的前端动画/游戏入门(一)
前言 本系列虽说是基础教程,但这是相对动画/游戏领域来说,在前端领域算是中级教程了,不适合前端小白或萌新.阅读前请确保自己对前端三大件(JavaScript+CSS+HTML)的基础已经十分熟悉,而且 ...
最新文章
- 面试官:精通 Mybatis?请回答下这几个问题
- 嵌入式成长轨迹11 【嵌入式环境及基础】【Linux shell深入】【深入讨论】
- 八十六、从拓扑排序探究有向图
- javajs ---- 判断字符串中是否包含子串
- oracle滚动统计,sql – 按月滚动或运行Oracle总计
- vs2015安装vax助手
- Swarm创始人:强调BZZ主网上线不需要质押
- 你应该懂得的关于电脑配置冷知识
- 爬虫 and 数据分析 | 一万条b站评论看工作细胞
- Chromium内核和Webkit的关系到底是什么?
- 华为光纤猫HG8240破解,开启路由功能表
- C# 后台GC 的前因后果
- 数据分析:当回音哥唱music时,他在唱些什么~~~
- InnoDB Persistent Statistics问题
- 搭建网站用虚拟主机好还是云服务器好?
- tiny4412 裸机程序 八、重定位到DRAM及LCD实验
- 日语在线翻译网站大全
- Swiper轮播图插件之如何修改前进后退按钮swiper-button-prev和swiper-button-next的默认样式
- 4月10日服务器例行维护公告,4月10日服务器例行维护公告
- 2017年8月23日 星期三 --出埃及记 Exodus 29:2
热门文章
- DXperience12.2入门设置以及应用教程
- 源码多多- Discuz x2.5 版块的常用设置方法和技巧
- 操作系统实验及代码(全)
- 计算机毕业设计之答辩
- 固态硬盘在线测试软件,SSD检测工具(SSDlife Pro)
- CMM3 正式评估全过程
- c语言设计一个自动阅卷功能,程序阅卷论文,关于编程题自动阅卷系统的设计实现相关参考文献资料-免费论文范文...
- 二、Json对象、Json数组和Json字符串
- 孩子学Java编程_7个最适合儿童学习编程的应用程序(上)
- Eclipse安装SVN插件的方法