android游戏引擎andengine学习系列三:绘制游戏虚拟摇杆

android游戏引擎andengine学习系列三:绘制游戏虚拟摇杆如何高效的学习,这才是我们最值得去学习的。  andengine中绘制虚拟游戏摇杆非常简单,只需要实现AnalogOnScreenControl模拟摇杆类,在设置一些属性即可。先看效果图:左边的摇杆是控制精灵上下左右移动,右边的摇杆空值精灵的旋转。代码结构跟andengine学习系列二一样,其中很多注释在系列二中有说明,在该章内便不多复述。onLoadEngine()方法:

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

 如何高效的学习,这才是我们最值得去学习的。

 

 

andengine中绘制虚拟游戏摇杆非常简单,只需要实现AnalogOnScreenControl模拟摇杆类,在设置一些属性即可。先看效果图:

android游戏引擎andengine学习系列三:绘制游戏虚拟摇杆

左边的摇杆是控制精灵上下左右移动,右边的摇杆空值精灵的旋转。代码结构跟andengine学习系列二一样,其中很多注释在系列二中有说明,在该章内便不多复述。

onLoadEngine()方法:

@Override
	public Engine onLoadEngine() {
		this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		final Engine engine = new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));

		try {		//因为有两个摇杆,需要两个手指同时进行,所以这里要注册多点触控
			if(MultiTouch.isSupported(this)) {
				engine.setTouchController(new MultiTouchController());
				if(MultiTouch.isSupportedDistinct(this)) {
					Toast.makeText(this, "MultiTouch detected --> Both controls will work properly!", Toast.LENGTH_LONG).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();
			}
		} catch (final MultiTouchException e) {
			Toast.makeText(this, "Sorry your Android Version does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();
		}

		return engine;
	}

 

onLoadResources()方法:

public void onLoadResources() {

		this.mTexture = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mFaceTextureRegion = TextureRegionFactory.createFromAsset(this.mTexture, this, "face_box.png", 0, 0);

		this.mOnScreenControlTexture = new Texture(256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		this.mOnScreenControlBaseTextureRegion = TextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_base.png", 0, 0);	//这里是加载摇杆的地盘的纹理图片 
		this.mOnScreenControlKnobTextureRegion = TextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_knob.png", 128, 0);	//这里是加载摇杆的纹理图片

		this.mEngine.getTextureManager().loadTextures(this.mTexture, this.mOnScreenControlTexture);
	}

onLoadScene()方法,关键的业务逻辑便在该方法中:

public Scene onLoadScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());

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

		final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
		final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
		final Sprite face = new Sprite(centerX, centerY, this.mFaceTextureRegion);

		scene.getTopLayer().addEntity(face);

//-------------------------------------------以下为左摇杆的实现----------------------------------------------------------------------																final int x1 = 0;													//y坐标为屏幕的高度减去摇杆底盘的高度,注意屏幕在前面已经被强制横屏
		final int y1 = CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight();																				//AnalogOnScreenControl构造方法中:第一第二参数是该摇杆的坐标,第三个参数为上面定义camera,第四第五个参数为摇杆底盘和摇杆的纹理区域,第六个参数为pTimeBetweenUpdates界面的更新
		final AnalogOnScreenControl velocityOnScreenControl = new AnalogOnScreenControl(x1, y1, this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, new IAnalogOnScreenControlListener() {											//备注1
			@Override
			public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
				Log.i("test","x1:"+x1+",y1:"+y1+",pValueX:"+pValueX+",pValueY:"+pValueY);
				face.setVelocity(pValueX * 100, pValueY * 100);	//备注2
			}

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

		scene.setChildScene(velocityOnScreenControl);
//-------------------------------------------------------end 坐摇杆的实现------------------------------------------------------------//-------------------------------------------------------以下为右摇杆的实现----------------------------------------------------------

		final int y2 = (this.mPlaceOnScreenControlsAtDifferentVerticalLocations) ? 0 : y1;
		final int x2 = CAMERA_WIDTH - this.mOnScreenControlBaseTextureRegion.getWidth();
		final AnalogOnScreenControl rotationOnScreenControl = new AnalogOnScreenControl(x2, y2, this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, new IAnalogOnScreenControlListener() {
			@Override
			public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
				Log.i("test","x2:"+x2+",y2:"+y2+",pValueX:"+pValueX+",pValueY:"+pValueY);
				if(pValueX == x1 && pValueY == x1) {
					face.setRotation(x1);
				} else {
					face.setRotation(MathUtils.radToDeg((float)Math.atan2(pValueX, -pValueY)));	
								//备注5
				}
			}

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

		velocityOnScreenControl.setChildScene(rotationOnScreenControl);		//备注6

		return scene;
	}														//---------------------------------------------end 右摇杆的实现------------------------------------------------------------

 

备注1:关于AnalogOnScreenControl 类的第六个参数pTimeBetweenUpdates,我在这里把他理解成界面的延时程度,值设的越高,则精灵跟随摇杆变换的越缓慢;但是如果设成0,则两个摇杆失灵,于是我们在这里把他设置成0.1f,便可以看到精灵跟随摇杆很灵活的变换而没有卡壳和延时的现象

备注2:face.setVelocity,整个精灵移动的核心代码便是这一句,怎么样?比起用SurfaceView实现的摇杆简单方便的多吧!

备注3:onControlClick(),这个方法是当我们点击摇杆的时候会触发的方法,比如我们在这里可以把摇杆设置放大1.5倍,当没有点击的时候又恢复原来的状态,给人一种真实的感觉。

备注4:关于这里颜色的混合可以参考http://www.cnblogs.com/yujunyong/archive/2011/04/13/2015467.html,比较全面。

备注5:face.setRotation(),精灵的转动也是这一句代码便可实现,MathUtils.radToDeg方法返回的是:(180/PI)*方法中的参数; Math.atan2()函数返回点(x,y)和原点(0,0)之间直线的倾斜角。具体可以参考http://apps.hi.baidu.com/share/detail/50270911

备注6:这里可能会有疑问,为什么是velocityOnScreenControl.setChildScene,而不是scene.setChildScene,事实上,经过测试发现,scene.setChildScene这种情况会把前面定义好的左边的摇杆覆掉,也就没有了,scene只会显示最后一个定义的摇杆,于是我们在这里写好的右边的摇杆需要setChildScene左边的摇杆中,然后一起setChildScene整个场景中,这样两个摇杆都会显示了。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/192684.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 关于Cocos2d-x 3.0正式版 粒子问题在IOS上正常显示,在Android下有问题的解决方式

    关于Cocos2d-x 3.0正式版 粒子问题在IOS上正常显示,在Android下有问题的解决方式

    2022年1月26日
    44
  • tk mapper和mybatis plus_dozermapper

    tk mapper和mybatis plus_dozermapperTKmapper(通用Mapper)和MPmapepr(MyBatis-Plus)是mybatis两大插件,功能相同,都提供了常规的增删改查操作,增强mybatis的功能,篇幅有限,文章仅说下两者的区别!PageHelper是一个分页插件目录TKmapper1.SpringBoot集成2.Example用法3.Mapper接口4.MybatisGeneat…

    2022年9月27日
    4
  • redisson读写锁使用场景_Redisson酒店

    redisson读写锁使用场景_Redisson酒店读写锁一次只有一个线程可以占有写模式的读写锁,但是可以有多个线程同时占有读模式的读写锁.正是因为这个特性,当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞.当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是如果线程希望以写模式对此锁进行加锁,它必须直到所有的线程释放锁.通常,当读写锁处于读模式锁住状态时,如果有另外线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求,这样可以避免读模式锁长期占用,而等待的写模式

    2022年8月12日
    7
  • 语义分割(Semantic Segmentation)方法「建议收藏」

    语义分割(Semantic Segmentation)方法「建议收藏」翻译来自:https://gist.github.com/khanhnamle1994/e2ff59ddca93c0205ac4e566d40b5e88语义分割方面的资源:https://github.com/mrgloom/awesome-semantic-segmentation1.什么是语义分割语义分割是当今计算机视觉领域的关键问题之一。从宏观上看,语义分割是一项高层次的任务,…

    2022年6月8日
    26
  • sudoers修改_sudoers配置使用

    sudoers修改_sudoers配置使用sudo是linux下常用的允许普通用户使用超级用户权限的工具,允许系统管理员让普通用户执行一些或者全部的root命令,如halt,reboot,su等等。这样不仅减少了root用户的登陆和管理时间,同样也提高了安全性。Sudo不是对shell的一个代替,它是面向每个命令的。它的特性主要有这样几点:§sudo能够限制用户只在某台主机上运行某些命令。§sudo提供了丰富的日志,详细地记录了每个…

    2022年6月20日
    28
  • 安防监控项目(Remeo)概要设计

    安防监控项目(Remeo)概要设计1. 项目背景随着人们在家居生活中使用的电器越来越多,由此带来的安全隐患也有了明显的增多。为了降低电器的不合理使用带来的异常情况,大众对家庭智能监控的需求也越来越高。家庭智能监控主要依托摄像头,温湿度传感器等设备实现实时监控和智能报警的功能。RomeoMonitor主要是为模拟是家庭安防监控的简易系统。主要基于温湿度传感器、运动传感器和摄像头、蜂鸣器、LED等硬件作为终端,基于TCP和zig…

    2022年6月28日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号