libgdx 3D CameraInputController WASD控制器

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);    

libgdx 3D CameraInputController WASD控制器,布布扣,bubuko.com

时间: 2024-10-12 19:33:08

libgdx 3D CameraInputController WASD控制器的相关文章

libgdx 3D 瞄准星和隐藏鼠标

1. 瞄准星 1 /**画瞄准星*/ 2 private void drawSight(){ 3 debugRenderer.begin(ShapeRenderer.ShapeType.Line); 4 float w = 50; 5 float h = 40; 6 Rectangle rect = new Rectangle((Gdx.graphics.getWidth()-w)/2, (Gdx.graphics.getHeight()-h)/2, w, h); 7 debugRenderer

Libgdx New 3D API 教程之 -- 加载3D场景的背后-第二部分

http://bbs.9ria.com/thread-221699-1-1.html 在本教程的第一部分,我们已经看过LibGDX 3D API中Model类的总体结构.在第2部分中,我们将会分析渲染管道,从加载模型开始,到真正的渲染模型.我们将不会在渲染管道的某个问题上进行深入探讨.我们只会介绍一些非常基本的内容,这是我觉得你使用3D API时,应该了解的. 在这一部分,我们要分析渲染究竟做了什么.明白我们在渲染时所做的事很重要.在前一部分本教程,我们已经看到,一个Model是由很多个Node

Libgdx New 3D API 教程之 -- Libgdx中的3D frustum culling

This blog is a chinese version of xoppa's Libgdx new 3D api tutorial. For English version, please refer to >>LINK<< 我要偷懒了,好久没看LibGDX,也很久没看3D,新教程的题目我就不懂了.不过看了课程的内容,相信你们都会理解. 正文: 当渲染一个3d场景时,其中真正可见的对象通常都比总对象数少很多.因此渲染全部的物体,包括那些根本看不到的,即浪费了富贵的GPU时间,

百度地图_api

这一天主要讲的是百度地图api的使用,由于百度有很详细的开发文档了,所以我这里只做一个大概的笔记 百度地图API的使用 1,入门 1.1,三大核心 ①SDKInitializer 整个百度的初始化工具类,引擎 ②MapView 用来显示地图的控件 ③baiduMap 相当于控制器,缩放,旋转,移动 1.2,准备工作(到百度地图LBS开放平台上查看) 获取API Key,按网上的帮助文档走步骤 获取SHA1码 百度地图的Key和应用是相互绑定的,一个Key对应一个应用. 1.3,创建工程拷贝jar

Libgdx New 3D API 教程之 -- 使用Libgdx加载模型

http://bbs.9ria.com/thread-221701-1-1.html 在前面的教程中,我们已经看到如何设置libgdx渲染3D场景.我们已经设置了Camera,增加了一些灯光并渲染一个绿色的盒子.现在让我们添加一个比盒子更有趣的东西,模型Model. 您可以从您喜爱的建模应用程序或使用已有的模型.我找了gdx-invaders里面的飞船模型文件,你可以点这里下载.您可以解压缩后,将文件放到的android项目的assets目录下.请注意,它包含三个文件,这些文件需要放同一个文件夹

libgdx游戏引擎3D开发教程-第一章-基础教程

开卷语:我最近才开始学习游戏编程,因为想做个网游玩,所以前几天找了不少引擎来看,于是不出意料的选中了libgdx,值得感谢的是libgdx的文档很多很全,所以没有走多少弯路就成功的配置好了环境.基础教程很完善,好多大神都已经写的很详细了,但是3D方面的很少见,所以我正好要学,索性直接翻译过来,大家共同进步.注意:教程基本是从Wiki上翻译过来,外加自己的小部分理解,所以一般来说应该没什么问题,如有错误请多多指教. =========================================

【Unity 3D】学习笔记三十八:角色控制器

角色控制器 在unity中,已经帮我们实现的上下左右跳等动作,并将他们封装成了角色控制器.角色控制器保存在unity标准资源包中,可以说是非常的强大.可以模拟第一或者第三人称视角.不受刚体的限制,非常适用于表现游戏中的主角运动.首先还是导入标准资源包.在project视图中点击右键,选择import package--character controller 第一人称 第一人称好比用自己的眼睛来观察游戏世界.其原理就是控制scene视图中的摄像机的移动,所以屏幕显示永远都是主角正前方的画面. 将

使用three.js创建3D机房模型-分享一

序:前段时间公司一次研讨会上,一市场部同事展现了同行业其他公司的3D机房,我司领导觉得这个可以研究研究,为了节约成本,我们在网上大量检索,最后找到一位前辈的博文[TWaver的技术博客],在那篇博文的评论区终于找到了那位前辈的源码,可惜下载后发现是压缩过的.min.js文件.经过各种研究发现,那是人家公司自己卖钱的库,不能完全共享,所以我司决定,派本人研究一下web3D的技术,于是乎便有了下面的技术分享. 一.本着开源的思想,使用three.js框架,封装常用的模型库.先学着那位前辈的样子,使用

ROS机器人程序设计(原书第2版)补充资料 (柒) 第七章 3D建模与仿真 urdf Gazebo V-Rep Webots Morse

ROS机器人程序设计(原书第2版)补充资料 (柒) 第七章 3D建模与仿真 urdf Gazebo V-Rep Webots Morse 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中使用. 提供ROS接口的3D软件比较多,本章以最典型的Gazebo介绍为主,从Player/Stage/Gazebo发展而来,现在独立的机器人仿真开发环境,目前2016年最新版本Gazebo7.1配合ROS(kinetic)使用. 补充内容:http://blo