博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
libgdx 3D CameraInputController WASD控制器
阅读量:6203 次
发布时间:2019-06-21

本文共 12353 字,大约阅读时间需要 41 分钟。

libgdx源码中有一个默认实现CameraInputController,基本实现了各种控制。

我想要的和他的有点区别,可能更类似于WOW或者CS的操作方式吧。。。

在他的基础上改改,见源码:

1 package com.mygdx.game;  2   3 import com.badlogic.gdx.Gdx;  4 import com.badlogic.gdx.Input.Keys;  5 import com.badlogic.gdx.Input.Buttons;  6 import com.badlogic.gdx.graphics.Camera;  7 import com.badlogic.gdx.input.GestureDetector;  8 import com.badlogic.gdx.math.MathUtils;  9 import com.badlogic.gdx.math.Vector2; 10 import com.badlogic.gdx.math.Vector3; 11  12 /** 13  * Created by HanHongmin on 14-7-25. 14  */ 15 public class CharacterCameraInputController extends GestureDetector { 16     /** 按下鼠标左键可以旋转视角 */ 17     public int rotateButton = Buttons.LEFT; 18     /** 当鼠标在屏幕上移动整个画面的宽和高时,视角转动角度 */ 19     public float rotateAngle = 360f; 20     /** 鼠标右键拖动画面可使视角横竖方向平移,不会前后移动。我们这里会禁用掉这个功能,亦或使用A,D键实现横向平移 */ 21     public int translateButton = Buttons.RIGHT; 22     /** The units to translate the camera when moved the full width or height of the screen. */ 23     public float translateUnits = 10f; // FIXME auto calculate this based on the target 24     /** 鼠标滚轮控制视角的前后移动。我们这里会禁用掉这个功能,亦或增加移动距离的限制 */ 25     public int forwardButton = Buttons.MIDDLE; 26     /** 开关,0全部开启 The key which must be pressed to activate rotate, translate and forward or 0 to always activate. */ 27     public int activateKey = 0; 28     /** 开关键是否被按下 Indicates if the activateKey is currently being pressed. */ 29     protected boolean activatePressed; 30     /** false 滚动时需要开关键按下,true不需要。Whether scrolling requires the activeKey to be pressed (false) or always allow scrolling (true). */ 31     public boolean alwaysScroll = true; 32     /** The weight for each scrolled amount. */ 33     public float scrollFactor = -0.1f; 34     /** World units per screen size */ 35     public float pinchZoomFactor = 10f; 36     /** Whether to update the camera after it has been changed. */ 37     public boolean autoUpdate = true; 38     /** 旋转镜头的基点,通常设置为cam的position. The target to rotate around. */ 39     public Vector3 target = new Vector3(); 40     /** Whether to update the target on translation */ 41     public boolean translateTarget = true; 42     /** Whether to update the target on forward */ 43     public boolean forwardTarget = true; 44     /** Whether to update the target on scroll */ 45     public boolean scrollTarget = false; 46     public int forwardKey = Keys.W;//前进 47     protected boolean forwardPressed; 48     public int backwardKey = Keys.S;//后退 49     protected boolean backwardPressed; 50     public int goLeftKey = Keys.A;//添加左右平移 51     protected boolean goLeftPressed; 52     public int goRightKey = Keys.D;//添加左右平移 53     protected boolean goRightPressed; 54     public int rotateRightKey = Keys.Q;//画面向右旋转即视角向左看,更改为按键Q 55     protected boolean rotateRightPressed; 56     public int rotateLeftKey = Keys.E;//画面向左旋转即视角向右看,更改为按键E 57     protected boolean rotateLeftPressed; 58     /** The camera. */ 59     public Camera camera; 60     /** The current (first) button being pressed. */ 61     protected int button = -1; 62  63     private float startX, startY; 64     private final Vector3 tmpV1 = new Vector3(); 65     private final Vector3 tmpV2 = new Vector3(); 66  67     protected static class CameraGestureListener extends GestureAdapter { 68         public CharacterCameraInputController controller; 69         private float previousZoom; 70  71         @Override 72         public boolean touchDown (float x, float y, int pointer, int button) { 73             previousZoom = 0; 74             return false; 75         } 76  77         @Override 78         public boolean tap (float x, float y, int count, int button) { 79             return false; 80         } 81  82         @Override 83         public boolean longPress (float x, float y) { 84             return false; 85         } 86  87         @Override 88         public boolean fling (float velocityX, float velocityY, int button) { 89             return false; 90         } 91  92         @Override 93         public boolean pan (float x, float y, float deltaX, float deltaY) { 94             return false; 95         } 96  97         @Override 98         public boolean zoom (float initialDistance, float distance) { 99             float newZoom = distance - initialDistance;100             float amount = newZoom - previousZoom;101             previousZoom = newZoom;102             float w = Gdx.graphics.getWidth(), h = Gdx.graphics.getHeight();103             return controller.pinchZoom(amount / ((w > h) ? h : w));104         }105 106         @Override107         public boolean pinch (Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {108             return false;109         }110     };111 112     protected final CameraGestureListener gestureListener;113 114     protected CharacterCameraInputController(final CameraGestureListener gestureListener, final Camera camera) {115         super(gestureListener);116         this.gestureListener = gestureListener;117         this.gestureListener.controller = this;118         this.camera = camera;119     }120 121     public CharacterCameraInputController(final Camera camera) {122         this(new CameraGestureListener(), camera);123     }124 125     public void update () {126         if (rotateRightPressed || rotateLeftPressed || goLeftPressed|| goRightPressed || forwardPressed || backwardPressed) {127             final float delta = Gdx.graphics.getDeltaTime();128             if (rotateRightPressed) {129                 //camera.rotate(camera.up, -delta * rotateAngle);130                 camera.rotate(Vector3.Y, delta * rotateAngle);131             }132             if (rotateLeftPressed) {133                 //camera.rotate(camera.up, delta * rotateAngle);134                 camera.rotate(Vector3.Y, -delta * rotateAngle);135             }136             if (forwardPressed) {137                 Vector3 t = tmpV1.set(camera.direction).scl(delta * translateUnits);138                 t.y = 0;//将y设置为0,在y轴方向即高度上不移动139                 camera.translate(t);140                 if (forwardTarget) target.add(tmpV1);141             }142             if (backwardPressed) {143                 Vector3 t = tmpV1.set(camera.direction).scl(-delta * translateUnits);144                 t.y = 0;//将y设置为0,在y轴方向即高度上不移动145                 camera.translate(t);146                 if (forwardTarget) target.add(tmpV1);147             }148 149             if (goLeftPressed) {150                 //direction旋转90度151                 Vector3 v = camera.direction.cpy();152                 v.rotate(Vector3.Y,-90);153                 Vector3 t = tmpV1.set(v).scl(-delta * translateUnits);154                 t.y = 0;//将y设置为0,在y轴方向即高度上不移动155                 camera.translate(t);156                 if (forwardTarget) target.add(tmpV1);157             }158 159             if (goRightPressed) {160                 Vector3 v = camera.direction.cpy();161                 v.rotate(Vector3.Y,90);162                 Vector3 t = tmpV1.set(v).scl(-delta * translateUnits);163                 t.y = 0;//将y设置为0,在y轴方向即高度上不移动164                 camera.translate(t);165                 if (forwardTarget) target.add(tmpV1);166             }167             if (autoUpdate) camera.update();168         }169     }170 171     private int touched;172     private boolean multiTouch;173 174     @Override175     public boolean touchDown (int screenX, int screenY, int pointer, int button) {176         touched |= (1 << pointer);177         multiTouch = !MathUtils.isPowerOfTwo(touched);178         if (multiTouch)179             this.button = -1;180         else if (this.button < 0 && (activateKey == 0 || activatePressed)) {181             startX = screenX;182             startY = screenY;183             this.button = button;184         }185         return super.touchDown(screenX, screenY, pointer, button) || activatePressed;186     }187 188     @Override189     public boolean touchUp (int screenX, int screenY, int pointer, int button) {190         touched &= -1 ^ (1 << pointer);191         multiTouch = !MathUtils.isPowerOfTwo(touched);192         if (button == this.button) this.button = -1;193         return super.touchUp(screenX, screenY, pointer, button) || activatePressed;194     }195 196     protected boolean process (float deltaX, float deltaY, int button) {197         if (button == rotateButton) {198             tmpV1.set(camera.direction).crs(camera.up).y = 0f;199             camera.rotateAround(target, tmpV1.nor(), deltaY * rotateAngle);200             camera.rotateAround(target, Vector3.Y, deltaX * -rotateAngle);201         } else if (button == translateButton) {202             camera.translate(tmpV1.set(camera.direction).crs(camera.up).nor().scl(-deltaX * translateUnits));203             camera.translate(tmpV2.set(camera.up).scl(-deltaY * translateUnits));204             if (translateTarget) target.add(tmpV1).add(tmpV2);205         } else if (button == forwardButton) {206             camera.translate(tmpV1.set(camera.direction).scl(deltaY * translateUnits));207             if (forwardTarget) target.add(tmpV1);208         }209         if (autoUpdate) camera.update();210         return true;211     }212 213     @Override214     public boolean touchDragged (int screenX, int screenY, int pointer) {215         boolean result = super.touchDragged(screenX, screenY, pointer);216         if (result || this.button < 0) return result;217         final float deltaX = (screenX - startX) / Gdx.graphics.getWidth();218         final float deltaY = (startY - screenY) / Gdx.graphics.getHeight();219         startX = screenX;220         startY = screenY;221         return process(deltaX, deltaY, button);222     }223 224     @Override225     public boolean scrolled (int amount) {226         return zoom(amount * scrollFactor * translateUnits);227     }228 229     public boolean zoom (float amount) {230         if (!alwaysScroll && activateKey != 0 && !activatePressed) return false;231         camera.translate(tmpV1.set(camera.direction).scl(amount));232         if (scrollTarget) target.add(tmpV1);233         if (autoUpdate) camera.update();234         return true;235     }236 237     protected boolean pinchZoom (float amount) {238         return zoom(pinchZoomFactor * amount);239     }240 241     @Override242     public boolean keyDown (int keycode) {243         if (keycode == activateKey) activatePressed = true;244         if (keycode == forwardKey)245             forwardPressed = true;246         else if (keycode == backwardKey)247             backwardPressed = true;248         else if (keycode == goLeftKey)249             goLeftPressed = true;//添加了左右平移250         else if (keycode == goRightKey)251             goRightPressed = true;//添加了左右平移252         else if (keycode == rotateRightKey)253             rotateRightPressed = true;254         else if (keycode == rotateLeftKey)255             rotateLeftPressed = true;256         return false;257     }258 259     @Override260     public boolean keyUp (int keycode) {261         if (keycode == activateKey) {262             activatePressed = false;263             button = -1;264         }265         if (keycode == forwardKey)266             forwardPressed = false;267         else if (keycode == backwardKey)268             backwardPressed = false;269         else if (keycode == goLeftKey)270             goLeftPressed = false;//添加左右平移271         else if (keycode == goRightKey)272             goRightPressed = false;//添加左右平移273         else if (keycode == rotateRightKey)274             rotateRightPressed = false;275         else if (keycode == rotateLeftKey)276             rotateLeftPressed = false;277         return false;278     }279 }

代码中将左右旋转改到了Q和E按键,增加了左右平移的A和D按键,修改了一些算法使其更适合作为角色视角。

代码中有个target很重要啊,做第三人称视角用的吧~~。

另:前进后退左右平移的速度是有变化的,比如看着脚面,速度就很慢。看使用场景吧,有兴趣的童鞋可以改改。

 

最后贴个如何使用的代码。。。

1         cam = new PerspectiveCamera(67, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 2         cam.position.set(0f, 7f, 0f); 3         cam.lookAt(1,7,1);//y可视为人物高度,在camera的controller中将y固定,除非有跳跃动作 4         cam.near = 1f; 5         cam.far = 30f;//视角最远 6         cam.update(); 7  8         camController = new CharacterCameraInputController(cam); 9         camController.target = cam.position;//旋转视角时以镜头位置为基点10         Gdx.input.setInputProcessor(camController);

转载于:https://www.cnblogs.com/hanhongmin/p/3868414.html

你可能感兴趣的文章
HDU2106 decimal system
查看>>
用hexo在github上搭建自己的静态博客
查看>>
关系运算
查看>>
MFC对话框控件访问的七种方式
查看>>
synchronized(this)与synchronized(class)
查看>>
IE6兼容改造中的反思
查看>>
ABBYY FineReader 12没你想得那么简单
查看>>
实习日记7.12
查看>>
02scikit-learn模型训练
查看>>
5. 常用控件(一)
查看>>
Java内存区域与内存溢出异常
查看>>
实时流式计算框架Storm 0.9.0发布通知(中文版)
查看>>
devGridView第一列显示行号
查看>>
UISwitch的常见属性
查看>>
[虚树模板] 洛谷P2495 消耗战
查看>>
每天一个小算法(matlab armijo)
查看>>
Joomla 2.5 中文语言包安装模板报错
查看>>
面向对象简述--对象、引用、指针
查看>>
JWT
查看>>
shiro的源码学习(三)shiro的SecurityManager类结构
查看>>