每个游戏中都有一些只有程序员自己才知道的控制功能,比如增加金钱,满血复活,无视防御,不死等等。
都是为了方便自己调试而在测试阶段使用的功能。
正如上一章提到的:我们也需要加些只有程序员才知道的控制功能。以方便调试。
在WorldController里加入:
public void update(float deltaTime) { handleDebugInput(deltaTime); updateTestObjects(deltaTime); } private void handleDebugInput(float deltaTime) { if (Gdx.app.getType() != ApplicationType.Desktop) return; // Selected Sprite Controls float sprMoveSpeed = 5 * deltaTime; if (Gdx.input.isKeyPressed(Keys.A)) moveSelectedSprite(-sprMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.D)) moveSelectedSprite(sprMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.W)) moveSelectedSprite(0, sprMoveSpeed); if (Gdx.input.isKeyPressed(Keys.S)) moveSelectedSprite(0, -sprMoveSpeed); } private void moveSelectedSprite(float x, float y) { testSprites[selectedSprite].translate(x, y); }
我们为什么要闲得在update里做判断呢,为什么不用监听器?(用监听器照样可以实现,这里略了,有兴趣可以自己试试)
因为我们需要知道按键是不是一直按着isKeyPressed()。监听器是事件触发的,直接这样做更省事。你可以按A, D, W, S看看现在效果。
当然了,现在我们要实现Reset功能,按R键。因为不用一直判断,所以我们可以直接用监听器了。
public class WorldController extends InputAdapter { // ... }
注册监听
private void init () { Gdx.input.setInputProcessor(this); initTestObjects(); }
这时候,Libgdx会把所有的input事件都发给注册了的监听器,你接到了input事件,该干嘛干嘛去。比如现在我们要处理R键和空格键。
@Override public boolean keyUp(int keycode) { // Reset game world if (keycode == Keys.R) { init(); Gdx.app.debug(TAG, "Game world resetted"); } // Select next sprite else if (keycode == Keys.SPACE) { selectedSprite = (selectedSprite + 1) % testSprites.length; Gdx.app.debug(TAG, "Sprite #" + selectedSprite + " selected"); } return false; }
跑起来,试试这些实现的功能吧。
接下来,我们来玩摄像机:
增加一个类:CameraHelper
package com.packtpub.libgdx.canyonbunny.util; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; public class CameraHelper { private static final String TAG = CameraHelper.class.getName(); private final float MAX_ZOOM_IN = 0.25f; private final float MAX_ZOOM_OUT = 10.0f; private Vector2 position; private float zoom; private Sprite target; public CameraHelper() { position = new Vector2(); zoom = 1.0f; } public void update(float deltaTime) { if (!hasTarget()) return; position.x = target.getX() + target.getOriginX(); position.y = target.getY() + target.getOriginY(); } public void setPosition(float x, float y) { this.position.set(x, y); } public Vector2 getPosition() { return position; } public void addZoom(float amount) { setZoom(zoom + amount); } public void setZoom(float zoom) { this.zoom = MathUtils.clamp(zoom, MAX_ZOOM_IN, MAX_ZOOM_OUT); } public float getZoom() { return zoom; } public void setTarget(Sprite target) { this.target = target; } public Sprite getTarget() { return target; } public boolean hasTarget() { return target != null; } public boolean hasTarget(Sprite target) { return hasTarget() && this.target.equals(target); } public void applyTo(OrthographicCamera camera) { camera.position.x = position.x; camera.position.y = position.y; camera.zoom = zoom; camera.update(); } }
可以控制摄像机上下左右移动,拉近放远,跟随目标。
ok,加入到control:
首先申明一个:public CameraHelper cameraHelper;
然后在init里初始化:cameraHelper = new CameraHelper();
接着在update里加上:cameraHelper.update(deltaTime);
最后修改keyup里的控制:
public CameraHelper cameraHelper; private void init() { Gdx.input.setInputProcessor(this); cameraHelper = new CameraHelper(); initTestObjects(); } public void update(float deltaTime) { handleDebugInput(deltaTime); updateTestObjects(deltaTime); cameraHelper.update(deltaTime); } @Override public boolean keyUp(int keycode) { // Reset game world if (keycode == Keys.R) { init(); Gdx.app.debug(TAG, "Game world resetted"); } // Select next sprite else if (keycode == Keys.SPACE) { selectedSprite = (selectedSprite + 1) % testSprites.length; // Update camera's target to follow the currently // selected sprite if (cameraHelper.hasTarget()) { cameraHelper.setTarget(testSprites[selectedSprite]); } Gdx.app.debug(TAG, "Sprite #" + selectedSprite + "selected"); } // Toggle camera follow else if (keycode == Keys.ENTER) { cameraHelper.setTarget(cameraHelper.hasTarget() ? null : testSprites[selectedSprite]); Gdx.app.debug(TAG, "Camera follow enabled: " + cameraHelper.hasTarget()); } return false; }
把对摄像机的上下左右控制加上:
private void handleDebugInput(float deltaTime) { if (Gdx.app.getType() != ApplicationType.Desktop) return; // Selected Sprite Controls float sprMoveSpeed = 5 * deltaTime; if (Gdx.input.isKeyPressed(Keys.A)) moveSelectedSprite(-sprMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.D)) moveSelectedSprite(sprMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.W)) moveSelectedSprite(0, sprMoveSpeed); if (Gdx.input.isKeyPressed(Keys.S)) moveSelectedSprite(0, -sprMoveSpeed); // Camera Controls (move) float camMoveSpeed = 5 * deltaTime; float camMoveSpeedAccelerationFactor = 5; if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) camMoveSpeed *= camMoveSpeedAccelerationFactor; if (Gdx.input.isKeyPressed(Keys.LEFT)) moveCamera(-camMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.RIGHT)) moveCamera(camMoveSpeed, 0); if (Gdx.input.isKeyPressed(Keys.UP)) moveCamera(0, camMoveSpeed); if (Gdx.input.isKeyPressed(Keys.DOWN)) moveCamera(0, -camMoveSpeed); if (Gdx.input.isKeyPressed(Keys.BACKSPACE)) cameraHelper.setPosition(0, 0); // Camera Controls (zoom) float camZoomSpeed = 1 * deltaTime; float camZoomSpeedAccelerationFactor = 5; if (Gdx.input.isKeyPressed(Keys.SHIFT_LEFT)) camZoomSpeed *= camZoomSpeedAccelerationFactor; if (Gdx.input.isKeyPressed(Keys.COMMA)) cameraHelper.addZoom(camZoomSpeed); if (Gdx.input.isKeyPressed(Keys.PERIOD)) cameraHelper.addZoom(-camZoomSpeed); if (Gdx.input.isKeyPressed(Keys.SLASH)) cameraHelper.setZoom(1); } private void moveCamera(float x, float y) { x += cameraHelper.getPosition().x; y += cameraHelper.getPosition().y; cameraHelper.setPosition(x, y); }
让摄像机跟随,还需要修改render:这样才能保证移动之后的摄像机,更新到了新的位置。
public void renderTestObjects() { worldController.cameraHelper.applyTo(camera); batch.setProjectionMatrix(camera.combined); batch.begin(); for (Sprite sprite : worldController.testSprites) { sprite.draw(batch); } batch.end(); }
按键总结说明:
AWSD控制箱子,空格键选择下一个箱子,R键重置游戏。
上下左右控制摄像机,逗号句号键放大缩小,破折号恢复正常大小。backspace键恢复原点位置,enter键让摄像机跟随控制的箱子。
开心的跑起来耍吧,骚年!