libgdx摄像头的移动

简介: 本文讲解了在libgdx游戏框架中如何实现2D和3D摄像头的移动。对于2D,使用OrthographicCamera并通过键盘输入实现摄像头的平移和缩放;对于3D,使用PerspectiveCamera和FirstPersonCameraController实现类似第一人称射击游戏的视角控制,允许玩家使用WSAD键进行移动。文章提供了详细的代码示例和结果展示图。

概述:要知道,做一个游戏,摄像头是必不可少的。接下来,我将讲解libgdx里面摄像头的移动

2d摄像头OrthographicCamera也叫做正交相机

结果展示:

按上下左右是可以移动的

OrthographicCamera camera的使用:
完整代码:

package com.brentaureli.mariobros.cam;


import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;

import static com.badlogic.gdx.Gdx.gl;

public class T1 implements ApplicationListener {

    private OrthographicCamera camera;
    private float VIEWPORT_WIDTH=100f;
    private float VIEWPORT_HEIGHT=100f;
    private SpriteBatch batch;
    private Sprite sprite;
    @Override
    public void create() {
        sprite=new Sprite(new Texture(Gdx.files.internal("block.png")));
        sprite.setSize(VIEWPORT_WIDTH,VIEWPORT_HEIGHT);
        sprite.setPosition(0, 0);
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();
        camera=new OrthographicCamera(100,100*h/w);
        camera.position.set(15f,11.25f,0);
        camera.update();
        batch=new SpriteBatch();
    }

    @Override
    public void resize(int width, int height) {

        //调整窗口,相机位置不变
        camera.viewportWidth = 30f;
        camera.viewportHeight = 30f * height / width;
        camera.update();
    }

    @Override
    public void render() {

        handleInput();
        resetCamera();
        camera.update();
        batch.setProjectionMatrix(camera.combined);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        sprite.draw(batch);
        batch.end();
    }

    private void resetCamera() {
        if (Gdx.input.isKeyPressed(Input.Keys.R)) {
            camera.position.set(camera.viewportWidth / 2f, camera.viewportHeight / 2f, 0);
            camera.zoom = 1;
            camera.rotate(0, 0, 0, 1);
        }
    }

    private void handleInput() {
        //放大相机
        if (Gdx.input.isKeyPressed(Input.Keys.A)) {
            camera.zoom += 0.02;
        }
        //缩小相机
        if (Gdx.input.isKeyPressed(Input.Keys.Q)) {
            camera.zoom -= 0.02;
        }
        //左移相机
        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
            camera.translate(-3, 0, 0);
        }
        //右移相机
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
            camera.translate(3, 0, 0);
        }
        //下移相机
        if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
            camera.translate(0, -3, 0);
        }
        //上移相机
        if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
            camera.translate(0, 3, 0);
        }
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void dispose() {
        sprite.getTexture().dispose();
        batch.dispose();
    }
}

主类完整代码:

package com.brentaureli.mariobros.desktop;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.brentaureli.mariobros.cam.T1;

public class DesktopLauncher {
    public static void main (String[] arg) {
        Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
        config.setForegroundFPS(60);
        config.setTitle("camera-example");
        new Lwjgl3Application(new T1(), config);
    }
}

先设置了一个背景

private Sprite sprite;
sprite=new Sprite(new Texture(Gdx.files.internal("block.png")));
sprite.setSize(VIEWPORT_WIDTH,VIEWPORT_HEIGHT);
sprite.setPosition(0, 0);

设置了背景的图片,背景的大小,背景位置。
接下来的代码:

 float w = Gdx.graphics.getWidth();
 float h = Gdx.graphics.getHeight();
 camera=new OrthographicCamera(100,100*h/w);
 camera.position.set(15f,11.25f,0);
 camera.update();
 batch=new SpriteBatch();

设置了camera的范围,camera的位置 camera.update();这个是每次更新camera的位置呀什么的都要进行一次更新。然后就是new了一个缓冲。
接下来的代码:

        //调整窗口,相机位置不变
        camera.viewportWidth = 30f;
        camera.viewportHeight = 30f * height / width;
        camera.update();

就是单纯的再调试了一下窗口。
接下来的代码:

private void handleInput() {
        //放大相机
        if (Gdx.input.isKeyPressed(Input.Keys.A)) {
            camera.zoom += 0.02;
        }
        //缩小相机
        if (Gdx.input.isKeyPressed(Input.Keys.Q)) {
            camera.zoom -= 0.02;
        }
        //左移相机
        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
            camera.translate(-3, 0, 0);
        }
        //右移相机
        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
            camera.translate(3, 0, 0);
        }
        //下移相机
        if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
            camera.translate(0, -3, 0);
        }
        //上移相机
        if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
            camera.translate(0, 3, 0);
        }
    }

添加了一下键盘输入的按键,camera.zoom += 0.02;就是将摄像的范围扩大同理camera.zoom -= 0.02;就是减少,而 camera.translate就是移动位置。
接下来的代码:

 private void resetCamera() {
        if (Gdx.input.isKeyPressed(Input.Keys.R)) {
            camera.position.set(camera.viewportWidth / 2f, camera.viewportHeight / 2f, 0);
            camera.zoom = 1;
            camera.rotate(0, 0, 0, 1);
        }
    }

就是单纯的按r重置摄像头
然后就是:

        camera.update();
        batch.setProjectionMatrix(camera.combined);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.begin();
        sprite.draw(batch);

        batch.end();

将摄像头进行更新,然后 batch.setProjectionMatrix(camera.combined);这个,这个可以说是固定搭配,就是配置一下摄像头。

        batch.begin();
        sprite.draw(batch);
        batch.end();

缓存区打开,然后画图,end方法结尾。这算是固定搭配。

3D摄像头PerspectiveCamera也叫做透视相机

完整代码:

package com.brentaureli.mariobros.cam;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
import com.badlogic.gdx.graphics.g3d.utils.FirstPersonCameraController;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;

import static com.badlogic.gdx.Gdx.gl;

public class T2 implements ApplicationListener {
    private PerspectiveCamera camera;
    private FirstPersonCameraController cameraController;
    private ModelBatch batch;
    private ModelBuilder builder;
    private Texture texture;
    private Model model;
    private  ModelInstance instance;
    @Override
    public void create() {
        camera=new PerspectiveCamera(70, Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
        camera.position.set(0,0,0);
        camera.near=0.1f;
        camera.far=1000f;
        camera.update();
        cameraController=new FirstPersonCameraController(camera);
        Gdx.input.setInputProcessor(cameraController);
        cameraController.update();

        batch=new ModelBatch();
        builder=new ModelBuilder();
        texture=new Texture(Gdx.files.internal("block.png"));
        Material material=new Material(new TextureAttribute(TextureAttribute.Diffuse,texture));
        int attributes= VertexAttributes.Usage.Position|VertexAttributes.Usage.TextureCoordinates;
        model= builder.createBox(3, 3, 3, material, attributes);
        instance= new ModelInstance(model);
        instance.transform.setToTranslation(0,0,-5);

    }

    @Override
    public void resize(int width, int height) {
        camera.viewportWidth=width;
        camera.viewportHeight=height;
        camera.update();
        cameraController.update();
    }

    @Override
    public void render() {
       gl.glClear(GL20.GL_COLOR_BUFFER_BIT|GL20.GL_DEPTH_BUFFER_BIT);
       camera.update();
       cameraController.update();
       batch.begin(camera);
       batch.render(instance);
       batch.end();
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void dispose() {

    }
}

主类就换个类名就行了,接下来是结果展示图:

按wsad可以上下左右移动。
由于篇幅可能过长,下一章也许会讲。

目录
相关文章
|
3月前
|
传感器 vr&ar 图形学
Vuforia⭐️Unity实现对手机陀螺仪的调用
Vuforia⭐️Unity实现对手机陀螺仪的调用
|
Android开发
[笔记]Android开发之相机开发 Camera1、2、X
[笔记]Android开发之相机开发 Camera1、2、X
101 0
|
运维 开发工具 C#
总结两种使用OpenCv连接海康相机播放视频画面方法
总结两种使用OpenCv连接海康相机播放视频画面方法
2076 0
|
计算机视觉 Kotlin
OpenCV + Kotlin 实现 USB 摄像头(相机)实时画面、拍照
OpenCV + Kotlin 实现 USB 摄像头(相机)实时画面、拍照
749 0
|
数据库 计算机视觉 Python
总结两种使用OpenCv连接海康相机播放视频画面方法(demo)
总结两种使用OpenCv连接海康相机播放视频画面方法(demo)
554 0
|
Android开发
Android开发技巧——Camera拍照功能
本篇是我对开发项目的拍照功能过程中,对Camera拍照使用的总结。由于camera2是在api level 21(5.0.1)才引入的,而Camera到6.0仍可使用,所以暂未考虑camera2。
1214 0