Android游戏开发中绘制游戏触摸轨迹的曲线图

   本篇文章主要来讲解怎样绘制游戏触摸轨迹的曲线图。

       我们在onTouchEvent方法中,可以获取到触摸屏幕时手指触摸点的x、y坐标,如何用这些点形成一条无规则轨迹并把这条无规则轨迹曲线显示在屏幕上就是本篇文章的主旨内容。

       Android Path类

       Android提供了一个Path类 , 顾名思义这个类可以设置曲线路径轨迹。任何无规则的曲线实际上都是由若干条线段组成,而线段的定义为两点之间最短的一条线。path类就 可以记录这两点之间的轨迹,那么若干个Path 就是我们须要绘制的无规则曲线。

       下面介绍一下API 中path类设置轨迹路径的方法。

       public class

       Path
       extends Object
       java.lang.Object
       android.graphics.Path

       quadTo(float x1, float y1, float x2, float y2)
       Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2).

       解释:

       参数1 轨迹起始点X坐标

       参数2 轨迹起始点Y坐标

       参数3 轨迹结束点X坐标

       参数4 轨迹结束点Y坐标

       所以根据这个参数就可以设置一条线段轨迹。

       分步讲解

       为了设置一条比较圆滑好看的曲线我们需要对游戏画笔进行一些设置。注释已经在代码中写的很清楚了,在这里我详细说一下 设置画笔风格  mPaint.setStyle(Paint.Style.STROKE); 意思是设置画笔的风格 android 画笔一共提供了三种风格Paint.Style.STROKE 、Paint.Style.FILL、Paint.Style.FILL_AND_STROKE 意思分别为 空心 、实心、实心与空心 。如果不设置的话默认为 Paint.Style.FILL,在这里必须设置成空心。因为如果一旦设置成实心或者实心与空心那么画笔会把path路径中间包住这样就不是曲线线段了,所以大家注意一下这里。

Java代码

  1. /** 创建曲线画笔 **/  
  2. mPaint = new Paint();   
  3. mPaint.setColor(Color.BLACK);   
  4. /**设置画笔抗锯齿**/  
  5. mPaint.setAntiAlias(true);   
  6. /**画笔的类型**/  
  7. mPaint.setStyle(Paint.Style.STROKE);   
  8. /**设置画笔变为圆滑状**/  
  9. mPaint.setStrokeCap(Paint.Cap.ROUND);   
  10. /**设置线的宽度**/  
  11. mPaint.setStrokeWidth(5);  

       在触摸按下事件中 通过moveTo() 方法设置触摸屏幕点为轨迹的起始点,这样在触摸移动事件中设置曲线的轨迹 起始点为上次触摸点 结束点为本次触摸点。使用quadTo方法记录每次移动产生的一个曲线线段 然后将所有的曲线线段绘制在屏幕中,如果触摸抬起将调用reset()方法重置曲线轨迹。

Java代码

  1. @Override  
  2. public boolean onTouchEvent(MotionEvent event) {   
  3.     /** 拿到触摸的状态 **/  
  4.     int action = event.getAction();   
  5.     float x = event.getX();   
  6.     float y = event.getY();   
  7.     switch (action) {   
  8.     // 触摸按下的事件   
  9.     case MotionEvent.ACTION_DOWN:   
  10.     /**设置曲线轨迹起点 X Y坐标**/  
  11.     mPath.moveTo(x, y);   
  12.     break;   
  13.     // 触摸移动的事件   
  14.     case MotionEvent.ACTION_MOVE:   
  15.     /**设置曲线轨迹**/  
  16.     //参数1 起始点X坐标   
  17.     //参数2 起始点Y坐标   
  18.     //参数3 结束点X坐标   
  19.     //参数4 结束点Y坐标   
  20.     mPath.quadTo(mposX, mposY, x, y);   
  21.     break;   
  22.     // 触摸抬起的事件   
  23.     case MotionEvent.ACTION_UP:   
  24.     /**按键抬起后清空路径轨迹**/  
  25.     mPath.reset();   
  26.     break;   
  27.     }   
  28.    //记录当前触摸X Y坐标   
  29.     mposX = x;   
  30.     mposY = y;   
  31.     return true;   
  32. }   

      游戏绘制中调用drawPath方法将onTouchEvent中记录的路径曲线绘制在屏幕当中。

Java代码

  1. private void Draw() {   
  2.     /**清空画布**/  
  3.     mCanvas.drawColor(Color.WHITE);   
  4.     /**绘制曲线**/  
  5.     mCanvas.drawPath(mPath, mPaint);   
  6.     /**记录当前触点位置**/  
  7.     mCanvas.drawText("当前触笔 X:" + mposX, 0, 20,mTextPaint);   
  8.     mCanvas.drawText("当前触笔 Y:" + mposY, 0, 40,mTextPaint);   
  9. }  

       代码的整体实现

       详细的论坛注释已经在代码中写出 欢迎大家阅读喔 哇咔咔~~~~

Java代码

  1. import android.app.Activity;   
  2. import android.content.Context;   
  3. import android.graphics.Canvas;   
  4. import android.graphics.Color;   
  5. import android.graphics.Paint;   
  6. import android.graphics.Path;   
  7. import android.os.Bundle;   
  8. import android.view.MotionEvent;   
  9. import android.view.SurfaceHolder;   
  10. import android.view.SurfaceView;   
  11. import android.view.Window;   
  12. import android.view.WindowManager;   
  13. import android.view.SurfaceHolder.Callback;   
  14. public class SurfaceViewAcitvity extends Activity {   
  15.     MyView mAnimView = null;   
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState) {   
  18.     super.onCreate(savedInstanceState);   
  19.     // 全屏显示窗口   
  20.     requestWindowFeature(Window.FEATURE_NO_TITLE);   
  21.     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   
  22.         WindowManager.LayoutParams.FLAG_FULLSCREEN);   
  23.     // 显示自定义的游戏View   
  24.     mAnimView = new MyView(this);   
  25.     setContentView(mAnimView);   
  26.     }   
  27.     public class MyView extends SurfaceView implements Callback,Runnable {   
  28.      /**每50帧刷新一次屏幕**/  
  29.     public static final int TIME_IN_FRAME = 50;   
  30.     /** 游戏画笔 **/  
  31.     Paint mPaint = null;   
  32.     Paint mTextPaint = null;   
  33.     SurfaceHolder mSurfaceHolder = null;   
  34.     /** 控制游戏更新循环 **/  
  35.     boolean mRunning = false;   
  36.     /** 游戏画布 **/  
  37.     Canvas mCanvas = null;   
  38.     /**控制游戏循环**/  
  39.     boolean mIsRunning = false;   
  40.     /**曲线方向**/  
  41.     private Path mPath;   
  42.     private float mposX, mposY;   
  43.     public MyView(Context context) {   
  44.         super(context);   
  45.         /** 设置当前View拥有控制焦点 **/  
  46.         this.setFocusable(true);   
  47.         /** 设置当前View拥有触摸事件 **/  
  48.         this.setFocusableInTouchMode(true);   
  49.         /** 拿到SurfaceHolder对象 **/  
  50.         mSurfaceHolder = this.getHolder();   
  51.         /** 将mSurfaceHolder添加到Callback回调函数中 **/  
  52.         mSurfaceHolder.addCallback(this);   
  53.         /** 创建画布 **/  
  54.         mCanvas = new Canvas();   
  55.         /** 创建曲线画笔 **/  
  56.         mPaint = new Paint();   
  57.         mPaint.setColor(Color.BLACK);   
  58.         /**设置画笔抗锯齿**/  
  59.         mPaint.setAntiAlias(true);   
  60.         /**画笔的类型**/  
  61.         mPaint.setStyle(Paint.Style.STROKE);   
  62.         /**设置画笔变为圆滑状**/  
  63.         mPaint.setStrokeCap(Paint.Cap.ROUND);   
  64.         /**设置线的宽度**/  
  65.         mPaint.setStrokeWidth(5);   
  66.         /**创建路径对象**/  
  67.         mPath = new Path();   
  68.         /** 创建文字画笔 **/  
  69.         mTextPaint = new Paint();   
  70.         /**设置颜色**/  
  71.         mTextPaint.setColor(Color.BLACK);   
  72.         /**设置文字大小**/  
  73.         mTextPaint.setTextSize(15);   
  74.     }   
  75.     @Override  
  76.     public boolean onTouchEvent(MotionEvent event) {   
  77.         /** 拿到触摸的状态 **/  
  78.         int action = event.getAction();   
  79.         float x = event.getX();   
  80.         float y = event.getY();   
  81.         switch (action) {   
  82.         // 触摸按下的事件   
  83.         case MotionEvent.ACTION_DOWN:   
  84.         /**设置曲线轨迹起点 X Y坐标**/  
  85.         mPath.moveTo(x, y);   
  86.         break;   
  87.         // 触摸移动的事件   
  88.         case MotionEvent.ACTION_MOVE:   
  89.         /**设置曲线轨迹**/  
  90.         //参数1 起始点X坐标   
  91.         //参数2 起始点Y坐标   
  92.         //参数3 结束点X坐标   
  93.         //参数4 结束点Y坐标   
  94.         mPath.quadTo(mposX, mposY, x, y);   
  95.         break;   
  96.         // 触摸抬起的事件   
  97.         case MotionEvent.ACTION_UP:   
  98.         /**按键抬起后清空路径轨迹**/  
  99.         mPath.reset();   
  100.         break;   
  101.         }   
  102.        //记录当前触摸X Y坐标   
  103.         mposX = x;   
  104.         mposY = y;   
  105.         return true;   
  106.     }   
  107.     private void Draw() {   
  108.         /**清空画布**/  
  109.         mCanvas.drawColor(Color.WHITE);   
  110.         /**绘制曲线**/  
  111.         mCanvas.drawPath(mPath, mPaint);   
  112.         /**记录当前触点位置**/  
  113.         mCanvas.drawText("当前触笔 X:" + mposX, 0, 20,mTextPaint);   
  114.         mCanvas.drawText("当前触笔 Y:" + mposY, 0, 40,mTextPaint);   
  115.     }   
  116.     @Override  
  117.     public void surfaceChanged(SurfaceHolder holder, int format, int width,   
  118.         int height) {   
  119.     }   
  120.     @Override  
  121.     public void surfaceCreated(SurfaceHolder holder) {   
  122.         /**开始游戏主循环线程**/  
  123.         mIsRunning = true;   
  124.         new Thread(this).start();   
  125.     }   
  126.     @Override  
  127.     public void surfaceDestroyed(SurfaceHolder holder) {   
  128.         mIsRunning = false;   
  129.     }   
  130.     @Override  
  131.     public void run() {   
  132.         while (mIsRunning) {   
  133.         /** 取得更新游戏之前的时间 **/  
  134.         long startTime = System.currentTimeMillis();   
  135.         /** 在这里加上线程安全锁 **/  
  136.         synchronized (mSurfaceHolder) {   
  137.             /** 拿到当前画布 然后锁定 **/  
  138.             mCanvas = mSurfaceHolder.lockCanvas();   
  139.             Draw();   
  140.             /** 绘制结束后解锁显示在屏幕上 **/  
  141.             mSurfaceHolder.unlockCanvasAndPost(mCanvas);   
  142.         }   
  143.         /** 取得更新游戏结束的时间 **/  
  144.         long endTime = System.currentTimeMillis();   
  145.         /** 计算出游戏一次更新的毫秒数 **/  
  146.         int diffTime = (int) (endTime - startTime);   
  147.         /** 确保每次更新时间为50帧 **/  
  148.         while (diffTime <= TIME_IN_FRAME) {   
  149.             diffTime = (int) (System.currentTimeMillis() - startTime);   
  150.             /** 线程等待 **/  
  151.             Thread.yield();   
  152.         }   
  153.         }   
  154.     }   
  155.     }   
  156. }  

       看懂并掌握了这些代码实例后,相信大家对如何绘制游戏触摸轨迹的曲线图有了方法上的认识了,希望大家在Android游戏开发中自如的运用它们。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android 开发,我们可以使用 Kotlin 语言来绘制曲线图。下面是一个绘制曲线图的示例代码: ```kotlin class CurveActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_curve) val curveView = findViewById<CurveView>(R.id.curve_view) // 设置曲线数据 val data = listOf( Point(0f, 400f), Point(50f, 350f), Point(100f, 200f), Point(150f, 250f), Point(200f, 300f), Point(250f, 450f), Point(300f, 400f) ) curveView.setData(data) } } class CurveView(context: Context, attrs: AttributeSet) : View(context, attrs) { private val paint = Paint() private val path = Path() private var data: List<Point>? = null init { paint.color = Color.BLACK paint.style = Paint.Style.STROKE paint.strokeWidth = 5f } fun setData(data: List<Point>) { this.data = data invalidate() } override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) // 绘制坐标系 canvas?.drawLine(50f, 50f, 50f, height - 50f, paint) canvas?.drawLine(50f, height - 50f, width - 50f, height - 50f, paint) // 绘制曲线 data?.let { if (it.isNotEmpty()) { path.moveTo(it[0].x, it[0].y) for (i in 1 until it.size) { path.quadTo((it[i - 1].x + it[i].x) / 2, (it[i - 1].y + it[i].y) / 2, it[i].x, it[i].y) } canvas?.drawPath(path, paint) } } } } data class Point(val x: Float, val y: Float) ``` 在这个示例,我们首先在 CurveActivity 设置曲线数据,然后将数据传递给 CurveView 来绘制曲线。在 CurveView ,我们使用了 setData 方法来设置曲线数据,并在 onDraw 方法绘制了坐标系和曲线。其,我们使用了 Path 类来存储曲线的路径,使用 Canvas 的 drawPath 方法来绘制曲线。在绘制曲线时,我们使用了二次贝塞尔曲线来连接所有的数据点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值