LibGDX Tutorial 4: Xử lý đầu vào phần 1 - Chuột và bàn phím
Bài đăng này đã không được cập nhật trong 9 năm
Xử lý thao tác bàn phím
Chúng ta bắt đầu với việc xử lý thao tác bàn phím, và đây là code:
package com.handlinginputdemo.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class HandlingInputDemo extends ApplicationAdapter {
SpriteBatch batch;
Texture texture;
private Sprite sprite;
@Override
public void create () {
float width = Gdx.graphics.getWidth();
float height = Gdx.graphics.getHeight();
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("dante.png"));
sprite = new Sprite(texture);
sprite.setPosition(width/2 -sprite.getWidth()/2, height/2 - sprite.getHeight()/2);
}
@Override
public void dispose() {
batch.dispose();
texture.dispose();
}
@Override
public void render () {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
if(Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))
sprite.translateX(-1f);
else
sprite.translateX(-10.0f);
}
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
if(Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))
sprite.translateX(1f);
else
sprite.translateX(10.0f);
}
batch.begin();
sprite.draw(batch);
batch.end();
}
}
sprite = new Sprite(texture);
sprite.setPosition(width/2 -sprite.getWidth()/2, height/2 - sprite.getHeight()/2);
Với đoạn code trên, chúng ta tạo ra một sprite
được hiển thị giữa màn hình.
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
if(Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))
sprite.translateX(-1f);
else
sprite.translateX(-10.0f);
}
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
if(Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))
sprite.translateX(1f);
else
sprite.translateX(10.0f);
Hàm translateX()
sử dụng để thay đổi tọa độ của sprite
. Chúng ta kiểm tra xem người dùng nhấn vào nút LEFT
hay RIGHT
. Khi nhấn những phím này kèm theo phím Ctrl
, sprite
sẽ di chuyển từ từ qua trái hoặc phải. Nếu không nhấn Ctrl
, sprite
sẽ di chuyển từng 10px thay vì di chuyển từ từ.
Các bạn cũng có thể sử dụng thêm hàm translateY()
dùng để thay đổi vị trí sprite
trên dưới, sử dụng các phím Input.Keys.UP
và Input.Keys.DOWN
để điều khiển sprite
di chuyển lên xuống. Ngoài ra bạn cũng có thể sử dụng nhiều phím cùng lúc giống như ví dụ của phím Ctrl
phía trên.
Xử lý thao tác với chuột
Bạn có thể thay thế đoạn code sau đây hoặc thêm vào sau đoạn code xử lý thao tác với bàn phím trong hàm render()
.
if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
sprite.setPosition(Gdx.input.getX() - sprite.getWidth()/2,
Gdx.graphics.getHeight() - Gdx.input.getY() - sprite.getHeight()/2);
}
if(Gdx.input.isButtonPressed(Input.Buttons.RIGHT)){
sprite.setPosition(Gdx.graphics.getWidth()/2 -sprite.getWidth()/2,
Gdx.graphics.getHeight()/2 - sprite.getHeight()/2);
}
Ở đây chúng ta sử dụng hàm isButtonPressed
để kiểm tra phím chuột được nhấn, sử dụng Gdx.input.getX()
và Gdx.input.getY()
để thiết lập vị trí đưa sprite
tới đó. Phép tính toán có vẻ trông hơi rắc rối, tại sao chúng ta không chỉ đơn giản là đưa sprite
tới vị trí getX/Y
. Có 2 lý do, đầu tiên nếu chúng ta thiết lập sprite
ở vị trí đó, tức là đưa sprite
tới vị trí đó theo tọa độ của góc trái bên dưới, chúng ta cần có 1 nửa chiều rộng và 1 nửa chiều cao của sprite
. Lý do tiếp theo xuất phát từ thực tế là LibGDX đặt gốc đặt ở góc trái bên dưới, nhưng vị trí con chuột là tương đối so với góc trên bên trái. Đơn giản chỉ cần trừ đi các vị trí từ độ cao màn hình sẽ cho bạn biết vị trí của các con chuột trong tọa độ màn hình. Chúng ta cũng kiểm tra xem nếu người dùng nhấn vào nút chuột phải, chúng ta đặt lại vị trí sprite
tại vị trí trung tâm.
Sự kiện xử lý bàn phím và chuột
Bây giờ chúng ta sẽ xem xét việc xử lý cả 2 ví dụ trên bằng cách tiếp cận theo sự kiện:
package com.handlinginputdemo.game;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class HandlingInputDemo implements ApplicationListener, InputProcessor {
private SpriteBatch batch;
private Texture texture;
private Sprite sprite;
private float positionX, positionY;
@Override
public void create () {
float width = Gdx.graphics.getWidth();
float height = Gdx.graphics.getHeight();
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("dante.png"));
sprite = new Sprite(texture);
positionX = width/2 - sprite.getWidth()/2;
positionY = width/2 - sprite.getWidth()/2;
sprite.setPosition(width/2 - sprite.getWidth()/2, height/2 - sprite.getHeight()/2);
Gdx.input.setInputProcessor(this);
}
@Override
public void resize(int width, int height) {
}
@Override
public void dispose() {
batch.dispose();
texture.dispose();
}
@Override
public void render () {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
sprite.setPosition(positionX, positionY);
batch.begin();
sprite.draw(batch);
batch.end();
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public boolean keyDown(int keycode) {
float moveAmount = 10.0f;
if(Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT))
moveAmount = 1f;
if(keycode == Input.Keys.LEFT)
positionX -= moveAmount;
if(keycode == Input.Keys.RIGHT)
positionX += moveAmount;
return true;
}
@Override
public boolean keyUp(int keycode) {
return false;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if(button == Input.Buttons.LEFT){
positionX = screenX - sprite.getWidth()/2;
positionY = Gdx.graphics.getHeight() - screenY - sprite.getHeight()/2;
}
if(button == Input.Buttons.RIGHT){
positionX = Gdx.graphics.getWidth()/2 - sprite.getWidth()/2;
positionY = Gdx.graphics.getHeight()/2 - sprite.getHeight()/2;
}
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
}
Các bạn sẽ thấy code khác trước một chút. Chúng ta có thể nhận thấy ngay từ việc khai báo lớp:
public class HandlingInputDemo implements ApplicationListener, InputProcessor {
Chúng ta đang implements một interface khác, đó là InputProcessor
, như bạn có thể thấy một số phương thức được ghi đè. Những phương thức quan trọng nhất mà chúng ta cần quan tâm trong ví dụ này là keyDown
và touchDown
. Ngoài việc cài đặt các phương thức của interface, chúng ta cũng cần phải đăng ký InputProcessor
, điều này được thực hiện như sau:
Gdx.input.setInputProcessor(this);
Code trong hàm keyDown
hoàn toàn tương tự như code xử lý thao tác với bàn phím phía trên. Code trong hàm touchDown
cũng tương tự với code xử lý thao tác với chuột, tuy nhiên điều bạn cần quan tâm là touch có nghĩa là chạm, LibGdx xử lý việc chạm vào màn hình hoàn toàn giống với chuột. Nhưng nếu chạm nhiều ngón tay thì sao? Bạn đừng lo, chúng ta sẽ nhắc lại vấn đề này khi khi xử lý thao tác với màn hình cảm ứng.
Source code
Bạn có có thể tham khảo source code của project này tại đây.
All rights reserved