Android 游戏开发入门简单示例

在Android系统上开发游戏是Android开发学习者所向往的,有成就感也有乐趣,还能取得经济上的报酬。那怎样开发Android游戏呢?下面介绍一个简单的入门实例。

       一、创建新工程  

首先,我们在Eclipse中新建一个名为Movement的工程,并且选择合适的Android SDK,在这里,我们选用的API是比较低的1.5版本,这样可以让其适应性更强。接下来,我们新建两个类,一个是UpdateThread类,一个是SurfaceView类,它们在项目中分别是负责处理线程和画面的两个类,在接下来会有详细介绍,如下图,分别建立这两个类,注意选择正确它们继承的父类:

在建立完成后,系统的项目结构看上去应该象如下的样子:

       二、编写Movment.java启动程序

任何一个Android应用都必须有一个主启动程序来启动,我们这里把这个启动程序命名为Movment,代码很简单如下:

Java代码

public class Movement extends Activity {
 @Override
 public void onCreate(Bundle savedInstanceState) {  

   super.onCreate(savedInstanceState);
   setContentView(new MovementView(this));
 }  

注意的是,我们这个启动程序不象其他程序一样,在启动的时候,在setContentView中传入界面布局文件,而是直接将MovementView的实例传递进来,也就是说,直接启动了MovementView这个类,在这个类中,我们将绘画我们的小球。

       三、什么是SurfaceView

在Android中,SurfaceView是一个重要的绘图容器,它可以可以直接从内存或者DMA等硬件接口取得图像数据。通常情况程序的View和用户响应都是在同一个线程中处理的,这也是为什么处理长时间事件(例如访问网络)需要放到另外的线程中去(防止阻塞当前UI线程的操作和绘制)。但是在其他线程中却不能修改UI元素,例如用后台线程更新自定义View(调用View的在自定义View中的onDraw函数)是不允许的。

如果需要在另外的线程绘制界面、需要迅速的更新界面或则渲染UI界面需要较长的时间,这种情况就要使用SurfaceView了。SurfaceView中包含一个Surface对象,而Surface是可以在后台线程中绘制的。

在本文中,我们将使用它,直接通过代码创建一个小球,并且随着UpdateThread线程的更新,不断改变小球的位置,下面我们开始学习MovementView的编写,先看下如何运用SurfaceView。

首先导入SurfaceView及绘图的相关库文件,如下所示:

Java代码

package example.movement;  

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView; 

接着,我们要继承SurfaceView并且实现SurfaceHolder.Callback接口,这是一个SurfaceHolder的内部接口,可以实现该接口获得界面改变的信息,代码如下,并且我们声明了一些成员变量:

Java代码

public class MovementView extends SurfaceView implements SurfaceHolder.Callback {
  private int xPos;
  private int yPos;  

  private int xVel;
  private int yVel;  

  private int width;
  private int height;  

  private int circleRadius;
  private Paint circlePaint;  

  UpdateThread updateThread;
}

而在MovementView的构造函数中,我们设置了小球的大小和在X,Y方向上的初始坐标,如下:

Java代码     

public MovementView(Context context) {
  super(context);
  getHolder().addCallback(this);   

  circleRadius = 10;
  circlePaint = new Paint();
  circlePaint.setColor(Color.BLUE);   

  xVel = 2;
  yVel = 2;
}

接着我们来看下ondraw方法的编写,在这里,我们将绘画小球,并且每次都把画布Canvas的背景色设置为白色,以重新覆盖之前一帧,代码如下:

Java代码

protected void onDraw(Canvas canvas) {  

    canvas.drawColor(Color.WHITE);  

    canvas.drawCircle(xPos, yPos, circleRadius, circlePaint);
}

我们再来看下updatePhysics这个方法如何编写。这个方法的作用有两个:一是处理小球的运动,二是更新小球的实时位置,因为小球在屏幕中不断地运动,因此当小球到达比如屏幕绘画区域的顶端后,要被弹回,因此代码如下:

Java代码

public void updatePhysics() {  

//更新当前的x,y坐标
    xPos += xVel;
    yPos += yVel;  

    if (yPos - circleRadius < 0 || yPos + circleRadius > height) {  

      if (yPos - circleRadius < 0) {  

        //如果小球到达画布区域的上顶端,则弹回  

        yPos = circleRadius;
      }else{  

        //如果小球到达了画布的下端边界,则弹回  

        yPos = height - circleRadius;
      }  

      // 将Y坐标设置为相反方向
      yVel *= -1;
    }
    if (xPos - circleRadius < 0 || xPos + circleRadius > width) {  

      if (xPos - circleRadius < 0) {  

        // 如果小球到达左边缘  

        xPos = circleRadius;
      } else {  

        // 如果小球到达右边缘  

        xPos = width - circleRadius;
      }  

      // 重新设置x轴坐标
      xVel *= -1;
    }
  }

最后我们看下surfaceCreated这个方法的代码,在这个方法中,主要是取得了可用的SurfaceView的区域的高度和宽度,然后设置了小球的起始坐标(将其设置在屏幕的正中央位置),并且启动了UpdateThread线程,代码如下:

Java代码

public void surfaceCreated(SurfaceHolder holder) {  

    Rect surfaceFrame = holder.getSurfaceFrame();
    width = surfaceFrame.width();
    height = surfaceFrame.height();  

    xPos = width / 2;
    yPos = circleRadius;  

    updateThread = new UpdateThread(this);
    updateThread.setRunning(true);
    updateThread.start();
  }

此外,我们要补上surfaceChanged这个方法,这个方法意思是界面尺寸改变时才调用,在我们这个应用中并没用到,所以我们保留为空的方法实现:

Java代码

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
  {  

  }  

而surfaceDestroyed方法中,主要实现的是界面被销毁时才调用,这里我们停止了当前的线程所处理的任务,这里使用了线程的join方法:

Java代码

public void surfaceDestroyed(SurfaceHolder holder) {  

    boolean retry = true;  

    updateThread.setRunning(false);
    while (retry) {
      try {
        updateThread.join();
        retry = false;
      } catch (InterruptedException e) {  

      }
    }
  }

归纳下,完整的MovementView代码如下:

Java代码

package example.movement;  

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;  

public class MovementView extends SurfaceView implements SurfaceHolder.Callback {  

  private int xPos;
  private int yPos;  

  private int xVel;
  private int yVel;  

  private int width;
  private int height;  

  private int circleRadius;
  private Paint circlePaint;  

  UpdateThread updateThread;  

  public MovementView(Context context) {  

    super(context);
    getHolder().addCallback(this);  

    circleRadius = 10;
    circlePaint = new Paint();
    circlePaint.setColor(Color.BLUE);  

    xVel = 2;
    yVel = 2;
  }
  @Override
  protected void onDraw(Canvas canvas) {  

    canvas.drawColor(Color.WHITE);
    canvas.drawCircle(xPos, yPos, circleRadius, circlePaint);
  }  

  public void updatePhysics() {
    xPos += xVel;
    yPos += yVel;  

    if (yPos - circleRadius < 0 || yPos + circleRadius > height) {
      if (yPos - circleRadius < 0) {
        yPos = circleRadius;
      }else{
        yPos = height - circleRadius;
      }
      yVel *= -1;
    }
    if (xPos - circleRadius < 0 || xPos + circleRadius > width) {
      if (xPos - circleRadius < 0) {
        xPos = circleRadius;
      } else {
        xPos = width - circleRadius;
      }
      xVel *= -1;
    }
  }  

  public void surfaceCreated(SurfaceHolder holder) {  

    Rect surfaceFrame = holder.getSurfaceFrame();
    width = surfaceFrame.width();
    height = surfaceFrame.height();  

    xPos = width / 2;
    yPos = circleRadius;  

    updateThread = new UpdateThread(this);
    updateThread.setRunning(true);
    updateThread.start();
  }  

  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  }  

  public void surfaceDestroyed(SurfaceHolder holder) {  

    boolean retry = true;  

    updateThread.setRunning(false);
    while (retry) {
      try {
        updateThread.join();
        retry = false;
      } catch (InterruptedException e) {
      }
    }
  }
}

         四、UpdateThread线程程序

下面,我们开始着手编写UpdateThread线程程序。这个程序主要是启动一个线程去不断更新当前小球的位置。先看声明及构造函数部分:

Java代码

package licksquid.movement;  

import android.graphics.Canvas;
import android.view.SurfaceHolder;  

public class UpdateThread extends Thread {
  private long time;
  private final int fps = 20;
  private boolean toRun = false;
  private MovementView movementView;
  private SurfaceHolder surfaceHolder;  

}
public UpdateThread(MovementView rMovementView) {
    movementView = rMovementView;
    surfaceHolder = movementView.getHolder();
  }
 public void setRunning(boolean run) {
    toRun = run;
  }

注意这里的setRunning方法中设置了线程是否应该停止的标记,下面来看重要的方法run:

Java代码

public void run() {  

    Canvas c;
    while (toRun) {  

      long cTime = System.currentTimeMillis();  

      if ((cTime - time) <= (1000 / fps)) {  

        c = null;
        try {
          c = surfaceHolder.lockCanvas(null);  

          movementView.updatePhysics();
          movementView.onDraw(c);
        } finally {
          if (c != null) {
            surfaceHolder.unlockCanvasAndPost(c);
          }
        }
      }
      time = cTime;
    }
  }

在run方法中,主要实现了如下几个任务:首先检查是否有允许启动该线程(在开始运行后,由于在MovementView中,启动UpdateThread的时候,已经设置了其值为true,即updateThread.setRunning(true)),接下来检查是否在指定的时间内(这里设置的是每秒20帧),如果是的话,则调用surfaceHolder的lockCanvas方法,锁定当前的画布绘画区域,并且调用movementView的updatePhysics方法及onDraw方法去画小球并判断小球的运动,最后记得要在finally中调用unlockCanvasAndPost方法。

       五、启动并运行程序

最后启动并运行程序,可以看到如下的效果,可以看到小球在做各个方向的弹跳运动。

到此就完成了这个Android游戏开发的入门实例,其实编写Android游戏就是这么简单。

以上就是简单的游戏开发程序,后续继续整理相关知识,谢谢大家对本站的支持!

(0)

相关推荐

  • Android使用VideoView播放本地视频和网络视频的方法

    1.效果展示 2.布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="matc

  • Android Service判断设备联网状态详解

    首先,要想获得当前android设备是否处于联网状态,那么android本身给我们提供了一个服务. private ConnectivityManager connectivityManager;//用于判断是否有网络 connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);//获取当前网络的连接服务 NetworkInfo info = co

  • Android 重力传感器在游戏开发中的应用

    手势操作可以说是智能手机的一种魅力所在,前两节给大家讲解了两种有趣的手势操作,将它们置于游戏当中,大大提升了游戏的可玩性和趣味性.本节将继续介绍智能手机的另一种神奇之处:传感器.    一.何为传感器 所谓传感器就是能够探测如光.热.温度.重力.方向等等的装置.    二.Android提供了哪些传感器 1.加速度传感器(重力传感器) 2.陀螺仪传感器 3.光传感器 4.恒定磁场传感器 5.方向传感器 6.恒定的压力传感器 7.接近传感器 8.温度传感器 今天我们给大家介绍的是游戏开发中最最常见

  • Android开发实例之多点触控程序

    智能终端设备的多点触控操作为我们带来了种种炫酷体验,这也使得很多Android开发者都对多点触控程序的开发感兴趣.实际上多点触控程序的实现并不是那么遥不可及,而是比较容易.本文就主要通过一个实例具体讲解多点触控程序的实现.        首先来了解一下Android中多点触控的原理. Android多点触控在本质上需要LCD驱动和程序本身设计上支持,目前市面上HTC.Motorola和Samsung等知名厂商只要使用电容屏触控原理的手机均可以支持多点触控Multitouch技术,对于网页缩放.手

  • 分析Android中应用的启动流程

    前言 在我们开始之前,希望您能最好已经满足以下条件: 1.有一份编译后的Android源码(亲自动手实践才会有更深入的理解) 2.对Binder机制有一定的了解 本文启动流程分析基于Android 5.1的源码.为什么是5.1的源码呢?因为手边编译完的代码只有这个版本-另外,用什么版本的源码并不重要,大体的流程并无本质上的区别,仅仅是实现细节的调整,找一个你熟悉的版本就好. 1.启动时序图 作为一个轻微强迫症的人,整理的时序图,相信大家按图索骥,一定能搞明白整个启动流程: 说明:为了让大家更清楚

  • Android开发之ScrollView的滑动监听

    我们需要监听ScroView的滑动情况,比如滑动了多少距离,是否滑到布局的顶部或者底部.可惜的是SDK并没有相应的方法,不过倒是提供了一个 protected void onScrollChanged(int l, int t, int oldl, int oldt) 显然这个方法是不能被外界调用的,因此就需要把它暴露出去,解决方式就是写一个接口 /** * Created by 刘楠 on 2016/8/21 0021.17:24 */ public interface ScrollViewL

  • Android 开发实例简单涂鸦板

    在Android上开发一些小应用既可以积累知识又可以增加乐趣,与任务式开发不同,所以想到在Android系统上实现一个简单的涂鸦板,这是我们练手的一种好的方法.   涂鸦板应用的代码实现 新建工程MyWall,修改/res/layout/main.xml文件,在里面添加一个SurfaceView和两个Button,用到了RelativeLayout布局,完整的main.xml文件如下: XML/HTML代码 <?xml version="1.0" encoding="u

  • Android游戏开发:实现手势操作切换图片的实例

    对于Android 的手势不光在软件中会经常用到,比如浏览器中的翻页,滚动页面等等;当然其实在我们开发Android游戏的时候加上了Android手势操作更会让游戏增加一个亮点,比如一般的CAG.PUZ等类型的游戏选择关卡.简单背景的移动等,都可以使用手势来操作即可,类似前段时间很火的<愤怒的小鸟>,小鸟这个游戏确实不错,我所看到的唯一的亮点是这款游戏的创意!说实话,现在的游戏没有做不出来的只有想不出来的好创意.回到话题来,那么下面我们来了解下什么是Android 手势!        手势识

  • Android使用Handler实现View弹性滑动

    弹性滑动原理 将一次大的滑动非为若干次小的滑动,并在一个时间段内完成.更好的用户体验 实现方式很多种,包括用Scroller,动画,延时策略. 使用Handler实现弹性滑动 效果可以看到按钮Button向滑动.注意这里是将View的内容改变. 你可以试一试将Button外层的RelitiveLayout去掉,把id放在Button下.发现是Button的文字滑动 <RelativeLayout xmlns:android="http://schemas.android.com/apk/r

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

    本篇文章主要来讲解怎样绘制游戏触摸轨迹的曲线图. 我们在onTouchEvent方法中,可以获取到触摸屏幕时手指触摸点的x.y坐标,如何用这些点形成一条无规则轨迹并把这条无规则轨迹曲线显示在屏幕上就是本篇文章的主旨内容. Android Path类 Android提供了一个Path类 , 顾名思义这个类可以设置曲线路径轨迹.任何无规则的曲线实际上都是由若干条线段组成,而线段的定义为两点之间最短的一条线.path类就 可以记录这两点之间的轨迹,那么若干个Path 就是我们须要绘制的无规则曲线. 下

随机推荐