Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Rzer

Оценить эту запись

Радиальный прогресс бар для Starling 2

Запись от Rzer размещена 01.07.2016 в 14:26

Реализация без масок и прочего. Рисует до 8 треугольников. Может кому пригодится.

Код AS3:
package simplify {
	import starling.textures.Texture;
	/**
	 * Картинка с радиальным заполнением
	 * @author rzer
	 */
	public class RadialImage extends RadialQuad {
 
		public function RadialImage(texture:Texture, startAngle:Number = Math.PI/2) {
			super(texture.width, texture.height,0,startAngle);
			this.texture = texture;
		}
 
	}
 
}
И сама реализация:
Код AS3:
package simplify {
 
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import starling.display.Mesh;
	import starling.rendering.IndexData;
	import starling.rendering.VertexData;
	import starling.styles.MeshStyle;
	import starling.textures.Texture;
 
	/**
	 * Радиальная заливка
	 * @author rzer
	 */
	public class RadialQuad extends Mesh {
 
		public static const PI4:Number = Math.PI / 4;
 
		private var _angle:Number = 0;
 
		private var rect:Rectangle;
		private var center:Point;
		private var currentVertex:int = 0;
		private var startAngle:Number = 0;
 
		public function RadialQuad(width:Number, height:Number, color:uint = 0xffffff, startAngle:Number = Math.PI / 2) {
 
			this.startAngle = startAngle;
 
			rect = new Rectangle(0, 0, width, height);
			center = new Point(width / 2, height / 2);
 
			var vertexData:VertexData = new VertexData(MeshStyle.VERTEX_FORMAT, 4*4);
            var indexData:IndexData = new IndexData(6*4);
 
            super(vertexData, indexData);
 
			setupVertices();
			this.color = color;
		}
 
 
		//Процент заполнения круга
		public function get ratio():Number {
			return angle/Math.PI*0.5;
		}
 
		public function set ratio(value:Number):void {
			if (value > 1) value = 1;
			if (value < 0) value = 0;
			angle = value * 2 * Math.PI;
 
		}
 
		//Угол заполнения круга
		public function get angle():Number {
			return _angle;
		}
 
		public function set angle(value:Number):void {
			_angle = value;
			setupVertices();
		}
 
		private function setupVertices():void {
 
			indexData.numIndices = 0;
			vertexData.numVertices = 1 + Math.ceil(angle / PI4)*2;
            vertexData.trim();
 
			currentVertex = 0;
 
			vertexData.setPoint(0, "position", center.x,  center.y);
 
			if (texture){
				texture.setTexCoords(vertexData, 0, "texCoords", 0.5, 0.5);
			}else{
				vertexData.setPoint(0, "texCoords", 0.5, 0.5);
			}
 
			for (var a:Number = 0; a < angle; a += PI4){
 
				var b:Number = a + PI4;
				if (b > angle) b = angle;
				setupTriangle(pointOnBounds(a+startAngle), pointOnBounds(b+startAngle))
			}
 
			setRequiresRedraw();
 
		}
 
 
		private function setupTriangle(p1:Point, p2:Point):void {
 
			indexData.addTriangle(0, currentVertex + 1, currentVertex + 2);
 
			vertexData.setPoint(currentVertex + 1, "position", p2.x,  p2.y);
			vertexData.setPoint(currentVertex + 2, "position", p1.x,  p1.y);
 
			if (texture){
				texture.setTexCoords(vertexData, currentVertex + 1, "texCoords", p2.x / rect.width, p2.y / rect.height);
				texture.setTexCoords(vertexData, currentVertex + 2, "texCoords", p1.x / rect.width, p1.y / rect.height);
			}else{
				vertexData.setPoint(currentVertex + 1, "texCoords", p2.x / rect.width, p2.y / rect.height);
				vertexData.setPoint(currentVertex + 2, "texCoords", p1.x / rect.width, p1.y / rect.height);
			}
 
			currentVertex += 2;
		}
 
		//Возвращает точку пересечения луча выходящего из центра с границами объекта
		public function pointOnBounds(angle:Number):Point{
			var point:Point = normalizedPoint(angle);
 
			point.offset(1, 1);
			point.x *= 0.5 * rect.width;
			point.y *= 0.5 * rect.height;
 
			return point;
		}
 
		//Возвращает значение от -1 до 1;
		public function normalizedPoint(a:Number):Point{
 
			a = a % (Math.PI * 2);
			if (a < 0) a += 2 * Math.PI;
 
			var s:Number = Math.floor(a / PI4) % 8;
			var p:Number = (s % 2 == 0) ? Math.tan(a % PI4) : Math.tan(PI4 - a % PI4);
 
			if (s == 0) return new Point(1, p);
			else if (s == 1) return new Point(p, 1);
			else if (s == 2) return new Point(-p, 1);
			else if (s == 3) return new Point(-1, p);
			else if (s == 4) return new Point(-1, -p);
			else if (s == 5) return new Point(-p, -1);
			else if (s == 6) return new Point(p, -1);
			return new Point(1, -p);
		}
 
 
	}
 
}
P.S: Неужели все ушли в Unity?
Всего комментариев 10

Комментарии

Старый 02.07.2016 02:57 in4core вне форума
in4core
 
Аватар для in4core
Код AS3:
if (s == 0) return new Point(1, p);
			else if (s == 1) return new Point(p, 1);
			else if (s == 2) return new Point(-p, 1);
			else if (s == 3) return new Point(-1, p);
			else if (s == 4) return new Point(-1, -p);
			else if (s == 5) return new Point(-p, -1);
			else if (s == 6) return new Point(p, -1);
Код AS3:
array = [new Point(p, 1)....]
return array [s - 1];
Старый 02.07.2016 11:20 Zebestov вне форума
Zebestov
 
Аватар для Zebestov
Пример в пост вставить не получится?
Старый 02.07.2016 20:31 udaaff вне форума
udaaff
in4core, для чего каждый раз массив создавать и восемь точек?
else, кстати, лишний в этой конструкции.
Старый 02.07.2016 22:15 ZackMercury вне форума
ZackMercury
 
Аватар для ZackMercury
udaaff, если не будет else RE будет с каждым сверять. Когда есть else, оно будет сверять только до того, как найдёт совпадающий. Зачем лишние сравнения?
Я бы switch использовал. Как раз тот случай, когда не нужны break в нём.
Старый 03.07.2016 01:50 in4core вне форума
in4core
 
Аватар для in4core
Цитата:
in4core, для чего каждый раз массив создавать и восемь точек?
Для человеческого код стайла, айдишники идут от 0 до Н, либо цикл либо массив. А насчет того, что создавать каждый раз - не бойтесь, фукнция не на таймере висит в 50 мс, оптимизировать тут до мелочи лишнее. Но опять же каждому свое.
Старый 03.07.2016 02:10 udaaff вне форума
udaaff
Цитата:
Когда есть else, оно будет сверять только до того, как найдёт совпадающий. Зачем лишние сравнения?
Там ретурн в каждом блоке.
Старый 03.07.2016 10:44 ZackMercury вне форума
ZackMercury
 
Аватар для ZackMercury
А, ну да) Про свитчи написал, что брейки не нужны, а про else не подумал)
Старый 04.07.2016 16:27 ShockWave512 вне форума
ShockWave512
Еще не все )) утащил к себе в проект )) Спасибо!
Старый 27.12.2016 02:10 Vortis вне форума
Vortis
печально, но не отображает в текущей версии.
Видимо что-то с настройкой вертиксов поменяли. (
Старый 29.12.2016 14:25 alexandrratush вне форума
alexandrratush
 
Аватар для alexandrratush
Vortis, Текущая это какая?
 

 


Часовой пояс GMT +4, время: 23:40.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.