这里是关于Input部分的实现,处理所有操作输入,下面是AndroidInput的具体代码
public class AndroidInput implements Input {
AccelerometerHandler accelHandler;
KeyboardHandler keyHandler;
TouchHandler touchHandler;
public AndroidInput(Context context, View view, float scaleX, float scaleY){
accelHandler=new AccelerometerHandler(context);
keyHandler=new KeyboardHandler(view);
if(Integer.parseInt(VERSION.SDK)<5){
touchHandler=new SingleTouchHandler(view, scaleX, scaleY);
}else{
touchHandler=new MultiTouchHandler(view, scaleX, scaleY);
}
}
@Override
public float getAccelX() {
return accelHandler.getAccelX();
}
@Override
public float getAccelY() {
return accelHandler.getAccelY();
}
@Override
public float getAccelZ() {
return accelHandler.getAccelZ();
}
@Override
public List<KeyEvent> getKeyEvents() {
return keyHandler.getKeyEvents();
}
@Override
public List<TouchEvent> getTouchEvents() {
return touchHandler.getTouchEvents();
}
@Override
public int getTouchX(int pointer) {
return touchHandler.getTouchX(pointer);
}
@Override
public int getTouchY(int pointer) {
return touchHandler.getTouchY(pointer);
}
@Override
public boolean isKeyPressed(int keyCode) {
return keyHandler.isKeyPressed(keyCode);
}
@Override
public boolean isTouchDown(int pointer) {
return touchHandler.isTouchDown(pointer);
}
}
可以看到Input的输入其实分为三类,分别是传感器,键盘以及触屏,分别对应的3个Handler,而在触屏的出来上还有比较特殊的一点,因为多点触控是从API5才开始的,所以需要判断之后,决定使用单点还是多点触控
先从比较清晰简单的开始,传感器AccelerometerHandler
public class AccelerometerHandler implements SensorEventListener {
float accelX;
float accelY;
float accelZ;
public AccelerometerHandler(Context context){
SensorManager manager=(SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if(manager.getSensorList(Sensor.TYPE_ACCELEROMETER).size()!=0){
Sensor accelermeter=manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
manager.registerListener(this, accelermeter, SensorManager.SENSOR_DELAY_GAME);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuray) {
}
@Override
public void onSensorChanged(SensorEvent event) {
accelX=event.values[0];
accelY=event.values[1];
accelZ=event.values[2];
}
public float getAccelX() {
return accelX;
}
public float getAccelY() {
return accelY;
}
public float getAccelZ() {
return accelZ;
}
}
然后来看单点和多点触控的部分SingleTouchHandler和MultiTouchHandler,以及父类TouchHandler
public interface TouchHandler extends OnTouchListener {
public boolean isTouchDown(int pointer);
public int getTouchX(int pointer);
public int getTouchY(int pointer);
public List<TouchEvent> getTouchEvents();
}
public class SingleTouchHandler implements TouchHandler {
boolean isTouched;
int touchX;
int touchY;
Pool<TouchEvent> touchEventPool;
List<TouchEvent> touchEvents=new ArrayList<TouchEvent>();
List<TouchEvent> touchEventsBuffer=new ArrayList<TouchEvent>();
float scaleX;
float scaleY;
public SingleTouchHandler(View view, float scaleX, float scaleY){
PoolObjectFactory<TouchEvent> factory=new PoolObjectFactory<TouchEvent>(){
@Override
public TouchEvent createObject() {
return new TouchEvent();
}
};
touchEventPool=new Pool<TouchEvent>(factory,100);
view.setOnTouchListener(this);
this.scaleX=scaleX;
this.scaleY=scaleY;
}
@Override
public List<TouchEvent> getTouchEvents() {
synchronized (this) {
int len=touchEvents.size();
for(int i=0;i<len;i++){
touchEventPool.free(touchEvents.get(i));
}
touchEvents.clear();
touchEvents.addAll(touchEventsBuffer);
touchEventsBuffer.clear();
return touchEvents;
}
}
@Override
public int getTouchX(int pointer) {
synchronized (this) {
return touchX;
}
}
@Override
public int getTouchY(int pointer) {
synchronized (this) {
return touchY;
}
}
@Override
public boolean isTouchDown(int pointer) {
synchronized (this) {
if(pointer==0){
return isTouched;
}else{
return false;
}
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
synchronized (this) {
TouchEvent touchEvent=touchEventPool.newObject();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
touchEvent.type=TouchEvent.TOUCH_DOWN;
isTouched=true;
break;
case MotionEvent.ACTION_MOVE:
touchEvent.type=TouchEvent.TOUCH_DRAGGED;
isTouched=true;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
touchEvent.type=TouchEvent.TOUCH_UP;
isTouched=false;
break;
}
touchEvent.x=touchX=(int)(event.getX()*scaleX);
touchEvent.y=touchY=(int)(event.getY()*scaleY);
touchEventsBuffer.add(touchEvent);
return true;
}
}
}
public class MultiTouchHandler implements TouchHandler {
boolean[] isTouched=new boolean[20];
int[] touchX=new int[20];
int[] touchY=new int[20];
Pool<TouchEvent> touchEventPool;
List<TouchEvent> touchEvents=new ArrayList<TouchEvent>();
List<TouchEvent> touchEventsBuffer=new ArrayList<TouchEvent>();
float scaleX;
float scaleY;
public MultiTouchHandler(View view, float scaleX, float scaleY){
PoolObjectFactory<TouchEvent> factory=new PoolObjectFactory<TouchEvent>(){
@Override
public TouchEvent createObject() {
return new TouchEvent();
}};
touchEventPool=new Pool<TouchEvent>(factory,100);
view.setOnTouchListener(this);
this.scaleX=scaleX;
this.scaleY=scaleY;
}
@Override
public List<TouchEvent> getTouchEvents() {
synchronized (this) {
int len=touchEvents.size();
for(int i=0;i<len;i++){
touchEventPool.free(touchEvents.get(i));
}
touchEvents.clear();
touchEvents.addAll(touchEventsBuffer);
touchEventsBuffer.clear();
return touchEvents;
}
}
@Override
public int getTouchX(int pointer) {
synchronized (this) {
if(pointer<0||pointer>=20){
return 0;
}else{
return touchX[pointer];
}
}
}
@Override
public int getTouchY(int pointer) {
synchronized (this) {
if(pointer<0||pointer>=20){
return 0;
}else{
return touchY[pointer];
}
}
}
@Override
public boolean isTouchDown(int pointer) {
synchronized (this) {
if(pointer<0||pointer>=20){
return false;
}else{
return isTouched[pointer];
}
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
synchronized (this) {
int action=event.getAction()&MotionEvent.ACTION_MASK;
int pointerIndex=(event.getAction()&MotionEvent.ACTION_POINTER_ID_MASK)>>MotionEvent.ACTION_POINTER_ID_SHIFT;
int pointerId=event.getPointerId(pointerIndex);
TouchEvent touchEvent;
switch(action){
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
touchEvent=touchEventPool.newObject();
touchEvent.type=TouchEvent.TOUCH_DOWN;
touchEvent.pointer=pointerId;
touchEvent.x=touchX[pointerId]=(int)(event.getX(pointerIndex)*scaleX);
touchEvent.y=touchY[pointerId]=(int)(event.getY(pointerIndex)*scaleY);
isTouched[pointerId]=true;
touchEventsBuffer.add(touchEvent);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
touchEvent=touchEventPool.newObject();
touchEvent.type=TouchEvent.TOUCH_UP;
touchEvent.pointer=pointerId;
touchEvent.x=touchX[pointerId]=(int)(event.getX(pointerIndex)*scaleX);
touchEvent.y=touchY[pointerId]=(int)(event.getY(pointerIndex)*scaleY);
isTouched[pointerId]=false;
touchEventsBuffer.add(touchEvent);
break;
case MotionEvent.ACTION_MOVE:
int pointerCount=event.getPointerCount();
for(int i=0;i<pointerCount;i++){
pointerIndex=i;
pointerId=event.getPointerId(pointerIndex);
touchEvent=touchEventPool.newObject();
touchEvent.type=TouchEvent.TOUCH_DRAGGED;
touchEvent.pointer=pointerId;
touchEvent.x=touchX[pointerId]=(int)(event.getX(pointerIndex)*scaleX);
touchEvent.y=touchY[pointerId]=(int)(event.getY(pointerIndex)*scaleY);
touchEventsBuffer.add(touchEvent);
}
break;
}
}
return true;
}
}
最后是关于键盘输入的KeyboardHandler
public class KeyboardHandler implements OnKeyListener {
boolean[] pressedKeys=new boolean[128];//KEYCODE正好是0-127
Pool<KeyEvent> keyEventPool;
List<KeyEvent> keyEventsBuffer=new ArrayList<KeyEvent>();
List<KeyEvent> keyEvents=new ArrayList<KeyEvent>();
public KeyboardHandler(View view){
PoolObjectFactory<KeyEvent> factory=new PoolObjectFactory<KeyEvent>(){
@Override
public KeyEvent createObject() {
return new KeyEvent();
}
};
keyEventPool = new Pool<KeyEvent>(factory,100);
view.setOnKeyListener(this);
view.setFocusableInTouchMode(true);
view.requestFocus();
}
@Override
public boolean onKey(View v, int keyCode, android.view.KeyEvent event) {
if(event.getAction()==android.view.KeyEvent.ACTION_MULTIPLE){
return false;
}
synchronized (this) {
KeyEvent keyEvent=keyEventPool.newObject();
keyEvent.keyCode=keyCode;
keyEvent.keyChar=(char)event.getUnicodeChar();
if(event.getAction()==android.view.KeyEvent.ACTION_DOWN){
keyEvent.type=KeyEvent.KEY_DOWN;
if(keyCode>0&&keyCode<127){
pressedKeys[keyCode]=true;
}
}
if(event.getAction()==android.view.KeyEvent.ACTION_UP){
keyEvent.type=KeyEvent.KEY_UP;
if(keyCode>0&&keyCode<127){
pressedKeys[keyCode]=false;
}
}
keyEventsBuffer.add(keyEvent);
}
return false;
}
public boolean isKeyPressed(int keyCode){
if(keyCode<0||keyCode>127){
return false;
}
return pressedKeys[keyCode];
}
public List<KeyEvent> getKeyEvents(){
synchronized (this) {
int len=keyEvents.size();
for(int i=0;i<len;i++){
keyEventPool.free(keyEvents.get(i));
}
keyEvents.clear();
keyEvents.addAll(keyEventsBuffer);
keyEventsBuffer.clear();
return keyEvents;
}
}
}
可以看到的是在触控和键盘中,有一个新的类Pool,这是我们自己定义的一个新类,他的作用是对所有的处理动作做出一个缓存
import java.util.ArrayList;
import java.util.List;
import com.cookie.androidgames.framework.Input.TouchEvent;
public class Pool<T> {
public interface PoolObjectFactory<T>{
public T createObject();
}
private final List<T> freeObjects;
private final PoolObjectFactory<T> factory;
private final int maxSize;
public Pool(PoolObjectFactory<T> factory,int maxSize){
this.factory=factory;
this.maxSize=maxSize;
this.freeObjects=new ArrayList<T>(maxSize);
}
public T newObject(){
T object=null;
if(freeObjects.size()==0){
object=factory.createObject();
}else{
object=freeObjects.remove(freeObjects.size()-1);
}
return object;
}
public void free(T object){
if(freeObjects.size()<maxSize){
freeObjects.add(object);
}
}
/* 用法示例:
PoolObjectFactory<TouchEvent> factory=new PoolObjectFactory<TouchEvent>() {
@Override
public TouchEvent createObject() {
return new TouchEvent();
}
};
Pool<TouchEvent> touchEventPool=new Pool<T>(factory, 50);
TouchEvent touchEvent=touchEventPool.newObject();
..do Something here..
touchEventPool.free(touchEvent);
*/
}
这是非常精妙的一个类,简单的说就是他规定了一个固定大小的事件缓冲池,而所有的动作都被记录在这个缓存池中,每次产生一个新的动作,并不会被立即执行,而是被放入缓冲池,如果缓冲池已满,那么会从中移除之前的操作,这样就保证了事件处理数量的上限,而不会造成同一时间内事件过多却由于一些原因得不到及时处理的问题
分享到:
相关推荐
《Beginning Android Games》一书由Mario Zechner撰写,旨在为初学者提供全面的Android游戏开发指南。本书从Android平台的基础知识入手,逐步深入到游戏开发的各个环节,涵盖了从简单的2D游戏到复杂的3D游戏的开发...
《Beginning Android Games 2012》这本书是一本关于Android游戏开发的专业教程书籍,由Mario Zechner和Robert Green共同撰写。该书以Android智能手机和平板电脑的游戏应用程序开发为主题,针对的是那些对Android游戏...
《Beginning Android Games, 2nd Edition》是一本深入浅出的Android游戏开发指南,由Mario Zechner与Robert Green合著。本书旨在帮助读者构建针对Android智能手机和平板电脑的游戏应用程序,涵盖了从基础知识到高级...
- **书籍名称**:《Beginning Android Games》(Android游戏开发入门) - **作者**:Mario Zechner - **出版信息**:Apress出版社,2011年4月10日发行 - **ISBN**:1430230428 - **资源格式**:PDF - **语言**:英文...
《Beginning Android Games, 第二版》是一本专注于Android游戏开发的权威图书,由Mario Zechner和Robert Green共同撰写。本书旨在为读者提供一个全面的游戏开发入门教程,涵盖了从基础的游戏设计概念到高级的编程...
### Apress.Beginning Android Games.2011 #### 知识点概览 - **Android游戏开发基础知识** - **Android SDK入门** - **游戏开发基础理论** - **OpenGL ES图形编程** - **2D与3D游戏编程技巧** - **Android游戏开发...
### 关于《Beginning Android Games》的关键知识点 #### 一、书籍概述 本书是一本非常出色的Android游戏开发入门书籍,由Mario Zechner撰写。作者在书中深入浅出地介绍了从2D到3D游戏开发的基本原理和技术细节。...
- **书名**:《Beginning Android 4 Games Development》 - **作者**: Mario Zechner 和 Robert Green - **出版社**: Apress Media, L.L.C. - **出版日期**: 2011年 - **ISBN**: - 纸质版: 978-1-4302-3987-1 - ...
### 关于《Beginner Android Games》的知识点梳理 #### 一、引言与目标受众 - **书籍定位**:本书面向初学者,旨在教授如何在Android平台上开发游戏应用。 - **主要内容**:涵盖Android基础知识、音频及图形编程、...
### Android游戏开发基础:《Beginning.Android.Games》关键知识点概览 #### 一、书籍简介与目标受众 《Beginning.Android.Games》是一本专为初学者设计的经典Android游戏开发教程。作者Mario Zechner通过本书带领...
2. **Java编程基础**:Android应用主要用Java语言编写,因此对Java的基本语法、面向对象编程概念和异常处理的理解至关重要。此外,了解Java的多线程处理能力对于游戏开发中的实时性能管理非常重要。 3. **Android...
《Apress.Beginning.Android.Games》是一本专为Android游戏开发者设计的详尽指南,由Mario Zechner撰写。本书不仅介绍了Android平台的基础知识,还深入探讨了游戏开发的各个方面,包括音频、图形编程、数学、物理...
- **图形音频输入**:演示如何使用Android的API实现图形渲染、音频处理和用户输入等功能。 - **2D与3D游戏开发**:通过实例教授如何基于Canvas API和OpenGL ES开发2D游戏;并介绍如何创建完整的3D游戏。 - **发布与...
安卓游戏框架android 游戏框架,基于kilobolt.com 上的教程,该教程本身基于《Beginning Android Games Development》(由Mario Zechner 和Robert Green 编写)。 目前,我直接基于教程进行此操作,但很快就会开始...
《Apress Beginning Android 4 Games Development 2011》是一本专为初学者设计的Android游戏开发指南,旨在帮助读者掌握使用Android平台创建游戏所需的技术和知识。这本书的出版年份是2011年,尽管Android系统已经...
- **"Beginning.Android.4.Games.Development.Dec.2011"**:该标题表明本书旨在为初学者提供Android 4游戏开发的基础知识。发布于2011年12月,反映了当时Android平台的发展状况及游戏开发的技术背景。 #### 描述...
开发者在创建这款游戏的过程中,参照了Mario Zechner所著的《 Beginning Android Games》这本书,这是一本非常权威且深入浅出的Android游戏开发指南,对于初学者和有经验的开发者来说都是宝贵的资源。 首先,让我们...