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

你可能感兴趣的:(controller)