`
archy123
  • 浏览: 28322 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

libgdx学习笔记系列(三)会动的小人

阅读更多
(重要提示:Stage类在3.19号被作者更新后初始化方法已经改变,本篇代码在最新的版本中,会出错。详细请参考源码,及文档和第七篇笔记viewpoint的介绍
上次弄好了文字显示,可能有的同学感觉很繁琐。今天开始之前先给大家介绍下另外一种文字显示方法。直接使用字体文件。
拷贝今天刚刚更新编译的好的freetype的相关jar包和so文件。还有字体文件,(系统盘中的windows/fonts目录下有大量字体可以用,当然你也可以下载个性字体。)
修改上篇的代码如下:

@Override
    public void create() {
        //加载字体文件从电脑上拷贝的华文琥珀字体,当然你可以使用任意一种中文字体。
        FreeTypeFontGenerator freeTypeFontGenerator =
                new FreeTypeFontGenerator(Gdx.files.internal("data/font/STHUPO.TTF"));
        
        //关于字体的一些配置参数,详细的可以看官方API和FreeTypeFontGenerator的源码
        FreeTypeFontGenerator.FreeTypeFontParameter fontParameter = 
                new FreeTypeFontGenerator.FreeTypeFontParameter();
        
        //注意这不是我们要显示的文字,其实相当于我们上篇使用的文字工具编辑的字符串内容,
        // 这里是默认的字符串加上了我们要使用的汉字。
        fontParameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + "你好";
        
        //根据参数设置生成的字体数据,这就相当于上篇的myfont.fnt文件和myfont.png
        FreeTypeFontGenerator.FreeTypeBitmapFontData fontData =
                freeTypeFontGenerator.generateData(fontParameter);
        
        //及时释放资源,避免内存泄漏,因为中文字体文件一般都比较大
        freeTypeFontGenerator.dispose();
        
        //从字面看,其实也是加载的图片
        bitmapFont = new BitmapFont(fontData, fontData.getTextureRegions(), false);
        batch = new SpriteBatch();
        //文字绘制 (注释掉昨天的)
//        bitmapFont = new BitmapFont(Gdx.files.internal("data/font/myfont.fnt"),
//                Gdx.files.internal("data/font/myfont.png"), false);

    }

确实比原来的方便了点,起码不用使用工具类手动编辑文字了。
如果游戏中的文字比较少,推荐使用上篇手动生成,节省系统资源,毕竟加载字体文件开销还是比较大的。如果文字比较多,可以使用这种方法。但是一定注意及时释放资源。


好了,接下来显示个人物吧
人物图片


拷贝人物图片到android中的assets目录
我放到了data/image目录下

修改Mygame如下:
package com.me.mygdxgame;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;

public class MyGame implements ApplicationListener {
    private SpriteBatch batch;
    private BitmapFont bitmapFont;
    private Texture texture;

    @Override
    public void create() {
        //加载字体文件从电脑上拷贝的华文琥珀字体,当然你可以使用任意一种中文字体。
        FreeTypeFontGenerator freeTypeFontGenerator =
                new FreeTypeFontGenerator(Gdx.files.internal("data/font/STHUPO.TTF"));

        //关于字体的一些配置参数,详细的可以看官方API和FreeTypeFontGenerator的源码
        FreeTypeFontGenerator.FreeTypeFontParameter fontParameter =
                new FreeTypeFontGenerator.FreeTypeFontParameter();

        //注意这不是我们要显示的文字,其实相当于我们上篇使用的文字工具编辑的字符串内容,
        // 这里是默认的字符串加上了我们要使用的汉字。
        fontParameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + "你好";

        //根据参数设置生成的字体数据,这就相当于上篇的myfont.fnt文件和myfont.png
        FreeTypeFontGenerator.FreeTypeBitmapFontData fontData =
                freeTypeFontGenerator.generateData(fontParameter);

        //及时释放资源,避免内存泄漏,因为中文字体文件一般都比较大
        freeTypeFontGenerator.dispose();

        //从字面看,其实也是加载的图片
        bitmapFont = new BitmapFont(fontData, fontData.getTextureRegions(), false);
        batch = new SpriteBatch();
        //文字绘制 (注释掉昨天的)
//        bitmapFont = new BitmapFont(Gdx.files.internal("data/font/myfont.fnt"),
//                Gdx.files.internal("data/font/myfont.png"), false);

        texture = new Texture(Gdx.files.internal("data/image/girl.png"));

    }

    @Override
    public void render() {
        //这个经常出现的代码就是opengl ES的清屏方法
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        //使用一种颜色填充屏幕
        //前三个是屏幕颜色的参数,最后一个是透明度,注意颜色不是我们熟悉的RGB
        Gdx.gl.glClearColor(0.57f, 0.40f, 0.55f, 1.0f);

        batch.begin();
        bitmapFont.draw(batch, "你好libgdx!......", Gdx.graphics.getWidth() * 0.4f, Gdx.graphics.getHeight() / 2);
        batch.draw(texture,0, 0);
        batch.end();

    }

    @Override
    public void dispose() {
        batch.dispose();
        bitmapFont.dispose();
        texture.dispose();

    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }


}


其实主要就2行代码
加载人物
 texture = new Texture(Gdx.files.internal("data/image/01.png"));

显示出来
 batch.draw(texture,0, 0);

注意后边的三个参数,texture人物纹理,后边两个参数其实就是指屏幕的左下角原点。
libgdx是以屏幕左下角为起始点的。


但是这个小人还不会动。
在开始动之前,先要说下Stage和Actor的概念。顾名思义,舞台和演员。
其实很好理解。以现实中的舞台和演员为例。比如京剧,其中演员就是指的具体的角色青衣,花旦等等扮演者都是演员。舞台当然就是表演的场所了。
具体在游戏中,演员本身有自己的一些特性,比如会走动,会唱歌,跳舞等等,舞台就是容纳演员表演的舞台。游戏中的演员一般就是指具体的游戏元素,例如我们图片中的人物,还有中间显示的文字。
再举个大家大部分都玩过的游戏。愤怒的小鸟,什么是演员呢。小鸟,猪,弹弓,被关的小鸟,场景中的各种冰块,石头,木制。建筑物,甚至于,显示的分数,碰撞的特效都可以称为演员。舞台呢,就是容纳这些演员的一个容器。
我们先看看Actor的源码中的解释
2D scene graph node. An actor has a position, rectangular size, origin, scale, rotation, Z index, and color. The position
 * corresponds to the unrotated, unscaled bottom left corner of the actor. The position is relative to the actor's parent. The
 * origin is relative to the position and is used for scale and rotation.
 * <p>
 * An actor has a list of in progress {@link Action actions} that are applied to the actor (often over time). These are generally
 * used to change the presentation of the actor (moving it, resizing it, etc). See {@link #act(float)}, {@link Action} and its
 * many subclasses.
 * <p>
 * An actor has two kinds of listeners associated with it: "capture" and regular. The listeners are notified of events the actor
 * or its children receive. The regular listeners are designed to allow an actor to respond to events that have been delivered.
 * The capture listeners are designed to allow a parent or container actor to handle events before child actors. See {@link #fire}
 * for more details.
 * <p>
 * An {@link InputListener} can receive all the basic input events. More complex listeners (like {@link ClickListener} and
 * {@link ActorGestureListener}) can listen for and combine primitive events and recognize complex interactions like multi-touch
 * or pinch.

演员中主要包括它的位置信息,大小,缩放,旋转,颜色等等特征。
具体可参考官方的API文档。
源码+API文档=最权威教程
希望大家善用API文档和源码。
然后再看下stage的源码和文档的解释。



我们看到Group root;这个定义。group是什么呢
Group 就是舞台中的所有演员,舞台是通过Group的 addActor方法来添加演员的。
大概概念介绍到这里,如有疑问可以参考一些教程和官方文档

我们来新建一个演员类如下
package com.me.mygdxgame;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;


public class GirlActor extends Actor {
    TextureRegion[] girlRegion;
    float stateTime;
    //当前帧
    TextureRegion currentFrame;
    Animation animation;

    public GirlActor(Texture[] texture) {
        girlRegion = new TextureRegion[16];
        //把Texture转换下
        for (int i = 0; i < 16; i++) {
            girlRegion[i] = new TextureRegion(texture[i]);
        }
        //动画播放,参数为动画播放速度。和纹理数组
        //0.06*16=0.96 大概就是1秒钟播放完这个动画。
        animation = new Animation(0.06f, girlRegion);
    }


    @Override
    public void draw(Batch batch, float parentAlpha) {
        stateTime += Gdx.graphics.getDeltaTime();
        //下一帧
        currentFrame = animation.getKeyFrame(stateTime, true);
        //绘制人物
        batch.draw(currentFrame, 0, 0);
    }
}


修改MyGame类
package com.me.mygdxgame;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;

import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;

public class MyGame implements ApplicationListener {
    private SpriteBatch batch;
    private BitmapFont bitmapFont;
    private Texture texture;
    private Stage stage;

    @Override
    public void create() {
        //加载字体文件从电脑上拷贝的华文琥珀字体,当然你可以使用任意一种中文字体。
        FreeTypeFontGenerator freeTypeFontGenerator =
                new FreeTypeFontGenerator(Gdx.files.internal("data/font/STHUPO.TTF"));

        //关于字体的一些配置参数,详细的可以看官方API和FreeTypeFontGenerator的源码
        FreeTypeFontGenerator.FreeTypeFontParameter fontParameter =
                new FreeTypeFontGenerator.FreeTypeFontParameter();

        //注意这不是我们要显示的文字,其实相当于我们上篇使用的文字工具编辑的字符串内容,
        // 这里是默认的字符串加上了我们要使用的汉字。
        fontParameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + "你好";

        //根据参数设置生成的字体数据,这就相当于上篇的myfont.fnt文件和myfont.png
        FreeTypeFontGenerator.FreeTypeBitmapFontData fontData =
                freeTypeFontGenerator.generateData(fontParameter);

        //及时释放资源,避免内存泄漏,因为中文字体文件一般都比较大
        freeTypeFontGenerator.dispose();

        //从字面看,其实也是加载的图片
        bitmapFont = new BitmapFont(fontData, fontData.getTextureRegions(), false);
        batch = new SpriteBatch();
        //文字绘制 (注释掉昨天的)
//        bitmapFont = new BitmapFont(Gdx.files.internal("data/font/myfont.fnt"),
//                Gdx.files.internal("data/font/myfont.png"), false);
        texture = new Texture(Gdx.files.internal("data/image/girl.png"));
        Texture[] girlTextures = new Texture[16];
        //加载人物动作的16幅图片
        for (int i = 0; i < 16; i++) {
            girlTextures[i] = new Texture(Gdx.files.internal("data/image/" + (i + 1) + ".png"));
        }
        //初始化演员类
        GirlActor girlActor = new GirlActor(girlTextures);
        //初始化舞台,舞台大小为屏幕大小
        stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);

        //把演员放入舞台
        stage.addActor(girlActor);


    }

    @Override
    public void render() {
        //这个经常出现的代码就是opengl ES的清屏方法
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        //使用一种颜色填充屏幕
        //前三个是屏幕颜色的参数,最后一个是透明度,注意颜色不是我们熟悉的RGB
        Gdx.gl.glClearColor(0.57f, 0.40f, 0.55f, 1.0f);


        stage.act();
        //画出舞台中的演员,draw方法其实就跟下边的方法类似也是以begin开始,end结束,所以我们就不用再写了。
        stage.draw();


        batch.begin();
        bitmapFont.draw(batch, "你好libgdx!......", Gdx.graphics.getWidth() * 0.4f, Gdx.graphics.getHeight() / 2);
//        batch.draw(texture,0, 0);
        batch.end();

    }

    @Override
    public void dispose() {
        batch.dispose();
        bitmapFont.dispose();
        texture.dispose();
        stage.dispose();


    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }


}


运行下,好了,动起来了。(相关图片可以在源码中获取)
Animation 是我们实现动画的关键类。其实通过查看它的源码我们可以知道。
其实它就是通过切换单个图片文件来实现连续动画的。并且我们还可以改变它的播放模式,
例如动画只播放一次,循环播放,倒退播放(可以想象下磁带倒着播放),循环随机播放等等
这里我们使用的是正常播放模式,默认循环播放。
Gdx.graphics.getDeltaTime();

这是干什么用的呢。还是那句话,看源码
return the time span between the current frame and the last frame in seconds. Might be smoothed over n frames.
什么意思呢,它返回的是当前帧和前一帧之间的时间跨度。
为了更直观。我输出了下它的变化。
 @Override
    public void draw(Batch batch, float parentAlpha) {
        System.out.println("DeltaTime====="+Gdx.graphics.getDeltaTime());
        stateTime += Gdx.graphics.getDeltaTime();
        //下一帧
        currentFrame = animation.getKeyFrame(stateTime, true);
        //绘制人物
        batch.draw(currentFrame, 0, 0);

输出结果(注意,这里我使用的是真实的设备:华为C8813)
03-18 08:51:57.994    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016970333
03-18 08:51:58.004    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016164333
03-18 08:51:58.024    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016304668
03-18 08:51:58.034    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016325668
03-18 08:51:58.054    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.015347001
03-18 08:51:58.074    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.015698
03-18 08:51:58.084    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016385
03-18 08:51:58.104    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016376335
03-18 08:51:58.124    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016360667
03-18 08:51:58.134    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016013334
03-18 08:51:58.154    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016335
03-18 08:51:58.164    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016316334
03-18 08:51:58.184    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016595
03-18 08:51:58.204    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016330667
03-18 08:51:58.214    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016255334
03-18 08:51:58.234    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016421335
03-18 08:51:58.254    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016354334
03-18 08:51:58.264    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016077667
03-18 08:51:58.284    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016364332
03-18 08:51:58.304    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016402
03-18 08:51:58.314    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016265666
03-18 08:51:58.334    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016333
03-18 08:51:58.344    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016339
03-18 08:51:58.364    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016320666
03-18 08:51:58.394    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016559333
03-18 08:51:58.404    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.017074665
03-18 08:51:58.414    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016678333
03-18 08:51:58.434    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016316665
03-18 08:51:58.444    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016318668
03-18 08:51:58.464    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016178
03-18 08:51:58.474    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.015533668
03-18 08:51:58.504    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016484333
03-18 08:51:58.514    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016375002
03-18 08:51:58.534    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016400667
03-18 08:51:58.544    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016734667
03-18 08:51:58.564    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016447667
03-18 08:51:58.574    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.015874667
03-18 08:51:58.594    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016333
03-18 08:51:58.614    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016313998
03-18 08:51:58.624    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.015864002
03-18 08:51:58.644    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016313668
03-18 08:51:58.654    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016386667
03-18 08:51:58.674    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016461
03-18 08:51:58.694    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016348667
03-18 08:51:58.704    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016316665
03-18 08:51:58.724    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016343666
03-18 08:51:58.744    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016439
03-18 08:51:58.754    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016340334
03-18 08:51:58.774    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016478999
03-18 08:51:58.794    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016400333
03-18 08:51:58.804    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016583
03-18 08:51:58.824    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016164333
03-18 08:51:58.834    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016223
03-18 08:51:58.854    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016178
03-18 08:51:58.874    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016279334
03-18 08:51:58.884    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016175
03-18 08:51:58.904    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016370334
03-18 08:51:58.924    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016302332
03-18 08:51:58.934    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016382333
03-18 08:51:58.954    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016404334
03-18 08:51:58.974    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016325668
03-18 08:51:58.984    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016703665
03-18 08:51:59.004    3604-3747/com.me.mygdxgame I/System.out﹕ DeltaTime=====0.016402332

恩,每帧之间的间隔大约是0.016s。这说明什么呢。
在理解这个之前我们要先了解下帧和帧率的概念,什么是帧呢,简单理解就是屏幕刷新一次。显示出我们需要看到的内容。还记得以前的老电影吗?播放胶片的那个(当然现在也是播放胶片),它每秒大约播放24张胶片,每张胶片为1帧,相当于每秒刷新24次,那么它的帧率就是24.对于游戏简单来说,帧率就是我们每秒刷新屏幕的次数,还记得前面说的render()方法吗,我不是说它其实就像个循环方法一样不停循环码,其实这个可以认为是它每秒执行了多少次。执行了多少次呢。算下吧。1s/0.016s≈62.5 也就是大概60。大家可以数下上面日志输出的个数。从第二行58秒开始到倒数第二行结束。这一秒内输出了多少次。
当然为了验证下我的计算和猜测。我们来输出下我们游戏真实的帧率。
修改MyGame代码如下
package com.me.mygdxgame;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;

import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;

public class MyGame implements ApplicationListener {
    private SpriteBatch batch;
    private BitmapFont bitmapFont;
    private Texture texture;
    private Stage stage;
    Label fps;
    Label newFPS;

    @Override
    public void create() {
        //加载字体文件从电脑上拷贝的华文琥珀字体,当然你可以使用任意一种中文字体。
        FreeTypeFontGenerator freeTypeFontGenerator =
                new FreeTypeFontGenerator(Gdx.files.internal("data/font/STHUPO.TTF"));

        //关于字体的一些配置参数,详细的可以看官方API和FreeTypeFontGenerator的源码
        FreeTypeFontGenerator.FreeTypeFontParameter fontParameter =
                new FreeTypeFontGenerator.FreeTypeFontParameter();

        //注意这不是我们要显示的文字,其实相当于我们上篇使用的文字工具编辑的字符串内容,
        // 这里是默认的字符串加上了我们要使用的汉字。
        fontParameter.characters = FreeTypeFontGenerator.DEFAULT_CHARS + "你好";

        //根据参数设置生成的字体数据,这就相当于上篇的myfont.fnt文件和myfont.png
        FreeTypeFontGenerator.FreeTypeBitmapFontData fontData =
                freeTypeFontGenerator.generateData(fontParameter);

        //及时释放资源,避免内存泄漏,因为中文字体文件一般都比较大
        freeTypeFontGenerator.dispose();

        //从字面看,其实也是加载的图片
        bitmapFont = new BitmapFont(fontData, fontData.getTextureRegions(), false);
        batch = new SpriteBatch();
        //文字绘制 (注释掉昨天的)
//        bitmapFont = new BitmapFont(Gdx.files.internal("data/font/myfont.fnt"),
//                Gdx.files.internal("data/font/myfont.png"), false);
        texture = new Texture(Gdx.files.internal("data/image/girl.png"));
        Texture[] girlTextures = new Texture[16];
        //加载人物动作的16幅图片
        for (int i = 0; i < 16; i++) {
            girlTextures[i] = new Texture(Gdx.files.internal("data/image/" + (i + 1) + ".png"));
        }
        //初始化演员类
        GirlActor girlActor = new GirlActor(girlTextures);
        //初始化舞台,舞台大小为屏幕大小
        stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);

        //黑色显示
        Label.LabelStyle labelStyle = new Label.LabelStyle(new BitmapFont(), Color.BLACK);
        //显示内容
        fps = new Label("FPS:", labelStyle);
        fps.setName("fps");
        //显示在左上角位置,减去显示字体的高度,要不然会跑到屏幕外面,根本看不到
        fps.setY(Gdx.graphics.getHeight() - fps.getHeight());
        fps.setX(0);


        //把演员放入舞台
        stage.addActor(girlActor);
        stage.addActor(fps);

    }

    @Override
    public void render() {
        //这个经常出现的代码就是opengl ES的清屏方法
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        //使用一种颜色填充屏幕
        //前三个是屏幕颜色的参数,最后一个是透明度,注意颜色不是我们熟悉的RGB
        Gdx.gl.glClearColor(0.57f, 0.40f, 0.55f, 1.0f);

        //因为render方法在不停执行,那么我们就在这里实时的更新系统帧率的数据
        //获取fps,然后修改它的显示为获取的系统帧率值
        newFPS = (Label) stage.getRoot().findActor("fps");
        newFPS.setText("FPS:" + Gdx.graphics.getFramesPerSecond());

        stage.act();
        //画出舞台中的演员,draw方法其实就跟下边的方法类似也是以begin开始,end结束,所以我们就不用再写了。
        stage.draw();


        batch.begin();
        bitmapFont.draw(batch, "你好libgdx!......", Gdx.graphics.getWidth() * 0.4f, Gdx.graphics.getHeight() / 2);
//        batch.draw(texture,0, 0);
        batch.end();

    }

    @Override
    public void dispose() {
        batch.dispose();
        bitmapFont.dispose();
        texture.dispose();
        stage.dispose();


    }

    @Override
    public void resize(int width, int height) {

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }


}




62的帧率。验证了我的猜测。
在这里我要提醒下大家,不要把帧率,和动画播放速度弄混了。
动画切换速度为0.06s。帧率间隔为0.016,为了直观算作0.02好了。
估算下,每张图片显示的时间,屏幕刷新了几次。
这么弱的数学题我就不算了
  stateTime += Gdx.graphics.getDeltaTime();
        //下一帧
        currentFrame = animation.getKeyFrame(stateTime, true);

通过上面的介绍,相信都能了解上面两句的含义了。留给大家理解。
好了,收工。
源码地址:http://pan.baidu.com/s/1sjHFJh7
注意:图片资源来自于互联网,仅限学习,请勿用于商业用途,否则后果自负。
  • 大小: 24.2 KB
  • 大小: 4.1 KB
  • 大小: 46.5 KB
  • 大小: 179.7 KB
  • 大小: 44.9 KB
分享到:
评论

相关推荐

    libgdx学习资料

    - 社区提供了许多第三方库,如Ashley(实体系统)、TiledMap(地图编辑器支持)和Hiero(位图字体生成器)等,进一步扩展了LibGDX的功能。 这个“libgdx学习资料”压缩包可能包含了上述领域的教程、示例代码、API...

    libgdx学习文档 DOC格式

    Libgdx是一款强大的开源游戏开发框架,它支持2D和3D游戏的开发,并且跨平台,可以在JavaSE环境(包括Mac、Linux、Windows等操作系统)以及Android平台...开发者可以通过学习和掌握Libgdx,快速地构建起自己的游戏项目。

    LibGDX制作android动态壁纸

    在LibGDX项目中,这个Activity通常会继承自`com.badlogic.gdx.backends.android.AndroidApplication`,并覆盖`onCreate()`方法来启动壁纸服务。 动态壁纸的主体部分是实现`WallpaperService`,这是一个Android原生...

    libGDX学习记录(三) 接水滴源码 Drop.zip

    在这个“libGDX学习记录(三) 接水滴源码”中,我们将深入探讨如何使用libGDX来构建一个简单的游戏——接水滴。这个例子可能是为了教授初学者基本的游戏逻辑、动画处理和用户交互。 在libGDX中,游戏的核心通常由`...

    libGDX学习记录(三)项目源码 接水滴(欢迎界面及计分器) Drop.zip

    这个压缩包"Drop.zip"包含的是一个基于libGDX的游戏项目,名为"接水滴",它提供了欢迎界面和计分系统,是一个很好的学习libGDX入门的实例。在深入探讨这个项目之前,我们需要了解libGDX的基本概念。 libGDX是一个全...

    Libgdx专题系列 UI篇

    通过学习和实践这个"Libgdx专题系列 UI篇",你将掌握如何利用TWL库和TableLayout在Libgdx中创建出高效、美观的用户界面,为你的游戏或应用增添更多互动性和吸引力。记得不断尝试和迭代,让UI设计适应你的项目需求,...

    libGDX学习记录(一)源码

    libGDX学习记录(一)源码,搭建一个桌面端和android端的libGDX框架,展示图片。 详细地址:https://blog.csdn.net/weixin_47450795/article/details/110003413

    Libgdx专题系列 第一篇 第七节

    总的来说,"Libgdx专题系列 第一篇 第七节"会带你走进Libgdx的文本世界,教你如何有效地使用`BitmapFont`和`Label`进行文本渲染,同时涵盖文本的格式化、动态更新和性能优化。通过学习这一节,你将具备在Libgdx游戏...

    Libgdx专题系列 斜45°地图

    通过深入学习和实践,开发者可以利用LibGDX创造出具有丰富视觉效果和互动性的2D游戏世界。提供的文件“LibgdxText_3”可能是这个专题系列的源代码或文档,可以帮助进一步理解和实现斜45°地图的细节。

    Libgdx专题系列第一篇 第一节

    在第一节的学习中,你可能会接触到以下步骤: 1. 创建一个新的Libgdx项目,并理解项目结构。 2. 设置屏幕分辨率和视口管理,例如使用FitViewport或StretchViewport。 3. 加载BitmapFont并创建一个Label实例,展示...

    libGDX学习记录(二)阶段源码

    libGDX学习记录(二)阶段源码 展示TexturePacker合成的图片,详细地址: https://blog.csdn.net/weixin_47450795/article/details/110037945

    Libgdx实现动画效果示例

    Libgdx实现了动画效果,项目含:源码+效果图+APK 教程地址:http://blog.csdn.net/yangyu20121224/article/details/9208095

    libgdx学习总结

    libgx学习过程总结,记录本人所遇到的问题和心得

    Libgdx专题系列 地图移动

    通过这个“Libgdx专题系列 地图移动”的学习,你将掌握如何在Libgdx环境中构建可交互、可探索的游戏世界,并为玩家提供流畅的地图导航体验。无论是初学者还是经验丰富的开发者,都能从中获得宝贵的知识和技巧。记得...

    libgdx学习文档

    libgdx的中文学习文档,资料太少,将就用吧

    Libgdx 中文输入显示

    在游戏开发领域,LibGDX 是一款非常流行的开源游戏框架,它允许开发者使用 Java 语言构建跨平台的游戏应用。然而,LibGDX 的原生功能并不包含对中文输入的直接支持,这使得在开发需要中文输入的游戏或应用时,开发者...

    使用Libgdx模仿智龙迷城三消demo

    使用Libgdx模仿智龙迷城三消demo,只是实现智龙迷城的三消形式

    libgdx_wiki学习文档

    libGdx是一个跨平台的2D/3D的游戏开发框架,它由Java/C/C++语言编写而成。libgdx兼容Windows、Linux、Max OS X、Java Applet、Javascript/WebGL与Android(1.5版本+)平台。该文档为libgdx在wiki上的官方学习文档。

Global site tag (gtag.js) - Google Analytics