android游戏开发框架libgdx的使用(二)--图形绘制

转自:http://www.apkbus.com/forum.php?mod=viewthread&tid=19746&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline%26orderby%3Ddateline

 

首先了解一下何为texture。按照英文解释来理解:一个图片从原始格式解码并上传到GPU就被称为纹理。(说实话我不是很清楚这个的定义哈,求指点)

为了绘制texture,常常使用几何来描述,通过几何对应的顶点来描述纹理。比如要描述一个矩形,可以通过描述每个顶点来描述矩形。

要绘图时,首先要绑定纹理,然后传递一个几何描述给OpenGL进行绘制。而绘图的大小和位置由几何描述和OpenGL的viewport的设置共同决定。

当然大部分的游戏都会让viewport的大小和屏幕一致。这就意味使用像素更容易让纹理绘制在合适的大小和位置。

绘制一个矩形的几何图形是非常常见的,同样让同一个纹理在不同位置以不同大小位置也是非常常见的,比如漫天的弹幕。但是每次都传递每个形状到GPU进行绘制的效率是较低的。

所以许多相同纹理可以一起描述并一起送入GPU,这就是SpriteBatch类所要做的。

SpriteBatch被赋予了纹理和坐标以便每个图形的绘制。它(SpriteBatch)汇集了很多图形而没有直接提交给GPU。如果它被赋予的纹理不同于原有的,它将保持原有的图形,并获取新的图形。

上一篇文章其实就使用了SpriteBatch,但是没有绘制图形,现在我们来试试绘制。

先找张图片来,分辨率必须是2的次方(如32*32,256*512)。

我截取了我的桌面的一部分,分辨率调成512*512。


1.jpg

 

2012-1-16 22:40 上传
下载附件(45.75 KB)


 

拷贝到assets文件夹中,图片文件最好都是放在这个里面哈。


2.jpg

 

2012-1-16 22:40 上传
下载附件(18.6 KB)


 

然后修改代码

  1. private Texture texture;
复制代码

实例化texture,texture=new Texture(Gdx.files.internal("image1.jpg"));然后来说一下为什么要将图片放在assets文件夹中。Gdx.files是libgdx的文件模块,主要提供以下5大功能。

  • 读取文件
  • 写文件
  • 复制文件
  • 移动文件
  • 列出文件和目录
    而获取操作文件的FileHandle有4种方法。
    1.Classpath
    路径相对于classpath,文件通常为只读。
    2.Internal
    内部文件路径相对于程序根目录或者android 的assets文件夹。
    3.External
    外部文件路径是相对于SD卡根目录
    4.Absolute
    assets文件夹本身就是存储资源的文件夹,而且相比resource文件夹,它其中的资源不会生成R中的ID,用来放图片很是合适。
    所以用Gdx.files.internal("image1.jpg")获取图片,然后调用batch.draw(texture,20,10);绘制图形,20,10是坐标,笛卡尔座标,以左下角为原点。
    完整代码:

    1. package com.cnblogs.htynkn;

    2. import com.badlogic.gdx.ApplicationListener;
    3. import com.badlogic.gdx.Gdx;
    4. import com.badlogic.gdx.graphics.GL10;
    5. import com.badlogic.gdx.graphics.Texture;
    6. import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    7. public class FirstGame implements ApplicationListener {
    8. //绘图用的SpriteBatch
    9. private SpriteBatch batch;
    10. //纹理
    11. private Texture texture;
    12. @Override
    13. public void create() {
    14. batch = new SpriteBatch(); //实例化
    15. texture=new Texture(Gdx.files.internal("image1.jpg"));
    16. }

    17. @Override
    18. public void dispose() {
    19. // TODO Auto-generated method stub

    20. }

    21. @Override
    22. public void pause() {
    23. // TODO Auto-generated method stub

    24. }

    25. @Override
    26. public void render() {
    27. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏
    28. batch.begin();
    29. batch.draw(texture,20,10);
    30. batch.end();
    31. }

    32. @Override
    33. public void resize(int width, int height) {
    34. // TODO Auto-generated method stub

    35. }

    36. @Override
    37. public void resume() {
    38. // TODO Auto-generated method stub

    39. }

    40. }
    复制代码
    效果:
  • 3.jpg
    2012-1-16 22:40 上传
    下载附件(51.61 KB)
  • 可以看到图片不能完整显示,而实际操作中我们也经常使用图片的一部分,或者将多个图片资源集合在一个图片文件中。而要显示图片的一部分就可以使用TextureRegion类了。最常用的方法是draw(TextureRegion region, float x, float y, float width, float height)指定初始点和长宽。修改代码:
    1. package com.cnblogs.htynkn;

    2. import com.badlogic.gdx.ApplicationListener;
    3. import com.badlogic.gdx.Gdx;
    4. import com.badlogic.gdx.graphics.GL10;
    5. import com.badlogic.gdx.graphics.Texture;
    6. import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    7. import com.badlogic.gdx.graphics.g2d.TextureRegion;

    8. public class FirstGame implements ApplicationListener {
    9. //绘图用的SpriteBatch
    10. private SpriteBatch batch;
    11. //纹理
    12. private Texture texture;
    13. //区域
    14. private TextureRegion region;
    15. @Override
    16. public void create() {
    17. batch = new SpriteBatch(); //实例化
    18. texture=new Texture(Gdx.files.internal("image1.jpg"));
    19. region=new TextureRegion(texture, 30,80, 200,200);
    20. }

    21. @Override
    22. public void dispose() {
    23. // TODO Auto-generated method stub

    24. }

    25. @Override
    26. public void pause() {
    27. // TODO Auto-generated method stub

    28. }

    29. @Override
    30. public void render() {
    31. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏
    32. batch.begin();
    33. batch.draw(region,0,0);
    34. batch.end();
    35. }

    36. @Override
    37. public void resize(int width, int height) {
    38. // TODO Auto-generated method stub

    39. }

    40. @Override
    41. public void resume() {
    42. // TODO Auto-generated method stub

    43. }

    44. }
    复制代码
    效果: 4.jpg
    2012-1-16 22:41 上传
    下载附件(49.78 KB)
    也许你觉得TextureRegion不够强大,没有关系,还可以使用Sprite。Sprite不光包含TextureRegion的功能,还可以指定位置和颜色。关键代码:
    1. sprite=new Sprite(texture, 80, 80, 400, 300);
    2. sprite.setPosition(10, 10); //位置
    3. sprite.setRotation(15);
    复制代码
    稍微想一下前几个例子就可以发现,其实Sprite的功能就是以上的集合。但是Sprite更方便,它用一个对象描述了一切。完整代码如下:
    1. package com.cnblogs.htynkn;

    2. import com.badlogic.gdx.ApplicationListener;
    3. import com.badlogic.gdx.Gdx;
    4. import com.badlogic.gdx.graphics.GL10;
    5. import com.badlogic.gdx.graphics.Texture;
    6. import com.badlogic.gdx.graphics.g2d.Sprite;
    7. import com.badlogic.gdx.graphics.g2d.SpriteBatch;

    8. public class FirstGame implements ApplicationListener {
    9. //绘图用的SpriteBatch
    10. private SpriteBatch batch;
    11. //纹理
    12. private Texture texture;
    13. //精灵
    14. private Sprite sprite;
    15. @Override
    16. public void create() {
    17. batch = new SpriteBatch(); //实例化
    18. texture=new Texture(Gdx.files.internal("image1.jpg"));
    19. sprite=new Sprite(texture, 80, 80, 400, 300);
    20. sprite.setPosition(10, 10); //位置
    21. sprite.setRotation(15); //旋转
    22. }

    23. @Override
    24. public void dispose() {
    25. // TODO Auto-generated method stub

    26. }

    27. @Override
    28. public void pause() {
    29. // TODO Auto-generated method stub

    30. }

    31. @Override
    32. public void render() {
    33. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏
    34. batch.begin();
    35. sprite.draw(batch);
    36. batch.end();
    37. }

    38. @Override
    39. public void resize(int width, int height) {
    40. // TODO Auto-generated method stub

    41. }

    42. @Override
    43. public void resume() {
    44. // TODO Auto-generated method stub

    45. }

    46. }
    复制代码
    效果:
  • 5.jpg
    2012-1-16 22:41 上传
    下载附件(43.01 KB)
  • 同时可以通过sprite的setColor方法为图形着色。
    1. setColor(float r, float g, float b, float a)
    复制代码
    其中颜色的表述都是介于0,1之间的数。
  • 6.jpg
    2012-1-16 22:41 上传
    下载附件(22.39 KB)
    7.jpg
    2012-1-16 22:40 上传
    下载附件(17.86 KB)
  • 绘制的内容基本就这么多,下一篇是关于关于2D场景的。写在最后:1.关于混合问题,默认是开启混合了的。这意味着图形绘制完成时半透明的部分已经被混合了。当混合被关闭是任何已经在场景上的东西都会被纹理代替,这适合绘制大背景。
    1. batch.disableBlending();
    2. backgroundSprite.draw(batch);
    3. batch.enableBlending();
    复制代码
    2.关于性能优化SpriteBatch 有个构造函数可以指定最大缓冲数目。如果数值过低会造成额外的GPU调用;过高的话将占用过多的内存。在SpriteBatch有个字段为maxSpritesInBatch,可以先设置一个很高的缓冲数目,然后观察maxSpritesInBatch的值以确定合适的缓冲值。还有一个字段renderCalls,在end被调用时,它的值表示在begin和end之间几何声明被送入GPU的次数。还有一个构造函数可以指定缓冲大小和数量,合理的设置可以极大地提供性能。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值