Libgdx学习笔记:使用ShapeRenderer绘制贝塞尔曲线路线图

2019独角兽企业重金招聘Python工程师标准>>> hot3.png


上图红色路径即为贝塞尔曲线的路线。

核心思路:

获取贝塞尔曲线上的所有的点,然后通过ShapeRenderer画线即可。


代码展示:

package com.oahcfly.chgame.core.ui;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Bezier;
import com.badlogic.gdx.math.Vector2;
import com.oahcfly.chgame.core.mvc.CHActor;

/**
 * 
 * 贝塞尔路线 : 使用ShapeRenderer绘制
 * @author haocao
 *
 */
public class CHBezierLine extends CHActor {

	// 以左上角为原点进行绘制的
	private ShapeRenderer shapeRenderer;
	private Bezier bezier;
	// 点列表
	private Vector2[] points;
	// 线条颜色
	private Color lineColor = Color.RED;

	public CHBezierLine (Bezier bezier) {
		this(bezier, Color.RED);
	}

	public CHBezierLine (Bezier bezier, Color lineColor) {
		updateBezier(bezier);
		this.lineColor = lineColor;
		shapeRenderer = new ShapeRenderer();
		shapeRenderer.setAutoShapeType(true);
	}

	/**
	 * 更新贝塞尔曲线参数
	 * @param bezier
	 */
	public void updateBezier (Bezier bezier) {
		this.bezier = bezier;
		// 计算所有点
		int dis = (int)(this.bezier.points.get(this.bezier.points.size - 1).x - this.bezier.points.get(0).x);
		if (dis == 0) {
			dis = (int)(this.bezier.points.get(this.bezier.points.size - 1).y - this.bezier.points.get(0).y);
		}
		points = new Vector2[dis];
		for (int i = 0; i < dis; i++) {
			float t = i * 1f / dis;
			Vector2 out = new Vector2();
			this.bezier.valueAt(out, t);
			points[i] = out;
		}
	}

	@Override
	public void draw (Batch batch, float parentAlpha) {
		batch.flush();

		// 设置用于渲染的投影矩阵
		getStage().getCamera().update();
		shapeRenderer.setProjectionMatrix(getStage().getCamera().combined);

		shapeRenderer.begin(ShapeType.Line);
		shapeRenderer.setColor(this.lineColor);
		for (int i = 0, l = points.length - 1; i < l; i++) {
			Vector2 cur = points[i];
			Vector2 next = points[i + 1];
			shapeRenderer.line(cur, next);
		}
		shapeRenderer.end();

		// 结束本次绘制
		batch.end();
		// 重新开始新的
		batch.begin();

	}

	@Override
	public boolean remove () {
		// TODO Auto-generated method stub
		shapeRenderer.dispose();
		return super.remove();
	}

}

关联代码:

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;

/** 
 * 二次封装的actor
 * 
 * date: 2014-12-11
 * 
 *   * @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); } /** 
	 * 使用缓存池
	 * 
	 * date: 2015-1-3
	 * 
 *   * @author caohao  * @return */ @SuppressWarnings("unchecked") public static  T obtain (Class type) { Pool pool = (Pool)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 clipRectangleArr = new Array(); /**  * 添加裁剪矩形,范围为当前Actor的显示区域即:(0,0)~(w,h) 左下角  * @param rectangle  */ public void addClipRectangle (Rectangle rectangle) { clipRectangleArr.add(rectangle); } 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/591595

你可能感兴趣的:(测试,python,git)