Osmond?? 2016-07-27 01:38 采纳率: 0%
浏览 1047

怎样给三个大小不同圆加一个线速度,并且停止的时候会因为角速度的不同,停止的时间不一样

public class LuckyPanView extends SurfaceView implements Callback, Runnable
{
private SurfaceHolder mHolder; // SurfaceView是 SurfaceHolder对象完成的
private Canvas mCanvas; //与SurfaceHolder这个对象绑定的Canvas
private Thread t; //用于绘制的线程
private boolean isRunning; //线程的控制开关
private boolean rotateEnabled = false;
public RotateListener listern;
public String[] mStrs = new String[] { "0", "1", "2", "3", //转盘上的的数字
"4", "5","6","7","8","9" };
public int[] mColors = new int[] { 0xFFFFC300, 0xFFF17E01, 0xff00ffff, //每个盘块的颜色
0xFFFFA500, 0xFF7FFF00, 0xFFB0C4DE,0xFFF08080,0xFFB0E0E6, 0xFF444444,
0xFF008B8B, };
private int mItemCount = 10;//盘块的个数

private RectF mRange = new RectF();// 绘制盘块的范围
private RectF mRange1 = new RectF();
private RectF mRange2 = new RectF();

private float mRadius;//圆的半径
private float mRadius1;
private float mRadius2;

private Paint mArcPaint;//绘制盘块的画笔

private Paint mTextPaint;//绘制文字的画笔

private double mSpeed; //滚动的速度

private volatile float mStartAngle = 0;

private boolean isShouldEnd;//是否点击了停止

private int mPadding;  //控件的padding,


/**
 * 文字的大小
 */
private float mTextSize = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_SP, 15, getResources().getDisplayMetrics());

public LuckyPanView(Context context)
{
    this(context, null);//初始化,设置生命周期回调方法??
}

public LuckyPanView(Context context, AttributeSet attrs)//设置Surface生命周期回调
{
    super(context, attrs);
    mHolder = getHolder();
    mHolder.addCallback(this);//设置Surface生命周期回调

    setFocusable(true);
    setFocusableInTouchMode(true);
    this.setKeepScreenOn(true);

}

/**
 * 设置控件为正方形   View在屏幕上显示出来要先经过measure(计算)和layout(布局).
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)//调用onMeasure方法  然后传入两个参数——widthMeasureSpec和
// heightMeasureSpec 来确定占多大的地方
{
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);


    int width = Math.min(getMeasuredWidth(), getMeasuredHeight());
    //int width=width1/2;

    mRadius = (width - getPaddingLeft()+30 )/2;// 获取圆形的直径
    mRadius1 = (width - getPaddingLeft() - getPaddingRight())/4;
    mRadius2 = (width - getPaddingLeft() - getPaddingRight()+50)/6;

    mPadding = getPaddingLeft();// padding值
}

@Override
public void surfaceCreated(SurfaceHolder holder)
{
    // 初始化绘制圆弧的画笔
    mArcPaint = new Paint();
    mArcPaint.setAntiAlias(true);
    mArcPaint.setDither(true);
    // 初始化绘制文字的画笔
    mTextPaint = new Paint();
    mTextPaint.setColor(0xFFffffff);
    mTextPaint.setTextSize(mTextSize);
    // 圆的四个顶点绘制范围  虚拟机上的比例
     mRange = new RectF(getPaddingLeft()-35, getPaddingRight()-40, mRadius
            + getPaddingLeft()-35, mRadius + getPaddingLeft()-40);
    mRange1=new RectF(getPaddingLeft()+400, getPaddingRight()+590, mRadius1
            + getPaddingLeft()+400, mRadius1 + getPaddingLeft()+590);
    mRange2=new RectF(getPaddingLeft()+200, getPaddingRight()+595, mRadius2
            + getPaddingLeft()+200, mRadius2 + getPaddingLeft()+595);


    // 圆的四个顶点绘制范围
  /**  mRange = new RectF(getPaddingLeft()-35, getPaddingRight()-40, mRadius
            + getPaddingLeft()-35, mRadius + getPaddingLeft()-40);
    mRange1=new RectF(getPaddingLeft()+80, getPaddingRight()+800, mRadius1
            + getPaddingLeft()+80, mRadius1 + getPaddingLeft()+800);
    mRange2=new RectF(getPaddingLeft()+360, getPaddingRight()+460, mRadius2
            + getPaddingLeft()+360, mRadius2 + getPaddingLeft()+460);  **/

    // 开启线程
    isRunning = true;
    t = new Thread(this);
    t.start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,  //初始化了绘制需要用到的变量,
                           int height)
{

}

@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
    // 通知关闭线程
    isRunning = false;
}

@Override
public void run()
{
    // 不断的进行draw  控制转速
    while (isRunning)
    {
        long start = System.currentTimeMillis(); //System.currentTimeMillis(); 是获得当前时间 距离 起始时间的经过毫秒数
        draw();
        long end = System.currentTimeMillis();
        try
        {
            if (end - start < 50)//  数值越大 越慢
            {
                Thread.sleep(50- (end - start));
            }
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }

    }
}
private void draw()
{
    try
    {
        // 使用通过 mHolder.lockCanvas();获得Canvas,然后就可以绘制了
        mCanvas = mHolder.lockCanvas();
        if (mCanvas != null)
        {
            // 绘制背景图
            drawBg();
            /**
             * 绘制每个块块,每个块块上的文本,
             */
            float tmpAngle = mStartAngle;

            float sweepAngle = (float) (360 / mItemCount); //每一块的角度
            for (int i = 0; i < mItemCount; i++)
            {
                // 绘制块块
                mArcPaint.setColor(mColors[i]);
                //画扇形
                mCanvas.drawArc(mRange, tmpAngle, sweepAngle, true,
                        mArcPaint);
                mCanvas.drawArc(mRange1, tmpAngle, sweepAngle, true,
                        mArcPaint);
                mCanvas.drawArc(mRange2, tmpAngle, sweepAngle, true,
                        mArcPaint);
                // 绘制文本
                drawText(tmpAngle, sweepAngle, mStrs[i]);

                tmpAngle += sweepAngle;  //生成全部的扇形块
            }

            // 如果mSpeed不等于0,则相当于在滚动
            mStartAngle += mSpeed;

            // 点击停止时,设置mSpeed为递减,为0值转盘停止
            if (isShouldEnd)
            {
                mSpeed -= 1;
            }
            if (mSpeed <= 0)
            {
                mSpeed = 0;
                isShouldEnd = false;
            }
            // 根据当前旋转的mStartAngle计算当前滚动到的区域
            calInExactArea(mStartAngle);

        }
    } catch (Exception e)
    {
        e.printStackTrace();
    } finally
    {
        if (mCanvas != null)
            mHolder.unlockCanvasAndPost(mCanvas);
    }

}

/**
 * 根据当前旋转的mStartAngle计算当前滚动到的区域 绘制背景  绘制一个棕色的圆盘
 */
private void drawBg()
{
    mCanvas.drawColor(0xffccccc);  //背景灰色
}

/**
 * 根据当前旋转的mStartAngle计算当前滚动到的区域
 */
public void calInExactArea(float startAngle)
{
    // 让指针从水平向右开始计算
    float rotate = startAngle + 90;
    rotate %= 360.0;
    for (int i = 0; i < mItemCount; i++)  // for循环,且角度每次递增(360 / mItemCount);就是绘制每个盘块以及盘块上的字体和图标了。
    {
        // 每个的中奖范围
        float from = 360 - (i + 1) * (360 / mItemCount);
        float to = from + 360 - (i) * (360 / mItemCount);

        if ((rotate > from) && (rotate < to))
        {
            listern.showEndRotate(mStrs[i]);
            Log.d("TAG", mStrs[i]);
            return;
        }
    }
}

/**
 * 绘制文本
 *
 * @param startAngle
 * @param sweepAngle
 * @param string
 */
private void drawText(float startAngle, float sweepAngle, String string)
{
    Path path = new Path();
    path.addArc(mRange, startAngle, sweepAngle);//利用Path,添加入一个Arc,然后设置水平和垂直的偏移量,
    // 垂直偏移量就是当前Arc朝着圆心移动的距离;水平偏移量,就是顺时针去旋转
    Path path1 = new Path();
    path1.addArc(mRange1, startAngle, sweepAngle);

    Path path2 = new Path();
    path2.addArc(mRange2, startAngle, sweepAngle);

    float textWidth = mTextPaint.measureText(string);

    /*偏移 (mRadius * Math.PI / mItemCount / 2 - textWidth / 2);目的是为了文字居中。mRadius * Math.PI 是圆的周长;

周长/ mItemCount / 2 是每个Arc的一半的长度;拿Arc一半的长度减去textWidth / 2,就把文字设置居中了。最后,用过path去绘制文本 */

    float hOffset = (float) (mRadius * Math.PI / mItemCount / 2 - textWidth / 2);// 利用水平偏移让文字居中
    float vOffset = mRadius / 2 / 4;// 垂直偏移
    mCanvas.drawTextOnPath(string, path, hOffset, vOffset, mTextPaint);

    float hOffset1 = (float) (mRadius1 * Math.PI / mItemCount / 2 - textWidth/2 );// 利用水平偏移让文字居中
    float vOffset1= mRadius1 / 6;// 垂直偏移
    mCanvas.drawTextOnPath(string, path1, hOffset1, vOffset1, mTextPaint);

    float hOffset2 = (float) (mRadius2 * Math.PI / mItemCount / 2 - textWidth/2 );// 利用水平偏移让文字居中
    float vOffset2= mRadius2 / 6;// 垂直偏移
    mCanvas.drawTextOnPath(string, path2, hOffset2, vOffset2, mTextPaint);
}
public void setRotateListener(RotateListener ln) {
    listern = ln;
}

/**
 * 点击开始旋转
 *
 * @param luckyIndex
 */
public void luckyStart(int luckyIndex)
{
    // 每项角度大小
    float angle = (float) (360 / mItemCount);
    // 中奖角度范围(因为指针向上,所以水平第一项旋转到指针指向,需要旋转72-144;)
    float from = 144 - (luckyIndex + 1) * angle;

    float to = from + angle;
    // 停下来时旋转的距离
    float targetFrom = 2 *10 + from;//targetFrom是决定你点击停止的时候转多长距离 4圈多 多的用from和to调整
    float v1 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetFrom) - 1) / 2;
    float targetTo = 2 * 360 + to;
    float v2 = (float) (Math.sqrt(1 * 1 + 8 * 1 * targetTo) - 1) / 2;

    mSpeed = (float) (v1 + Math.random() * (v2 - v1));
    isShouldEnd = false;
}

public void luckyEnd()//让圆盘停止滚动
{
    mStartAngle = 0;

    isShouldEnd = true;
}

public boolean isStart()
{
    return mSpeed != 0;
}
public boolean isShouldEnd()
{
    return isShouldEnd;
}
public boolean isRotateEnabled() {
    return rotateEnabled;
}

}

  • 写回答

1条回答 默认 最新

报告相同问题?

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。