[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键让摄像机跟随控制的箱子。
开心的跑起来耍吧,骚年!
[libgdx游戏开发教程]使用Libgdx进行游戏开发(3)-给游戏添加一些控制功能的更多相关文章
- [libGDX游戏开发教程]使用libGDX进行游戏开发(12)-Action动画
前文章节列表: 使用libGDX进行游戏开发(11)-高级编程技巧 使用libGDX进行游戏开发(10)-音乐音效不求人,程序员也可以DIY 使用libGDX进行游戏开发(9)-场景过渡 ...
- [libGDX游戏开发教程]使用libGDX进行游戏开发(1)-游戏设计
声明:<使用Libgdx进行游戏开发>是一个系列,文章的原文是<Learning Libgdx Game Development>,大家请周知.后续的文章连接在这里 使用Lib ...
- 使用Html5+C#+微信 开发移动端游戏详细教程 :(三)使用html5引擎搭建游戏框架
教程里的案例我们是通过H5游戏引擎开发,目前H5的游戏引擎比较好用的是白鹭,不过对于新手来说白鹭的开发环境和工具使用过于复杂,这里推荐一个国内大神编写的游戏引擎:lufylegend. 直接在页面引入 ...
- 微信小程序开发教程 #043 - 在小程序开发中使用 npm
本文介绍了如何在微信小程序开发中使用 npm 中包的功能,大大提高微信小程序的开发效率,同时也是微信小程序系列教程的视频版更新. 微信小程序在发布之初没有对 npm 的支持功能,这也是目前很多前端开发 ...
- PythonWeb开发教程(一),开发之前需要准备什么
什么是web开发呢,其实就是开发一个网站了.那开发网站需要用到哪些知识呢 1.python基础,因为用python开发的,所以python指定要会,最起码你也得会条件判断,循环,函数,类这些知识: 2 ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(11)-高级编程技巧 Box2d和Shader
高级编程技巧只是相对的,其实主要是讲物理模拟和着色器程序的使用. 本章主要讲解利用Box2D并用它来实现萝卜雨,然后是使用单色着色器shader让画面呈现单色状态:http://files.cnblo ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(10)-音乐和音效
本章音效文件都来自于公共许可: http://files.cnblogs.com/mignet/sounds.zip 在游戏中,播放背景音乐和音效是基本的功能. Libgdx提供了跨平台的声音播放功能 ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(2)-游戏框架搭建
让我们抛开理论开始code吧. 入口类CanyonBunnyMain的代码: package com.packtpub.libgdx.canyonbunny; import com.badlogic. ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(9)-场景过渡
本章主要讲解场景过渡效果的使用.这里将用到Render to Texture(RTT)技术. Libgdx提供了一个类,实现了各种常见的插值算法,不仅适合过渡效果,也适合任意特定行为. 在本游戏里面, ...
- [libgdx游戏开发教程]使用Libgdx进行游戏开发(7)-屏幕布局的最佳实践
管理多个屏幕 我们的菜单屏有2个按钮,一个play一个option.option里就是一些开关的设置,比如音乐音效等.这些设置将会保存到Preferences中. 多屏幕切换是游戏的基本机制,Libg ...
随机推荐
- asp.net中的cookie
一.cookie导读,理解什么是cookie 1.什么是cookie:cookie是一种能够让网站服务器把少量数据(4kb左右)存储到客户端的硬盘或内存.并且读可以取出来的一种技术. 2.当你浏览某网 ...
- [fzu 2282]置换不动点大于等于k的排列数
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2282 编号1~n的置换,不动点个数大于等于k的方案数. 参考百度百科错排公式,可以知道长度为n,每个数都不在自 ...
- Codeforces Round #524 (Div. 2) A. Petya and Origami
A. Petya and Origami 题目链接:https://codeforc.es/contest/1080/problem/A 题意: 给出n,k,k表示每个礼品里面sheet的数量(礼品种 ...
- c++ STL(2)
Vector: #include "stdafx.h" #include<iostream> #include<vector> #include<al ...
- 问题总结——window平台下grunt\bower安装后无法运行的问题
一.问题: 安装grunt或者bower后,在cmd控制台运行grunt -version 或者 bower -v会出现:“xxx不是内部或外部命令,也不是可运行的程序或批处理文件”,
- python最简单发送邮件
#!/usr/bin/env python #coding:utf8 #Author:lsp #Date:下午5:51:13 #Version:0.1 #Function: #导入smtplib和MI ...
- 【BZOJ】1708: [Usaco2007 Oct]Money奶牛的硬币
[算法]DP [题解] 如果每个排列算一种,则令f[i]表示凑成面值为i的方案数,容易推出f[i]+=f[i-a[j]]. 现在是每个组合才算一种,令f[i][j]第二维表示只使用前j种面值,f[i] ...
- NYOJ 284 坦克大战 (广搜)
题目链接 描述 Many of us had played the game "Battle city" in our childhood, and some people (li ...
- bzoj 1066 最大流
将每个石柱拆成两个点,分别是进入的和出去的,两个点之间连石柱的高度 然后每个出去的点连别的石柱的进去的点, 源点连所有蜥蜴所在柱子,每个能跳出去的连汇点,然后最大流就行了 /************* ...
- 【Python实例一】使用minidom读取xml文件
前言:最近刚在廖雪峰老师的网站里学习了Python的基础内容,想着循序渐进地找点实例练练手,网上看到有很多相关资料,决定针对感兴趣的内容实际编码实践一下,昨天刚好看到有关使用Python来读取XML文 ...