AndEngine中手柄的使用——DigitalOnScreenControl && AnalogOnScreenControl

本文深入探讨游戏开发与AI音视频处理领域的关键技术和实践应用,包括游戏引擎、Unity、Cocos2d-X等,以及AR、语音识别、深度学习等AI音视频处理技术的实际操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



package org.andengine.examples;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.camera.hud.controls.AnalogOnScreenControl;
import org.andengine.engine.camera.hud.controls.AnalogOnScreenControl.IAnalogOnScreenControlListener;
import org.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.input.touch.controller.MultiTouch;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.math.MathUtils;

import android.opengl.GLES20;
import android.widget.Toast;

/**
 * (c) 2010 Nicolas Gramlich
 * (c) 2011 Zynga
 *
 * @author Nicolas Gramlich
 * @since 00:06:23 - 11.07.2010
 */
public class AnalogOnScreenControlsExample extends SimpleBaseGameActivity {
 // ===========================================================
 // Constants
 // ===========================================================

 private static final int CAMERA_WIDTH = 480;
 private static final int CAMERA_HEIGHT = 320;

 // ===========================================================
 // Fields
 // ===========================================================

 private Camera mCamera;

 private BitmapTextureAtlas mBitmapTextureAtlas;
 private ITextureRegion mFaceTextureRegion;

 private BitmapTextureAtlas mOnScreenControlTexture;
 private ITextureRegion mOnScreenControlBaseTextureRegion;
 private ITextureRegion mOnScreenControlKnobTextureRegion;

 private boolean mPlaceOnScreenControlsAtDifferentVerticalLocations = false;

 // ===========================================================
 // Constructors
 // ===========================================================

 // ===========================================================
 // Getter & Setter
 // ===========================================================

 // ===========================================================
 // Methods for/from SuperClass/Interfaces
 // ===========================================================

 @Override
 public EngineOptions onCreateEngineOptions() {
  this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

  final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera);
  engineOptions.getTouchOptions().setNeedsMultiTouch(true);
//设置多点触控,因为有两个手柄
  if(MultiTouch.isSupported(this)) {
   if(MultiTouch.isSupportedDistinct(this)) {
    Toast.makeText(this, "MultiTouch detected --> Both controls will work properly!", Toast.LENGTH_SHORT).show();
   } else {
    this.mPlaceOnScreenControlsAtDifferentVerticalLocations = true;
    Toast.makeText(this, "MultiTouch detected, but your device has problems distinguishing between fingers.\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();
   }
  } else {
   Toast.makeText(this, "Sorry your device does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();
  }

  return engineOptions;
 }

 @Override
 public void onCreateResources() {
  BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

  this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 32, 32, TextureOptions.BILINEAR);
  this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "face_box.png", 0, 0);
  this.mBitmapTextureAtlas.load();

  this.mOnScreenControlTexture = new BitmapTextureAtlas(this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
  this.mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_base.png", 0, 0);
  this.mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_knob.png", 128, 0);
  this.mOnScreenControlTexture.load();
 }

 @Override
 public Scene onCreateScene() {
  this.mEngine.registerUpdateHandler(new FPSLogger());

  final Scene scene = new Scene();
  scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

  final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
  final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
  final Sprite face = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager());
  final PhysicsHandler physicsHandler = new PhysicsHandler(face);
  face.registerUpdateHandler(physicsHandler);

  scene.attachChild(face);

//这是第一个手柄,控制平移的

  /* Velocity control (left). */
  final float x1 = 0;
  final float y1 = CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight();
  final AnalogOnScreenControl velocityOnScreenControl = new AnalogOnScreenControl(x1, y1, this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, this.getVertexBufferObjectManager(), new IAnalogOnScreenControlListener() {
   @Override
   public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
    physicsHandler.setVelocity(pValueX * 100, pValueY * 100);
   }

   @Override
   public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
    /* Nothing. */
   }
  });
  
  velocityOnScreenControl.getControlBase().setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
  velocityOnScreenControl.getControlBase().setAlpha(0.5f);

  scene.setChildScene(velocityOnScreenControl);

//这是第二个手柄,控制旋转的
  /* Rotation control (right). */
  final float y2 = (this.mPlaceOnScreenControlsAtDifferentVerticalLocations) ? 0 : y1;
  final float x2 = CAMERA_WIDTH - this.mOnScreenControlBaseTextureRegion.getWidth();
  final AnalogOnScreenControl rotationOnScreenControl = new AnalogOnScreenControl(x2, y2, this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, this.getVertexBufferObjectManager(), new IAnalogOnScreenControlListener() {
   @Override
   public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
    if(pValueX == x1 && pValueY == x1) {
     face.setRotation(x1);
    } else {
     face.setRotation(MathUtils.radToDeg((float)Math.atan2(pValueX, -pValueY)));
    }
   }

   @Override
   public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
    /* Nothing. */
   }
  });

//设置混合色的代码
  rotationOnScreenControl.getControlBase().setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
  rotationOnScreenControl.getControlBase().setAlpha(0.5f);

  velocityOnScreenControl.setChildScene(rotationOnScreenControl);

  return scene;
 }

 // ===========================================================
 // Methods
 // ===========================================================

 // ===========================================================
 // Inner and Anonymous Classes
 // ===========================================================
}

在视野(scene)中有三个对象,分别为被控制的对象(face),左边的手柄(velocityOnScreenControl),右边的手柄,(rotationOnScreenControl),将这三个对象分别加入到视野中用到如下三句核心代码:scene.attachChild(face); scene.setChildScene(velocityOnScreenControl);

velocityOnScreenControl.setChildScene(rotationOnScreenControl);这时注意第三句用的是velocityOnScreenControl而并不是scene,原因是:如果用的是scene的话,就会覆盖前一个手柄。

以上用的是AnalogOnScreenControl(模拟手柄),当然了,我们也可以使用另一种”数字手柄“,即DigitalOnScreenControl,下面直接看代码啦:

package org.andengine.examples;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.andengine.engine.camera.hud.controls.BaseOnScreenControl.IOnScreenControlListener;
import org.andengine.engine.camera.hud.controls.DigitalOnScreenControl;
import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.opengl.GLES20;

/**
 * (c) 2010 Nicolas Gramlich
 * (c) 2011 Zynga
 *
 * @author Nicolas Gramlich
 * @since 00:06:23 - 11.07.2010
 */
public class DigitalOnScreenControlExample extends SimpleBaseGameActivity {
 // ===========================================================
 // Constants
 // ===========================================================

 private static final int CAMERA_WIDTH = 480;
 private static final int CAMERA_HEIGHT = 320;
 private static final int DIALOG_ALLOWDIAGONAL_ID = 0;

 // ===========================================================
 // Fields
 // ===========================================================

 private Camera mCamera;

 private BitmapTextureAtlas mBitmapTextureAtlas;
 private ITextureRegion mFaceTextureRegion;

 private BitmapTextureAtlas mOnScreenControlTexture;
 private ITextureRegion mOnScreenControlBaseTextureRegion;
 private ITextureRegion mOnScreenControlKnobTextureRegion;

 private DigitalOnScreenControl mDigitalOnScreenControl;

 // ===========================================================
 // Constructors
 // ===========================================================

 // ===========================================================
 // Getter & Setter
 // ===========================================================

 // ===========================================================
 // Methods for/from SuperClass/Interfaces
 // ===========================================================

 @Override
 public EngineOptions onCreateEngineOptions() {
  this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

  return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera);
 }

 @Override
 public void onCreateResources() {
  BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

  this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 32, 32, TextureOptions.BILINEAR);
  this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "face_box.png", 0, 0);
  this.mBitmapTextureAtlas.load();

  this.mOnScreenControlTexture = new BitmapTextureAtlas(this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
  this.mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_base.png", 0, 0);
  this.mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_knob.png", 128, 0);
  this.mOnScreenControlTexture.load();
 }

 @Override
 public Scene onCreateScene() {
  this.mEngine.registerUpdateHandler(new FPSLogger());

  final Scene scene = new Scene();
  scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

  final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
  final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
  final Sprite face = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager());
  final PhysicsHandler physicsHandler = new PhysicsHandler(face);
  face.registerUpdateHandler(physicsHandler);

  scene.attachChild(face);

  this.mDigitalOnScreenControl = new DigitalOnScreenControl(0, CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight(), this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, this.getVertexBufferObjectManager(), new IOnScreenControlListener() {
   @Override
   public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
    physicsHandler.setVelocity(pValueX * 100, pValueY * 100);
   }
  });
  this.mDigitalOnScreenControl.getControlBase().setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
  this.mDigitalOnScreenControl.getControlBase().setAlpha(0.5f);
  this.mDigitalOnScreenControl.getControlBase().setScaleCenter(0, 128);
  this.mDigitalOnScreenControl.getControlBase().setScale(1.25f);
  this.mDigitalOnScreenControl.getControlKnob().setScale(1.25f);
  this.mDigitalOnScreenControl.refreshControlKnobPosition();

  scene.setChildScene(this.mDigitalOnScreenControl);

  return scene;
 }

 @Override
 public void onGameCreated() {
  this.showDialog(DIALOG_ALLOWDIAGONAL_ID);
 }

 @Override
 protected Dialog onCreateDialog(final int pID) {
  switch(pID) {
   case DIALOG_ALLOWDIAGONAL_ID:
    return new AlertDialog.Builder(this)
    .setTitle("Setup...")
    .setMessage("Do you wish to allow diagonal directions on the OnScreenControl?")
    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
     @Override
     public void onClick(final DialogInterface pDialog, final int pWhich) {
      DigitalOnScreenControlExample.this.mDigitalOnScreenControl.setAllowDiagonal(true);
     }
    })
    .setNegativeButton("No", new DialogInterface.OnClickListener() {
     @Override
     public void onClick(final DialogInterface pDialog, final int pWhich) {
      DigitalOnScreenControlExample.this.mDigitalOnScreenControl.setAllowDiagonal(false);
     }
    })
    .create();
  }
  return super.onCreateDialog(pID);
 }

 // ===========================================================
 // Methods
 // ===========================================================

 // ===========================================================
 // Inner and Anonymous Classes
 // ===========================================================
}

 

该功能是使用了一个手柄来控制物体的移动。DigitalOnScreenControl ,AnalogOnScreenControl的功能类似。


DigitalOnScreenControlDigitalOnScreenControlDigitalOnScreenControlDigitalOnScreenControlDigitalOnScreenControlDigitalOnScreenControl

 

电动汽车数据集 该综合数据集包含许多品牌和年份的电动汽车和插电式车型的记录,捕获了技术规格、性能、定价、制造原产地、销售和安全相关属性。每一行代表由Vehicle_ID标识的唯一车辆列表。 主要特征 覆盖范围:全球制造商和车型组合,包括纯电动汽车和插电式混合动力汽车。 范围:电池化学成分、容量、续航里程、充电标准和速度、价格、产地、自主水平、排放、安全等级、销售和保修。 时间跨度:模型跨越多个年份(旧版和即将推出的)。 数据质量说明: 某些行的某些字段可能缺失(空白)。 多个分类字段包含不同的特定于供应商的值(例如,Charging_Type、Battery_Type)。 单位在列之间混合;注意千瓦时、公里、小时、美元、克/公里和额定等级。 列 Vehicle_ID 每个车辆记录的唯一标识符。 制造者 车辆品牌或 OEM。 型 年 Battery_Type 使用的电池化学/技术 Battery_Capacity_kWh 标称电池容量(以千瓦时为单位)。 Range_km 充满电后声称的行驶里程(公里)。 Charging_Type 主要的充电接口或功能。 Charge_Time_hr 大致充电时间(小时),上下文因充电方法而异 Price_USD 以美元为单位的指示性车辆价格。 颜色 Country_of_Manufacture 车辆制造/组装的国家/地区。 Autonomous_Level 自动化能力级别(例如,0-5),可能包括子级别的小数。 CO2_Emissions_g_per_km 尾气二氧化碳排放量(以克/公里为单位)(纯电动汽车通常为 0) Safety_Rating 安全等级 Units_Sold_2024 在 2024 年售出的单位 Warranty_Years 保修期(以年为单位)。
【CRM客户管理系统(vue+springboot)】是一个典型的现代Web应用程序开发案例,它结合了前端的Vue.js框架和后端的Spring Boot技术,用于实现高效、便捷的客户关系管理功能。这个系统具备基础的用户认证机制,如登录和注册,并且支持对客户数据的基本操作,包括增加、删除、修改和查询。 Vue.js是当前流行的JavaScript前端框架之一,以其轻量级、组件化和易于学习的特点而受到开发者喜爱。在CRM系统中,Vue.js负责处理用户界面的交互和动态更新,构建可复用的组件,提高代码的可维护性和开发效率。Vue Router作为官方的路由库,帮助管理页面导航和状态,实现单页应用(SPA)的流畅体验。 Spring Boot是Java领域的一个微服务框架,以其快速开发、内置依赖管理和自动配置等特性简化了后端服务的构建。在这个CRM系统中,Spring Boot被用来搭建RESTful API,为前端提供数据接口。Spring Data JPA和Hibernate等ORM工具可以方便地操作数据库,简化数据访问层的代码编写。同时,Spring Security可能被用于实现用户身份验证和授权,确保系统的安全性。 系统的核心功能包括用户管理模块,它实现了用户注册和登录功能。注册通常涉及用户信息的收集与验证,登录则需要安全的身份验证,如哈希加盐密码存储,防止密码泄露。此外,还有客户管理模块,通过API接口,前端可以向后端发送HTTP请求,执行CRUD操作,即创建(Create)、读取(Read)、更新(Update)和删除(Delete)客户数据。这通常涉及到数据库设计,如实体类的定义、表结构的映射以及事务管理,确保数据的一致性。 在开发过程中,前端与后端通过JSON格式的数据交换信息,利用Ajax进行异步通信,使得用户体验更加流畅。开发完成后,可能还需要进行性能优化,如使用缓存来减少数据库查询,以及接口调用的优化,提升系统响应速度。 CRM客户管理系统(vue+springboot)展示了现代Web开发的常见架构,涉及到了前端UI设计、后端服务构建、数据库操作、用户认证和权限控制等多个领域的知识点。对于想要学习或提升这些技能的IT从业者来说,这是一个很好的实践项目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值