PDA

Volledige versie bekijken : Slider over timeline met meerdere scenes


sjors-wat?
%Europe/Berlin %574 %2009, 14:47
Daar zit ik weer.

Voor mijn werk heb ik een 3d object en dat moet nu in flash met een slider ronddraaien. Ik heb nu het object 360graden laten draaien. Daar heb ik frames van gerenderd (250).

Wat ik al heb:
1 scene met een preloader, het bestand is best groot.
2de scene is een intro. Waar dmv een filmpje word laten zien dat je over enkele onderdelen van het object kan rollen met je muis om meer informatie te krijgen.
3de scene het object (een airco-systeem of iets dergelijks).

In de 3de scene moet je dus met een slider dat object kunnen controleren. Daarvoor heb ik 2 .as files geschreven die het (raar genoeg) in een oudere versie van dit project wel doen
Nouja hier is mijn script en de script van de .as files:

Slides.as:

/* dependencies:
- Knob = library item
- TriangleButton = library item
*/
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.geom.Rectangle;

public class Slider extends Sprite
{
private var knob:Knob;
private var slot:Sprite;
private var leftButton:TriangleButton;
private var rightButton:TriangleButton;
private var _width:Number;
private var _height:Number;
private var _value:Number = 0;
private var slideSpace:Number;
private var maxX:Number;
private var beginX:Number;
private const BUTTON_WIDTH:Number = 10;

// constructor
public function Slider (w:Number = 100, h:Number = 15)
{
_width = w;
_height = h;
leftButton = new TriangleButton();
leftButton.addEventListener(MouseEvent.MOUSE_DOWN, startMoveLeft);
leftButton.addEventListener(MouseEvent.MOUSE_UP, stopMoveLeft);
leftButton.rotation = 180;
leftButton.x = BUTTON_WIDTH/2 + leftButton.width/2;
rightButton = new TriangleButton();
rightButton.addEventListener(MouseEvent.MOUSE_DOWN , startMoveRight);
rightButton.addEventListener(MouseEvent.MOUSE_UP, stopMoveRight);
knob = new Knob();
knob.addEventListener(MouseEvent.MOUSE_DOWN, startSlide);
knob.addEventListener(MouseEvent.MOUSE_UP, stopSlide);
addEventListener(Event.ADDED_TO_STAGE, addLeaveHandler);
addChild(knob);
addChild(leftButton);
addChild(rightButton);
slideSpace = _width - (BUTTON_WIDTH * 2) - knob.width;
beginX = BUTTON_WIDTH + 2;
maxX = beginX + slideSpace;
draw();
}

// getters and setters for width
public override function set width(w:Number):void
{
if (w > _width - (BUTTON_WIDTH * 2) + 8 - knob.width) {
_width = w;
slideSpace = _width - (BUTTON_WIDTH * 2) - knob.width;
maxX = beginX + slideSpace;
draw();
}
}

public override function get width():Number
{
return _width;
}

// getters and setters for height
public override function set height(h:Number):void
{
_height = h;
draw();
}

public override function get height():Number
{
return _width;
}

// getters and setters for value
public function set value(val:Number):void
{
if (val >= 0 || val <= 1) {
_value = val;
}
draw();
}

public function get value():Number
{
return _value;
}

// slider renderer
private function draw():void
{
graphics.lineStyle(1, 0x1F6B85);
graphics.drawRect(0,0,_width,_height);
graphics.endFill();
leftButton.y = _height/2 + leftButton.height/2;
rightButton.x = _width - BUTTON_WIDTH/2 - rightButton.width/2;
rightButton.y = _height/2 - rightButton.height/2;
knob.height = _height-1;
knob.scaleX = knob.scaleY;
leftButton.buttonMode = true;
rightButton.buttonMode = true;
knob.buttonMode = true;
knob.y = 1;
knob.x = beginX + slideSpace * _value;
}

// event callbacks
private function startMoveLeft(event:MouseEvent):void {
addEventListener(Event.ENTER_FRAME, moveLeft);
}

private function stopMoveLeft(event:MouseEvent) {
removeEventListener(Event.ENTER_FRAME, moveLeft);
}

private function moveLeft(event:Event):void {
knob.x -= 10;
if (knob.x < beginX) {
knob.x = beginX;
}
_value = (knob.x - beginX)/slideSpace;
dispatchEvent(new SlideEvent(SlideEvent.SLIDE));
}

private function startMoveRight(event:MouseEvent) {
addEventListener(Event.ENTER_FRAME, moveRight);
}

private function stopMoveRight(event:MouseEvent) {
removeEventListener(Event.ENTER_FRAME, moveRight);
}

private function moveRight(event:Event):void {
knob.x += 10;
if (knob.x > maxX) {
knob.x = maxX;
}
_value = (knob.x - beginX)/slideSpace;
dispatchEvent(new SlideEvent(SlideEvent.SLIDE));
}

private function startSlide(event:MouseEvent):void {
var rect = new Rectangle(beginX,1,slideSpace,0);
knob.startDrag(false, rect);
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragging);
trace("sliding");
}

private function stopSlide(event:MouseEvent):void {
trace("stop sliding");
knob.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragging);
}

private function leaveSlider(event:Event):void {
knob.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragging);
}

private function dragging(event:MouseEvent):void {
dispatchEvent(new SlideEvent(SlideEvent.SLIDE));
event.updateAfterEvent();
_value = (knob.x - beginX)/slideSpace;
trace("dragging; value:",_value);
}

private function addLeaveHandler(event:Event):void {
stage.addEventListener(MouseEvent.MOUSE_UP, stopSlide);
stage.addEventListener(Event.MOUSE_LEAVE, leaveSlider);
}

}
}

SlideEvent.as:

package
{
import flash.events.Event;

public class SlideEvent extends Event {
public static var SLIDE:String = "slide";

public function SlideEvent (type:String, bubbles:Boolean = false, cancelable:Boolean = false) {
super(type, bubbles, cancelable);
}

public override function clone():Event {
return new SlideEvent(type, bubbles, cancelable);
}

public override function toString():String {
return formatToString("SlideEvent", "type", "bubbles", "cancelable", "eventPhase");
}
}
}


En dan het script dat op het eerste frame van mijn flash bestand staat:
var startFrame:uint = 0;

startFrame = currentFrame;
trace("deze scene begint op frame",startFrame);

//gotoAndStop(3);

gotoAndStop(123);

var slider:Slider = new Slider(690,12);
slider.x = 10;
slider.y = 425;
slider.addEventListener(SlideEvent.SLIDE, update);
slider.alpha =1;
slider.value = .492;
addChild(slider);

function update(event:SlideEvent):void {
trace("sliding");
gotoAndStop(Math.ceil((scenes["Slider"].numFrames) * event.target.value));
}

Dat is alles zo'n beetje.. Ik krijg geen compile errors maar in mijn output veld krijg ik dit te zien als ik probeer te sliden:
deze scene begint op frame 1
sliding
sliding
TypeError: Error #1010: A term is undefined and has no properties.
at slide_3d_V4_fla::MainTimeline/update()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at Slider/dragging()
dragging; value: 0.4902944563250535
sliding

Wat wel en niet werkt:
Sliden, je kan de slider heen en weer halen maar dat krijg ik dus die TypeError de HELE tijd.
Het object draait niet.
De rollovers van de objecten heb ik er nog niet opstaan omdat previews kijken zo vervelend zijn de hele tijd.

Heeft iemand een oplossing om de slider de tijdlijn wel te laten controleren? en dan alleen die van de 3de scene? Ik heb het idee dat er met de Slider.as en SlideEvent.as niets aan de hand is.. Alleen met het script in mijn flash zelf.

Alvast hartelijk bedankt,

Groeten sjors,

Jan
%Europe/Berlin %602 %2009, 15:27
TypeError: Error #1010: A term is undefined and has no properties.
Dat zijn zo van die vervelende, vage, nietzeggende errors die je vooral (of enkel) krijgt bij framescripts.
Gelukkig is je functie daar maar 1 regel lang.
Ik zou om te beginnen dus in die functie al het mogelijke tracen zodat je tenminste weet wat er concreet undefined is, en dan kunnen we verder zoeken/oplossen.
Waarschijnlijk target je een frame(nummer) dat niet bestaat.
Misschien voorlopig eens met floor ipv ceil proberen?

Groeten;
Jan

sjors-wat?
%Europe/Berlin %638 %2009, 16:19
Hey, bedankt voor je snelle reactie.

Ik heb even alles weggegooid wat ik net gepost had omdat het eigenlijk nergens over ging.
Ik heb gevonden wat nu echt 'undefined' is volgens flash.
Dit namelijk:

* event.target.value)); De rest van het script doet gewoon waar het voor bedoeld is.

Jan
%Europe/Berlin %662 %2009, 16:54
Ik bedoelde met 'alles tracen' eigenlijk dit:
function update(event:SlideEvent):void
{
trace(event.target);
trace(event.target.value);
trace(scenes["Slider"]);
trace(scenes["Slider"].numFrames)
trace(scenes["Slider"].numFrames * event.target.value)
trace(Math.ceil(scenes["Slider"].numFrames * event.target.value));
//gotoAndStop(Math.ceil((scenes["Slider"].numFrames) * event.target.value));
}
En dan kan je zien wat er undefined is, gezien je zelf weet hoeveel frames er in die scene zitten.

Edit: net te laat. :)
Ik heb even alles weggegooid wat ik net gepost had omdat het eigenlijk nergens over ging.
Vond ik ook. :D

Groeten;
Jan

sjors-wat?
%Europe/Berlin %664 %2009, 16:56
Ah, dit zag ik nog niet. Ik was net bezig met typen toen ik erachter kwam dat het dus echt aan event.target.value ligt. Dit ga ik wel even proberen ;) over 1minuut een update

EDIT: Tja, daar kwam ik pas achter toen ik het nog een keer las nadat ik er al weer even bezig was met de oplossing zoeken :D.

sjors-wat?
%Europe/Berlin %666 %2009, 17:00
deze scene begint op frame 1
sliding
[object Slider]
0.492
TypeError: Error #1010: A term is undefined and has no properties.
at slide_3d_V4_fla::MainTimeline/update()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at Slider/dragging()
dragging; value: 0.4902944563250535

Dit kreeg ik terug van de trace die je voorstelde. Eigenlijk is er dus maar 1 verschil. En dat is dat er nu [object slider] en 0.492 bijstaat. die 0.492 gaf ik als position aan van mijn slider omdat hij op 1:123= 0.492 moet beginnen als hij op frame 123 begint.


EDIT: Waar het dus mis gaat is:
Math.ceil(scenes["Slider"].numFrames Ik heb ook het gevoel dat dat veel makkelijker moet kunnen..

Jan
%Europe/Berlin %670 %2009, 17:05
De fout zit dus hier lijkt me (aangezien de derde trace undefined is):
trace(scenes["Slider"]);
Als ik in de help kijk zie ik dat dat een 'gewone' Array is en dus moet je de scenes opvragen met scenes[3] oid en niet met scenes["Slider"].

Uit de F1:
import flash.display.Scene;

for (var i:uint = 0; i < mc1.scenes.length; i++)
{
var scene:Scene = mc1.scenes[i];
trace("scene " + scene.name + ": " + scene.numFrames + " frames");
}

Groeten,
Jan

sjors-wat?
%Europe/Berlin %682 %2009, 17:22
Ja, ik zag ook net dat het daar wel aan moet liggen. Even kijken wat ik met dat stukje script kan doen wat je zojuist poste.

sjors-wat?
%Europe/Berlin %699 %2009, 17:46
deze scene begint op frame 1
scene Preloader: 3 frames
scene Sliderenrollover: 250 frames
scene Animatie: 999 frames
sliding
[object Slider]
0.492
TypeError: Error #1010: A term is undefined and has no properties.
at slide_3d_V4_fla::MainTimeline/update()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at Slider/dragging()
dragging; value: 0.4902944563250535

Ja, ik heb dus die array gebruikt die je net voorstelde, even aangepast naar this. ipv mc1. Omdat het hier om de complete .swf gaat,, doe ik dit goed?

Dan is dus het bovenstaande mijn nieuwe output...

Animatie staat onder mijn Slideenrollover omdat ik anders elke keer op die animatie moet wachten tijdens het bouwen..

Dit is mijn script:
import flash.display.Scene;

var startFrame:uint = 0;

startFrame = currentFrame;
trace("deze scene begint op frame",startFrame);

gotoAndStop(123);

var slider:Slider = new Slider(690,12);
slider.x = 10;
slider.y = 425;
slider.addEventListener(SlideEvent.SLIDE, update);
slider.alpha =1;
slider.value = .492;
addChild(slider);

for (var i:uint = 0; i < this.scenes.length; i++) {
var scene:Scene = this.scenes[i];
trace("scene " + scene.name + ": " + scene.numFrames + " frames");
}

function update(event:SlideEvent):void {
// gotoAndStop(Math.floor(123) * event.target.value);
trace(event.target);
trace(event.target.value);
trace(scenes["Slider"].numFrames)
trace(scenes["Slider"].numFrames * event.target.value)
trace(Math.ceil(scenes["Slider"].numFrames * event.target.value));
gotoAndStop(Math.ceil((scenes[2].numFrames) * event.target.value));
}

Misschien heb ik je advies wel helemaal verkeerd geïnterpreteerd. En daardoor ook het script op een verkeerde manier aangepast...

In elk geval hartsikke bedankt alvast. Ik heb echt het gevoel dat ik verder kom met deze hulp en dat ik ook echt wat leer ;)

groeten sjors,

p.s. ik ben nu afgewerkt dus ik ga er morgen pas weer naar kijken.

Jan
%Europe/Berlin %739 %2009, 18:44
scene Preloader: 3 frames
scene Sliderenrollover: 250 frames
scene Animatie: 999 frames
Een array begint bij 0 dus moest je scenes[1] nemen ipv 2:
function update(event:SlideEvent):void
{
trace(1, event.target);
trace(2, event.target.value);
trace(3, scenes[1].numFrames)
trace(4, scenes[1].numFrames * event.target.value)
trace(5, Math.ceil(scenes[1].numFrames * event.target.value));
gotoAndStop(Math.floor((scenes[1].numFrames) * event.target.value));
}
En blijkbaar heette je scene ook helemaal niet Slider maar Sliderenrollover...

Groeten;
Jan

sjors-wat?
%Europe/Berlin %351 %2009, 09:26
Hallo Jan,

Harttikke bedankt voor je reactie. Dit werkt.
Die scene heb ik zelf hernoemt en dat heb ik ook in mijn script gedaan. Om verwarring bij mezelf te voorkomen omdat er ook al een class is die Slider heet.

Die scenes[1] heb ik naar currentsScene verandert.. Omdat de volgorde als ik straks klaar ben de volgorde veranderd word. Er zat nog een bug in.. De slider kon naar frame nul dus daar heb ik even nog even 1 frame van het totaal afgehaald en +1 erbij waar hij overheen kan sliden. Dit is mijn script en het werkt :D

import flash.display.Scene;

var startFrame:uint = 1;

startFrame = currentFrame;
trace("deze scene begint op frame",startFrame);

if (slider == null) {
gotoAndStop(123);

var slider:Slider = new Slider(690,12);
slider.x = 10;
slider.y = 425;
slider.addEventListener(SlideEvent.SLIDE, update);
slider.alpha =1;
slider.value = .492;
addChild(slider);
}

for (var i:uint = 0; i < this.scenes.length; i++) {
var scene:Scene = this.scenes[i];
trace("scene " + scene.name + ": " + scene.numFrames + " frames");
}

function update(event:SlideEvent):void {
// gotoAndStop(Math.floor(123) * event.target.value);
trace(event.target);
trace(event.target.value);
trace(currentScene.numFrames)
trace(currentScene.numFrames * event.target.value)
trace(Math.ceil(currentScene.numFrames * event.target.value));
gotoAndStop(Math.floor((currentScene.numFrames-1) * event.target.value)+1);
}

Ohja en ik hij maakte ook nog een extra slider object aan als ie bij 0 stond en je drukte op een pijltje van de slider. Daarom heb ik die if slider == 0 even om de code gezet waarmee hij de slider aanmaakt.

Hartstikke bedankt! :)

groeten sjors,