由于平常工作和生活琐事的种种原因,所以这个系列的教程更新的有点慢,还请大家见谅。在这期的主题中,博
主给大家来的教学是关于图形图像的绘制,要知道一个最基本的应用程序都会有一个精美的图像,那么就更别说一个
成功的游戏了,首先要有绚丽的图片背景才是吸引玩家试玩的关键,不是嘛?
在这篇文章中主要讲解到的有Texture、SpriteBatch、Sprite和Pixmap这四个类。
一、Texture和SpriteBatch类
1、Texture介绍
我们先来看一下官方API文档,如下图所示:
该类存放在com.badlogic.gdx.graphics包下,继承自Object,实现了Disposable接口,凡是实现了该接口的类,
都应该在程序结束时对该类进行销毁(上上一篇文章中提到过)。
2、Texture用途
其实就是承装获取到的目的图片的容器,为了方便大家理解我就这里打一个比方,比如:你盛一碗粥,从锅里盛
出来需要用到汤勺,这个汤勺就相当于Texture,他们都是用来获取东西的一个容器,是中间者。
3、SpriteBatch介绍
该类存放在com.badlogic.gdx.graphics.g2d的包下,也是继承自Object,实现了Disposable接口。
4、SpriteBatch用途
SpriteBatch可以把许多相同纹理一起描述并一起送入GPU,同时赋予纹理和坐标以便每个图形的绘制。其实可以
把SpriteBatch理解为就是一个画笔,没有画笔是画不了画的。
5、实现的效果图
大家肯定会觉得奇怪为什么显示的图片会出现在下方?等下讲解代码的时候我在详细解释。
6、项目结构图
7、详细代码编写
package com.yangyu.mylibgdx01;
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 MyGame 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() {
batch.dispose();
texture.dispose();
}
@Override
public void pause() {
}
@Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); // 清屏
batch.begin();
batch.draw(texture, 0, 0, 480, 320);
batch.end();
}
@Override
public void resize(int arg0, int arg1) {
}
@Override
public void resume() {
}
}
<1> 让我们来详细分析一下这段代码,先看这行代码:
texture = new Texture(Gdx.files.internal("image1.jpg"));
这里简单介绍下Gdx.files,它是libgdx的文件模块,主要提供以下5大功能:读取文件,写入文件、复制文件、移动文件、列出文件和目录。其中获取文件有几种方法:
<1> Classpath:路径相对于classpath,文件通常为只读;
<2> Internal:内部文件路径相对于程序根目录或者android 的assets文件夹;
<3> External:外部文件路径是相对于SD卡根目录;
<4> Absolute:assets文件夹本身就是存储资源的文件夹,而且相比resource文件夹,它其中的资源不会生成R中
的ID,用来放图片很是合适。
<2> 这里还有个地方需要注意,libgdx绘制的图片必须是2的n次方分辨率(如32*32,256*512)的图片否则识别
不了,那么为什么libgdx要使用2的N次方的图片呢?
图片是2的n次方是这个引擎的一大悲哀,不过有没有办法可以解决呢?答案是肯定的。
解决方法:
① 在MainActivity.java类中,把initialize()方法中的useGL2IfAvailable参数改为true就行了,就可以随便任何分
辨率图片不必是2的N次方了。不过需要特别注意的是最好在安卓真机上进行调试,模拟器很容易报错不识别
OpenGLES 2.0,如下图所示:
② 还有一种方法实现起来会稍微复杂一点,所以博主会在后面的文章对其进行详细的介绍。
<3> 获取完图片,然后调用batch.draw(texture,x,y,height,width)方法绘制图形
batch.draw(texture, 0, 0, 480, 320);
这里的(x,y)是绘图的起点坐标,(height,width)绘制图形的大小,libgdx使用的是笛卡尔坐标系,以左下角
为原点,绘制方向是由下向上,由左到右。如下图所示:
二、TextureRegion类
1、TextureRegion介绍
该类存放在com.badlogic.gax.graphics.g2d包下,该类的子类有Sprite、TextureAtlas、AtlasRegion。
2、API的定义
大概的意思是说:定义了一个矩形区域的纹理,使用左上角的顶点为坐标系统的原点,x轴指向右,Y轴指向下。
3、TextureRegion用途
实际操作中我们也经常使用图片的一部分,或者将多个图片资源集合在一个图片文件中。而要显示图片的一部分
就可以使用TextureRegion类。其实可以理解为就是截图工具,从左上角开始截图,然后可以定义截图的大小。
textureRegion = new(texture, 48 , 48 , -48, -48),他对应的截图区域和方向,如下图:
4、实现效果图
正向截图 反向截图
5、项目结构图
6、详细代码编写
package com.yangyu.mylibgdx01;
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 MyGame implements ApplicationListener {
//绘图用的SpriteBatch
private SpriteBatch batch;
//纹理
private Texture texture;
public TextureRegion textureRegion;
@Override
public void create() {
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("image1.jpg"));
// textureRegion = new TextureRegion(texture, 0, 0, 512, 256);
textureRegion = new TextureRegion(texture, 512, 256, -512, -256);
}
@Override
public void dispose() {
batch.dispose();
texture.dispose();
}
@Override
public void pause() {
}
@Override
public void render() {
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 arg0, int arg1) {
}
@Override
public void resume() {
}
}
三、Sprite类
1、Sprite介绍
该类在com.badlogic.gdx.graphics.g2d包下,继承自TextureRegion类,它的子类有TextureAtlas、AtlasSprite。
2、API的定义
先来看一下官方的解释,如下图所示:
3、Sprite用途
4、实现效果图
5、详细代码编写
package com.yangyu.mylibgdx03;
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;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
public class MyGame 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("xianjian.jpg"));
TextureRegion region = new TextureRegion(texture, 0, 0, 256, 512);
sprite = new Sprite(region);
// 设置绘制的大小
sprite.setSize(256, 512);
// 设置旋转的中心点为屏幕的中心点
sprite.setOrigin(sprite.getWidth() / 2, sprite.getHeight() / 2);
// 以中心点为旋转中心,设置旋转的角度
sprite.setRotation(50);
// 设置图片的起始位置
sprite.setPosition(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() {
}
}
我们来详细分析一下这段代码:
<1> 在前面已经说过了, TextureRegion是Sprite的加强版,Sprite包含TextureRegion的功能:
TextureRegion region = new TextureRegion(texture, 0, 0, 256, 512); sprite = new Sprite(region);
可以把这两行代码替换为:
sprite = new Sprite(texture, 0, 0, 256, 512);
<2>可以通过sprite的setColor方法为图形着色:
sprite.setColor(1, 0, 1, 1);
其中颜色的表述都是介于0到1之间的数。
<3> 关于清屏:
Gdx.gl.glClearColor(1, 1, 1, 1);// 设置背景颜色为白色 Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);// 清屏
可能大家不能理解为什么要清屏?其实很简单,OpenGL中我们是将纹理贴上去的,但是要绘制动画,或者绘制
另外的图片时候,他会残留上一张的痕迹,所以只有清屏后,才能显示新的图片,这个感兴趣的同学可以自己去测试
一下,这两行代码,如果不是很熟悉的libgdx的新手同学的话可以当做固定格式来用,编程的时候在render()方法中
都是必须加入的,也不需要大家理解,建议大家直接背下来。
四、 Pixmap类
1、Pixmap介绍
该类存放在com.badlogic.gdx.graphics包下,继承自Object,实现了Disposable接口。
2、Pixmap用途
Libgdx所提供的像素级图像渲染用类,由于Libgdx目前以JNI方式自带图像解码器,所以我们可以直接将Pixmap理
解为一个Android中 Bitmap的替代者,两者间实现细节虽有差别,但具体作用却大同小异。Pixmap支持Alpha、
LuminanceAlpha、RGB565、 RGBA4444、RGB888、RGBA8888等五种图像彩色模式,支持png、jpg、bmp等三
种图像文件的读取和加载。一般来说,Pixmap 必须和Texture混用才能真正显示画面。不过在事实上,Libgdx的
Texture里已经内置有Pixmap了。
3、实现效果图
4、代码详细编写
package com.yangyu.mylibgdx04; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; public class MyGame implements ApplicationListener { // 准备绘图用SpriteBatch SpriteBatch spriteBatch; // Pixmap是Libgdx提供的针对opengl像素操作的上级封装,它可以凭空构建一个像素贴图, // 但是它的现实必须通过Texture。 Pixmap pixmap; // 准备Texture Texture texture; public void create() { // 构建SpriteBatch spriteBatch = new SpriteBatch(); // 构建Pixmap(在Android环境使用internal加载模式时,文件必须放置于assets文件夹下) pixmap = new Pixmap(Gdx.files.internal("image1.jpg")); // 绘制一个蓝方块到Ball图像之上 pixmap.setColor(Color.BLUE.r, Color.BLUE.g, Color.BLUE.b, Color.BLUE.a); pixmap.drawRectangle(15, 15, 40, 40); // 以指定Pixmap构建Texture texture = new Texture(pixmap); } public void dispose() { // 注入Texture后的pixmap已经没用,可以注销 pixmap.dispose(); spriteBatch.dispose(); texture.dispose(); } public void pause() { } public void render() { // 清屏 Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); // 初始化绘图调用 spriteBatch.begin(); // 绘制精灵到游戏屏幕 spriteBatch.draw(texture, 100, 180); // 结束绘图调用 spriteBatch.end(); } public void resize(int width, int height) { } public void resume() { } }
这一期图形图像绘制的基本内容差不多就讲完了,下一期会更加精彩!
源码下载地址(包含本期中所有的示例讲解)