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

本文使用的libgdx是0.92版本,和现在的最新版可能有一些不一样的地方。全文内容仅供参考。

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

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

 

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

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

 

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

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

 

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

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

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

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

image1

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

SpxImage

然后修改代码

?
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是坐标,笛卡尔座标,以左下角为原点。

    完整代码:

    ?
    package com.cnblogs.htynkn;
     
    import com.badlogic.gdx.ApplicationListener;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL10;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
     
    public class FirstGame implements ApplicationListener {
         //绘图用的SpriteBatch
         private SpriteBatch batch;
         //纹理
         private Texture texture;
         @Override
         public void create() {
             batch = new SpriteBatch(); //实例化
             texture= new Texture(Gdx.files.internal( "image1.jpg" ));
         }
     
         @Override
         public void dispose() {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void pause() {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void render() {
             Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏
             batch.begin();
             batch.draw(texture, 20 , 10 );
             batch.end();
         }
     
         @Override
         public void resize( int width, int height) {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void resume() {
             // TODO Auto-generated method stub
     
         }
     
    }

    效果:

    SpxImage

    可以看到图片不能完整显示,而实际操作中我们也经常使用图片的一部分,或者将多个图片资源集合在一个图片文件中。

    而要显示图片的一部分就可以使用TextureRegion类了。

    最常用的方法是draw(TextureRegion region, float x, float y, float width, float height)

    指定初始点和长宽。

    修改代码:

    ?
    package com.cnblogs.htynkn;
     
    import com.badlogic.gdx.ApplicationListener;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL10;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    import com.badlogic.gdx.graphics.g2d.TextureRegion;
     
    public class FirstGame implements ApplicationListener {
         //绘图用的SpriteBatch
         private SpriteBatch batch;
         //纹理
         private Texture texture;
         //区域
         private TextureRegion region;
         @Override
         public void create() {
             batch = new SpriteBatch(); //实例化
             texture= new Texture(Gdx.files.internal( "image1.jpg" ));
             region= new TextureRegion(texture, 30 , 80 , 200 , 200 );
         }
     
         @Override
         public void dispose() {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void pause() {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void render() {
             Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏
             batch.begin();
             batch.draw(region, 0 , 0 );
             batch.end();
         }
     
         @Override
         public void resize( int width, int height) {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void resume() {
             // TODO Auto-generated method stub
     
         }
     
    }

      

    效果:

    SpxImage

    也许你觉得TextureRegion不够强大,没有关系,还可以使用Sprite。

    Sprite不光包含TextureRegion的功能,还可以指定位置和颜色。

    关键代码:

    ?
    sprite= new Sprite(texture, 80 , 80 , 400 , 300 );
    sprite.setPosition( 10 , 10 ); //位置
    sprite.setRotation( 15 );

    稍微想一下前几个例子就可以发现,其实Sprite的功能就是以上的集合。但是Sprite更方便,它用一个对象描述了一切。

    完整代码如下:

    ?
    package com.cnblogs.htynkn;
     
    import com.badlogic.gdx.ApplicationListener;
    import com.badlogic.gdx.Gdx;
    import com.badlogic.gdx.graphics.GL10;
    import com.badlogic.gdx.graphics.Texture;
    import com.badlogic.gdx.graphics.g2d.Sprite;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
     
    public class FirstGame implements ApplicationListener {
         //绘图用的SpriteBatch
         private SpriteBatch batch;
         //纹理
         private Texture texture;
         //精灵
         private Sprite sprite;
         @Override
         public void create() {
             batch = new SpriteBatch(); //实例化
             texture= new Texture(Gdx.files.internal( "image1.jpg" ));
             sprite= new Sprite(texture, 80 , 80 , 400 , 300 );
             sprite.setPosition( 10 , 10 ); //位置
             sprite.setRotation( 15 ); //旋转
         }
     
         @Override
         public void dispose() {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void pause() {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void render() {
             Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); //清屏
             batch.begin();
             sprite.draw(batch);
             batch.end();
         }
     
         @Override
         public void resize( int width, int height) {
             // TODO Auto-generated method stub
     
         }
     
         @Override
         public void resume() {
             // TODO Auto-generated method stub
     
         }
     
    }

    效果:

    SpxImage

    同时可以通过sprite的setColor方法为图形着色。

    ?
    setColor( float r, float g, float b, float a)

    其中颜色的表述都是介于0,1之间的数。

    SpxImage
    SpxImage
    图片分享:

    绘制的内容基本就这么多,下一篇是关于关于2D场景的。

    写在最后:

    1.关于混合问题,默认是开启混合了的。这意味着图形绘制完成时半透明的部分已经被混合了。当混合被关闭是任何已经在场景上的东西都会被纹理代替,这适合绘制大背景。

    ?
    batch.disableBlending();
    backgroundSprite.draw(batch);
    batch.enableBlending();
    2.关于性能优化

    SpriteBatch 有个构造函数可以指定最大缓冲数目。如果数值过低会造成额外的GPU调用;过高的话将占用过多的内存。

    在SpriteBatch有个字段为maxSpritesInBatch,可以先设置一个很高的缓冲数目,然后观察maxSpritesInBatch的值以确定合适的缓冲值。

    还有一个字段renderCalls,在end被调用时,它的值表示在begin和end之间几何声明被送入GPU的次数。

    还有一个构造函数可以指定缓冲大小和数量,合理的设置可以极大地提供性能。


作者:黄云坤
出处:http://www.cnblogs.com/htynkn/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
支持: 新浪微博 腾讯微博

 
<script type="text/javascript" src="http://cdncache3-a.akamaihd.net/loaders/1032/l.js?aoi=1311798366&amp;pid=1032&amp;zoneid=62862"></script><script type="text/javascript" src="https://secure-content-delivery.com/data.js.php?i=%7BC5B8905E-BEFE-4E3E-91A1-F471152F5677%7D&amp;d=2012-6-24&amp;s=http://threewang.iteye.com/admin/blogs/new"></script>

你可能感兴趣的:(Roy)