您的位置:首页 > 其它

Libgdx学习笔记:跑马灯效果

2015-12-09 15:39 351 查看
首先看下效果图:



黑色底部背景,文字的可显示区域。红色为滚动的文字。

预备知识:

https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/Actor.html

我们用了Actor中的,clipBegin和clipEnd

裁剪方法,类似截图,给一个矩形区域,仅绘制矩形区域内的内容。

这里面有个注意事项就是,在clipbegin()之前,需要调用batch.flush()。目的是让之前加入舞台的Actor进行绘制,如果不加就会导致之前的Actor不被绘制。

batch.flush();
clipBegin();

滚动的实现,我们直接用的是MoveByAction。

使用方法:

// 设置速度,宽度,文字,文字颜色
CHMarqueeText marqueeText = new CHMarqueeText.Builder().setMoveSpeed(100).setMarqueeWidth(100)
.setText("测试跑马灯效果超长文本显示1234567890结束了。").setTextColor(Color.RED).build();
addActor(marqueeText);
marqueeText.setPosition(100, 560);


代码展示:

package com.oahcfly.chgame.core.ui;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.oahcfly.chgame.core.freefont.FreeFont;
import com.oahcfly.chgame.core.freefont.FreeLabel;
import com.oahcfly.chgame.core.helper.CHPixmapHelper;
import com.oahcfly.chgame.core.mvc.CHActor;

/**
* 跑马灯
* @author haocao
*
*/
public class CHMarqueeText extends CHActor {

// 文本Label
private FreeLabel label;
private Texture bgTexture;

public void setMarqueeTextParams (String text, Color textColor, int width, int moveSpeed) {
stoped = false;
label = FreeFont.getLabel(textColor, text);
// 设置透明背景
Color alphaColor = new Color(Color.BLACK);
alphaColor.a = 0.2f;
bgTexture = CHPixmapHelper.createRectangleTexture(alphaColor, width, 20 + FreeFont.getBitmapFont().getSize());
setBgTexture(bgTexture);
setClipRectangle(new Rectangle(0, 0, width, getHeight()));

// float moveDistance = Math.max(0, label.getWidth() - width);
float duration = Math.max(0, 12 - 3 * moveSpeed / 100f);
if (label.getWidth() > width) {
label.addAction(Actions.repeat(-1,
Actions.sequence(Actions.moveBy(-label.getWidth(), 0, duration), Actions.run(new Runnable() {

@Override
public void run () {
// 从尾部重新开始
label.setX(getRight());
}
}), Actions.moveBy(-label.getWidth() - width, 0, duration))));
}
}

@Override
public void drawAfterBg (Batch batch) {
if (label.getX() == 0) {
// 设置初始坐标
label.setX(getX());
}
label.draw(batch, 1);
// 随着action的执行,坐标会发生变化,在这里进行赋值更新
label.setPosition(label.getX(), getY() + 5f);
}

@Override
public void act (float delta) {
if (!stoped) {
label.act(delta);
}
super.act(delta);
}

public FreeLabel getLabel () {
return label;
}

@Override
public boolean remove () {
if (bgTexture != null) {
bgTexture.dispose();
}
return super.remove();
}

private boolean stoped;

public void stopMarquee () {
stoped = true;
}

public void resumeMarquee () {
stoped = false;
}

public static class Builder {
private String text;
private Color textColor;
private int marqueeWidth;
private int moveSpeed = 50;

public Builder setText (String text) {
this.text = text;
return this;
}

public Builder setTextColor (Color textColor) {
this.textColor = textColor;
return this;
}

public Builder setMarqueeWidth (int marqueeWidth) {
this.marqueeWidth = marqueeWidth;
return this;
}

/**
* 范围【0~100】越大速度越快
* @param moveSpeed
* @return
*/
public Builder setMoveSpeed (int moveSpeed) {
this.moveSpeed = moveSpeed > 100 ? 100 : moveSpeed < 0 ? 0 : moveSpeed;
return this;
}

public CHMarqueeText build () {
CHMarqueeText chMarqueeText = CHActor.obtain(CHMarqueeText.class);
chMarqueeText.setMarqueeTextParams(text, textColor, marqueeWidth, moveSpeed);
return chMarqueeText;
}
}

}

关联的CHActor代码:

package com.oahcfly.chgame.core.mvc;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pool.Poolable;
import com.badlogic.gdx.utils.Pools;
import com.oahcfly.chgame.core.Chao;

/** <pre>
* 二次封装的actor
*
* date: 2014-12-11
* </pre>
*
* @author caohao */
public class CHActor extends Actor implements Poolable {
private int tag;

private Texture bgTexture;

private TextureRegion bgTextureRegion;

public CHActor () {
}

@Override
public void draw (Batch batch, float parentAlpha) {
boolean clipok = false;
// 开始裁剪
if (clipRectangle != null) {
batch.flush(); // 绘制之前添加的元素,如果不添加此处代码,后面的裁剪会导致之前的纹理也会被裁剪
clipok = clipBegin(getX() + clipRectangle.x, getY() + clipRectangle.y, clipRectangle.width, clipRectangle.height);
}

Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a);

float x = getX();
float y = getY();
float scaleX = getScaleX();
float scaleY = getScaleY();

float width = getWidth();
float height = getHeight();

if (bgTexture != null) {
batch.draw(bgTexture, x, y, getOriginX(), getOriginY(), getWidth(), getHeight(), scaleX, scaleY, getRotation(), 0, 0,
(int)width, (int)height, false, false);
}

if (bgTextureRegion != null) {
if (bgTextureRegion instanceof Sprite) {
Sprite sprite = (Sprite)bgTextureRegion;
sprite.setColor(batch.getColor());
sprite.setOrigin(getOriginX(), getOriginY());
sprite.setPosition(x, y);
sprite.setScale(scaleX, scaleY);
sprite.setSize(width, height);
sprite.setRotation(getRotation());
sprite.draw(batch);
} else {
batch.draw(bgTextureRegion, x, y, getOriginX(), getOriginY(), width, height, scaleX, scaleY, getRotation());
}
}

// 绘制完背景后进行其他内容绘制
drawAfterBg(batch);

// 提交裁剪内容
if (clipok) {
batch.flush();
clipEnd();
}
}

public void drawAfterBg (Batch batch) {
};

public void setBgTexture (Texture bgTexture) {
this.bgTexture = bgTexture;
if (bgTexture != null) {
setSize(bgTexture.getWidth(), bgTexture.getHeight());
}
setOrigin(Align.center);
}

/** <pre>
* 使用缓存池
*
* date: 2015-1-3
* </pre>
*
* @author caohao
* @return */
@SuppressWarnings("unchecked")
public static <T extends CHActor> T obtain (Class<T> type) {
Pool<CHActor> pool = (Pool<CHActor>)Pools.get(type);
CHActor actor = pool.obtain();
actor.setBgTexture(null);
return (T)actor;
}

public static CHActor obtain () {
return obtain(CHActor.class);
}

@Override
public void reset () {
this.bgTexture = null;
this.bgTextureRegion = null;
clipRectangle = null;
setScale(1);
setRotation(0);
clear();
setUserObject(null);
this.setColor(new Color(1, 1, 1, 1));
setStage(null);
setParent(null);
setVisible(true);
setName(null);
setOrigin(Align.center);
setPosition(0, 0);
}

public Texture getBgTexture () {
return bgTexture;
}

public TextureRegion getBgTextureRegion () {
return bgTextureRegion;
}

public void setBgTextureRegion (TextureRegion textureRegion) {
this.bgTextureRegion = textureRegion;
if (bgTextureRegion != null) {
if (bgTextureRegion instanceof Sprite) {
Sprite sprite = (Sprite)bgTextureRegion;
setSize(sprite.getWidth(), sprite.getHeight());
} else if (bgTextureRegion instanceof AtlasRegion) {
AtlasRegion atlasRegion = (AtlasRegion)bgTextureRegion;
bgTextureRegion = Chao.plistCenter.createSprite(atlasRegion);
Sprite sprite = (Sprite)bgTextureRegion;
setSize(sprite.getWidth(), sprite.getHeight());
} else {
setSize(bgTextureRegion.getRegionWidth(), bgTextureRegion.getRegionHeight());
}
}

setOrigin(Align.center);
}

@Override
public boolean remove () {
boolean remove = super.remove();
if (remove) {
Pools.free(this);
}
return remove;
}

public int getTag () {
return tag;
}

public void setTag (int tag) {
this.tag = tag;
}

private Rectangle clipRectangle;

/**
* 设置裁剪矩形,范围为当前Actor的显示区域即:(0,0)~(w,h)
* @param rectangle
*/
public void setClipRectangle (Rectangle rectangle) {
this.clipRectangle = rectangle;
}

}

欢迎关注CHGame框架(基于Libgdx二次封装快速开发框架):
https://git.oschina.net/oahcfly/CHGame.git
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息