Comunidad de diseño web y desarrollo en internet online

Obtener Dimensiones de MC dinámico

Citar            
MensajeEscrito el 13 Feb 2007 03:54 pm
Un saludo a todos de la comunidad Cristal Lab:

Una vez mas recurro a los expertos en Action Script para que me puedan echar una manito.

Estoy haciendo una Animación Educativa, similar a un rompecabezas (hmm, esto mismo escribí en un post anterior) con un conjunto de piezas y diferentes opciones sobre cada pieza. Es decir, tengo un conjunto de Piezas que podrán ser movidas por el usuario, con la posibilidad de ser borradas de la animación, escaladas, rotadas o pintadas, si así se desea. Sin mencionar la opción de 'Deshacer'. Todo esto solo con ActionScript.

Bueno, para pude definir una clase que extiende de MovieClip, con los métodos de eventos sobrecargados y métodos para las diferentes acciones que se puede llevar a cabo sobre una pieza. Todo esto lo pude hacer gracias a este portal, recogiendo trozos de códigos ejemplo y preguntas que fueron respondidas por verdaderos expertos de esta comunidad. Les paso la clase que definí:


import flash.geom.ColorTransform

class Pieza extends MovieClip{
static var symbolName:String = "__Packages.Pieza";
static var symbolOwner:Function = Pieza;
static var symbolLinked = Object.registerClass(symbolName, symbolOwner);
var miColor:ColorTransform;

var img:MovieClip;
var tinta:MovieClip;
var rajaduraClip:MovieClip;

var seleccionado:Boolean;
var mancha:Boolean;
var presionado:Boolean;

var rajaduras:Array;
var pilaManchas:Array;

var indexRajadura:Number;
var indexManchas:Number;
var px:Number;
var py:Number;
var posIniX:Number;
var posIniY:Number;
var numeroPieza:Number;
var posActualX:Number;
var posActualY:Number;

static function __resolve(name){
return Pieza[name];
}

public function drawShape( imagen:String, contenedor:String, xx:Number, yy:Number, nroPieza:Number){

/** Cargar la imagen en el punto (0,0) del movie clip principal */
img = createEmptyMovieClip (contenedor, this.getNextHighestDepth () );
img._x = 0;
img._y = 0;
var loader:MovieClipLoader = new MovieClipLoader();
loader.loadClip(imagen, img);

/** Definir la posición de la pieza de acuerdo a las acciones pasadas */
img._x = xx;
img._y = yy;
posIniX = xx;
posIniY = yy;

rajaduras = new Array();
indexRajadura = 0;

/** Sobrecarga de los eventos para esta pieza */
onPress = doOnPress;
onRelease = doOnRelease;
onRollOver = doOnRollOver;
onRollOut = doOnRollOut;
onMouseMove = doOnMouseMove;

/** Banderas auxiliares */
seleccionado = false;
presionado = false;
mancha = false;

pilaManchas = new Array();
indexManchas = 0;
miColor = new ColorTransform();
numeroPieza = nroPieza;
trace("Dimensiones Iniciales" + getDimensiones() );
}

public function getCoords(){
return [img._x, img._y]
}

public function getDimensiones(){
return [img._height, img._width]
}

/** Sobrecarga del método 'onPress' del MovieClip */
private function doOnPress():Void{

if( seleccionado ){
miColor.alphaMultiplier = 1;
seleccionado = false;
}else{
if( _root.manchas.selectedIndex<=0 ){
miColor.alphaMultiplier = .5;
seleccionado = true;
}
}

tinta.clear();
/** Realizar una accion en base a la accion del usuario */
switch(_root.accion){
case "rajadura":{
rajaduraClip = img.createEmptyMovieClip(img._name, img.getNextHighestDepth() );
rajaduraClip.moveTo(rajaduraClip._xmouse, rajaduraClip._ymouse);
rajaduras[indexRajadura] = [rajaduraClip._xmouse, rajaduraClip._ymouse];
indexRajadura ++;
presionado = true;
}break;
case "reestablecer":{
reestablecer();
_root.caries.selectedIndex = 0;
}break;
case "mover":{
img.startDrag();
}break;
case "tintas":{
if( _root.caries.selectedIndex > 0 ){
tinta.clear();
agregarMancha(this._name);
}
}break;
case "rehubicar":{
devolverPosicion();
}break;
case "rotar":{
posActualX = img._x;
posActualX = img._y;
rotarPieza();
}break;
default:{
img.transform.colorTransform = miColor;
}
}
}

private function doOnRelease():Void{
img.stopDrag();
tinta.clear();
presionado = false;
if( mancha ){
drawAllManchas();
}
}

private function doOnMouseMove():Void{
if( presionado && _root.accion=="rajadura" ){
dibujarRajadura(img._xmouse, img._ymouse, rajaduraClip);
rajaduras[indexRajadura] = [img._xmouse, img._ymouse];
indexRajadura ++;
}
}

private function doOnRollOver():Void {
// definir acciones
}

private function doOnRollOut():Void {
// definir acciones
}

private function doOnMouseDown():Void {
this.miColor.alphaMultiplier = .5;
img.transform.colorTransform = miColor;
}

public function agregarMancha(contenedor:String):Void{

px = _xmouse-img._x;
py = _ymouse-img._y;
if(_root.caries.selectedIndex==1 ){
pilaManchas[indexManchas] = ["I",px,py];
indexManchas ++;
}
if(_root.caries.selectedIndex==2){
pilaManchas[indexManchas] = ["II",px,py];
indexManchas ++;
}
if(_root.caries.selectedIndex==3){
pilaManchas[indexManchas] = ["III",px,py];
indexManchas ++;
}
if(_root.caries.selectedIndex==4){
pilaManchas[indexManchas] = ["IV",px,py];
indexManchas ++;
}
drawAllManchas(contenedor);
mancha = true;
}

/**
* Dibuja una mancha sobre una máscara, dependiendo del tipo Mancha
* seleccionada por el usuario y el tipo de pieza
*/
public function drawAllManchas(contenedor:String ):Void{
tinta = createEmptyMovieClip (contenedor, getNextHighestDepth() );
tinta._x = img._x;
tinta._y = img._y;
var Mx = new flash.geom.Matrix();

var lados:Object = {x1:0, y1:0, x2:0, y2:0,
x3:0, y3:0, x4:0, y4:0 };
var colores;
var alphas;
var ratios;
var a;
var b;
var foco;
var difx;
var dify;

if( isPiezaSuperior() ){
lados.x1 = this._x+(img._width/5); lados.y1 = this._y+img._height-(2*img._height/3);
lados.x2 = this._x+img._width-(img._width/5); lados.y2 = this._y+img._height-(2*img._height/3);
lados.x3 = this._x+img._width; lados.y3 = this._y+img._height;
lados.x4 = this._x; lados.y4 = this._y+img._height;
}else{
lados.x1 = this._x; lados.y1 = this._y;
lados.x2 = this._x+img._width; lados.y2 = this._y;
lados.x3 = this._x+img._width-(img._width/5); lados.y3 = this._y+img._height-(img._height/3);
lados.x4 = this._x+(img._width/5); lados.y4 = this._y+img._height-(img._height/3);
}

for(var i=0; i<this.pilaManchas.length; i++) {

switch (pilaManchas[i][0]){
case "I":{
/** Combinacion de valores para Mancha GRADO 1 */
colores = [0x000000,0x3F1C0515,0x94604000,0xffffcc];
alphas = [80,90,85,0];
ratios = [0,10,25,250];
a = 20; b = 20; foco = 0;
difx = 8; dify = 8;
}break;
case "II":{
/** Combinacion de valores para Mancha GRADO 2 */
colores = [0x000000,0x3F1C0515,0x94604000,0xffffcc];
alphas = [80,90,85,0];
ratios = [0,30,55,150];
a = 35; b = 35; foco = 0;
difx = 17; dify = 17;
}break;
}

px = pilaManchas[i][1] -difx;
py = pilaManchas[i][2] -dify;
Mx.createGradientBox(a,b,Math.PI/2,px, py);
//tinta.lineStyle(1, 0x000000, 100);
tinta.beginGradientFill("radial",colores,alphas,ratios,Mx,"pad","RGB",foco);
tinta.moveTo(lados.x1, lados.y1);
tinta.lineTo(lados.x2, lados.y2);
tinta.lineTo(lados.x3, lados.y3);
tinta.lineTo(lados.x4, lados.y4);
tinta.lineTo(lados.x1, lados.y1);
tinta.endFill();
}
}

function dibujarRajadura(xx:Number, yy:Number, lienzo:MovieClip):Void {
lienzo.lineStyle(1, 0x3F1C05, 100);
lienzo.lineTo(xx, yy);
lienzo.lineStyle(10, 0xFCF7E2, 15);
lienzo.lineTo(xx+1, yy+1);
}

private function isPiezaSuperior():Boolean{
if( this._name.charAt(1)=="1" || this._name.charAt(1)=="2" ){
return true;
}else{
return false;
}
}

private function devolverPosicion():Void{
img._x = posIniX;
img._y = posIniY;
}

private function reestablecer():Void{
tinta.clear();
rajaduraClip.clear();
pilaManchas = new Array();
rajaduras = new Array();
indexRajadura = 0;
indexManchas = 0;
devolverPosicion();
}

private function rotarPieza():Void{
img._x += img._width/2;
img._y += img._height/2;
img._rotation += 5;
img._x += posActualX;
img._y += posActualY;
}
}


Y mi FLA, tiene una barra de herramientas para llevar a cabo las acciones necesarias, uso varios Clips de Película a manera de botones. Les paso el codigo de una opción de mi barra:

Código :

onClipEvent(mouseDown){
   if (this.hitTest(_root._xmouse,_root._ymouse)){
      if( _root.accion=="mover" )   _root.accion = "";
      else [b]_root.accion = "mover";[/b]
         
      _root.accionLabel.htmlText = "Acción: <b>"+_root.accion.toUpperCase()+"</b>";
      this._height = 22;
      this._width  = 22;
   }
}

onClipEvent(mouseUp){
   if (this.hitTest(_root._xmouse,_root._ymouse)){
      this._height=20;
      this._width=20;
   }
}


Y la forma de instaciar una pieza, es como sigue (dentro del mismo FLA):

Código :

import Pieza;

/* Variables Globales */
var accion = "";

/**
* Cargar Piezas Cuadrante 1
*/
attachMovie(Pieza.symbolName,"p16",getNextHighestDepth());
p16.drawShape("piezas/f_16_m.png","p16",179.3,108.5, 16);

attachMovie(Pieza.symbolName,"p15",getNextHighestDepth());
p15.drawShape("piezas/f_15_m.png","p15",187.8,112, 15);

attachMovie(Pieza.symbolName,"p14",getNextHighestDepth());
p14.drawShape("piezas/f_14_m.png","p14",203,118, 14);

attachMovie(Pieza.symbolName,"p13",getNextHighestDepth());
p13.drawShape("piezas/f_13_v.png","p13",215.8,123, 13);

attachMovie(Pieza.symbolName,"p12",getNextHighestDepth());
p12.drawShape("piezas/f_12_v.png","p12",234.3,128, 12);

attachMovie(Pieza.symbolName,"p11",getNextHighestDepth());
p11.drawShape("piezas/f_11_v.png","p11",262.0,131, 11);


Todo esto debo hacerlo solo en ActionScript, ya que para mas adelante los nombres de las imágenes me las pasaran como parámetros leidos de una BD, por medio de AMFPHP. Las imágenes se muestran bien y puedo moverlas sin problema, tambien pintarlas o reestablecerlas.

Mi problema, es que para la accion de 'Rotar' (en el método 'rotarPieza') necesito conocer, desde que se instancia un objeto, las dimensiones del MC que se crea, de manera que pueda calcular el centro y se muestre adecuadamente la rotacion, pero al instanciar el objeto obtengo los valores de (0,0) de las dimensiones (hago un trace en el método 'drawShape').

Intenté cargar la imagen de varias maneras, para así obtener las dimensiones iniciales de la imagen pero no conseguí mucho :crap:.

No entiendo qué estoy haciendo mal, agradezco mucho de antemano el que hayan leido, por lo menos, este post y más aun si me sugieren algo.

Saludos

PD: Hmmm, mi codigo sale con con salto de linea doble :?

Por felippe

7 de clabLevel



Genero:Masculino  

opera
Citar            
MensajeEscrito el 13 Feb 2007 03:58 pm
Evento onLoadInit de MovieClipLoader. Búscalo en la ayuda de flash o en el foro, donde está repetido muchas veces.
grr, estoy pensando en poner un postIt sobre esto.

Por Zah

BOFH

4290 de clabLevel

27 tutoriales
5 articulos

  Bastard Operators From Hell Editores

Zaragoza, España

firefox
Citar            
MensajeEscrito el 13 Feb 2007 08:31 pm
Gracias por responder.


grr, estoy pensando en poner un postIt sobre esto.


Si he hecho algo indebido, me disculpo por eso. Comprendo que el post que puse es demasiado largo para una simple pregunta (tal vez trivial para muchos de uds), pero he recurrido a uds, porque he probado varios ejemplos de otras preguntas relacionadas con mi pregunta, pero no consegui buenos resultados.

También he probado con onLoadInit, como indicas, pero no consigo recoger las dimensiones adecuadamente. Me explico, he definido un 'listener' dentro mi método 'drawShape' y le agregué el evento 'onLoadInit', y lo que obtuve fue que los valores de las dimensiones solamente tienen valor dentro de esa funcion, intente recuperarlo por medio de atificios sin exito.

Te muestro lo que probé antes (dentro del método drawShape):

Código :

         img  = createEmptyMovieClip (contenedor, this.getNextHighestDepth () );
     img._x = 0;
     img._y = 0;
     var mclListener:Object = new Object();

     mclListener.onLoadInit = function(target_mc:MovieClip) {
               setAlto(target_mc._height);
               setAncho(target_mc._width);
      this.alto  = target_mc._height;
          this.ancho = target_mc._width;
      trace("dimensiones Alto: "+alto+" Ancho:"+ancho);
          };
      
     var loader:MovieClipLoader = new MovieClipLoader();
     loader.addListener(mclListener);
     loader.loadClip(imagen, img);


El trace dentro de la funcion onLoadInit, devuelve bien los valores, pero no sale de ahí, ya que como veras habia dos métodos (setAlto, setAncho) que en teoría deberian funcionar, pero no es así.

Intenté con este mismo listener dentro del FLA para luego setear el ancho y alto, y tampoco me funciono.

También intente sobrecargar el método 'onLoad' de MovieClip, con resultados similares. Al parecer, los valores de target_mc._height y target_mc._width, no salen de ese ámbito.

De todos modos, gracias por la sugerencia.

Por felippe

7 de clabLevel



Genero:Masculino  

opera
Citar            
MensajeEscrito el 13 Feb 2007 08:44 pm
Me refería a que esta pregunta ha aparecido muchísimas veces en el foro, y que quizá ponga un postIt (uno de esos topics que siempre están arriba).
En cuanto a tu duda, no has mostrado cómo ni donde defines los métodos, pero supongo que será un problema de ámbitos. Quizá leer esto te pueda ayudar:
http://www.cristalab.com/tips/28962/ambito-de-variables-en-actionscript-scope-this

Por Zah

BOFH

4290 de clabLevel

27 tutoriales
5 articulos

  Bastard Operators From Hell Editores

Zaragoza, España

firefox
Citar            
MensajeEscrito el 13 Feb 2007 09:33 pm
Hola zah:

Tenias razon, el problema no era la carga de la imagen o la forma de cargarlo, el problema era por el ámbito; acabo de leer tu Tutorial sobre 'Ámbito de variables en ActionScript, scope, this' que me ayudó a recuperarme del dolor de ojos que tengo (de tanto darle vueltas a mi problema). :lol:

No conocía el truco de definir una variable auxiliar con this, yo suponía que usando 'this' estaría haciendo referencia, en todo y por sobre todo, a mis métodos y atributos de clase.

Muy agradecido por la ayuda !!!!

Un Saludo

Por felippe

7 de clabLevel



Genero:Masculino  

opera

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.