 |
|
O loop for...in exibe as propriedades na ordem em que elas foram definidas, sendo que as últimas aparecem primeiro.
obj = {}
obj[1] = null;
obj[2] = null;
obj[3] = null;
for(prop in obj) trace(prop);
O resultado será:
3
2
1
Durante o desenvolvimento do DENG (parser RSS / XHTML / CSS / SVG / XForms / XFrames em Flash), o Claus Wahlers teve um problema parecido. Era preciso usar o loop for...in para obter os nomes das propriedades de um objeto, mas também era necessário realizar este processo em ordem correta. Trabalhei com ele para encontrar uma solução, e acabei criando a seguinte função:
_global.reOrderObject = function(obj) {
var indices = [], objOld = obj;
for (var i in objOld) {
indices.push(i);
}
var iLen = indices.sort(function (a, b) { return a-b;}).length;
for (var j = iLen, objNew = {}; j--; ) {
objNew[indices[j]] = objOld[indices[j]];
}
return objNew;
};
obj = {};
obj[1] = null;
obj[6] = null;
obj[10] = null;
obj[11] = null;
for (prop in obj) {
trace(prop);
}
obj = reOrderObject(obj);
for (prop in obj) {
trace(prop);
}
Basicamente, o que esta função faz é redefinir todas as propriedades de um objeto de 1 nível (não é recursiva), para que elas sejam exibidas em ordem num loop for..in.
-----------------------------------------------------------
_global.reOrderObject = function(obj) {
var indices = [], objOld = obj;
for(var i in objOld) indices.push(i);
-----------------------------------------------------------
A array indices[] armazenará os nomes de todas as propriedades do objeto. Com isso, podemos aplicar o método sort para ordenar as propriedades corretamente:
-----------------------------------------------------------
var iLen = indices.sort(
function(a, b) { return a - b; }
).length;
-----------------------------------------------------------
Usei uma função de comparação no sort para garantir que números fossem ordenados corretamente. Após fazer isso, basta redefinir as propriedades em ordem reversa (para que sejam exibidas na ordem correta no for..in):
-----------------------------------------------------------
for(var j = iLen, objNew = {}; j--;) {
objNew[indices[j]] = objOld[indices[j]];
};
return objNew;
-----------------------------------------------------------
Espero que tenha ficado claro :-)
Jonas Galvez
( 1 COMENTÁRIO ) | ( LINK PERMANENTE ) | |
 |
Hmm, use enterFrame ao invés de keyDown:
onClipEvent(enterFrame) {
if(Key.isDown(Key.LEFT)) this._x -= 4;
else if(Key.isDown(Key.RIGHT)) this._x += 4;
else if(Key.isDown(Key.UP)) this._y -= 4;
else if(Key.isDown(Key.DOWN)) this._y += 4;
}
Se você estiver usando Flash MX, considere substituir o onClipEvent por eventos dinâmicos com funções. Desta forma você pode anexar todo o código necessário em um frame da timeline, evitando ter que editar código em movieclips.
nome_do_movieclip.onEnterFrame = function() {
if(Key.isDown(Key.LEFT)) this._x -= 4;
else if(Key.isDown(Key.RIGHT)) this._x += 4;
else if(Key.isDown(Key.UP)) this._y -= 4;
else if(Key.isDown(Key.DOWN)) this._y += 4;
};
Como fazer o movimeto diagonal e ainda por cima limitar esse movimeto a um retângulo imaginário?
Um script com um funcionamento próximo da perfeição seria o seguinte:
x_minimo = 100;
y_minimo = 100;
x_maximo = 400-nome_do_movieclip._width;
y_maximo = 400-nome_do_movieclip._height;
nome_do_movieclip.onEnterFrame = function() {
var v = 4;
// velocidade
var xmais = this._x+v, xmenos = this._x-v;
var ymais = this._y+v, ymenos = this._y-v;
if (Key.isDown(Key.LEFT)) {
this._x = (xmenos } else if (Key.isDown(Key.RIGHT)) {
this._x = (xmais>x_maximo) ? x_maximo : xmais;
}
if (Key.isDown(Key.UP)) {
this._y = (ymenos } else if (Key.isDown(Key.DOWN)) {
this._y = (ymais>y_maximo) ? y_maximo : ymais;
}
};
Isto considerando que o conteúdo do movieclip está posicionado em {0,0}. Adaptei o código acima de uma classe para criação de games que comecei a criar há algum tempo atrás. Acabou faltando ânimo para terminá-la, mas acho que o entusiasmo voltará com o novo Flash hehe :-)
Jonas Galvez
( 3 COMENTÁRIOS ) | ( LINK PERMANENTE ) | |
 |
HTML completo? Infelizmente, você pode usar apenas algumas tags do HTML dentro de um campo de texto, tais como <b>, <i> e <u>. Realmente bastante limitado. Se precisar mesmo de algo mais completo, dê uma olhada no DENG:
http://claus.packts.net/deng/
Engine COMPLETA (e até consideravelmente rápida) para XHTML/CSS/XForms/XFrames/SVG, em puro ActionScript :-)
Jonas Galvez
( 0 COMENTÁRIO ) | ( LINK PERMANENTE ) | |
 |
Bom, a maneira de se criar classes mudou completamente. Mas uma coisa importante a ser observada é que a forma antiga continua funcionando normalmente. E inclusive, código em ActionScript 2 é compilado no mesmo bytecode de código em ActionScript antigo.
A primeira grande mudança: para criar classes, é preciso usar arquivos de script EXTERNOS. São como arquivos CLASS do Java. São definidos separadamente e carregados no programa, quando necessário. Mas ao mesmo tempo, não é mais preciso usar #include. Ao invés, definimos um CLASSPATH (ou vários), que é um diretório onde o Flash deverá buscar as classes quando for necessário. Por exemplo:
var minhaSopa = new Sopa();
Com esta linha de código, o compilador irá procurar e carregar um arquivo de script chamado Sopa.as (o nome do arquivo tem que ser exatamente o nome da classe), que deverá estar no mesmo diretório do SWF ou num diretório que foi definido como CLASSPATH (esta configuração é feita através dâ janela de preferências do Flash). A classe Sopa poderia estar definida da seguinte forma:
class Sopa {
var sabor:String = "";
var ingredientes:Array = [];
}
A sintaxe do ActionScript 2 é baseada no ECMA 262 Ed 4. Por isso, se você quiser ficar por dentro, veja:
http://www.mozilla.org/js/language/es4/index.html
É muito parecido com Java, mas bem limitado em comparação. Como você pode notar, agora utiliza-se a palavra-chave "class" para definir classes. Ou seja, não precisamos mais simular isto com funções. Dentro de uma declaração de classe, a palavra-chave "var" assume o papel de definir propriedades (e não variáveis locais como seria o caso em um outro código) da classe.
Com a declaração "var", também podemos definir o tipo exato de uma variável. Se ela é uma string (texto) ou number, por exemplo. Isto nos ajuda a evitar erros. Por exemplo, no caso da classe Sopa, se usássemos o seguinte script:
minhaSopa = new Sopa();
minhaSopa.sabor = 10;
Obteríamos um erro e o SWF não seria compilado. Isto aconteceria porque na definição da classe, indicamos que a propriedade sabor é uma string (texto), e não número:
var sabor:String = "";
// o equivalente em Java seria:
// String sabor = "";
O tipo de dado armazenado na variável ou propriedade é definido após o sinal de dois pontos, logo após o nome da variável (no Java, o tipo de dado é definido no começo da declaração, como mostrei no exemplo acima).
Na definição de métodos, também é possível indicar quais os tipos de dado que deverão ser passados como parâmetros:
class Sopa {
var sabor:String = "";
var ingredientes:Array = [];
function cozinhar(temperatura:Number, duracao:Number) {
// código da função
}
}
Com esta declaração, especificamos que o método cozinhar() deverá receber dois parâmetros: temperatura e duracao. E ambos devem ter valores numéricos. Caso contrário, o SWF não será compilado. Se você parar para pensar, isso ajuda muito na prevenção de erros que, no ActionScript de hoje, seriam muito difíceis de detectar.
Jonas Galvez
( 0 COMENTÁRIO ) | ( LINK PERMANENTE ) | |
|