Android开发(14)-- 多线程中实现利用自定义控件绘制小球并完成小球自动下落的功能

android下写的小球下落的动画 这个资源是我参照《Android2.0游戏开发实战宝典》中的一个例子写的,但是这个例子有些错误,而且有些地方写的让人不太容易懂,针对这点我加以了改进和注释,希望新手能够更容易的理解android下的动画和游戏开发。以后我还会上传一些资料,希望大家多提宝贵意见,谢谢~~~ 立即下载

1、布局界面

  1. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:paddingBottom="@dimen/activity_vertical_margin"
  6. android:paddingLeft="@dimen/activity_horizontal_margin"
  7. android:paddingRight="@dimen/activity_horizontal_margin"
  8. android:paddingTop="@dimen/activity_vertical_margin"
  9. tools:context=".GameActivity">


  10. <www.youkuaiyun.com.tetris.view.GameView
  11. android:id="@+id/gameview"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"/>

  14. <Button
  15. android:id="@+id/btn_left"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:layout_alignLeft="@+id/gameview"
  19. android:layout_alignParentBottom="true"
  20. android:text="@string/btn_text"/>

  21. <Button
  22. android:id="@+id/btn_right"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:layout_alignBottom="@+id/gameview"
  26. android:layout_centerHorizontal="true"
  27. android:layout_alignParentBottom="true"
  28. android:text="@string/btn_right"/>



  29. </RelativeLayout>
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context=".GameActivity" >  
  10.   
  11.   
  12.     <www.youkuaiyun.com.tetris.view.GameView   
  13.         android:id="@+id/gameview"  
  14.         android:layout_width="wrap_content"  
  15.         android:layout_height="wrap_content"/>  
  16.   
  17.     <Button  
  18.         android:id="@+id/btn_left"  
  19.         android:layout_width="wrap_content"  
  20.         android:layout_height="wrap_content"  
  21.         android:layout_alignLeft="@+id/gameview"  
  22.         android:layout_alignParentBottom="true"  
  23.         android:text="@string/btn_text" />  
  24.   
  25.     <Button  
  26.         android:id="@+id/btn_right"  
  27.         android:layout_width="wrap_content"  
  28.         android:layout_height="wrap_content"  
  29.         android:layout_alignBottom="@+id/gameview"  
  30.         android:layout_centerHorizontal="true"  
  31.         android:layout_alignParentBottom="true"  
  32.         android:text="@string/btn_right" />  
  33.   
  34.       
  35.   
  36. </RelativeLayout>  


2、封装的一个绘制的图的类

  1. package www.youkuaiyun.com.tetris.domain;

  2. import www.youkuaiyun.com.tetris.view.GameView;

  3. public class Block {

  4. private int x=20,y=20;


  5. public GameView gameView;
  6. public Block(GameView gameView){
  7. this.gameView=gameView;
  8. }



  9. //向左移动
  10. public void moveLeft(){
  11. x-=10;
  12. gameView.invalidate();
  13. }

  14. //向右移动
  15. public void moveRight(){
  16. x+=10;
  17. gameView.invalidate();
  18. }

  19. //下落方法
  20. public void downLoad(){
  21. y+=10;
  22. gameView.invalidate();//重新绘制
  23. }

  24. public int getX() {
  25. return x;
  26. }

  27. public void setX(int x) {
  28. this.x = x;
  29. }

  30. public int getY() {
  31. return y;
  32. }

  33. public void setY(int y) {
  34. this.y = y;
  35. }


  36. }
  1. package www.youkuaiyun.com.tetris.domain;  
  2.   
  3. import www.youkuaiyun.com.tetris.view.GameView;  
  4.   
  5. public class Block {  
  6.   
  7.     private int x=20,y=20;  
  8.       
  9.       
  10.     public GameView gameView;  
  11.     public Block(GameView gameView){  
  12.         this.gameView=gameView;  
  13.     }  
  14.       
  15.       
  16.   
  17.     //向左移动  
  18.     public void moveLeft(){  
  19.         x-=10;  
  20.         gameView.invalidate();  
  21.     }  
  22.       
  23.     //向右移动  
  24.     public void moveRight(){  
  25.         x+=10;  
  26.         gameView.invalidate();  
  27.     }  
  28.       
  29.     //下落方法  
  30.         public void downLoad(){  
  31.             y+=10;  
  32.             gameView.invalidate();//重新绘制  
  33.         }  
  34.       
  35.     public int getX() {  
  36.         return x;  
  37.     }  
  38.   
  39.     public void setX(int x) {  
  40.         this.x = x;  
  41.     }  
  42.   
  43.     public int getY() {  
  44.         return y;  
  45.     }  
  46.   
  47.     public void setY(int y) {  
  48.         this.y = y;  
  49.     }  
  50.       
  51.       
  52. }  


3、创建一个画布和线程的操作

  1. package www.youkuaiyun.com.tetris.view;

  2. import android.content.Context;
  3. import android.graphics.Canvas;
  4. import android.graphics.Paint;
  5. import android.os.Handler;
  6. import android.os.Message;
  7. import android.util.AttributeSet;
  8. import android.view.View;
  9. import www.youkuaiyun.com.tetris.domain.Block;

  10. public class GameViewextends View {

  11. public static Block block;

  12. public Handler handler;
  13. //定义方向
  14. public staticint dir=-1;
  15. //上下左右
  16. public staticfinal int DIRUP=1;
  17. public staticfinal int DIRDOWN=2;
  18. public staticfinal int DIRLEFT=3;
  19. public staticfinal int DIRRIGHT=4;

  20. public GameView(Context context,AttributeSet attrs) {
  21. super(context);
  22. //创建俄罗斯方块对象
  23. this.block=new Block(this);


  24. handler=new Handler(){
  25. public void handleMessage(Message msg) {
  26. super.handleMessage(msg);
  27. switch (msg.what) {
  28. case DIRLEFT:
  29. GameView.block.moveLeft();
  30. break;
  31. case DIRRIGHT:
  32. GameView.block.moveRight();
  33. break;


  34. default:
  35. GameView.block.downLoad();
  36. break;
  37. }

  38. }
  39. };




  40. //创建线程
  41. new Thread (new Runnable(){

  42. @Override
  43. public void run() {
  44. while(true){
  45. try{
  46. System.out.println("子线程名称:::"+Thread.currentThread().getName());
  47. //block.downLoad();
  48. Thread.sleep(1000);
  49. handler.sendEmptyMessage(dir);
  50. }catch(Exception e){
  51. e.printStackTrace();
  52. }
  53. }

  54. }

  55. }).start();
  56. }

  57. @Override
  58. protected void onDraw(Canvas canvas) {

  59. super.onDraw(canvas);
  60. //设置了画布的颜色
  61. canvas.drawARGB(255, 0,0, 255);
  62. //设置一个画笔
  63. Paint paint=new Paint();
  64. paint.setARGB(255,255, 0,0);
  65. canvas.drawCircle(block.getX(), block.getY(), 10, paint);
  66. }

  67. }
  1. package www.youkuaiyun.com.tetris.view;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Paint;  
  6. import android.os.Handler;  
  7. import android.os.Message;  
  8. import android.util.AttributeSet;  
  9. import android.view.View;  
  10. import www.youkuaiyun.com.tetris.domain.Block;  
  11.   
  12. public class GameView extends View {  
  13.   
  14.     public static Block block;  
  15.       
  16.     public Handler handler;  
  17.     //定义方向  
  18.     public static  int dir=-1;  
  19.     //上下左右  
  20.     public static final int DIRUP=1;  
  21.     public static final int DIRDOWN=2;  
  22.     public static final int DIRLEFT=3;  
  23.     public static final int DIRRIGHT=4;  
  24.       
  25.     public GameView(Context context,AttributeSet attrs) {  
  26.         super(context);  
  27.         //创建俄罗斯方块对象  
  28.         this.block=new Block(this);  
  29.           
  30.           
  31.         handler=new Handler(){  
  32.             public void handleMessage(Message msg) {  
  33.                 super.handleMessage(msg);  
  34.                 switch (msg.what) {  
  35.                 case DIRLEFT:  
  36.                     GameView.block.moveLeft();  
  37.                     break;  
  38.                 case DIRRIGHT:  
  39.                     GameView.block.moveRight();  
  40.                     break;  
  41.                   
  42.                       
  43.                 default:  
  44.                     GameView.block.downLoad();  
  45.                     break;  
  46.                 }  
  47.   
  48.             }  
  49.         };  
  50.           
  51.           
  52.           
  53.           
  54.         //创建线程  
  55.         new Thread (new Runnable(){  
  56.   
  57.             @Override  
  58.             public void run() {  
  59.                 while(true){  
  60.                     try{  
  61.                         System.out.println("子线程名称:::"+Thread.currentThread().getName());  
  62.                         //block.downLoad();  
  63.                         Thread.sleep(1000);  
  64.                         handler.sendEmptyMessage(dir);  
  65.                     }catch(Exception e){  
  66.                         e.printStackTrace();  
  67.                     }  
  68.                 }  
  69.                   
  70.             }  
  71.               
  72.         }).start();  
  73.     }  
  74.   
  75.     @Override  
  76.     protected void onDraw(Canvas canvas) {  
  77.           
  78.         super.onDraw(canvas);  
  79.         //设置了画布的颜色  
  80.         canvas.drawARGB(255, 0, 0, 255);  
  81.         //设置一个画笔  
  82.         Paint paint=new Paint();  
  83.         paint.setARGB(255, 255, 0, 0);  
  84.         canvas.drawCircle(block.getX(), block.getY(), 10, paint);  
  85.     }  
  86.       
  87. }  


4、在MainActivity中的操作

  1. package com.example.tetris;



  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.os.Message;
  6. import android.view.Menu;
  7. import android.view.View;
  8. import android.widget.Button;
  9. import android.widget.Toast;
  10. import www.youkuaiyun.com.tetris.domain.Block;
  11. import www.youkuaiyun.com.tetris.view.GameView;


  12. public class GameActivityextends Activity {
  13. //声明按钮控件
  14. public Button btn_start;
  15. public Button btn_right;
  16. public Button btn_left;



  17. @Override
  18. protected void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.activity_game);
  21. //获取按钮控件
  22. btn_start=(Button) findViewById(R.id.btn_start);


  23. btn_start.setOnClickListener(new MyOnClickListener());
  24. System.out.println("主线程:::"+Thread.currentThread().getName());


  25. }

  26. @Override
  27. public boolean onCreateOptionsMenu(Menu menu) {
  28. // Inflate the menu; this adds items to the action bar if it is present.
  29. getMenuInflater().inflate(R.menu.main, menu);
  30. return true;
  31. }

  32. class MyOnClickListener implements View.OnClickListener{

  33. @Override
  34. public void onClick(View v) {
  35. int id=v.getId();
  36. switch (id) {
  37. case R.id.btn_start:
  38. //GameView gameView=new GameView(GameActivity.this,null);
  39. GameActivity.this.setContentView(R.layout.activity_layout);

  40. //获取控件
  41. btn_right=(Button) findViewById(R.id.btn_right);
  42. btn_left=(Button) findViewById(R.id.btn_left);

  43. btn_left.setOnClickListener(new MyOnClickListener());
  44. btn_right.setOnClickListener(new MyOnClickListener());


  45. break;
  46. case R.id.btn_left:
  47. Toast.makeText(GameActivity.this,"向左移动", Toast.LENGTH_LONG).show();
  48. GameView.block.moveLeft();
  49. //GameView.dir=GameView.DIRLEFT;
  50. break;
  51. case R.id.btn_right:
  52. Toast.makeText(GameActivity.this,"向右移动", Toast.LENGTH_LONG).show();
  53. GameView.block.moveRight();
  54. //GameView.dir=GameView.DIRRIGHT;
  55. break;

  56. default:
  57. break;
  58. }

  59. }

  60. }
  61. }

Android小球弹跳的例子 相信在看完这个例子之后,对你做运动的动画有很大的帮助! 立即下载

相关推荐

安卓android ui界面开发练习

通过这个简洁完整的例子,可以学习到android界面开发中很多的组件,如tabhost,listview,对话框,选项菜单,上下文菜单等等

pyqt5 自定义控件_PyQt5学习笔记(十二)多线程

多线程大一还没教到,咱也不敢瞎说。就谈谈本蒟蒻对多线程的一个直观的理解吧,可能会有贻笑大方之处,还请于评论区斧正,Thanks♪(・ω・)ノ(知道多线程的同学直接看下面的代码吧)。假设我们编写了一个图书管理系统(应该许多人都做过这个课设吧),为了防止电脑突然宕机,我们可能存在这样的一种需求:要求程序自运行开始,每隔一段时间可以自动保存文件(将文件缓冲区的内容写入静态存储区),但是我们的程序是死板的...

weixin_39784774的博客 376

Android开发之多线程中实现利用自定义控件绘制小球并完成小球自动下落功能实例

主要介绍了Android开发之多线程中实现利用自定义控件绘制小球并完成小球自动下落功能的方法,涉及Android多线程编程及图形绘制相关技巧,需要的朋友可以参考下

Android 属性动画:实现小球坠落

一、要做什么项目需要实现的效果:小球坠落 1. 首先绘制小球--自定义View 绘制圆; 2. 模拟小球坠落--属性动画,重绘小球轨迹; 3. 修改小球颜色--实现自定义TypeEvaluator; 实现的简单效果如下:二、思考怎么做实现步骤如下:1、自定义 AnimPointView:/** * Created by Troy on 2017/3/20. * * 通过对对象进行值操作来

happy_horse的博客 4879

科技中介服务机构想要提升服务效率,需要哪些数智工具支持?.docx

科技中介服务机构想要提升服务效率,需要哪些数智工具支持?

别再只测电压了!用STM32G474的ADC玩点花的:过采样提升精度与多通道扫描实战

本文深入探讨了STM32G474系列单片机的ADC高级应用,包括硬件过采样技术实现16位精度和多通道扫描结合DMA的自动数据采集方案。通过详细的配置步骤和实战案例,帮助开发者突破传统电压测量局限,提升信号采集精度和系统效率,适用于工业监控、医疗设备等高精度应用场景。

weixin_42647395的博客 240

android 雨松开发大合集

感谢雨松MOMOhttp://blog.youkuaiyun.com/xys289187120?viewmode=contents 1.Android软件开发之盘点所有Dialog对话框大合集(一) 2.Android软件开发之盘点自定义View界面大合集(二) 3.Android软件开发之盘...

94

别再纠结了!手把手教你根据项目需求选对目标检测框架(MMDetection/Detectron2/YOLOv8实战对比)

本文详细对比了三大目标检测框架MMDetection、Detectron2和YOLOv8的适用场景与实战技巧,帮助开发者根据项目需求精准选型。从毕业设计到工业落地,分析不同场景下的核心需求与框架优势,提供决策树和避坑指南,确保技术选型与项目目标高度匹配。

weixin_30342209的博客 554

多线程之小球的运动

多线程的学习如今做出了成果,便展示给大家 首先我们看一下效果图吧 小球运动,背景可以替换自己喜欢的图片,还有背景音乐,小球用图片来替换都很有趣! 听起来是不是有点花里胡哨,不过都只是看个人兴趣,选择自己喜欢的就是最好的。 再来看一下效果的实现 这些都是运动的小球,因为运用了随机数,颜色也是可以变化的 代码的编写用了四个类 ...

weixin_44655383的博客 802

jlink驱动安装

jlink驱动下载安装及keil识别

qq_43868701的博客 3万+

算法 | A*算法实现最优路径规划

启发式探索是利用问题拥有的启发信息来引导搜索,达到减少探索范围、降低问题复杂度的目的。A*寻路算法是启发式探索的一个典型实践,在寻路搜索的过程中,给每个节点绑定了一个估计值(即启发式),在对节点的遍历过程中采取估计值优先原则,估计值更优的节点会被优先遍历。...

不断学习,不断进步,提高自己 6630

java线程实现小球移动_java的Swing界面及多线程实现小球运动

这个程序是实现小球在swing界面运动的,具体的还是请读者自己将程序复制下来用java的IDE编译运行就知道了,多线程的实现用线程池实现,即ExecutorService和Executors.newFixedThreadPool()方法实现,可以用API文档来查看一下这具体的类,小球的控制部分完全由类Ball实现,这也是符合OOP的思想。添加小球于面板当中,在面板的按钮注册监听接口,实现对小球的行...

weixin_42382398的博客 1044

在 SAP 中,Primary Cost Element(初级成本要素)与Secondary Cost Element(次级成本要素)的核心区别、作用及业务含义可归纳如下

摘要:SAP中初级成本要素与次级成本要素的核心区别在于:初级要素必须关联FI模块的损益科目,直接影响财务报表,用于记录外部成本(如电费、薪酬);次级要素仅存在于CO模块,用于内部成本分配(如分摊、作业分配),不影响外部报表。初级要素是"外部成本入口",次级要素是"内部成本搬运工",二者共同实现成本的多维度追踪与管理。

金牌架构师 762

Java多线程实现同时进行小球的自由落体与平抛

Java多线程的实现方法有继承Thread和实现接口Runnable。我这里用的是通过实现接口Runnable来创建新线程的。 要实现自由落体与平抛。 首先,是小球在窗口中运动。将小球封装成一个类,继承Canvas。通过new小球的类,添加到窗口上。 运动的是不断的变化小球的位置,通过Sleep一小段时间。来实现动画的效果。 下面的是代码,有详细注释。 import java.a

XD 3783

在Android Jetpack Compose中实现夜间模式

Android基于Compose的深色主题实现

虎哥LoveDroid 1239

ADT MCP Server 把 ABAP 开发带进 Agent 模式

今天讨论 ADT MCP Server,不能只把它看成 Visual Studio Code 里多出来的一个开关。它真正有意思的地方,在于它把 ABAP 后端开发里那些原本需要手工点击、手工创建、手工激活、手工查服务元数据的动作,包装成一组可以被 GitHub Copilot 这类 coding agent 调用的工具。SAP 在 RAP130 练习里把它描述为运行在 ADT for Visual Studio Code 扩展内部的本地 HTTP Server,它实现的是 Model Context Pro

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 184

Android实现小球一直运动

private ObjectAnimator objectAnimator1; private ObjectAnimator objectAnimator2;private ObjectAnimator objectAnimator3;private ObjectAnimator objectAnimator4; 之前一直想着用死循环让动画一直运动,一点开始就崩溃; 只要是在最后一个而动

Happy_Develop_的专栏 2300

【硬件的单元测试 UT 3】PCIe 3.0及信号完整性测试方法

PCIe标准自从推出以来,1代和2代标准已经在PC和Server上逐渐普及,用于满足高速显卡、高速存储设备对于高速数据传输的要求。出于支持更高总线数据吞吐率的目的,PCI-SIG组织在2010年制定了PCIe 3.0,即PCIe 3代的规范,数据速率达到8Gbps。

qq_43416206的博客 1415

Android自定义组件系列【12】——非UI线程绘图SurfaceView

一、SurfaceView的介绍在前面我们已经会自定义View,使用canvas绘图,但是View的绘图机制存在一些缺陷。1、View缺乏双缓冲机制。2、程序必须重绘整个View上显示的图片,比较耗资源。3、非UI线程无法更新View组件,所以会占用主线程资源,当需要在主线程中处理逻辑的时候会很慢。在Android中为我们提供了一个SurfaceView来替代View实现绘制图形,一般在游戏绘图方

水寒 4499

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

android 使用SurfaceView实现小球高处落下并弹起的效果

用腾讯手机管家截的动态gif图片效果很不好,程序运行的效果要比这个好多了。 此程序是在《android游戏开发大全》第7章第2节案例的基础上做的改进 源码地址:http://download.youkuaiyun.com/detail/centralperk/5177413

Central-Perk的专栏 3521

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: Android开发(13)-- 互联网访问图片,在android客户端显示
下一篇: Android开发(15)-TextView显示丰富的文本
liu_yaoyang
博客等级 码龄19年 5粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值