首先说一下适用范围,使用AndEngine引擎,任何希望将关卡的选择作成滑动形式的界面,比如愤怒的小鸟等游戏的关卡选择!
基本原理,将我们所需要的显示的关卡精灵(就是关卡选择的按钮)以想要的样式绘制在一张大的场景里(你可以认为这个场景无限的大),然后移动游戏摄像机,拍摄这个场景的不同部分(RPG移动的也是这个原理),而这次展示的是滑动关卡选择,只需要横向滑动就可以了!
我在这里用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);
}
我这里用的是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;
}
}
@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);
}
}
/**
* 模拟显示等级载入
* @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();
}
});
}
}
颜色单调的效果图如下:
精致效果:
拖动效果: