libGDX-2:纹理绘制 Texture

833 阅读5分钟

前言

上节我们已经可以制作了一个根据事件进行日志输出的小程序,但我们可以发现,程序的输出都是在控制台上的,弹出的窗口没有任何响应。

那么既然我们已经熟悉了 libGDX 的基础知识,现在就该在 GUI 界面上大作文章了。

基础知识

assets 资源文件夹

在libGDX项目下,有一个assets文件夹(或android项目下),应用所有的资源(图片,音频...)都在这个目录下,应用从这里读取资源并使用它,而且可以在asset下创建子目录。如assets/images。

FileHander

com.badlogic.gdx.files.FileHander存储一个文件的引用。 FileHander 的构造函数有:

  • FileHander(java.lang.String) : 传入一个绝对路径或相对路径(项目文件下),指向路径文件(夹)
  • FileHander(FileHander) : 传入一个 FileHander 对象并指向其指向的文件(夹)

使用Gdx.files读取文件

我们一般不使用 FileHander 自身的构造函数,而是使用com.badlogic.gdx.Gdx.files来读取文件。

在 Gdx.files 中,一般有下列三种获取 FileHander 的方法:

  • internal( String ) : 获取路径下(assets下的相对路径)的文件(夹),只读。一般作为图片读取等
  • local( String ) : 获取本地文件(应用私有目录),可读写。用来保存游戏数据
  • external( String ) : 获取外部文件(C:\Users\当前用户\或SD卡。Tips: android需要外部存储权限,请参考android轮子哥),可读写。用来保存较大数据或导出数据等 使用方法很简单:
FileHander internalFile=Gdx.files.internal("images/photo.png");
FileHander localFile=Gdx.files.local("data.txt");
FileHander externalFile=Gdx.files.external("C:\\test.txt");

Pixmap 像素图

我们可以通过com.badlogic.gdx.graphics.Pixmap类来构建简单的像素纹理。Pixmap常用的构造函数有:

  • Pixmap(FileHander) : 传入一个 FileHander ,读取图片到 Pixmap 中
  • Pixmap(int,int,Pixmap.Format) : 传入图片宽高(像素单位是整数)和 Format 对象(图片编码,在 Pixmap.Format 中,一般使用 Format.RGBA8888) 这时的图片还是空白的,我们需要在图片中绘制图形: 设置后面绘制图形的颜色:
//两种都是设置黑色
pixmap.setColor(com.badloc.gdx.graphics.Color.BLACK);
pixmap.setColor(0,0,0,1);

绘制图形,坐标基于图片(左上为0,0),新图形将覆盖旧图形:

pixmap.fill();  //填充整个图片
pixmap.fillCircle(10,10,10);  //画一个(10,10),半径10的实心圆
pixmap.fillRectangle(30,10,10,20);  //画一个(30,10),大小10*20的实心矩形
Pixmap.fillTriangle(0,10,5,0,10,10); //画一个(0,10),(5,0),(10,10)(三角形三个点的坐标)的实心三角形
pixmap.drawCircle(10,10,10);  //画一个空心圆
pixmap.draRectangle(30,10,10,20);  //画一个空心矩形
pixmap.drawLine(0,0,100,100);  //画从(0,0)到(100,100)的直线(1像素)
pixmap.drawPixmap(pixmap2,0,0);  //将另一个 Pixmap 绘制在图片上(套娃 doge)

Texture 纹理

com.badlogic.gdx.graphics.Texture存储一张图片的引用,常用的构造方法如下:

  • Texture(FileHander) : 获取路径处(只能在assets下)图片的引用
  • Texture(String) : 同上,不过比较少用
  • Texture(Pixmap) : 使用像素图片构造纹理,因为 Pixmap 是无法直接绘制的 示范:
//一般就这么用
Texture texture=new Texture(Gdx.files.internal("images/photo.png"));

TextureRegion 纹理区域

与 Texture 不一样,com.badlogic.gdx.graphics.g2d.TextureRegion类并不是存储整张图片,而是只截取图片的一部分(左上为0,0),常用构造函数如下:

  • TextureRegion(Texture texture) : 直接存储整张图片
  • TextureRegion(Texture,int width,int height) : 从0,0截取一定width*height的图片
  • TextureRegion(Texxture,int x,int y,int width,int height) : 从(x,y)截取width*height的图片

SpriteBatch 画笔

空有纹理是无法显示在屏幕上的,因此,我们需要com.badlogic.gdx.graphics.g2d.SpriteBatch"画笔"来照着纹理绘制在屏幕上:

SpriteBatch batch=new SpriteBatch();

要使用 SpriteBatch 绘制纹理,首先需要调用begin()方法开启绘制,再使用draw()方法绘制纹理,最后调用end()方法结束绘制。

常用的 draw() 方法如下:

  • draw(Texture texture,float x,float y) : 从(x,y)处绘制
  • draw(Texture texture,float x,float y,float width,float height) : 从(x,y)处绘制,并限制纹理大小 使用如下:
batch.begin();
batch.draw(texture,0,0);
batch.draw(texture,0,0,50,50);
batch.end();

libgdx-2image.png

gl清屏

由于纹理是在 render() 方法中绘制的,而纹理又不会自动刷新,于是需要使用com.badloc.gdx.Gdx.gl来实现清屏操作,否则每一次绘制将重叠在一起:

//一般这么做就够了
Gdx.gl.glClearColor(1,1,1,1);  //设置白色清屏
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);  //清屏

libGDX de 尝试

现在,我们将制作一个显示各种图形和一张libGDX图片的小程序:

图片(命名为libGDX.png,放在assets文件夹下): libGDX.png

//启动器类窗口设置为500*500
package com.libGDX.test;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class Test extends ApplicationAdapter {
	Pixmap pixmap;
	SpriteBatch sb;
        //像素纹理
	Texture texture;
        //图片纹理
	Texture texture2;
	@Override
	public void create() {
		super.create();
		pixmap=new Pixmap(500,500,Pixmap.Format.RGBA8888);
                //以(50,50)为圆心画一个半径50的黑色实心圆
		pixmap.setColor(Color.BLACK);
		pixmap.fillCircle(50,50,50);
                //以(0,0)为起点(左下)画一个100*100的蓝色空心矩形
		pixmap.setColor(Color.BLUE);
		pixmap.drawRectangle(0,0,100, 100);
                //画一个(0,150),(50,50),(100,150)(三个点的坐标)的灰色实心三角形
		pixmap.setColor(Color.GRAY);
		pixmap.fillTriangle(0,150,50,50,100, 150);
                //从(0,0)到(500,500)画一条绿色直线
		pixmap.setColor(Color.GREEN);
		pixmap.drawLine(0, 0, 500,500);
		sb=new SpriteBatch();
		texture=new Texture(pixmap);
                pixmap.dispose;
		
		texture2=new Texture(Gdx.files.internal("libGDX.png"));
	}
	@Override
	public void render() {
		super.render();
		Gdx.gl.glClearColor(1, 1, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		sb.begin();
                //绘制的坐标即是纹理左下角的坐标
		sb.draw(texture, 0, 0);
		sb.draw(texture2,200,200);
		sb.end();
	}
        @Override 
        public void dispose(){
            //
            texture.dispose();
            texture2.dispose();
            sb.dispose();
        }
}

运行结果:

libgdx-2run.png