四、输入处理
在LWJGL中,使用Set***Callback进行输入处理。以下是所有的输入处理(第一个参数为窗口,第二个为匿名函数),当用户进行如下操作时调用匿名函数
GLFW.glfwSetWindowCloseCallback(window, null); // 窗口关闭 GLFW.glfwSetWindowContentScaleCallback(window, null); // 窗口比例更改 GLFW.glfwSetWindowFocusCallback(window, null); // 窗口获得焦点 GLFW.glfwSetWindowIconifyCallback(window, null); // 窗口最小化 GLFW.glfwSetWindowMaximizeCallback(window, null); // 窗口最大化 GLFW.glfwSetWindowPosCallback(window, null); // 窗口坐标改变 GLFW.glfwSetWindowRefreshCallback(window, null); // 窗口刷新 GLFW.glfwSetWindowSizeCallback(window, null); // 窗口大小改变 GLFW.glfwSetKeyCallback(window, null); // 按键按下 GLFW.glfwSetCharCallback(window, null); // (受修饰符影响)字符输入 GLFW.glfwSetCharModsCallback(window, null); // (不受修饰符影响)字符输入 GLFW.glfwSetMouseButtonCallback(window, null); // 鼠标按下 GLFW.glfwSetCursorPosCallback(window, null); // 鼠标指针位置改变 GLFW.glfwSetCursorEnterCallback(window, null); // 鼠标指针进入窗口 GLFW.glfwSetScrollCallback(window, null); // 窗口滚动 GLFW.glfwSetDropCallback(window, null); // 文件拖入窗口在engine包下创建io包,并新建Input类和各抽象类
public GLFWWindowCloseCallback closeCallback;
public GLFWWindowContentScaleCallback contentScaleCallback;
public GLFWWindowFocusCallback focusCallback;
public GLFWWindowIconifyCallback iconifyCallback;
public GLFWWindowMaximizeCallback maximizeCallback;
public GLFWWindowPosCallback posCallback;
public GLFWWindowRefreshCallback refreshCallback;
public GLFWWindowSizeCallback sizeCallback;
public GLFWKeyCallback keyCallback;
public GLFWCharCallback charCallback;
public GLFWCharModsCallback charModsCallback;
public GLFWMouseButtonCallback mouseButtonCallback;
public GLFWCursorPosCallback cursorPosCallback;
public GLFWCursorEnterCallback cursorEnterCallback;
public GLFWScrollCallback scrollCallback;
public GLFWDropCallback dropCallback;
- 在构造函数中实现这些类
public Input() {
closeCallback = new GLFWWindowCloseCallback() {
@Override
public void invoke(long window) {
// window 窗口
}
};
contentScaleCallback = new GLFWWindowContentScaleCallback() {
@Override
public void invoke(long window, float xscale, float yscale) {
// window 窗口
// xscale x方向的缩放
// yscale y方向的缩放
}
};
focusCallback = new GLFWWindowFocusCallback() {
@Override
public void invoke(long window, boolean focused) {
// window 窗口
// focused 是否获得焦点
}
};
iconifyCallback = new GLFWWindowIconifyCallback() {
@Override
public void invoke(long window, boolean iconified) {
// window 窗口
// iconified 是否最小化
}
};
maximizeCallback = new GLFWWindowMaximizeCallback() {
@Override
public void invoke(long window, boolean maximized) {
// window 窗口
// maximized 是否最大化
}
};
posCallback = new GLFWWindowPosCallback() {
@Override
public void invoke(long window, int xpos, int ypos) {
// window 窗口
// xpos x坐标
// ypos y坐标
}
};
refreshCallback = new GLFWWindowRefreshCallback() {
@Override
public void invoke(long window) {
// window 窗口
}
};
sizeCallback = new GLFWWindowSizeCallback() {
@Override
public void invoke(long window, int width, int height) {
// window 窗口
// width 新宽度
// height 新高度
}
};
keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
// window 窗口
// key 按键类型
// scancode 按键的系统专用扫描码
// action 按下的模式(释放、按下、反复)
// mods 修饰符
}
};
charCallback = new GLFWCharCallback() {
@Override
public void invoke(long window, int codepoint) {
// window 窗口
// codepoint 字符unicode编码
}
};
charModsCallback = new GLFWCharModsCallback() {
@Override
public void invoke(long window, int codepoint, int mods) {
// window 窗口
// codepoint 字符unicode编码
// mods 修饰符
}
};
mouseButtonCallback = new GLFWMouseButtonCallback() {
@Override
public void invoke(long window, int button, int action, int mods) {
// window 窗口
// button 鼠标按键类型
// action 按下类型(释放、按下、反复)
// mods 修饰符
}
};
cursorPosCallback = new GLFWCursorPosCallback() {
@Override
public void invoke(long window, double xpos, double ypos) {
}
};
cursorEnterCallback = new GLFWCursorEnterCallback() {
@Override
public void invoke(long window, boolean entered) {
// window 窗口
// entered 是否进入
}
};
scrollCallback = new GLFWScrollCallback() {
@Override
public void invoke(long window, double xoffset, double yoffset) {
// window 窗口
// xoffset x偏移量
// yoffset y偏移量
}
};
dropCallback = new GLFWDropCallback() {
@Override
public void invoke(long window, int count, long names) {
// window 窗口
// count 文件数
// names 名称
}
};
}
- 在Window类中实例化Input,并创建createCallback方法以设置窗口回调
public Input Input = new Input();
public void createCallback() {
GLFW.glfwSetWindowCloseCallback(window, input.closeCallback); // 窗口关闭
GLFW.glfwSetWindowContentScaleCallback(window, input.contentScaleCallback); // 窗口比例更改
GLFW.glfwSetWindowFocusCallback(window, input.focusCallback); // 窗口获得焦点
GLFW.glfwSetWindowIconifyCallback(window, input.iconifyCallback); // 窗口最小化
GLFW.glfwSetWindowMaximizeCallback(window, input.maximizeCallback); // 窗口最大化
GLFW.glfwSetWindowPosCallback(window, input.posCallback); // 窗口坐标改变
GLFW.glfwSetWindowRefreshCallback(window, input.refreshCallback); // 窗口刷新
GLFW.glfwSetWindowSizeCallback(window, input.sizeCallback); // 窗口大小改变
GLFW.glfwSetKeyCallback(window, input.keyCallback); // 按键按下
GLFW.glfwSetCharCallback(window, input.charCallback); // (受修饰符影响)字符输入
GLFW.glfwSetCharModsCallback(window, input.charModsCallback); // (不受修饰符影响)字符输入
GLFW.glfwSetMouseButtonCallback(window, input.mouseButtonCallback); // 鼠标按下
GLFW.glfwSetCursorPosCallback(window, input.cursorPosCallback); // 鼠标指针位置改变
GLFW.glfwSetCursorEnterCallback(window, input.cursorEnterCallback); // 鼠标指针进入窗口
GLFW.glfwSetScrollCallback(window, input.scrollCallback); // 窗口滚动
GLFW.glfwSetDropCallback(window, input.dropCallback); // 文件拖入窗口
}
- 在Input中创建数组保存按下的按键,并在keyCallback和mouseButtonCallback中记录
// 键盘按下按键
public boolean[] pressed_keys = new boolean[GLFW.GLFW_KEY_LAST];
// 鼠标按下按键
public boolean[] pressed_buttons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST];
keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
// window 窗口
// key 按键类型
// scancode 按键的系统专用扫描码
// action 按下的模式(释放、按下、反复)
// mods 修饰符
if(action == GLFW.GLFW_PRESS) pressed_keys[key] = true;
if(action == GLFW.GLFW_RELEASE) pressed_buttons[key] = false;
}
};
mouseButtonCallback = new GLFWMouseButtonCallback() {
@Override
public void invoke(long window, int button, int action, int mods) {
// window 窗口
// button 鼠标按键类型
// action 按下类型(释放、按下、反复)
// mods 修饰符
if(action == GLFW.GLFW_PRESS) pressed_buttons[button] = true;
if(action == GLFW.GLFW_RELEASE) pressed_buttons[button] = false;
}
};
- 在Window.update中检测ESC是否被按下,若是则关闭窗口
if(input.pressed_keys[GLFW.GLFW_KEY_ESCAPE])
GLFW.glfwSetWindowShouldClose(window, true);
- 在Window.create中调用createCallback以设置回调(放在创建窗口代码之后)
createCallback();
- 运行代码,可以发现按下ESC进程便会结束。以下是完整代码
// Main.java
package main;
import org.lwjgl.glfw.GLFW;
import engine.Window;
public class Main implements Runnable{
public Thread game;
public Window window;
public static final int WIDTH = 1280, HEIGHT = 720;
// 初始化
public void init() {
window = new Window(WIDTH, HEIGHT, "Game");
if(!window.create()) System.exit(1); // 窗口创建失败,结束进程
}
// 开始
public void start() {
game = new Thread(this, "game");
game.start();
}
// 运行
public void run() {
init();
// 窗口不应关闭时保持循环
while(!GLFW.glfwWindowShouldClose(window.window)) {
update();
render();
}
}
// 渲染
public void render() {
System.out.println("Game rendered");
}
// 更新
public void update() {
System.out.println("Game updated");
// 更新窗口
window.update();
}
// 主方法
public static void main(String[] argv) {
new Main().start();
}
}
// Window.java
package engine;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL;
import engine.io.Input;
public class Window {
public static int width, height; // 窗口宽度, 长度
public static String title;
public long window;
public Input input = new Input();
@SuppressWarnings("static-access")
public Window(int width, int height, String title) {
this.width = width;
this.height = height;
this.title = title;
}
// 创建窗口,并返回是否创建成功
public boolean create() {
// 初始化GLFW,并处理错误
if(!GLFW.glfwInit()) {
System.err.println("Unable to Init GLFW");
return false;
}
// 创建窗口
window = GLFW.glfwCreateWindow(width, height, title, 0, 0);
/*
* 创建一个窗口及其相关的OpenGL或OpenGL ES上下文
* public static long glfwCreateWindow(int width,
* int height,
* @NativeType("char const *") CharSequence title,
* @NativeType("GLFWmonitor *") long monitor,
* @NativeType("GLFWwindow *") long share)
*
* width 窗口宽度
* height 窗口高度
* title 窗口标题
* monitor 用于全屏模式的显示器,或者用于窗口模式的显示器为NULL
* share 要与之共享资源的窗口,或者不共享资源的窗口为NULL
* */
// 创建窗口失败
if(window == 0) {
System.err.println("Unable to Create Window");
return false;
}
GLFW.glfwMakeContextCurrent(window); // 垂直同步
createCallback();
GLFW.glfwShowWindow(window); // 显示窗口
GLFW.glfwSwapInterval(GLFW.GLFW_TRUE); // 垂直同步
// 创建成功
return true;
}
// 更新窗口
public void update() {
if(input.pressed_keys[GLFW.GLFW_KEY_ESCAPE])
GLFW.glfwSetWindowShouldClose(window, true);
GLFW.glfwPollEvents(); // 处理事件
GLFW.glfwSwapBuffers(window); // 交换窗口缓冲区
}
public void createCallback() {
GLFW.glfwSetWindowCloseCallback(window, input.closeCallback); // 窗口关闭
GLFW.glfwSetWindowContentScaleCallback(window, input.contentScaleCallback); // 窗口比例更改
GLFW.glfwSetWindowFocusCallback(window, input.focusCallback); // 窗口获得焦点
GLFW.glfwSetWindowIconifyCallback(window, input.iconifyCallback); // 窗口最小化
GLFW.glfwSetWindowMaximizeCallback(window, input.maximizeCallback); // 窗口最大化
GLFW.glfwSetWindowPosCallback(window, input.posCallback); // 窗口坐标改变
GLFW.glfwSetWindowRefreshCallback(window, input.refreshCallback); // 窗口刷新
GLFW.glfwSetWindowSizeCallback(window, input.sizeCallback); // 窗口大小改变
GLFW.glfwSetKeyCallback(window, input.keyCallback); // 按键按下
GLFW.glfwSetCharCallback(window, input.charCallback); // (受修饰符影响)字符输入
GLFW.glfwSetCharModsCallback(window, input.charModsCallback); // (不受修饰符影响)字符输入
GLFW.glfwSetMouseButtonCallback(window, input.mouseButtonCallback); // 鼠标按下
GLFW.glfwSetCursorPosCallback(window, input.cursorPosCallback); // 鼠标指针位置改变
GLFW.glfwSetCursorEnterCallback(window, input.cursorEnterCallback); // 鼠标指针进入窗口
GLFW.glfwSetScrollCallback(window, input.scrollCallback); // 窗口滚动
GLFW.glfwSetDropCallback(window, input.dropCallback); // 文件拖入窗口
}
}
// Input.java
package engine.io;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWCharCallback;
import org.lwjgl.glfw.GLFWCharModsCallback;
import org.lwjgl.glfw.GLFWCursorEnterCallback;
import org.lwjgl.glfw.GLFWCursorPosCallback;
import org.lwjgl.glfw.GLFWDropCallback;
import org.lwjgl.glfw.GLFWKeyCallback;
import org.lwjgl.glfw.GLFWMouseButtonCallback;
import org.lwjgl.glfw.GLFWScrollCallback;
import org.lwjgl.glfw.GLFWWindowCloseCallback;
import org.lwjgl.glfw.GLFWWindowContentScaleCallback;
import org.lwjgl.glfw.GLFWWindowFocusCallback;
import org.lwjgl.glfw.GLFWWindowIconifyCallback;
import org.lwjgl.glfw.GLFWWindowMaximizeCallback;
import org.lwjgl.glfw.GLFWWindowPosCallback;
import org.lwjgl.glfw.GLFWWindowRefreshCallback;
import org.lwjgl.glfw.GLFWWindowSizeCallback;
public class Input {
public GLFWWindowCloseCallback closeCallback;
public GLFWWindowContentScaleCallback contentScaleCallback;
public GLFWWindowFocusCallback focusCallback;
public GLFWWindowIconifyCallback iconifyCallback;
public GLFWWindowMaximizeCallback maximizeCallback;
public GLFWWindowPosCallback posCallback;
public GLFWWindowRefreshCallback refreshCallback;
public GLFWWindowSizeCallback sizeCallback;
public GLFWKeyCallback keyCallback;
public GLFWCharCallback charCallback;
public GLFWCharModsCallback charModsCallback;
public GLFWMouseButtonCallback mouseButtonCallback;
public GLFWCursorPosCallback cursorPosCallback;
public GLFWCursorEnterCallback cursorEnterCallback;
public GLFWScrollCallback scrollCallback;
public GLFWDropCallback dropCallback;
// 键盘按下按键
public boolean[] pressed_keys = new boolean[GLFW.GLFW_KEY_LAST];
// 鼠标按下按键
public boolean[] pressed_buttons = new boolean[GLFW.GLFW_MOUSE_BUTTON_LAST];
public Input() {
closeCallback = new GLFWWindowCloseCallback() {
@Override
public void invoke(long window) {
// window 窗口
}
};
contentScaleCallback = new GLFWWindowContentScaleCallback() {
@Override
public void invoke(long window, float xscale, float yscale) {
// window 窗口
// xscale x方向的缩放
// yscale y方向的缩放
}
};
focusCallback = new GLFWWindowFocusCallback() {
@Override
public void invoke(long window, boolean focused) {
// window 窗口
// focused 是否获得焦点
}
};
iconifyCallback = new GLFWWindowIconifyCallback() {
@Override
public void invoke(long window, boolean iconified) {
// window 窗口
// iconified 是否最小化
}
};
maximizeCallback = new GLFWWindowMaximizeCallback() {
@Override
public void invoke(long window, boolean maximized) {
// window 窗口
// maximized 是否最大化
}
};
posCallback = new GLFWWindowPosCallback() {
@Override
public void invoke(long window, int xpos, int ypos) {
// window 窗口
// xpos x坐标
// ypos y坐标
}
};
refreshCallback = new GLFWWindowRefreshCallback() {
@Override
public void invoke(long window) {
// window 窗口
}
};
sizeCallback = new GLFWWindowSizeCallback() {
@Override
public void invoke(long window, int width, int height) {
// window 窗口
// width 新宽度
// height 新高度
}
};
keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {
// window 窗口
// key 按键类型
// scancode 按键的系统专用扫描码
// action 按下的模式(释放、按下、反复)
// mods 修饰符
if(action == GLFW.GLFW_PRESS) pressed_keys[key] = true;
if(action == GLFW.GLFW_RELEASE) pressed_buttons[key] = false;
}
};
charCallback = new GLFWCharCallback() {
@Override
public void invoke(long window, int codepoint) {
// window 窗口
// codepoint 字符unicode编码
}
};
charModsCallback = new GLFWCharModsCallback() {
@Override
public void invoke(long window, int codepoint, int mods) {
// window 窗口
// codepoint 字符unicode编码
// mods 修饰符
}
};
mouseButtonCallback = new GLFWMouseButtonCallback() {
@Override
public void invoke(long window, int button, int action, int mods) {
// window 窗口
// button 鼠标按键类型
// action 按下类型(释放、按下、反复)
// mods 修饰符
if(action == GLFW.GLFW_PRESS) pressed_buttons[button] = true;
if(action == GLFW.GLFW_RELEASE) pressed_buttons[button] = false;
}
};
cursorPosCallback = new GLFWCursorPosCallback() {
@Override
public void invoke(long window, double xpos, double ypos) {
}
};
cursorEnterCallback = new GLFWCursorEnterCallback() {
@Override
public void invoke(long window, boolean entered) {
// window 窗口
// entered 是否进入
}
};
scrollCallback = new GLFWScrollCallback() {
@Override
public void invoke(long window, double xoffset, double yoffset) {
// window 窗口
// xoffset x偏移量
// yoffset y偏移量
}
};
dropCallback = new GLFWDropCallback() {
@Override
public void invoke(long window, int count, long names) {
// window 窗口
// count 文件数
// names 名称
}
};
}
}
版权声明:本文为TianX_Bili原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。