Libgdx学习笔记:可垂直滚动的文本组件CHScrollLabel

效果图:

094418_7ZJk_1866808.png

使用范例:

             CHScrollLabelStyle scrollLabelStyle = new CHScrollLabelStyle();
		// 文本背景
		scrollLabelStyle.background = Chao.game.getDrawable(CHRes.asset.zhao_png);
		// 右侧滚动条背景
		scrollLabelStyle.vScroll = Chao.game.getDrawable(CHRes.asset.loading_bg_jpg);
		// 滚动条浮标
		scrollLabelStyle.vScrollKnob = Chao.game.getDrawable(CHRes.asset.day_1_png);
		// 滚动条浮标高
		scrollLabelStyle.scrollBarHeight=30;
		// 滚动条浮标宽
		scrollLabelStyle.scrollBarWidth=10;
		
		CHScrollLabel scrollLabel = new CHScrollLabel(Color.RED, testText);
		// 设置宽,高
		scrollLabel.setSize(400, 300);
		CHUIUtil.toCenter(scrollLabel);
		addActor(scrollLabel);

		// 绑定样式
		scrollLabel.setScrollLabelStyle(scrollLabelStyle);


源码展示:

package com.oahcfly.chgame.core.ui;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.utils.Align;
import com.oahcfly.chgame.core.freefont.FreeFont;
import com.oahcfly.chgame.core.freefont.FreeLabel;
import com.oahcfly.chgame.core.mvc.CHActor;

/**
 * 
 * 
 * 可以滚动的文本
 * 
 * @author haocao
 *
 */
public class CHScrollLabel extends CHActor {

	private FreeLabel freeLabel;
	// 滚动偏移量,左下角为(0,0)
	private float scrollY;

	private CHScrollLabelStyle scrollLabelStyle;

	public CHScrollLabel (CHScrollLabelStyle style, Color textColor, String text) {
		this(style, FreeFont.DEFAULT_FONT_NAME, textColor, text);
	}

	public CHScrollLabel (Color textColor, String text) {
		this(new CHScrollLabelStyle(), FreeFont.DEFAULT_FONT_NAME, textColor, text);
	}

	public CHScrollLabel (CHScrollLabelStyle style, String fontName, Color textColor, String text) {
		this.scrollLabelStyle = style;
		freeLabel = FreeFont.getLabel(textColor, text);
		freeLabel.setWrap(true);
		freeLabel.setAlignment(Align.topLeft);
		setText(text);
		setTextColor(textColor);

		addListener(new ActorGestureListener() {

			@Override
			public void pan (InputEvent event, float x, float y, float deltaX, float deltaY) {
				scrollY(deltaY);
			}

			@Override
			public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
			}

		});
	}

	public CHScrollLabelStyle getScrollLabelStyle () {
		return scrollLabelStyle;
	}

	public void setScrollLabelStyle (CHScrollLabelStyle scrollLabelStyle) {
		this.scrollLabelStyle = scrollLabelStyle;
	}

	@Override
	public void drawAfterBg (Batch batch) {

		//背景
		if (scrollLabelStyle != null && scrollLabelStyle.background != null) {
			scrollLabelStyle.background.draw(batch, getX(), getY(), getWidth(), getHeight());
		}

		// 设置裁剪区域
		if (getClipRectangleArr().size == 0) {
			addClipRectangle(new Rectangle(0, 0, getWidth(), getHeight()));
		}

		freeLabel.setPosition(getX(), getY() + scrollY);
		freeLabel.setWidth(getWidth() - (scrollLabelStyle != null ? scrollLabelStyle.scrollBarWidth : 0));
		freeLabel.setHeight(getHeight());
		freeLabel.draw(batch, 1);

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

		if (scrollLabelStyle != null && scrollLabelStyle.vScroll != null) {
			scrollLabelStyle.vScroll.draw(batch, getRight() - scrollLabelStyle.scrollBarWidth, getY(),
				scrollLabelStyle.scrollBarWidth, getHeight());
		}

		if (scrollLabelStyle != null && scrollLabelStyle.vScrollKnob != null) {
			// w=10,h=30,yRange=[gety~gettop-30]
			float scrollH = getTop() - scrollLabelStyle.scrollBarHeight - getY();
			float percent = scrollY / (freeLabel.getTextHeight() - getHeight());
			scrollLabelStyle.vScrollKnob.draw(batch, getRight() - scrollLabelStyle.scrollBarWidth, getY() + scrollH * (1 - percent),
				scrollLabelStyle.scrollBarWidth, scrollLabelStyle.scrollBarHeight);
		}
	}

	public void setText (String text) {
		freeLabel.setText(text);
	}

	public void setTextColor (Color textColor) {
		freeLabel.setColor(textColor);
	}

	public void scrollY (float value) {
		float temp = freeLabel.getTextHeight() - getHeight();
		if (temp <= 0) {
			return;
		}

		scrollY += value;

		// 边界检测
		if (scrollY > temp) {
			scrollY = temp;
		}
		if (scrollY < 0) {
			scrollY = 0;
		}
	}

	public FreeLabel getLabel () {
		return freeLabel;
	}

	/**
	 * 
	 * 
	 * 样式:背景,
	 * @author haocao
	 *
	 */
	static public class CHScrollLabelStyle {
		/** Optional. */
		public Drawable background;
		/** Optional. */
		public Drawable vScroll, vScrollKnob;

		public float scrollBarWidth = 10, scrollBarHeight = 30;

		public CHScrollLabelStyle () {
		}

		public CHScrollLabelStyle (Drawable background, Drawable vScroll, Drawable vScrollKnob) {
			this.background = background;
			this.vScroll = vScroll;
			this.vScrollKnob = vScrollKnob;
		}

		public CHScrollLabelStyle (CHScrollLabelStyle style) {
			this.background = style.background;
			this.vScroll = style.vScroll;
			this.vScrollKnob = style.vScrollKnob;
		}
	}
}
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.Array;
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;

	private Sprite sprite;

	public CHActor () {
	}

	/**
	 * 绑定一个精灵,此时CHActor的属性会同步到精灵上。
	 * @param sprite
	 */
	public void bindSprite (Sprite sprite) {
		this.sprite = sprite;
		setSize(this.sprite.getWidth(), this.sprite.getHeight());
		setOrigin(Align.center);
	}

	@Override
	public void draw (Batch batch, float parentAlpha) {
		if (clipRectangleArr.size > 0) {
			for (Rectangle cRectangle : clipRectangleArr) {
				this.drawCore(batch, parentAlpha, cRectangle);
			}
		} else {
			this.drawCore(batch, parentAlpha, null);
		}
	}

	/**
	 * 核心绘制
	 * @param batch
	 * @param parentAlpha
	 * @param clipRectangle
	 */
	private void drawCore (Batch batch, float parentAlpha, Rectangle clipRectangle) {
		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());
			}
		}

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

		// 绘制完背景后进行其他内容绘制
		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;
		clipRectangleArr.clear();
		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 Array<Rectangle> clipRectangleArr = new Array<Rectangle>();

	/**
	 * 添加裁剪矩形,范围为当前Actor的显示区域即:(0,0)~(w,h) 原点为左下角
	 * @param rectangle
	 */
	public void addClipRectangle (Rectangle rectangle) {
		clipRectangleArr.add(rectangle);
	}

	public Array<Rectangle> getClipRectangleArr () {
		return clipRectangleArr;
	}

	public Sprite getSprite () {
		return sprite;
	}

	private Rectangle boundsRectangle;

	@Override
	protected void sizeChanged () {
		if (boundsRectangle == null) {
			boundsRectangle = new Rectangle();
		}
		boundsRectangle.width = getWidth();
		boundsRectangle.height = getHeight();
	}

	/**
	 * 用于碰撞检测的矩形区域
	 * @return
	 */
	public Rectangle getBoundsRectangle () {
		boundsRectangle.x = getX();
		boundsRectangle.y = getY();
		return boundsRectangle;
	}

}


基于Libgdx开发的开源游戏框架CHGame:

http://git.oschina.net/oahcfly/CHGameFrame


转载于:https://my.oschina.net/oahcfly/blog/612808

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值