pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

Camera 如何在 Libgdx 和 Viewport 中工作

How Camera works in Libgdx and together with Viewport(Camera 如何在 Libgdx 和 Viewport 中工作)
本文介紹了Camera 如何在 Libgdx 和 Viewport 中工作的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

如果您使用 LibGdx,您很快就會來到相機和視口.如果您第一次使用相機和視口,您會遇到一些關于它如何工作以及如何使用它的問題.所以:

  • 如何在 LibGdx 中使用相機?視口的寬度和高度是多少?
  • 什么是視口,如何使用它以及它如何與相機配合使用?

解決方案

如何在 LibGdx 中使用相機?什么是視口寬度和高度?

首先,重要的是您要知道相機使用的是世界單位而不是像素.世界單位不是常規單位.您可以自己定義一個世界單位是多少.以后再說吧.

首先,我們創建一個OrthographicCamera、一個SpriteBatch和一個Texture:

private OrthographicCamera 相機;私有 SpriteBatch 批處理;私人紋理img;@覆蓋公共無效創建(){//我們創建一個OrthographicCamera,通過它我們可以看到50x50的世界單位相機 = 新的 OrthographicCamera(50,50);批處理 = 新 SpriteBatch();img = new Texture("badlogic.jpg");}

我們創建一個 OrthographicCamera 并在構造函數中定義如果我們通過這個相機觀察我們的世界,我們會看到多少個世界單位.在我們的示例中,50 x 50 世界單位是視口寬度和高度.所以我們創建了一個視口寬度和高度為 50 的相機.

在 render() 方法中我們渲染我們的圖像:

@Override公共無效渲染(){//清屏(1)Gdx.gl.glClearColor(1, 1, 1, 1);Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);//設置SpriteBatch的ProjectionMatrix(2)batch.setProjectionMatrix(camera.combined);批處理.開始();//在位置 0, 0 上繪制圖像,寬度為 25,高度為 25 (3)batch.draw(img, 0, 0, 25, 25);批處理.end();}

(1) 清除屏幕,如果我們不這樣做,每個紋理都會覆蓋另一個,如果我們繪制動畫,我們將看到舊的幀.

(2) batch 是我們的抽屜,他繪制我們的圖像、動畫等.默認情況下,他繪制了一個世界,其中有很多世界單位,例如屏幕有像素,所以在這種情況下 1 個世界單位 =1 像素.但現在我們將看到 50 x 50 世界單位,不管屏幕有多大.要說 Batch 應該畫出我們通過相機看到的東西,我們必須調用:batch.setProjectionMatrix(camera.combined);

(3) 現在我們在位置 0,0 上繪制 img 但是 0, 0 并不意味著在 Pixel 位置 0,0 上,這意味著圖像將在 World 位置 0,0 上繪制寬度和高度也不是像素,而是世界單位,因此 img 將在位置 0,0 25x25 世界單位大上繪制.因此,在 50x50 的視口上,圖像占據了整個屏幕的四分之一.

圖像完全按預期填充了整個屏幕的四分之一.但是為什么它在右上角而不是在左下角呢?

問題是相機點的中心在位置 0,0

所以我們的圖像被繪制在位置 0,0 他填充右上角.我們必須設置相機的位置,使 0,0 在左下角:

camera = new OrthographicCamera(50,50);camera.position.set(camera.viewportWidth/2, camera.viewportHeight/2, 0);

在 render() 方法中,我們必須添加 camera.update(),因為每次我們更改相機的位置或比例或其他內容時,我們都必須更新相機.

現在圖像在左下角.

像素在哪里?

我們總是談論世界單位,但像素在哪里?像素還在.如果我們的屏幕尺寸為 200 x 200 像素,則批處理將始終繪制 200 x 200 像素.使用方法 batch.setProjectionMatrix(camera.combined); 我們只說批次有多少世界單位是一個像素.

如果我們有一個 200 x 200 像素的屏幕并且我們創建一個具有 50 x 50 世界單位的視口的相機,那么 SpriteBatch 知道 1 WorldUnit = 4 像素.現在我們繪制一個 25 x 25 World Units 大的圖像,SpriteBatch 知道他必須繪制 25 * 4 = 100 像素大的圖像.

所以像素仍然存在,但在世界單位中更容易思考.如果還不夠清楚,這里有一點更詳細的描述:

圖像的比率為 1,因為 50(寬度)/50(高度)= 1,因此圖像將始終具有相同的寬度和高度.側面的條在我們的視口之外,將以您在此處定義的顏色繪制:Gdx.gl.glClearColor(1, 1, 1, 1);

擴展視口

也許我們不會在旁邊設置欄,然后我們可以使用 ExtendViewport.ExtendViewport 通過在一個方向上擴展世界來保持世界縱橫比沒有條.意味著在寬高比較大的屏幕上,您會看到更多的世界.

在 400x200 縱橫比 = (400/200 = 2) 的屏幕上,您將看到比在 300x200 (300/200 = 1.5) 的屏幕上看到的更多;

為了顯示這一點,創建一個 ExtendViewport 并繪制大于視口的圖像和第二個小圖像:

camera = new OrthographicCamera(50, 50);camera.position.set(camera.viewportWidth/2, camera.viewportHeight/2, 0);viewport = new ExtendViewport(camera.viewportWidth, camera.viewportHeight, camera);//在 render() 方法中批處理.開始();batch.draw(img, 0, 0, 100, 50);batch.draw(img, -20, 0, 20, 20);批處理.end();

如果我們現在以 200x200 的屏幕尺寸啟動我們的程序,我們會看到:

如果我們在 x 軸上調整屏幕的大小來使屏幕更寬:

現在我們可以看到第一張圖片和第二張圖片的更多信息,但比例始終相同.圖像被拉伸只是因為我們將其繪制為 100x50,而不是因為調整大小.

如果您將了解更多信息、閱讀并查看一些教程并閱讀 LibGdx wiki,我希望這將解決一些關于相機和視口的問題:https://github.com/libgdx/libgdx/wiki

If you work with LibGdx it goes not long until you come to Camera and viewport. If you work the first time with camera and Viewport you get some questions about how it works and how to use it. So:

  • How can I use a Camera in LibGdx? What's viewport width and height?
  • What is a Viewport, how can I use it and how it works together with the Camera?

解決方案

How can I use a Camera in LibGdx? What's viewport width and height?

Firstly it's important that you know the Camera works with World units not with Pixels. World units are not a regular Unit. You self can define how much one World Unit is. Later more.

First, we create an OrthographicCamera a SpriteBatch and a Texture:

private OrthographicCamera camera;
private SpriteBatch batch;
private Texture img;

@Override
public void create () {
    //We create a OrthographicCamera through which we see 50x50 World Units
    camera = new OrthographicCamera(50,50);
    batch = new SpriteBatch();
    img = new Texture("badlogic.jpg");
}

We create a OrthographicCamera and in the Constructor we define how many World Units we see if we look through this camera into our world. In our example 50 x 50 World Units these are the viewport width and height. So we have created a Camera with a viewport width and height of 50.

In the render() method we render our image:

@Override
public void render () {
    //Clear the screen (1)
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    //Set ProjectionMatrix of SpriteBatch (2)
    batch.setProjectionMatrix(camera.combined);

    batch.begin();
    //Draw image on position 0, 0 with width 25 and height 25 (3)
    batch.draw(img, 0, 0, 25, 25); 
    batch.end();
}

(1) Clear the Screen, if we don't do that every Texture will draw over the other and if we draw a Animation we will see the old Frames.

(2) The batch is our Drawer he draws our Images, Animations etc. Default he draws a World which has so many World Units like the Screen has Pixels so in this case 1 World Unit = 1 Pixel. But now we will see 50 x 50 World Units doesn't matter how big the screen is. To say the Batch that he should draw what we see through our camera we must call: batch.setProjectionMatrix(camera.combined);

(3) Now we draw our img on Position 0,0 But 0, 0 doesn't mean on Pixel position 0,0 it means the Image will be drawn on World position 0,0 also width and height are not in Pixels they are in World units so the img will be drawn on Position 0,0 25x25 World Units big. So on a 50x50 viewport, the image fills one-quarter of the whole screen.

The Image fill one-quarter of the whole screen exactly as expected. But why it is on the right top and not on the bottom left?

The Problem is that the center of the Camera point on the position 0,0

So our Image is drawn on position 0,0 he fills the top right corner. We must set the position of the camera so 0,0 is in the bottom left corner:

camera = new OrthographicCamera(50,50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);

In the render() method we must add camera.update() because every time we change the position or the scale or what else of the camera we must update the camera.

Now the Image is in the bottom left.

Where are the Pixels?

We always speak about World units but where are the Pixels? The pixels are still there. If we have a Screen size of 200 x 200 pixels the batch will always draw 200 x 200 pixels. With the method batch.setProjectionMatrix(camera.combined); we only say the batch how much World Units are one Pixel.

If we have a Screen with 200 x 200 pixels and we create a Camera with a viewport of 50 x 50 world units the SpriteBatch know 1 WorldUnit = 4 Pixels. Now we draw a Image which is 25 x 25 World Units big the SpriteBatch knows he must draw the image 25 * 4 = 100 pixel big.

So the pixels still there but it's easier to think in World Units. If it's not clear enough here is a little bit more detailed description: Libgdx's World Units

Box2d

It's also very important to think in World Units if you use Box2d because Box2d works with Meters. So if you create a Body with a Force off 5 on the x axis, the Body is 5 m/s fast.

And now it's very cool to work with World Units because you can say 1 World Unit = 1 Meter so you can create a object with a width of 10 and you know after one second the Body will be in the Center of the Object. If you work with Pixels you will have a Problem if you have a different Screensize.

What is a Viewport, how can I use it and how it works together with the Camera?

Now we have the big Problem about different Screen sizes. Suddenly we have a Screen size of 350 x 200 pixels, now the Image will be stretched and don't look so nice as before.

For this Problem we use Viewports a few Viewports are StretchViewport, FitViewport and ExtendViewport. All viewports you can find here: https://github.com/libgdx/libgdx/wiki/Viewports.

Firstly what is a Viewport.

Imagine the camera is a speaker who speaks English. Different Screen Sizes are other People who speak German, French, Chinese etc. and the Viewport is the translator. The Translator doesn't change the sense of that what the English Speaker says but he adapts it so the others can understand it. Same are camera and Viewport. Viewport doesn't say or change what you can see on your screen if you run the program. He only handles that you always see the same on different Screen sizes. A Camera can life without Viewport. A Viewport not without Camera.

Add a viewport Object:

private Viewport viewport;

and the resize() method:

@Override
public void resize (int width, int height) {
    viewport.update(width, height);
}

StretchViewport

Create a StretchViewport:

camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new StretchViewport(camera.viewportWidth, camera.viewportHeight, camera);

In the StretchViewport Constructor, we define the viewport width and height and the Camera.

Now we get the same result as before if we have different Screensizes the Images will be stretched.

FitViewport

Maybe we won't stretch our Images we will matter about the ratio of x and y.

The ratio of x and y means: is an Object 2 width and 1 height he will always twice as wide as high for example 200x100, 30x15 but not 20x15.

Create a FitViewport:

camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new FitViewport(camera.viewportWidth, camera.viewportHeight, camera);

Now the Image will always be a square. To see the Bars on the Side lets draw the Image as big as our viewport:

batch.draw(img, 0, 0, 50, 50);

The Image has a Ratio of 1 because of 50(width)/50(height) = 1 so the Image will always have the same width and height. The Bars on the side are outside of our Viewport and will be drawn in the color you define here: Gdx.gl.glClearColor(1, 1, 1, 1);

ExtendViewport

Maybe we won't Bars on the Side then we can take a ExtendViewport. The ExtendViewport keeps the world aspect ratio without bars by extending the world in one direction. Means on a screen where the aspect ratio between width and height are bigger you will see more of the world.

On a screen 400x200 aspect ration = (400/200 = 2) you will see more than on a screen of 300x200 (300/200 = 1.5);

To show this create a ExtendViewport and draw the Image bigger than the viewport and a second small Image:

camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new ExtendViewport(camera.viewportWidth, camera.viewportHeight, camera);

// in render() method
batch.begin();
batch.draw(img, 0, 0, 100, 50);
batch.draw(img, -20, 0, 20, 20);
batch.end();

If we now start our Program with a Screen size of 200x200 we see:

And if we resize the Screen on x axis To make the screen wider:

Now we can see more off the first Image and additinal the Second image but the ratio will always be the same. The Image is only stretched because we draw it 100x50 not because of resizing.

I hope this will clear some Questions about Camera and Viewport if you will learn more, read and look some tutorials and read the LibGdx wiki: https://github.com/libgdx/libgdx/wiki

這篇關于Camera 如何在 Libgdx 和 Viewport 中工作的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Why does the android emulator camera stop unexpectedly?(為什么android模擬器相機會意外停止?)
Android camera , onPictureTaken(byte[] imgData, Camera camera) method amp; PictureCallback never called(Android camera , onPictureTaken(byte[] imgData, Camera camera) 方法 amp;PictureCallback 從未調用過) - IT屋-程序員軟件開發技
Understanding the libGDX Projection Matrix(了解 libGDX 投影矩陣)
QR code reading with camera - Android(使用相機讀取二維碼 - Android)
IP camera with OpenCv in Java(Java中帶有OpenCv的IP攝像頭)
Android mock Camera(Android 模擬相機)
主站蜘蛛池模板: 国际金融网_每日财经新资讯网 | 化妆品加工厂-化妆品加工-化妆品代加工-面膜加工-广东欧泉生化科技有限公司 | 好笔杆子网 - 公文写作学习交流分享平台| 中国品牌门窗网_中国十大门窗品牌_著名门窗品牌 | 橡胶膜片,夹布膜片,橡胶隔膜密封,泵阀设备密封膜片-衡水汉丰橡塑科技公司网站 | 广州小程序开发_APP开发公司_分销商城系统定制_小跑科技 | 青岛侦探_青岛侦探事务所_青岛劝退小三_青岛调查出轨取证公司_青岛婚外情取证-青岛探真调查事务所 | 轴承振动测量仪电箱-轴承测振动仪器-测试仪厂家-杭州居易电气 | 高压直流电源_特种变压器_变压器铁芯-希恩变压器定制厂家 | 蔬菜清洗机_环速洗菜机_异物去除清洗机_蔬菜清洗机_商用洗菜机 - 环速科技有限公司 | 注塑_注塑加工_注塑模具_塑胶模具_注塑加工厂家_深圳环科 | 家用净水器代理批发加盟_净水机招商代理_全屋净水器定制品牌_【劳伦斯官网】 | 儿童语言障碍训练-武汉优佳加感统文化发展有限公司 | 长沙网站建设制作「网站优化推广」-网页设计公司-速马科技官网 | 淄博不锈钢,淄博不锈钢管,淄博不锈钢板-山东振远合金科技有限公司 | 香蕉筛|直线|等厚|弧形|振动筛|香蕉筛厂家-洛阳隆中重工 | 济南办公室装修-厂房装修-商铺装修-工装公司-山东鲁工装饰设计 | 上海盐水喷雾试验机_两厢式冷热冲击试验箱-巨怡环试 | 咖啡加盟-咖啡店加盟-咖啡西餐厅加盟-塞纳左岸咖啡西餐厅官网 | 六自由度平台_六自由度运动平台_三自由度摇摆台—南京全控科技 | 转向助力泵/水泵/发电机皮带轮生产厂家-锦州华一精工有限公司 | 联系我们老街华纳娱乐公司官网19989979996(客服) | 淘气堡_室内儿童乐园_户外无动力儿童游乐设备-高乐迪(北京) | 东莞爱加真空科技有限公司-进口真空镀膜机|真空镀膜设备|Polycold维修厂家 | 圣才学习网-考研考证学习平台,提供万种考研考证电子书、题库、视频课程等考试资料 | 多功能真空滤油机_润滑油全自动滤油机_高效真空滤油机价格-重庆润华通驰 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 湖南专升本-湖南省专升本报名-湖南统招专升本考试网 | 开业庆典_舞龙舞狮_乔迁奠基仪式_开工仪式-神挚龙狮鼓乐文化传媒 | ★店家乐|服装销售管理软件|服装店收银系统|内衣店鞋店进销存软件|连锁店管理软件|收银软件手机版|会员管理系统-手机版,云版,App | 云南标线|昆明划线|道路标线|交通标线-就选云南云路施工公司-云南云路科技有限公司 | 杭州公司变更法人-代理记账收费价格-公司注销代办_杭州福道财务管理咨询有限公司 | 山东艾德实业有限公司 | 温室大棚建设|水肥一体化|物联网系统 | 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 淘剧影院_海量最新电视剧,免费高清电影随心观看 | 深圳货架厂_仓库货架公司_重型仓储货架_线棒货架批发-深圳市诺普泰仓储设备有限公司 | 生物制药洁净车间-GMP车间净化工程-食品净化厂房-杭州波涛净化设备工程有限公司 | 深圳市索富通实业有限公司-可燃气体报警器 | 可燃气体探测器 | 气体检测仪 | 合肥白癜风医院_[治疗白癜风]哪家好_合肥北大白癜风医院 | 深圳天际源广告-形象堆头,企业文化墙,喷绘,门头招牌设计制作专家 |