在开发游戏开发中,android相应的提供了几个重要的模块:

1、显示界面的视图:  Android 提供 View 和 SurfaceView

2、控制游戏整体结构: android 提供 Activity

3、逻辑控制类:专门用于处理游戏的逻辑计算

4、处理游戏界面与用户交互事件 : 利用 View 类提供的 onKeyDown onKeyUp onTounchEvent等方法

我们这里简单熟悉一下如何在视图上画东西。

1、View 类: android.view.View 

View 是Android中的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘画的画布,这个画布 可以进行任何扩展。

任何一个View类都只需要重写onDraw方法来实现界面显示,任何一个View都只需要重写 OnDraw 方法来实现界面显示,自定义的视图可以是复杂的3D实现,也可以是非常简单的文本或位图。

Android 中有个重要的东东: Android UI 线程

在这里 http://blog.csdn.net/andyhuabing/article/details/11921887 有对其简要精典的介绍及注意点,这里就不再重复说明了。

这里来个简单例子说明一下View的用法,利用线程变更显示颜色,通过上下左右移动矩形

TestView.java 类如下:

package com.example.testondraw;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View; /**
* View 是Android中的一个超类,这个类几乎包含了所有的屏幕类型。每一个View都有一个用于绘画的画布,这个画布 可以进行任何扩展。
*
* 任何一个View类都只需要重写onDraw方法来实现界面显示。
*
*/
public class TestView extends View {
int miCount = 0;
int x = 10, y = 10; public TestView(Context context) {
super(context);
} @Override
protected void onDraw(Canvas canvas) {
if (miCount < 100)
{
miCount++;
}
else
{
miCount = 0;
}
//绘图
Paint mPaint = new Paint();
switch (miCount%4)
{
case 0:
mPaint.setColor(Color.BLUE);
break;
case 1:
mPaint.setColor(Color.GREEN);
break;
case 2:
mPaint.setColor(Color.RED);
break;
case 3:
mPaint.setColor(Color.YELLOW);
break;
default:
mPaint.setColor(Color.WHITE);
break;
}
// 绘制矩形
canvas.drawRect(x, y, x + 120, y + 80, mPaint);
}
}

如何在 Acitivty 使用呢?示例代码如下:

package com.example.testondraw;

import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu; public class MainActivity extends Activity {
static final String TAG = "MainActivity";
private TestView mTestView = null;
private TestSurfaceView mTestSurfaceView = null;
private int mWidth = 0, mHeight = 0;
private MyHandler mHandler = new MyHandler(); @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); initView(); startTestView(); // setContentView(R.layout.main);
} void initView() {
// 使用自定义的View
mTestView = new TestView(this);
setContentView(mTestView); DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
mWidth = dm.widthPixels;
mHeight = dm.heightPixels;
Log.i(TAG, "Display Metrics width:" + mWidth + " mHeight:" + mHeight);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
} void startTestView() {
Thread th = new Thread(new Runnable() { @Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// 使用postInvalidate可以直接在线程中更新界面
// mTestView.postInvalidate(); // 使用发消息给UI线程
Message msg = Message.obtain();
msg.what = 1;
mHandler.sendMessage(msg); try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
});
th.start();
} class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
mTestView.invalidate();
break;
default:
break;
}
super.handleMessage(msg);
}
} public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:
if (mTestView.y >= mHeight)
mTestView.y = 0;
mTestView.y += 10;
break;
case KeyEvent.KEYCODE_DPAD_UP:
if (mTestView.y <= 0)
mTestView.y = mHeight;
mTestView.y -= 10;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (mTestView.x <= 0)
mTestView.x = mWidth;
mTestView.x -= 10;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (mTestView.x >= mWidth)
mTestView.x = 0;
mTestView.x += 10;
break;
}
return false;
};
}

2、SurfaceView  android.view.SurfaceView

当执行效率有要求很高时,View类就无法满足需求。必须使用 SurfaceView 类 -- 利用双缓冲技术

使用SurfaceView提供给需要直接画像素而不是使用画窗体部件的应用使用。

而每个Surface创建一个Canvas对象,用来管理View在Surface上的绘画操作。

简要说明一下具体的方法及使用:

SurfaceHolder 对象需要通过 getHolder() 获取

在 Layout 上摆一个 SurfaceView 组件:

mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
SurfaceHolder holder = mSurfaceView.getHolder();

对于SurfaceView 的创建,销毁及变更

@SuppressWarnings("unused")
private SurfaceHolder.Callback mSurfaceCbk = new SurfaceHolder.Callback() {

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {    // 在Surface 大小发生变更时触发
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) { // 在创建 Surface 时触发
// TODO Auto-generated method stub

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) { // 在销毁 Surface 时触发
// TODO Auto-generated method stub

}

};

添加及删除 SurfaceView 的回调函数:

display.addCallback(mSurfaceCbk);

display.removeCallback(mSurfaceCbk);

Canvas 的使用:

lockCanvas  锁定画布,绘图之前必须锁定画布才能得到当前画布对象

unlockCanvasAndPost 开始绘制时锁定画布,绘制完成之后解锁画布

下面例子是绘制一个不断变换颜色的圆,并实现 SurfaceView 的事件处理

TestSurfaceView.java 代码:

package com.example.testondraw;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView; /**
* 使用SurfaceView提供给需要直接画像素而不是使用画窗体部件的应用使用。
* 而每个Surface创建一个Canvas对象,用来管理View在Surface上的绘画操作。
*/
public class TestSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
// 控制循环
private boolean mbLoop = false; // 定义SurfaceHolder对象
private SurfaceHolder mSurfaceHolder = null;
private int miCount = 0;
public int x = 50, y = 50;
private int mWidth = 1280,mHeight = 720;
private Bitmap mBitmap = null; public TestSurfaceView(Context context) {
super(context); // 实例化SurfaceHolder
mSurfaceHolder = this.getHolder(); // 添加回调
mSurfaceHolder.addCallback(this);
this.setFocusable(true);
} public void setDisplayWH(int w, int h) {
mWidth = w;
mHeight = h;
} public void setBitmap(Bitmap bitmap) {
this.mBitmap = bitmap;
} @Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub } @Override
public void surfaceCreated(SurfaceHolder holder) {
mbLoop = true; Thread th = new Thread(new Runnable() { @Override
public void run() {
while (mbLoop){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
} synchronized( mSurfaceHolder ){
drawBitmap();
DrawData();
}
}
}
});
th.start();
} @Override
public void surfaceDestroyed(SurfaceHolder holder) {
mbLoop = false;
} private void drawBitmap() {
// 锁定画布,得到canvas
if (mSurfaceHolder == null || this.mBitmap == null)
return; Canvas canvas = mSurfaceHolder.lockCanvas();
if (canvas == null) {
return;
} // 绘图
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLUE); canvas.drawBitmap(this.mBitmap, 0, 0, paint); // 绘制后解锁,绘制后必须解锁才能显示
mSurfaceHolder.unlockCanvasAndPost(canvas);
} // 绘图方法
private void DrawData() {
if (mSurfaceHolder == null)
return; // 锁定画布,得到canvas
Canvas canvas = mSurfaceHolder.lockCanvas();
if (canvas == null) {
return;
} if (miCount < 100) {
miCount++;
} else {
miCount = 0;
} // 绘图
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK); // 绘制矩形--清屏作用
canvas.drawRect(0, 0, mWidth, mHeight, mPaint); switch (miCount % 4) {
case 0:
mPaint.setColor(Color.BLUE);
break;
case 1:
mPaint.setColor(Color.GREEN);
break;
case 2:
mPaint.setColor(Color.RED);
break;
case 3:
mPaint.setColor(Color.YELLOW);
break;
default:
mPaint.setColor(Color.WHITE);
break;
} // 绘制矩形--
canvas.drawCircle(x, y, 50, mPaint); // 绘制后解锁,绘制后必须解锁才能显示
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}

测试使用例子:

package com.example.testondraw;

import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView; public class MainActivity extends Activity {
static final String TAG = "MainActivity";
private TestSurfaceView mTestSurfaceView = null;
private int mWidth = 0, mHeight = 0; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); initView(); startTestSurfaceView(); // setContentView(R.layout.main);
} void initView() {
// 使用自定义的View
mTestSurfaceView = new TestSurfaceView(this);
setContentView(mTestSurfaceView); DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
mWidth = dm.widthPixels;
mHeight = dm.heightPixels;
Log.i(TAG, "Display Metrics width:" + mWidth + " mHeight:" + mHeight);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
} public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_DOWN:
if (mTestSurfaceView.y >= mHeight)
mTestSurfaceView.y = 0;
mTestSurfaceView.y += 10;
break;
case KeyEvent.KEYCODE_DPAD_UP:
if (mTestSurfaceView.y <= 0)
mTestSurfaceView.y = mHeight;
mTestSurfaceView.y -= 10;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (mTestSurfaceView.x <= 0)
mTestSurfaceView.x = mWidth;
mTestSurfaceView.x -= 10;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (mTestSurfaceView.x >= mWidth)
mTestSurfaceView.x = 0;
mTestSurfaceView.x += 10;
break;
case KeyEvent.KEYCODE_BACK:
this.finish();
break;
}
return false;
}; void startTestSurfaceView() {
mTestSurfaceView.setDisplayWH(mWidth, mHeight);
}
}

Android 画图类View与SurfaceView之学习的更多相关文章

  1. Android多媒体之view,SurfaceView,GLSurfaceView

    1.相关概念 不用画布,直接在窗口上进行绘图叫做无缓冲绘图. 用了一个画布,将所有内容都先画到画布上,在整体绘制到窗口上,就该叫做单缓冲绘图, 那个画布就是一个缓冲区.用了两个画布,一个进行临时的绘图 ...

  2. Android之View和SurfaceView

    Android之View和SurfaceView Android游戏当中主要的除了控制类外就是显示类View.SurfaceView是从View基类中派生出来的显示类.android游戏开发中常用的三 ...

  3. Android进阶笔记05:View、SurfaceView 和GLSurfaceView 的关系和区别

    1.  Android游戏当中主要的除了控制类外就是显示类View.SurfaceView是从View基类中派生出来的显示类.android游戏开发中常用的三种视图是:    (1) view.Sur ...

  4. [Android游戏开发学习笔记]View和SurfaceView

    本文为阅读http://blog.csdn.net/xiaominghimi/article/details/6089594的笔记. 在Android游戏中充当主要角色的,除了控制类就是显示类.而在A ...

  5. Android自定义控件:图形报表的实现(折线图、曲线图、动态曲线图)(View与SurfaceView分别实现图表控件)

    图形报表很常用,因为展示数据比较直观,常见的形式有很多,如:折线图.柱形图.饼图.雷达图.股票图.还有一些3D效果的图表等. Android中也有不少第三方图表库,但是很难兼容各种各样的需求. 如果第 ...

  6. Android中利用画图类和线程画出闪烁的心形

                                                        本文讲解主要涉及的知识点: 1.线程控制 2.画图类 3.心形函数 大家先看图片: <ig ...

  7. 【读书笔记《Android游戏编程之从零开始》】11.游戏开发基础(SurfaceView 游戏框架、View 和 SurfaceView 的区别)

    1. SurfaceView 游戏框架实例 实例效果:就是屏幕上的文本跟着点击的地方移动,效果图如下: 步骤: 新建项目“GameSurfaceView”,首先自定义一个类"MySurfac ...

  8. Android画图系列(二)——自己定义View绘制基本图形

    这个系列主要是介绍下Android自己定义View和Android画图机制.自己能力有限.假设在介绍过程中有什么错误.欢迎指正 前言 在上一篇Android画图系列(一)--自己定义View基础中我们 ...

  9. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

随机推荐

  1. Delphi里的RTTI与反射(举例换掉FOnChange)

    Delphi2010之后的RTTI做了很大休整,现在用起来很爽了哦.甚至可以获取某些类的内部私有单元,然后为其赋值!讲这个RTTI增强的,可以参考网上的多个博客内容,我列举一下:Delphi2010R ...

  2. 2014年最火的 21个JavaScript 框架

    下面,我们将会介绍 2014 年最火的 21 款JavaScript 框架,专为前端开发者准备的哦:)众所周知, JavaScript 框架是 JavaScript编程语言最棒的特性之一. JavaS ...

  3. zookeeper入门必读

    (如果感觉有帮助,请帮忙点推荐,添加关注,谢谢!你的支持是我不断更新文章的动力.本博客会逐步推出一系列的关于大型网站架构.分布式应用.设计模式.架构模式等方面的系列文章) 今天我想谈谈zookeepe ...

  4. tlplayer 所有平台版本支持水印叠加

    tlplayer支持视频渲染前水印叠加,各个系统版本同样支持. 联系方式:weinyzhou86@gmail.com QQ:514540005 版权所有,禁止转载. 发布自:http://blog.c ...

  5. Android开发之多媒体编程之获取图片的副本

    使用BitmapFactory的decodeFile()方法获取的Bitmap对象是只读的,无法进行编辑操作 需要进行编辑的话,需要获取到该对象的一个副本 代码如下: import android.a ...

  6. Python爬虫和情感分析简介

    摘要 这篇短文的目的是分享我这几天里从头开始学习Python爬虫技术的经验,并展示对爬取的文本进行情感分析(文本分类)的一些挖掘结果. 不同于其他专注爬虫技术的介绍,这里首先阐述爬取网络数据动机,接着 ...

  7. 【转】Android项目中编译 C的模块

    原文网址:http://blog.csdn.net/Harrison_zhu/article/details/4057738 Android编译环境本身比较复杂,且不像普通的编译环境:只有顶层目录下才 ...

  8. show slave status中的log_file / log_pos

    在MySQL的master-slave或dual master的架构中,我们经常使用show slave status命令来查看复制状态. 这里涉及几个重要的日志文件和位置: Master_Log_F ...

  9. C++ 文件操作(CFile类)

    原文:文件操作(CFile),C吉羊 一.Visual C++编程文件操作 有如下方法可进行操作: (1)使用标准C运行库函数,包括fopen.fclose.fseek等. (2)使用Win16下的文 ...

  10. log4j和web.xml配置webAppRootKey 的问题

    在tomcat下部署两个或多个项目时,web.xml文件中最好定义webAppRootKey参数,如果不定义,将会缺省为“webapp.root”,如下: <!-- 应用路径 --> &l ...