效果图:
使用范例:
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