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

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 25.12.2013, 23:50
Ioangum вне форума Посмотреть профиль Отправить личное сообщение для Ioangum Найти все сообщения от Ioangum
  № 1  
Ответить с цитированием
Ioangum

Регистрация: Aug 2013
Адрес: Москва
Сообщений: 59
По умолчанию Параллакс в двух направлениях

Доброго времени суток! Вот уже много времени бьюсь над решением задачи - всё никак не получается + в интернете подходящей информации найти не могу. Суть такова: нужно сделать эффект параллакса, но не только при изменении x и y координат, а ещё и при приближении. Это всё на примере звёздного неба. Когда по x и y таскать надо, всё получается, а вот с глубиной проблемы. Может, кто сталкивался с подобным. Буду очень признателен за совет. Спасибо

Старый 26.12.2013, 00:56
shmaser вне форума Посмотреть профиль Отправить личное сообщение для shmaser Найти все сообщения от shmaser
  № 2  
Ответить с цитированием
shmaser
 
Аватар для shmaser

Регистрация: Aug 2010
Сообщений: 22
Зависит от того, как сейчас у вас реализованы параллакс слои. Это спрайты с разной координатой z, или это спрайты, которые лежат на одном уровне, но перемещение спрайта, который должен быть дальше, просто делается медленнее? Если первое, то просто гоняете z, если второе, то создать эффект приближения можно, масштабируя спрайты, которые должны быть ближе к зрителю быстрее, чем те которые должны казаться дальше. Что-то типа:
Код AS3:
private var _scaleFactor:Number //чем ближе к зрителю объект, тем больше значение scaleFactor
sprite.scaleX *= _scaleFactor
sprite.scaleY *= _scaleFactor
Это все предположения, но, полагаю, что таким образом вполне можно реализовать то, что нужно.

Старый 26.12.2013, 05:18
alexandrratush вне форума Посмотреть профиль Отправить личное сообщение для alexandrratush Найти все сообщения от alexandrratush
  № 3  
Ответить с цитированием
alexandrratush
 
Аватар для alexandrratush

Регистрация: Jul 2013
Адрес: Днепр
Сообщений: 529
Отправить сообщение для alexandrratush с помощью ICQ Отправить сообщение для alexandrratush с помощью Skype™
Цитата:
а вот с глубиной проблемы.
Какие именно проблемы?

Старый 26.12.2013, 10:11
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 4  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
на вскидку такой вариант:
Дальняя картинка по размеру меньше ближней, соответственно, для дальней картинки масштабирование умножаем на ширинуДальней / ширинуБлижней
то есть, допустим ширина передней картинки 2000, а дальней 1000.
Код AS3:
var scaleFactor:Number = 2;
front.scaleX = front.scaleY = scaleFactor;
back.scaleX = back.scaleY = front.scaleX * (back.width / front.width);
Что-то типа того. Не проверял, но это первое, что пришло в голову

Старый 26.12.2013, 16:16
Ioangum вне форума Посмотреть профиль Отправить личное сообщение для Ioangum Найти все сообщения от Ioangum
  № 5  
Ответить с цитированием
Ioangum

Регистрация: Aug 2013
Адрес: Москва
Сообщений: 59
Не выходит, к сожалению. Появляется какой-то сдвиг после масштабирования, и как только переходим к перетаскиванию, картинка как бы делает скачок

Старый 26.12.2013, 17:31
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 6  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
Создайте столько контейнеров, сколько предполагаете глубин. Наполните их обьектами и положите все в один контейнер, который таскаете мышкой. При клике или при прокрутке мышкой, масштабируйте каждый с разными значениями в EnterFrame. И масштаб должен быть для всех контейнеров, от заданной точки, что то вроде -
Код AS3:
public static function scalePoint(target:DisplayObject, scaleX:Number, scaleY:Number, point:Point):void
{
	var dXS:Number = (target.x - point.x) / target.scaleX;
	var dYS:Number = (target.y - point.y) / target.scaleY;
 
	target.scaleX = scaleX;
	target.scaleY = scaleY;
 
	target.x = point.x + dXS * target.scaleX;
	target.y = point.y + dYS * target.scaleY;
}

Старый 26.12.2013, 17:40
Ioangum вне форума Посмотреть профиль Отправить личное сообщение для Ioangum Найти все сообщения от Ioangum
  № 7  
Ответить с цитированием
Ioangum

Регистрация: Aug 2013
Адрес: Москва
Сообщений: 59
А что тогда за точку брать для каждого конкретного слоя?

Старый 26.12.2013, 17:57
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 8  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
Цитата:
А что тогда за точку брать для каждого конкретного слоя?
Координаты мышки.

Старый 26.12.2013, 19:47
Ioangum вне форума Посмотреть профиль Отправить личное сообщение для Ioangum Найти все сообщения от Ioangum
  № 9  
Ответить с цитированием
Ioangum

Регистрация: Aug 2013
Адрес: Москва
Сообщений: 59
Может, я что-то не так делаю, но всё равно не то. Вот код основного класса Main:
Код AS3:
package  
{
	import flash.display.Sprite;
	import flash.geom.Point;
 
 
	public class Main extends Sprite
	{
		public var s:Space;
		public var stars:Vector.<Sprite> = new Vector.<Sprite>;
		private var s0: Star;
 
		private var pre_x:Number=0;
		private var pre_y:Number=0;
 
		public function Main() 
		{
			fillSky(1000, 800);
			s = new Space(500 - 700, 400 - 500); //Располагаем посередине. 700x500 - размер swf
			pre_x = s.x;
			pre_y = s.y;
			addChild(s);
		}
 
		private function fillSky(W:int, H:int) {
			//i - слой, j - звезда в слое
			//i=0 - слой, самый ближний к наблюдателю
			//j - звезда, размер выбирается рандомно в пределах слоя (внутри есть свойство dist = дальность {0..100})
			var sloy:Sprite;
			for (var i:int = 0; i < 10; i++) {
				sloy = new Sprite();
				for (var j:int = 0; j < 25; j++) {
					s0 = new Star(Math.random() * W, Math.random() * H, Math.random() * 10+i*10);
					sloy.addChild(s0);
				}
				stars.push(sloy);
				addChildAt(sloy,0);
			}
		}
 
		public function moveSky():void {
 
			//рассчитываем насколько сдвинулся Space
			var dx:Number = s.x-pre_x;
			var dy:Number = s.y - pre_y;
 
			//запоминаем положение Space для вычисления разницы
			pre_x = s.x;
			pre_y = s.y;
 
			//сдвигаем каждый слой соответственно его глубине
			for (var i:int = 0; i < stars.length; i++) {
				stars[i].x += dx / (10 - i +2); //по идее надо делать 10-i, но тогда при i=9 ,будет dx/1, что соответствует слою Space. А нужно сделать всё-таки чуть сзади
				stars[i].y += dy / (10 - i +2);
			}
 
		}
 
		public function scalePoint(target:Sprite, scaleX:Number, scaleY:Number, point:Point):void{
			var dXS:Number = (target.x - point.x) / target.scaleX;
			var dYS:Number = (target.y - point.y) / target.scaleY;
 
			target.scaleX = scaleX;
			target.scaleY = scaleY;
 
			target.x = point.x + dXS * target.scaleX;
			target.y = point.y + dYS * target.scaleY;
		}
 
		public function scaleSky(bigger:Boolean):void {
			var p:Point;
			for (var i:int = 0; i < stars.length; i++) {
				p = new Point(stage.stageWidth/2, stage.stageHeight/2);
				p = globalToLocal(p);
				scalePoint(stars[i], s.scaleX * (1 - 1 / (10 - i +2)), s.scaleY * (1 - 1 / (10 - i +2)), p);
			}
		}
 
	}
 
}
В классе Space ничего особенного: его можно таскать и увеличивать. Ну и всё. Но на всякий пожарный вот он:
Код AS3:
package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
 
	public class Space extends Sprite
	{
		public const GEN_W:int = 700; //horizontal size of swf file
		public const GEN_H:int = 500; //vertical size of swf file 
		public var WW:Number = 1000; //данные о начальной высоте спейса
		public var HH:Number = 800; //данные о начальной ширине спейса
		public var scale_f:Number = 1;
 
		private var droped:Boolean = false;
 
		public function Space(XX:int, YY:int) 
		{
			x = XX;
			y = YY;
 
			graphics.beginFill(0x000000,0.5);
			graphics.drawRect(0, 0, 1000, 800);
			graphics.endFill();
 
			graphics.beginFill(0x00FF00);
			graphics.drawCircle(400, 300, 100);
			graphics.endFill();
 
			graphics.beginFill(0x00FF00);
			graphics.drawCircle(200, 700, 50);
			graphics.endFill();
 
			addEventListener(MouseEvent.MOUSE_DOWN, onMDown);
			addEventListener(MouseEvent.MOUSE_UP, onMUp);
			addEventListener(MouseEvent.MOUSE_WHEEL, sScale);
			addEventListener(Event.ENTER_FRAME, EF);
		}
 
		private function onMDown(e:MouseEvent) {
			var dx:Number = WW-stage.stageWidth; 
				var dy:Number = HH-stage.stageHeight; 
				var dragRect:Rectangle = new Rectangle(-dx,-dy, dx,dy);
				startDrag(false, dragRect);
				droped = true;
		}
 
		private function onMUp(e:MouseEvent) {
			stopDrag();
			droped = false;
		}
 
		//изменение масштаба карты
		private function sScale(e:MouseEvent):void {
			var sc:Number = 0.95;
			var p = new Point(GEN_W/2, GEN_H/2);
			p = globalToLocal(p);
			if ((e.delta < 0) && (WW*sc>=GEN_W) && (HH*sc>=GEN_H)) {
				width *= sc;
				height *= sc;
				WW *= sc;
				HH *= sc;
 
				scale_f *= sc;
				(parent as Main).scaleSky(false);
			}
			else if ((e.delta > 0) && (scale_f<5)) {
				width /= sc;
				height /= sc;
				WW /= sc;
				HH /= sc;
 
				scale_f /= sc;
				(parent as Main).scaleSky(true);
			}
 
			p = localToGlobal(p);
			x += GEN_W/2 - p.x;
			y += GEN_H / 2 -p.y;
 
			if (x > 0) x = 0;
			if (y > 0) y = 0;
			if (x + WW < GEN_W) x = GEN_W - WW;
			if (y + HH < GEN_H) y = GEN_H - HH;
		}
 
		private function EF(e:Event) {
			if (droped) (parent as Main).moveSky();
		}
 
	}
 
}
Ну и класс Star - обычный шейп:
Код AS3:
package  
{
	import flash.display.Shape;
 
	public class Star extends Shape
	{
		public var dist:Number = 0; //0..100
		public var x0:int = 0;
		public var y0:int = 0;
 
		public function Star(X:Number, Y:Number, D: Number = 0)
		{
			dist = D;
			x0 = X;
			y0 = Y;
			x = X;
			y = Y;
			graphics.beginFill(0xFFFFFF);
			graphics.drawCircle(0, 0,D/100+0.01);
			graphics.endFill();
		}
 
	}
 
}
Вложения
Тип файла: swf Параллакс.swf (2.4 Кб, 89 просмотров)

Старый 26.12.2013, 21:08
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 10  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
Цитата:
Может, я что-то не так делаю, но всё равно не то.
Да, это не просто, возможно Вам придётся не один день просидеть, чтобы довести до ума.
И помочь, если честно, я тоже не могу, мне так же, как и Вам придётся долго думать.

Создать новую тему Ответ Часовой пояс GMT +4, время: 18:04.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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