`

玩转Android---2D图形及动画---View类使用

 
阅读更多

由于游戏界面是由大量美工资源图片构成的,所以,在设计游戏界面的时候,千万不能用Layout来布局,因为这样的话,会将游戏界面中的对象当成一个组件来处理,开发过程中就会出现各种各样的问题。

其实,游戏就是通过状态机让Canvas不断的在View上画你想要的东西,这个状态机不仅包括游戏的内部执行,还包括外部的输入。

 

View类是Android的一个超类,这个类几乎包含了所有的屏幕类型。

public class

View

extends Object
implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource

上面的是SDK中对View类的一个定义,可以看到,有很多类是它的直接子类或者间接子类。

每个View类都有个可以进行绘画的画布,这个画布可以进行任一扩展。在游戏当中,可以自定义视图(View),使得这个画布的功能更能满足我们在游戏中的需要。

 

在Android中,任何一个View类都要重写onDraw()方法来实现画面显示,自定义的视图或者3D实现。

 

游戏中经常会使用触屏、键盘等事件,在View中同样也要实现它们来满足相应的功能。

onKeyUp,onKeyDown,onKeyMultiple,onKeyPreIme,onTouchEvent,onTrackballEvent等方法,在继承View的时候需要重载这些方法。

 

其实,游戏的核心就是不断的刷新界面和绘图,绘图可以在onDraw()方法中实现,那么刷新界面呢?Android中提供了

invalidate()方法来实现界面刷新,注意,invalidate不能直接在线程中调用,因为它违背了单线程模型:Android UI操作不是线程安全的,并且这些线程必须在UI线程中执行,因此Android中最常用的方法是利用Handler来实现UI线程的更新。

 

下面是个例子:

ViewDemo.java

package com.loulijun.viewdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;

public class ViewDemo extends View {
	//用于后面生成不同颜色而定义的变量
    int count = 0;
    //重写ViewDemo的构造方法
    public ViewDemo(Context context)
    {
    	super(context);
    }
    //画图方法
    public void onDraw(Canvas canvas)
    {
    	if(count < 100)
    	{
    		count++;
    	}
    	else
    	{
    		count = 0;
    	}
    	Paint paint = new Paint();
    	switch(count%4)
    	{
    	case 0:paint.setColor(Color.BLUE);break;
    	case 1:paint.setColor(Color.GREEN);break;
    	case 2:paint.setColor(Color.RED);break;
    	case 3:paint.setColor(Color.YELLOW);break; 
    	default:paint.setColor(Color.WHITE);break;
    	}
    	//画一个坐标在(100,100),半径为60的圆
    	canvas.drawCircle(100,100,60,paint);
    }
   
}
 

MainActivity.java

package com.loulijun.viewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class MainActivity extends Activity {
	//设置一个id
	public static final int REFRESH = 0X000001;
	//声明ViewDemo
	private ViewDemo mv = null;
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		//实例化ViewDemo对象
		mv =  new ViewDemo(this);
		//设置显示为我们自定义的View
		setContentView(mv);
		//开启线程
		new Thread(new GameThread()).start();
	}
	Handler handler = new Handler()
	{
		//接收消息后处理
		public void handleMessage(Message msg)
		{
			switch(msg.what)
			{
			case MainActivity.REFRESH:mv.invalidate();break;
			}
			super.handleMessage(msg);
		}
	};
	//内部类,需要实现一个Runnable接口
	class GameThread implements Runnable
	{

		@Override
		public void run() {
			//如果当前线程没有中断
			while(!Thread.currentThread().isInterrupted())
			{
				Message message = new Message();
				message.what = MainActivity.REFRESH;
				//发送消息
				handler.sendMessage(message);
				try
				{
					Thread.sleep(500);
				}catch(InterruptedException e)
				{
					Thread.currentThread().interrupt();
				}
			}
		}
		
	}

 

分析:

这里,通过实例化一个Handler对象并重写handleMessage方法来实现一个消息接收器,然后再线程中通过sendMessage()方法发送更新界面的消息,当接收器收到更新界面的时候,便开始执行invalidate()方法更新屏幕信息。

 

当然,还可以直接在线程中使用postInvalidate()方法在线程中更新界面,而不用再使用Handler来接收消息了

MainActivity.java

package com.loulijun.viewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class MainActivity extends Activity {
	//设置一个id
	public static final int REFRESH = 0X000001;
	//声明ViewDemo
	private ViewDemo mv = null;
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		//实例化ViewDemo对象
		mv =  new ViewDemo(this);
		//设置显示为我们自定义的View
		setContentView(mv);
		//开启线程
		new Thread(new GameThread()).start();
	}

	//内部类,需要实现一个Runnable接口
	class GameThread implements Runnable
	{

		@Override
		public void run() {
			//如果当前线程没有中断
			while(!Thread.currentThread().isInterrupted())
			{
				try
				{
					Thread.sleep(500);
				}catch(InterruptedException e)
				{
					Thread.currentThread().interrupt();
				}
				//使用postInvalidate()也可以直接在线程中更新界面,这样就不再需要HandlerMessage来接收消息了
				mv.postInvalidate();
			}
		}
		
	}
	
	//触笔事件
	public boolean onTouchEvent(MotionEvent event)
	{
		return true;
	}
	
	//按键按下事件
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		
		return true;
	}
	//按键弹起事件
	public boolean onKeyUp(int keyCode, KeyEvent event)
	{
		return false;
	}
	
	public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event)
	{
		return true;
	}
}
 

 

 

运行结果如下:




 

 

 
  • 大小: 9.5 KB
  • 大小: 9.4 KB
  • 大小: 9.4 KB
  • 大小: 9.3 KB
分享到:
评论

相关推荐

    Android代码-CatchThePigeonAndroid.zip

    6. **物理模拟**:为了模拟真实世界的运动,项目可能使用Box2D或自定义的物理引擎来处理碰撞检测、重力等。 四、性能优化 1. **多线程**:游戏的计算密集型部分应放在工作线程中,以保持UI流畅。 2. **内存管理**...

    Android三种姿势带你玩转360度全景图功能

    总的来说,要玩转Android的360度全景图功能,你需要掌握OpenGL ES、Google VR SDK和Three.js的相关知识,以及Android Studio项目管理和构建工具的使用。通过不断学习和实践,你将能够创造出引人入胜的全景体验。

    【经典Android游戏源码15】Android 涂鸦跳跃源码

    3. **2D图形绘制**:Android提供了Canvas和SurfaceView等组件用于绘制2D图形。游戏中的角色、障碍物和背景等元素都需要通过这些API来绘制。 4. **物理引擎**:为了模拟真实的跳跃效果,涂鸦跳跃可能会使用简单的...

    Android游戏开发20回合

    开发者可以通过它们创建丰富的2D图形。 5. **Path和Typeface**:`Path`用于构造复杂的矢量图形路径,而`Typeface`用来改变文字的字体风格,对于游戏中的文字和标识设计很重要。 6. **手势识别**:Android提供了`...

    android 俄罗斯方块

    游戏逻辑可能通过自定义View或者使用游戏引擎如Unity、Cocos2d-x来实现。 3. **用户界面**:Android版俄罗斯方块需要设计直观且响应迅速的用户界面,包括游戏主屏幕、开始游戏、设置选项和排行榜等功能。UI元素应...

    安卓Android源码——水果忍者点击屏幕效果.zip

    对于复杂的游戏图形,开发者可能选择使用OpenGL ES,这是一个为嵌入式设备设计的2D和3D图形库。在《水果忍者》这种游戏中,利用OpenGL ES可以实现高效且流畅的图形渲染,例如切割水果时的粒子效果、刀片轨迹等。 4...

    java开源包1

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包10

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包8

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    地铁跑酷小游戏

    开发者可能使用Unity的层级视图(Hierarchy View)和场景视图(Scene View)来构建游戏世界,包括地铁轨道、建筑、道具等元素。同时,他们可以通过编写脚本来随机生成或预定义关卡布局,增加游戏的可玩性和重玩价值...

    java开源包11

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包2

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包3

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包6

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包5

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包4

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包7

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    java开源包9

    GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的...

    JAVA上百实例源码以及开源项目源代码

    此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这...

Global site tag (gtag.js) - Google Analytics