Android应用程序入门 推箱子游戏开发(一) surfaceView 实现动画效果

Android学习笔记:使用SurfaceView制作简单游戏(1) Android上制作个小游戏《潜艇大战》,使用SurfaceView实现 阅读详情
        SurfaceView是View的子类,常用于实现游戏中的动画效果。SurfaceView最大的特点就是:从主线程中,把具体的绘图线程独立出来。这样做的好处在于:当绘图任务比较繁重时,避免主线程的阻塞,从而提高主线程的反应速度。

        废话少说,言归正传,下面用几个例子说明surfaceview的使用。

 

(一) 基本功能:用SurfaceView显示一副背景图片。 运行后的效果很简单,就是在屏幕上显示一副图片。 

package com.pushBox;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class PushBoxActivity extends Activity {
	//欢迎界面
	WelcomeView welcomeView = null;	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        //显示欢迎界面
        welcomeView = new WelcomeView( this );        
        setContentView( welcomeView ); 
    }
    
    //内部类,欢迎界面
    class WelcomeView extends SurfaceView implements SurfaceHolder.Callback
    {
    	private SurfaceHolder holder;    
    	private WelcomeViewDrawThread welcomeViewDrawThread;
    	//背景图片,大小640 * 480
    	Bitmap background;
    	
    	//图片显示的位置
    	int backgroundX = 0;
    	int backgroundY = 0;
    	
    	public WelcomeView( Context context )
    	{
    		super( context );    		
    		holder = this.getHolder();
    		holder.addCallback( this );    		
    		background = BitmapFactory.decodeResource( getResources(), R.drawable.background );
    		//创建一个绘图线程
    		welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder );
    	}
    	
    	//自定义的绘图函数,具体的绘图在这里完成
    	public void onDraw( Canvas c )
    	{
    		c.drawBitmap( background, backgroundX, backgroundY, null );    		
    	}
    	
    	@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			// TODO Auto-generated method stub			
		}
		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			// TODO Auto-generated method stub
			//启动绘图线程
			welcomeViewDrawThread.setFlag( true );
			welcomeViewDrawThread.start();
		}
		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			// TODO Auto-generated method stub
			welcomeViewDrawThread.setFlag( false );
		}
    }    
        
    //内部类,欢迎界面的绘图线程
    class WelcomeViewDrawThread extends Thread
    {
    	private WelcomeView welcomeView;
    	private SurfaceHolder holder;
    	private boolean isRun;  
    	private int sleepSpan = 200;
    	
    	public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder )
    	{
    		this.welcomeView = welcomeView;
    		this.holder = holder;
    		isRun = true;
    	}
    	public void setFlag( boolean flag )
    	{
    		isRun = flag;
    	}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while( isRun )
			{
				Canvas c = null;
				try
				{
					c = holder.lockCanvas();
					synchronized( holder )
					{
						//调用绘图函数
						welcomeView.onDraw( c );						
					}
				}finally
				{
					if( c != null )
					{
						holder.unlockCanvasAndPost( c );
					}
				}
				
				try{
					//睡眠200毫秒
					Thread.sleep( sleepSpan );
				}
				catch(Exception e){
					e.printStackTrace();
				}
			}
		}    	
    }
}


(二) 初露锋芒:用SurfaceView显示一个动态打开的门。运行后的效果,左右两扇门缓缓打开。     

        如果只用SurfaceView显示一副背景图片,那绝对是“大炮打蚊子”------大材小用。从主线程中拉出一个单独的线程,就是为了处理动态效果。这里具体实现的时候有两个线程:welcomeViewGoThread和welcomeViewDrawThread。welcomeViewGoThread只负责修改图片显示的坐标,welcomeViewDrawThread负责在具体的位置显示图片。这种进一步分离,使得各模块的功能更加独立和明确。

package com.pushBox;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class PushBoxActivity extends Activity {
	//欢迎界面
	WelcomeView welcomeView = null;	
	//欢迎界面的动画线程
	WelcomeViewGoThread welcomeViewGoThread = null;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        //显示欢迎界面
        welcomeView = new WelcomeView( this );        
        setContentView( welcomeView ); 
        welcomeViewGoThread = new WelcomeViewGoThread( welcomeView );
        //启动动画线程
        welcomeViewGoThread.start();
    }
    
    //内部类,欢迎界面
    class WelcomeView extends SurfaceView implements SurfaceHolder.Callback
    {
    	private SurfaceHolder holder;    
    	private WelcomeViewDrawThread welcomeViewDrawThread;
    	//背景图片,大小640 * 480
    	Bitmap background;
    	//左边的木门,大小180 * 450
    	Bitmap leftWood;
    	Bitmap rightWood;
    	
    	//图片显示的位置
    	int backgroundX = 0;
    	int backgroundY = 0;
    	int leftWoodX = 10;
    	int leftWoodY = 15;
    	int rightWoodX = 150;
    	int rightWoodY = 15;
    	
    	public WelcomeView( Context context )
    	{
    		super( context );    		
    		holder = this.getHolder();
    		holder.addCallback( this );    		
    		background = BitmapFactory.decodeResource( getResources(), R.drawable.background );
    		leftWood = BitmapFactory.decodeResource( getResources(), R.drawable.image33 );
    		rightWood = BitmapFactory.decodeResource( getResources(), R.drawable.image3 );
    		
    		//创建一个绘图线程
    		welcomeViewDrawThread = new WelcomeViewDrawThread( this, holder );
    	}
    	
    	//自定义的绘图函数,具体的绘图在这里完成
    	public void onDraw( Canvas c )
    	{
    		c.drawBitmap( background, backgroundX, backgroundY, null );  
    		c.drawBitmap( leftWood, leftWoodX, leftWoodY, null ); 
    		c.drawBitmap( rightWood, rightWoodX, rightWoodY, null ); 
    	}
    	
    	@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			// TODO Auto-generated method stub			
		}
		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			// TODO Auto-generated method stub
			//启动绘图线程
			welcomeViewDrawThread.setFlag( true );
			welcomeViewDrawThread.start();
		}
		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			// TODO Auto-generated method stub
			welcomeViewDrawThread.setFlag( false );
		}
    } 
    
    //内部类,欢迎界面的动画线程,只修改坐标,不负责具体显示
    class WelcomeViewGoThread extends Thread
    {
    	private WelcomeView welcomeView;
    	private int sleepSpan = 200;
    	private boolean isRun;
    	
    	public WelcomeViewGoThread( WelcomeView welcomeView )
    	{
    		this.welcomeView = welcomeView;
    		isRun = true;
    	}
    	public void setFlag( boolean flag )
    	{
    		isRun = flag;
    	}
    	
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		while( isRun )
    		{
    			// 修改木门坐标
    			welcomeView.leftWoodX -= 2;
    			welcomeView.rightWoodX += 2;
    			if( welcomeView.leftWoodX < -90 )
    			{
    				welcomeView.leftWoodX = 10;
        			welcomeView.rightWoodX = 150;
    			}    			
    			try{
    				//睡眠200毫秒
    				Thread.sleep( sleepSpan );
    			}
    			catch(Exception e){
    				e.printStackTrace();
    			}
    		}
    	}    	
    }
        
    //内部类,欢迎界面的绘图线程
    class WelcomeViewDrawThread extends Thread
    {
    	private WelcomeView welcomeView;
    	private SurfaceHolder holder;
    	private boolean isRun;  
    	private int sleepSpan = 200;
    	
    	public WelcomeViewDrawThread( WelcomeView welcomeView, SurfaceHolder holder )
    	{
    		this.welcomeView = welcomeView;
    		this.holder = holder;
    		isRun = true;
    	}
    	public void setFlag( boolean flag )
    	{
    		isRun = flag;
    	}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while( isRun )
			{
				Canvas c = null;
				try
				{
					c = holder.lockCanvas();
					synchronized( holder )
					{
						//调用绘图函数
						welcomeView.onDraw( c );						
					}
				}finally
				{
					if( c != null )
					{
						holder.unlockCanvasAndPost( c );
					}
				}
				
				try{
					//睡眠200毫秒
					Thread.sleep( sleepSpan );
				}
				catch(Exception e){
					e.printStackTrace();
				}
			}
		}    	
    }
}

(三) 脱胎换骨:修改程序框架。

           上述的程序框架有问题,所有代码都放在一个文件里。下面要做的就是把相关的class都独立出来。代码改起来也很简单,只要把几个内部类单独写到一个文件即可。

(四) 重出江湖:用SurfaceView实现一个完整的欢迎界面


 

Android游戏开发:使用AnimationDrawable实现动画 在上述示例中,我们通过findViewById()方法获取到ImageView的实例,并将其转换为AnimationDrawable类型。如果你需要控制动画的播放和停止,可以使用AnimationDrawable的start()、stop()和isRunning()方法。在上述代码中,我们指定了ImageView的id为"animationImageView",并将src属性设置为之前创建的AnimationDrawable资源文件。接下来,在布局文件中添加个ImageView,用于显示帧动画效果 阅读详情

相关推荐

lammps教程:实例讲解npt、nvt系综的选择

对于lammps新手来说,系综的选择令人困惑,到底是应该用nvt系综还是npt系综? 我在初学lammps时就被这个问题困扰了很久。如果去问别人,可能会告诉你个答案:根据模拟需要确定。 其实和没说样。 到底如何确定系综,确实不是句两句能够说清楚的,不同的体系、不同的模拟目的要选择不同的系综。 前几天遇到的个合金的模拟案例,比较有代表性,分享出来供大家参考。 建模方法和之前介绍过的高熵合金建模方法类似,先建立单晶模型,然后使用替换原子的命令获得合金结构。 建模完成后,按照常规,先上nvt系综进行驰豫

lammps_jiayou的博客 9744

Android 超实用的开关特效

自定义开关,类似小米4.0.x上面的开关效果,如飞行模式开关。USB开关。里面包含了动画效果代码,监听器的高级使用代码。以及自定义组件的状态判断。类似mars的mp3里面的部分判断。

AgentScope Java 2.0 项目实战: 从零构建自己的个人AI助手“小龙虾“

本文系统介绍如何基于Spring Boot WebFlux、React 18和TypeScript,从零搭建个本地化的个人AI助手管理平台——AgentScope Paw。项目支持多Agent创建与管理、SSE流式对话、工作区文件CRUD、技能市场、子智能体孵化、AI辅助起草Agent配置等核心功能,并深度集成钉钉、企业微信、飞书、GitHub等IM通道。

program哲学 1302

Android---SurfaceView(使游戏主角动起来)

新建两个类,个继承Activity,个继承SurfaceView实现SurfaceHolder.Callback和Runnable接口, 将要实现动画效果的图片放到drawable中,我这里图片命名是以fish 开头的   SurfaceView 实现绘图的过程: 1.getHolder():得到这个SurfaceView的SurfaceHolder对象holder 2.holde

zlQQhs(莫落)的专栏 1221

android人物移动设计软件,实现SurfaceView上移动游戏人物

首先给大家介绍个RPG素材网站这几天直在捣鼓这个有很多游戏人物图片可以用来实现人物动画游戏画面如下图 代码如下只实现了移动人物,对碰撞之类的还没有实现。package com.example.gamethree;import android.view.KeyEvent;import android.view.SurfaceView;import android.view.SurfaceHold...

weixin_29348211的博客 299

【移动开发】Android游戏开发SurfaceView应用----手指发动小球(小球碰撞检测例子)...

为了复习SurfaceView的使用,在此写了个经典的小球碰撞检测例子程序,希望能够够帮助正在学习游戏的人。先看效果图: 下面我们就来逐分析下它的实现过程:1.启动入口:import android.os.Bundle; import android.app.Activity; import android.view.Window; im...

weixin_34220834的博客 412

Android使用SurfaceView开发《捉小猪》小游戏 ()

我们在上(Android使用SurfaceView开发《捉小猪》小游戏 ())搞懂了这个模式的基本实现思路,小猪如何找出最短的逃跑路线和如何播放路径动画. 还封装了我们自己的PathAnimation和Drawable。 还差下面树桩出现的效果: 哈哈,记得植物大战僵尸里面有个关卡的道具出现也是这种效果的。 本来做这个效果的时候,想着用个方便快捷的方法:个新线程中,不断遍历已出...

陈小缘的博客 5118

推箱子游戏开发surfaceView 实现动画效果

SurfaceView是View的子类,常用于实现游戏中的动画效果SurfaceView最大的特点就是:从主线程中,把具体的绘图线程独立出来。这样做的好处在于:当绘图任务比较繁重时,避免主线程的阻塞,从而提高主线程的反应速度。         废话少说,言归正传,下面用几个例子说明surfaceview的使用。 () 基本功能:用SurfaceView显示副背景图片。 运行后的效果

IT涤生 1107

SurfaceView教程篇

SurfaceView教程篇 Andrioid---SurfaceView 的基本应用 http://www.eoeandroid.com/thread-46976-1-1.html Android游戏开发之旅(七)自定义SurfaceView http://www.eoeandroid.com/thread-36574-1-1.html 【Android2D游戏开发之三】剖

killmice的专栏 1078

Android下的推箱子游戏源码分享

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33895657的博客 778

无人机温室气体监测系统设计:从传感器选型到数据同步的完整实践

环境气体监测正从固定站点走向移动平台,无人机凭借灵活部署与高空间分辨率,成为填补地面与卫星观测空白的关键工具。实现精准测量涉及传感器技术、数据采集同步与飞行环境影响等多维度工程问题。非色散红外与可调谐激光吸收光谱是当前温室气体检测的主流技术,分别适用于二氧化碳与甲烷的快速走航测量;而采样频率、GPS时间戳与飞行速度的协同设计,决定了每个浓度点能否准确映射到空间位置。在垃圾填埋场泄漏排查、农业排放评估与工业区逸散监测等场景中,无人机航测可快速生成浓度分布场,辅助热点定位与源强反演。本文从系统架构、关键参数选型

weixin_34161064的博客 382

推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动

先看效果图。         我们的目标是:通过键盘按键,控制人物在屏幕上自由移动。要实现这个目标,只要完成下面三件事就行:1. 监听键盘,获取按键值 2. 根据按键值,修改人物在屏幕上的坐标 3. 在新的坐标位置显示人物 下面是程序的基本框图。         如上图所示:主Activity依次:创建人物、创建键盘监听线程、启动键盘监听线程、显示游戏界面。在游戏界面启动后,游戏

IT涤生 1612

Android PlayGame

[b][size=large][align=center]PushBox[/align][/size][/b] 这里介绍款经典小游戏:PushBox,共分四部分介绍。在编写代码之前,应先设计游戏的框架,了解各个类之间的关系,游戏的流程,前期的准备是做出游戏的必备条件。 [list] [*][b]欢迎动画界面的设计与实现 [/b] [/list] 当玩家运行游戏时,首先看到的是欢迎界...

android菜鸟的专栏 265

Android使用SurfaceView开发《捉小猪》小游戏 ()

先上效果图: 哈哈, 说下实现思路: 我们可以把每个树桩, 小猪, 车厢都看成是个Drawable, 这个Drawable里面保存了x, y坐标, 我们的SurfaceView在draw的时候, 就把这些Drawable draw出来. 那可能有的小伙伴就会问了: 1. 那小猪是怎么让它跑起来, 并且腿部还不断地在动呢? 2. 还有小猪是怎么找到出路的呢? 刚刚...

陈小缘的博客 1万+

android 人物走动_Android游戏开发学习(2)--SurfaceView实例控制角色移动

先看效果我用到的图片-在看代码package dk.game;import android.app.Activity;import android.os.Bundle;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity {/** Called ...

weixin_39682940的博客 466

Android 推箱子人物移动

文章目录实现MainActivity.javaGameView.java效果基于示例代码修改说明地图map0.map示例修改后MainActivity.java示例修改后GameView.java示例 实现 MainActivity.java /** * 划动方向即工人移动方向 * */ class Controller implements View.OnTouchListener { @Override public boolean o

Link2Points的博客 427

Android游戏添加游戏动画,Android游戏中的动画制作

游戏中常见的元素就是图片了,想让游戏中的角色看起来更生动,单靠简单的移动和旋转图片是远远不够的,我们应该为角色添加动画,“动起来”的角色看起来既生动又贴近现实,具有更好的用户体验。那么动画游戏中是如何实现的呢?我们拿当今红的发紫的【捕鱼达人】这个游戏来说明。如果我们有这样张图片,想让这只鲨鱼动起来是很简单的件事情,我们只需要将这张图片再每帧绘制的时候改变坐标就可以了。代码片段如下:…ma...

weixin_39628105的博客 439

Android游戏动画实现

1. 介绍 对于游戏等对界面要求较高的程序,般需要控制View中的具体图像显示(如动画功能)下面介绍实现此功能常用的SurfaceView控制。 1)       常用的绘制图像的方法 a)        View的invalidate() 直接调用onDraw()绘图 b)       View的postInvalidate() 通过消息调用onDraw()绘图 c)

谢彦的技术博客 4788

移动软件开发——推箱子游戏

遇到问题:解决方法:检查发现是data.js中的地图数据每行间没有加逗号导致,虽然不加不会被检测到问题,但会导致页面跳转失败并报错遇到问题:方向键显示框样式有问题解决方法:检查代码发现代码写的没有问题,最后发现是基础库版本的问题,改成3.5.5版本样式就能正确显示了。收获:通过本次实验,我学会了基本的小程序游戏开发知识,canvas游戏画布组件的使用、游戏地图的设计以及函数逻辑的实现,对小程序开发有了更加全面的理解。

plumageee的博客 1986

基于Android推箱子游戏 源码

完整工程已打包放在我的资源文件中https://download.csdn.net/download/huangshuai147/11151692 package com.example.pushbox; import android.os.Bundle; import android.app.Activity; import android.app.AlertDialog; i...

持之以恒_fighting 9868

华证ESG评级-得分2009-2023.dta

1、资源内容地址:https://blog.csdn.net/2301_79696294/article/details/1437365242、数据特点:今年全新,手工精心整理,放心引用,数据来自权威,且标注《数据来源》,相对于其他人的控制变量数据准确很多,适合写论文做实证用 ,不会出现数据造假问题3、适用对象:大学生,本科生,研究生小白可用,容易上手!!!4、课程引用: 经济学,地理学,城市规划与城市研究,公共政策与管理,社会学,商业与管理

上一篇: 地铁系统 POJ1635 subway tree systems 判断树同构 DFS搜索子串
下一篇: Android应用程序入门 推箱子游戏开发(二) 键盘事件监听 角色在屏幕上移动
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值