Orthographic camera-正交摄像头

来源:互联网 发布:火影人物实力排名知乎 编辑:程序博客网 时间:2024/05/22 15:09

This page presents the OrthographicCamera class and usage. The orthographic camera is to be used in 2D environments only as it implements a parallel (orthographic) projection and there will be no scale factor for the final image regardless where the objects are placed in the world.

由于内部是平行投影,常用于2D环境,不管对象所放的位置,对最后的结果不会有缩放效果。

Description 
The Camera class operates as a very simple real world camera. It is possible to

move and rotate the camera around,
zoom in and out,
change the viewport,
project/unproject points to and from window coordinate/ world space

就像真是环境的摄像头,实现了移动旋转,放大缩小,改变视窗,窗口坐标和世界坐标的相互投影


Using the camera is the easy way to move around a game world without having to manually operate on the matrices. All the projection and view matrix operations are hidden in the implementation. 下面看个例子

<span style="font-family:Microsoft YaHei;font-size:14px;">import com.badlogic.gdx.ApplicationListener;import com.badlogic.gdx.Gdx;import com.badlogic.gdx.Input;import com.badlogic.gdx.backends.lwjgl.LwjglApplication;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;public class OrthographicCameraExample implements ApplicationListener {    static final int WORLD_WIDTH = 100;// 定义world的宽和高    static final int WORLD_HEIGHT = 100;    private OrthographicCamera cam;//控制观察    private SpriteBatch batch; //渲染出这个world    private Sprite mapSprite; //绘制地图    private float rotationSpeed;//旋转速度    @Override    public void create() {        rotationSpeed = 0.5f;        mapSprite = new Sprite(new Texture(Gdx.files.internal("sc_map.png")));        mapSprite.setPosition(0, 0);        mapSprite.setSize(WORLD_WIDTH, WORLD_HEIGHT);//100*100Unit 这里不是像素        float w = Gdx.graphics.getWidth(); //这里是我们设备的宽 和 高 单位是像素        float h = Gdx.graphics.getHeight();        // Constructs a new OrthographicCamera, using the given viewport width and height        // Height is multiplied by aspect ratio.        cam = new OrthographicCamera(30, 30 * (h / w)); // 视窗的宽和高决定我们可以看到的整个世界的多大部分,并且根据设备宽高比例做了调整        cam.position.set(cam.viewportWidth / 2f, cam.viewportHeight / 2f, 0);//摄像头的位置        cam.update(); //最重要的一步,更新摄像头,才能让前面的设置生效        batch = new SpriteBatch();    }    @Override    public void render() {        handleInput();        cam.update();        batch.setProjectionMatrix(cam.combined);// 将精灵和摄像头关联(view 和 投影矩阵)        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);        batch.begin();        mapSprite.draw(batch);        batch.end();    }    private void handleInput() { //按键的处理        if (Gdx.input.isKeyPressed(Input.Keys.A)) {            cam.zoom += 0.02;        }        if (Gdx.input.isKeyPressed(Input.Keys.Q)) {            cam.zoom -= 0.02;        }        if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {            cam.translate(-3, 0, 0);        }        if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {            cam.translate(3, 0, 0);        }        if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {            cam.translate(0, -3, 0);        }        if (Gdx.input.isKeyPressed(Input.Keys.UP)) {            cam.translate(0, 3, 0);        }        if (Gdx.input.isKeyPressed(Input.Keys.W)) {            cam.rotate(-rotationSpeed, 0, 0, 1);        }        if (Gdx.input.isKeyPressed(Input.Keys.E)) {            cam.rotate(rotationSpeed, 0, 0, 1);        }<span style="white-space:pre"></span>//下面5行,控制摄像头的不会缩放太大或大小,保证在0< delta < 100 之间        cam.zoom = MathUtils.clamp(cam.zoom, 0.1f, 100/cam.viewportWidth);        float effectiveViewportWidth = cam.viewportWidth * cam.zoom;        float effectiveViewportHeight = cam.viewportHeight * cam.zoom;        cam.position.x = MathUtils.clamp(cam.position.x, effectiveViewportWidth / 2f, 100 - effectiveViewportWidth / 2f);        cam.position.y = MathUtils.clamp(cam.position.y, effectiveViewportHeight / 2f, 100 - effectiveViewportHeight / 2f);    }    //改变大小的时候,不同的分辨率和 长宽比的处理策略    @Override    public void resize(int width, int height) {        cam.viewportWidth = 30f; // 固定的30unit        cam.viewportHeight = 30f * height/width;        cam.update();        //cam.viewportWidth = width/32f;  // We will see width/32f units! 根据分辨率来        //cam.viewportHeight = cam.viewportWidth * height/width;        //cam.update();   }    @Override    public void resume() {    }    @Override    public void dispose() {        mapSprite.getTexture().dispose();        batch.dispose();    }    @Override    public void pause() {    }    public static void main(String[] args) {        new LwjglApplication(new OrthographicCameraExample());    }}</span>

Many people make the mistake of thinking in pixels when it comes to their world, and this is something that you should avoid doing. It leads to unnecessary multiplying and dividing by constants, having weird "Pixel per unit" ratios dotted around your code,poor understanding of the pipeline and it confuses you! There are many other problems, which can be easily avoided when you stop "thinking" in pixels.


Some examples - 
If we created our camera with viewport width of 100 and viewport height of 100 ('new OrthographicCamera(100, 100)') and centered it correctly, we would be able to see the 'whole' map, our 'whole' world at once.
 全部都可以看见,不需要移动
If we created our camera with viewport width of 100 and viewport height of 50 ('new OrthographicCamera(100, 50)') we would be able to see 'half' of the map at any given time 

高度的一半

If we created our camera with viewport width of 50 and viewport height of 50 ('new OrthographicCamera(50, 50)') we would be able to see a 'quarter' of the map at any given time

宽度的一半

0 0
原创粉丝点击