游戏引擎Andengine总结(六):滑动关卡选择的实现

首先说一下适用范围,使用AndEngine引擎,任何希望将关卡的选择作成滑动形式的界面,比如愤怒的小鸟等游戏的关卡选择!


基本原理,将我们所需要的显示的关卡精灵(就是关卡选择的按钮)以想要的样式绘制在一张大的场景里(你可以认为这个场景无限的大),然后移动游戏摄像机,拍摄这个场景的不同部分(RPG移动的也是这个原理),而这次展示的是滑动关卡选择,只需要横向滑动就可以了!


1.创建显示内容

a.再简单介绍一下HUD(Head Up Display),继承于CameraScene,说白了就是一个Scene的子类,相对于Camera来说是显示部分,不论场景如何变化,Camera如何转动,HUD显示都不会变化(你可以想象成贴在摄像机上的贴画,不论摄像机拍什么,贴画的位置都是一样的,就像是电视台的台标)

我在这里用HUD做了一个不随菜单滑动的按钮(可以用于返回上一菜单)

/**
	 * 创建HUD层
	 */
	private void createHUD()
	{
		// 不用考虑层
		hud = new HUD();
		Rectangle hudBox = new Rectangle(20, 700, 80, 80, getVertexBufferObjectManager())
		{
			@Override
			public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX,
					float pTouchAreaLocalY)
			{
				// TODO Auto-generated method stub
				if (pSceneTouchEvent.isActionUp())
				{
					runOnUiThread(new Runnable()
					{
						@Override
						public void run()
						{
							// TODO Auto-generated method stub
							Toast.makeText(ScrollMenuActivity.this, "BACK", Toast.LENGTH_SHORT).show();
						}
					});
				}
				
				return true;
			}
		};
		hudBox.setColor(Color.RED);
		hud.attachChild(hudBox);
		hud.registerTouchArea(hudBox);
		camera.setHUD(hud);
	}

b.创建关卡选择精灵(这里只是用一些矩形来代替,你可以换成你想要的其他任何图片)

我这里用的是3*3的矩阵显示,并且是横向扩展的

/**
	 * 创建关卡盒子
	 */
	private void createLevelBoxes()
	{
		// 计算行间距
		int spaceBetweenRaws = (CAMERA_HEIGHT / LEVEL_ROWS_PER_SCREEN) - LEVEL_PADDING;
		// 计算列间距
		int spaceBetweenColumns = (CAMERA_WIDTH / LEVEL_COLUMNS_PER_SCREEN) - LEVEL_PADDING;

		int level = 0;

		int boxX = LEVEL_PADDING;
		int boxY = LEVEL_PADDING;
		
		for (int i=0; i<LEVEL_PAGES; i++)
		{
			int startX = i * CAMERA_WIDTH;
			
			for (int j=0; j<LEVEL_ROWS_PER_SCREEN; j++)
			{
				for (int k=0; k<LEVEL_COLUMNS_PER_SCREEN; k++)
				{
					final int levelToLoad = level;
					Rectangle box = new Rectangle(startX + boxX, boxY, 100, 100, getVertexBufferObjectManager())
					{
						@Override
						public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX,
								float pTouchAreaLocalY)
						{
							// TODO Auto-generated method stub
							levelClicked = levelToLoad;
							
							return false;
						}
					};
					if (level >= maxLevelReached) 
					{
						box.setColor(0, 0, 0.9f);
					}
					else
					{
						box.setColor(0, 0.9f, 0);
					}
					scene.attachChild(box);
					scene.registerTouchArea(box);
					int textOffX = 0;
					if (level < 10)
					{
						textOffX = 28;
					}
					else
					{
						textOffX = 20;
					}
					box.attachChild(new Text(textOffX, 20, font, String.valueOf(level + 1), getVertexBufferObjectManager()));
					
					level++;
					boxX += spaceBetweenColumns + LEVEL_PADDING;
					if (level > LEVELS)
					{
						break;
					}
				}
				if (level > LEVELS)
				{
					break;
				}
				boxY += spaceBetweenRaws + LEVEL_PADDING;
				boxX = LEVEL_PADDING;
			}
			
			boxY = LEVEL_PADDING;
		}
	}


2.SurfaceScrollDetector检测滑动

剩下的部分就很简单了,即SurfaceScrollDetector来检测用户的手指滑动,每次滑动,都将摄像机的位置向反方向移动手指滑动的距离,但是为了做出滑动距离超过某一部分,则自动翻页的效果,需要在滑动开始时清空一下记录值,然后在滑动过程中平移摄像机镜头,在滑动结束时判断是否需要翻页

@Override
	public void onScrollStarted(ScrollDetector pScollDetector, int pPointerID, float pDistanceX,
			float pDistanceY)
	{
		// TODO Auto-generated method stub
		distanceX = 0;
	}

	@Override
	public void onScroll(ScrollDetector pScollDetector, int pPointerID, float pDistanceX, float pDistanceY)
	{
		// TODO Auto-generated method stub
		camera.offsetCenter(-pDistanceX, 0);

		distanceX += pDistanceX;
	}

	@Override
	public void onScrollFinished(ScrollDetector pScollDetector, int pPointerID, float pDistanceX,
			float pDistanceY)
	{
		// TODO Auto-generated method stub
		Log.d(TAG, "page: " + page);
		
		// 判断是否翻页,注意:手指向左滑动是想看到右一页
		if ((distanceX > TURN_PAGE_DISTANCE) && (page > 0))
		{
			Log.d(TAG, "上翻一页");
			page--;
			camera.offsetCenter(distanceX - CAMERA_WIDTH, 0);
		}
		else if ((distanceX < -TURN_PAGE_DISTANCE) && (page < LEVEL_PAGES - 1))
		{
			Log.d(TAG, "下翻一页");
			page++;
			camera.offsetCenter(distanceX + CAMERA_WIDTH, 0);
		}
		else
		{
			Log.d(TAG, "不翻");
			camera.offsetCenter(distanceX, 0);
		}
	}

3.上述部分就基本完成了,补充一个点击事件吧,使用的是ClickDetector,然后模拟一下关卡的载入。。

/**
	 * 模拟显示等级载入
	 * @param level
	 */
	private void loadLevel(final int level)
	{
		if (level != -1)
		{
			runOnUiThread(new Runnable()
			{
				@Override
				public void run()
				{
					// TODO Auto-generated method stub
					Toast.makeText(GameActivity.this, "Loading the " + level + " level!", Toast.LENGTH_SHORT)
							.show();
				}
			});
		}
	}


颜色单调的效果图如下:

精致效果:

游戏引擎Andengine总结(六):滑动关卡选择的实现_第1张图片

拖动效果:

游戏引擎Andengine总结(六):滑动关卡选择的实现_第2张图片


好吧,我承认我解释的不是很清楚,源码地址




你可能感兴趣的:(游戏,扩展,移动游戏,float,引擎,distance)