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         @Override
107         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     @Override
175     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     @Override
189     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     @Override
214     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     @Override
225     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     @Override
242     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     @Override
260     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

libgdx 3D CameraInputController WASD控制器相关推荐

  1. libgdx 3D 测试一

    参考教程地址:http://blog.xoppa.com/basic-3d-using-libgdx-2/ 1. 创建项目 2. 代码 1 package com.mygdx.game; 2 3 im ...

  2. libgdx 3D 渲染优化

    原文地址:http://blog.xoppa.com/3d-frustum-culling-with-libgdx/ 非翻译,详细内容请见原文,捡点我能理解的说说吧~ 关于矩阵之类的知识可以看一下 h ...

  3. libgdx 3d_使用Java和libgdx进行3D游戏编程,使用Blender建立模型

    libgdx 3d Or- the journey through the x, y, and z axes through the lens of a computer screen. 或 -通过x ...

  4. 3d 根据弧长算角度_三分钟带你了解三姆森3D玻璃厚度及轮廓度检测

    曲面玻璃成为手机盖板市场主流 随着3C行业产品的发展需求和创新,催生了3D 曲面玻璃这一炙手可热的市场蓝海,陆续出现了相关的3D 曲面玻璃产品:如智能手机.智能手表.平板计算机.可穿戴式智能产品.仪表 ...

  5. 在iPhone上使用3D Touch

    3D Touch入门 在iOS 9中,新iPhone将第三维度添加到了用户界面. 用户现在可以用力摁下主屏按钮来快速调出应用提供的功能菜单. 在应用中,用户现在可以用力摁下视图以查看更多内容的预览并且 ...

  6. 惯性传感将决定未来游戏控制器的工作方式

    一旦被降级到诸如高空和航向基准系统的航天应用中,惯性传感器经常出现在高度集成的惯性测量单元(IMU)中,它结合了陀螺仪.加速度计.磁强计和压力传感器--在高级游戏中找到了新的生命.D工业应用,如机器人 ...

  7. Mozilla开发全新的公开网络API WebXR 来实现增强现实

    在添加了Firefox对WebVR的支持之后,Mozilla现在正在开发一款新的API,叫WebXR,来实现网络混合现实的功能.Mozilla去年首次宣布WebXR将会取代WebVR,并将对使用Web ...

  8. Ardupilot代码学习笔记

    本文为学习ardupilot官网文档做的笔记. ardupilot总体架构 ArduCopter架构 手动模式架构(Stabilize.Acro.Drift) 自动模式架构(RTL.Guided.Au ...

  9. 调节e18-d80nk的测量距离_教程 | GOM数字图像处理三维光学测量系统(ARAMIS) 的设备标定方法...

    点击关注↑↑↑更多分享内容! ARAMIS光学测量系统 设备标定教程 运用本系统进行光学测量是基于疲劳试验基础上开展的,设备操作内容包括"标定.散斑制作和光学应变测量"等部分.本教 ...

最新文章

  1. HEVC与3D-HEVC简介
  2. dft变换的两幅图_快速傅里叶变换FFT计算方法 原理及公式
  3. CodeForces 797C Minimal string
  4. 360加固逆向脱壳之过反调试
  5. dw2019连接mysql数据库_Python3连接MySQL数据库
  6. 拓端tecdat|R语言生态学建模:增强回归树(BRT)预测短鳍鳗生存分布和影响因素
  7. AllenNLP常用命令记录
  8. 2018 6月底阿里、网易面试经历简单回忆
  9. 地铁路线程序C语言,个人作业-北京地铁出行路线规划命令行程序完成总结
  10. pentaho mysql_pentaho5.0.1,mysql5 配置,安装
  11. 双击桌面计算机删除,笔记本电脑点击图标自动删除怎么办
  12. R语言 面板数据分析 plm包实现(二)——随机效应模型
  13. 该如何提高个人影响力
  14. 基于cosmol软件的光纤热力学分析
  15. 持NPDP证书在深圳可享受子女入学、医疗保健、安居保障等福利
  16. 帆软bi 观远bi_与电源bi一起加入
  17. 网站app被劫持怎么办?dns被劫持,域名被劫持,HTTPDNS阿里云域名防劫持, DNSPod移动解析防劫持服务D+...
  18. Oracle数据库 表空间
  19. 如何架设部署V2EX社区/论坛(Google App Engine版)
  20. 社区活动| Apache Doris 社区开发者会议议题征集中

热门文章

  1. Git正确的协作方式(很简单)
  2. ASP.NET关闭下载窗口
  3. 第六章 线程的基础知识
  4. *args和**kargs
  5. OpenCV图像处理(1)——指定文件夹写入图像
  6. linux安装或卸载mysql5,Linux环境下卸载、安装及配置MySQL5.1
  7. python安装与配置虚拟环境包_python 虚拟环境配置及pypi包使用及包怎么
  8. python cursor函数_执行从python返回cursor的db2plsql函数
  9. php试题多选,php考试题 (选择题).doc
  10. oracle基本的查询语句,Oracle中的基本查询语句总结