zoukankan      html  css  js  c++  java
  • [libgdx游戏开发教程]使用Libgdx进行游戏开发(3)-给游戏添加一些控制功能

    每个游戏中都有一些只有程序员自己才知道的控制功能,比如增加金钱,满血复活,无视防御,不死等等。

    都是为了方便自己调试而在测试阶段使用的功能。

    正如上一章提到的:我们也需要加些只有程序员才知道的控制功能。以方便调试。

    在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键让摄像机跟随控制的箱子。

    开心的跑起来耍吧,骚年!

  • 相关阅读:
    二级指针内存模型(二)
    Winserver-FailoverCluster验证异常
    IIS-This configuration section cannot be used at this path.
    SQL SERVER-Extendevent捕获堵塞
    SQL SERVER-Extendevent
    Powershell-加域脚本
    SQL SERVER-端口Port
    WinServer-SMTP服务
    Linux-开机启动程序
    SQL SERVER-修改服务器名称
  • 原文地址:https://www.cnblogs.com/mignet/p/Learning_Libgdx_Game_Development_03.html
Copyright © 2011-2022 走看看