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

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

Libgdx的图形绘制是学习libgdx的基础,一个成功的游戏必须要有炫丽的游戏背景,所以今天我们就来学习一下libgdx是如何绘制一张图片作为游戏的背景图片的。今天我们主要学习个类:SpriteBatch、Texture 、TextureRegion 、 Sprite 以及一些基本的方法调用,由于官方给的这几个类的定义都是比较难懂,土豆这里大胆一下,把自己对这几个类的理解,从用途方面解释下去,毕竟大家学习libgdx只有理解后才能够活用,如果有不妥之处欢迎指正。

 
Libgdx游戏引擎(1群): 187378034
Libgdx游戏引擎(2群): 148848483
Libgdx游戏引擎(3群):  79168470

1. Texture 类
 
API定义: 图片从原始格式解码并上传到GPU就被称为纹理。-------这里我也不是很清楚,求大神解答。
功能用途:其实就是承装获取到的目的图片的容器。------- 其实你就直接把Texture当成图片,这样好理解。
Texture一般都是作为传入的参数使用的,这里解释下 Gdx.files.internal("data/Potato.jpg")是什么意思,他是获取图片的常用写法,同学们硬背下来就行一般都是这么用,data是assets下面的一个目录,特别注意读取的文件必须注明格式,比如这个文件是“.jpg”就必须写明是“.jpg”格式的,否则会报错。
这里简单介绍下Gdx.files,它是libgdx的文件模块,主要提供以下5大功能:读取文件,写入文件、复制文件、移动文件、列出文件和目录。其中获取文件有许多种办法:
1.Classpath:  路径相对于classpath,文件通常为只读。

2.Internal: 内部文件路径相对于程序根目录或者android 的assets文件夹。

3.External: 外部文件路径是相对于SD卡根目录

4.Absolute:assets文件夹本身就是存储资源的文件夹,而且相比resource文件夹,它其中的资源不会生成R中的ID,用来放图片很是合适

所以用   Gdx.files.internal("data/Potato.jpg")   获取图片,然后调用   batch.draw(texture,x,y,height,width) 绘制图形,这里的(x,y)是绘图的起点坐标,(height,width)绘制图形的大小,libgdx使用的是笛卡尔坐标系,以左下角为原点。,绘制方向是由下向上,由左到右。

为了方便大家理解我就这里打一个比方,比如你盛一碗粥,从锅里盛出来需要用到汤勺,这个汤勺就相当于Texture,他们都是用来获取东西的一个容器,是中间者。一般使用方法如下图:
 
2.SpriteBatch类
 
API定义:SpriteBatch用于绘制二维矩形参考纹理(区域)。SpriteBatch类可用于批量绘图命令和优化处理的GPU。
功能用途: SpriteBatch可以把 许多相同纹理一起描述并一起送入GPU,同时 赋予纹理和坐标以便每个图形的绘制 。------------- 其实我的理解就是SpriteBatch就是一个画笔,没有画笔是画不了图片的(个人理解)。
它的用法,首先声明类名,实例化、在绘制的的时候分三步,必须先调用begin()方法,然后再调用draw()方法,最后画完了调用end()结束,这个顺序是绘制的固定格式,也是应该背下来的。
如下图:

下面我们就来绘制一张图片,libgdx绘制的图片必须是 2的n次方分辨率的图片否则识别不了,我选择了一张土豆比较喜欢的图片来绘制一下。
 
PS:如果想使用不是2的N次方分辨率的图片:
(1)将 desktop和项目中  main.java    中的  useGL20 = false 改为 useGL20 = true 就可以随便任何分辨率图片不必是2的N次方了。
(2)将 android和项目中  mainactivity  中的  useGL20 = false  改为  useGL20 = true 就可以随便任何分辨率图片不必是2的N次方了。
如图:




为什么libgdx要使用2的N次方的图片呢?
Android上画图可以使用OpenGL ES,分两个不兼容的版本:OpenGL ES 1.x,和 OpenGL ES 2.0。
它们之间的一个重要区别就是: OpenGL ES  1.x的图片大小必须是2的整数次幂,而 OpenGL ES  2.0则无此要求。而libgdx在早期使用OpenGL es1.x 的版本所以只支持2的整数次幂的图像,并一直沿用至今,新版本(0.9.8)中允许开发者使用OpenGL ES 2.0,这样使用OpenGL ES 2.0就可以不用管图片分辨率的问题了。android系统对opengl es的支持情况: OpenGL ES 1.0--------->andoid 1.0-2.1(api 7)而 OpenGL ES 2.0------------>android 2.2(api 8)以上,但是在模拟器上即使是4.2的系统,也只有open es 1.0可用所以还是建议大家用安卓真机进行调试,模拟器很容易报错不识别OpenGL ES 2.0。 所以 使用libgdx的gdx-setup-ui.jar创建项目时,选中: show advance settings->targetSDkVersion>默认值是17,但adt中并没有安装该版本的sdk,所以之后会被覆盖为7(android2.1),该版本只支持opengl es1.0, 设置为8以上的值即可(对应的sdk必须已安装好) 最后可以在android项目的project.properties文件中查看所使用的sdk版本。
操作如下图:


 
 
常用 2的n次方分辨率:32 X 32 ,64 X 64 ,128  X 128 , 512 X 512 ,1024 X 1024
   32 X 64 ,64 X 128 ,128 X 512 , 512 X 1024等等。  
我们要画的就是这张图片(分辨率1024 X 512)


将这个张图片放进 assets的data文件夹中,图片文件尽量都放在这个里面。



我这里还是用上一个教程的HelloWorld项目来修改代码。这里我在说一次,代码写在核心项目里面(即HelloWorld项目)。
 
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
 
public class HelloWorld implements ApplicationListener {
 
public SpriteBatch batch;
// 声明纹理
public Texture texture;
public Sprite sprite;
@Override
public void create() {
 
batch = new SpriteBatch();
// 实例化texture
texture = new Texture(Gdx.files.internal("data/Potato.jpg"));
}
 
@Override
public void dispose() {
batch.dispose();
texture.dispose();
}
 
@Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);// 设置背景为白色
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);// 清屏
batch.begin();
batch.draw(texture, 0, 0, 480, 320);
batch.end();
}
 
@Override
public void resize(int width, int height) {
}
 
@Override
public void pause() {
}
 
@Override
public void resume() {
}
}
运行效果图:
        

3.TextureRegion 类
API定义:定义了一个矩形区域的纹理。使用的坐标系统与x轴指向右,Y轴向下在左上角的起源。
功能用途: 实际操作中我们也经常使用图片的一部分,或者将多个图片资源集合在一个图片文件中。 而要显示图片的一部分就可以使用TextureRegion类。----------其实就是截图工具,从左下角开始截图,然后可以定义截图的大小(个人理解)。
TextureRegion一般都是截取texture,然后定义截取起点(x,y)随后再定义宽高(width,height),如果宽高是正数,那么就是沿x,y正方向截取,如果是负就是沿x,y负方向截取,方向只和宽高的正负有关。这里我举个例子再结合用个图来解释下。
 
比如:t extureRegion = new(texture,0 ,0 ,48,48);他对应的截图区域和方向,如下图:

     t extureRegion = new(texture,48 ,48 ,-48,-48);他对应的截图区域和方向,如下图:

下面我们来测试一下 t extureRegion 效果,我们来画Potato图片中的女生(即左半部分),同时展示2种图不同方向截图的效果,代码如下:
package com.potato;
 
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
 
public class HelloWorld implements ApplicationListener {
 
public SpriteBatch batch;
//声明纹理
public Texture texture;
public TextureRegion textureRegion;
public Sprite sprite;
@Override
public void create() {
 
batch = new SpriteBatch();
//实例化texture
texture = new Texture(Gdx.files.internal("data/Potato.jpg"));
textureRegion = new TextureRegion(texture, 0, 0, 512, 512);
// textureRegion = new TextureRegion(texture, 512, 512, -512, -512); ---反方向截图
}
 
@Override
public void dispose() {
batch.dispose();
texture.dispose();
}
 
@Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
 
batch.begin();
// batch.draw(texture, 0, 0, 480, 320);
batch.draw(textureRegion,0,0,480, 320);
batch.end();
}
 
@Override
public void resize(int width, int height) {
}
 
@Override
public void pause() {
}
 
@Override
public void resume() {
}
}
效果图:

4.Sprite 类
API定义:持有的几何形状,颜色,和纹理信息使用加载绘制2D精灵。一个精灵有定位和给定的宽度和高度尺寸。的位置是相对于通过加载指定的坐标系的原点。begin()和各自的矩阵。一个精灵总是矩形和它的位置(x,y)是位于左下角的矩形。一个精灵也有一个起点,旋转和缩放的执行(即,产地不通过旋转和缩放修改),起点是相对于左下角的精灵,它的位置。
功能用途:TextureRegion的加强版,比TextureRegion多了一些功能,如: 可以指定位置、颜色、旋转等。
 
其实Sprite的功能就是以上的集合。但是Sprite更方便,它用一个对象描述了一切,但是同时加入了很多TextureRegion和Texture没有的东西,如 位置、颜色、旋转。使用介绍,如图:

下面我们就用代码来实践一下Sprite的用法,这次我们绘制Potato中右面的图片(男生图片),代码如下:

package com.potato;
 
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
 
public class HelloWorld implements ApplicationListener {
 
public SpriteBatch batch;
//声明纹理
public Texture texture;
public Sprite sprite;
@Override
public void create() {
 
batch = new SpriteBatch();
//实例化texture
texture = new Texture(Gdx.files.internal("data/Potato.jpg"));
TextureRegion region = new TextureRegion(texture, 512, 0, 512, 512);
sprite = new Sprite(region);
sprite.setSize(120, 120);// 设置绘制的大小,为了方便我们设置的120,120,小一点方便查看
sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);// 设置旋转的中心点,咱们就设置为屏幕的中心点
 
sprite.setRotation(50);// 这个是以上面设置的中心点为中心,旋转一定角度的设置
 
sprite.setPosition(150, 110);// 起始位置设置为中心区域附近(150,110)
sprite.setColor(1, 0, 1, 1);// 颜色就设置为粉色吧
}
 
@Override
public void dispose() {
batch.dispose();
texture.dispose();
}
 
@Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);// 设置背景颜色为白色
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);// 清屏
batch.begin();
sprite.draw(batch);
batch.end();
}
 
@Override
public void resize(int width, int height) {
}
 
@Override
public void pause() {
}
 
@Override
public void resume() {
}
}
运行效果图:
5.关于清屏
关于清屏的问题,大家也看到了在render方法里面有2句话,我注释上写道是负责清屏的,可能大家不能理解为什么要清屏呢?其实很简单,OpenGL中我们是将纹理贴上去的,但是要绘制动画,或者绘制另外的图片时候,他会残留上一张的痕迹,所以只有清屏后,才能显示新的图片,这个留个大家自己去测试吧,土豆当初测试过,另外这2句话,如果 不是很熟悉的libgdx的新手同学的话可以当做 固定格式来用,编程的时候在render()方法中都是必须加入的,也不需要大家理解, 建议大家直接背下来
代码图:
写在最后,有关于图形绘制的基本类和基本方法就介绍到这里了,这些知识图形绘制的基础,API文档中还有许多我没有介绍到了,希望大家配合着翻译工具多多阅读(金山词霸直接复制翻译很好用),下一篇是有关于如何使用libgdx做到中文显示和汉字绘制》 果大家有什么问题可以加我QQ:316344618,一起讨论下。 。PS:吐血了,早上10.00开始写一直写到下午14.00,午饭还没吃,饿死了。。。
                                                                                                                           
 ------------奋斗小土豆丶
                                                                                                                             2013 年 4 月 9 日

 

转载于:https://www.cnblogs.com/WeYingKG/archive/2013/04/17/3025842.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值