您的位置:首页 > 其它

Orthographic camera-正交摄像头

2016-04-11 14:46 260 查看
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

宽度的一半
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: