ActionScript 3 várias instâncias, mesmo nome, pergunta
-
12-09-2019 - |
Pergunta
Eu estou tentando criar uma grade onde os usuários podem 'desenhar' através dele e mudar as cores dos quadrados de grade para uma cor escolhida.
Neste código, eu estou criando a grade com quadrados. Eu tenho a funcionalidade 'trabalhando', mas ele só está trabalhando no último quadrado instanciado.
Como faço para obtê-lo para trabalhar em todas as praças, e não apenas o último?
Obrigado por qualquer ajuda que você pode me dar.
JD -
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
public class ClassBoxColor extends MovieClip {
public var boxColor = "0xFFFFFF";
public var lineColor = "0x666666";
public function ClassBoxColor() {
// ****Create the Grid****
var xpos:Number;
var xposStart:Number = 20; // Initial Placement of grid along x axis
var ypos:Number = 100; // Initial Placement of grid along y axis
var xNum:Number = 10; // Size of Grid across in squares
var yNum:Number = 10; // Size of Grid across in squares
for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
xpos = xposStart;
for (var xaxis:Number = 1; xaxis <= xNum; xaxis++) {
// Draw the square
var colorBox:Sprite = new Sprite();
colorBox.graphics.beginFill(boxColor, 1 );
colorBox.graphics.lineStyle(1, lineColor);
colorBox.graphics.drawRect(0,0,20,20);
colorBox.x = xpos;
colorBox.y = ypos;
colorBox.buttonMode = true;
addChild(colorBox);
xpos += 20;
}
ypos += 20;
}
// LISTENERS
Grey_btn.addEventListener(MouseEvent.CLICK, setGrey); // This button instance is onstage
DarkGrey_btn.addEventListener(MouseEvent.CLICK, setDarkGrey); // This button instance is onstage
stage.addEventListener(MouseEvent.MOUSE_DOWN, drawColor);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawColor);
colorBox.addEventListener(MouseEvent.CLICK, changeColor);
// FUNCTIONS & ACTIONS
Grey_btn.buttonMode = true;
DarkGrey_btn.buttonMode = true;
CurrentBoxColor_txt.text = boxColor;// Display the currently selected color in the CurrentBoxColor_txt instance textfield that is onstage
function setGrey(event:MouseEvent):void {
boxColor = "0xCCCCCC";
CurrentBoxColor_txt.text = boxColor;
}
function setDarkGrey(event:MouseEvent):void {
boxColor = "0x666666";
CurrentBoxColor_txt.text = boxColor;
}
function changeColor(event:MouseEvent):void {
colorBox.graphics.clear();
colorBox.graphics.lineStyle(1, lineColor);
colorBox.graphics.beginFill(boxColor, 1);
colorBox.graphics.drawRect(0,0,20,20);
colorBox.graphics.endFill();
}
function drawColor(event:MouseEvent):void {
//colorBox.addEventListener(MouseEvent.MOUSE_DOWN, changeColor);
colorBox.addEventListener(MouseEvent.ROLL_OVER, changeColor);
}
function stopDrawColor(event:MouseEvent):void {
//colorBox.removeEventListener(MouseEvent.MOUSE_DOWN, changeColor);
colorBox.removeEventListener(MouseEvent.ROLL_OVER, changeColor);
}
}
}
}
Solução
Você realmente precisa de um retrabalho em toda esta classe. Você tem todo o seu código e métodos definidos diretamente no construtor, alguns nomes de instância não definido, etc. Eu estou interessado em saber como você conseguiu isso para compilar. Como nota, não colocar classe em nome de sua classe AS.
O que você precisa é ter uma classe ColorBox que lida com coisas muito simples, como capotamento, etc para gerenciar cor por si só. Deixar a criação / colocação da fora da caixa da classe ColorBox único.
Aqui é um retrabalho da mesma multa classe trabalhadora no Flash Player 10. separei as coisas em duas classes. Alguns dos nomes / estilo que você começou com ainda estão em jogo. Eu não reescrever cada linha.
ColorBox é uma caixa. É isso aí. Ele não faz nada, mas gerenciar as cores.
ColorBoxRoot é a classe raiz do documento. Defina o seu FLA para esta classe e Let'er rip. Abra um novo fla para teste. Tirei o código do botão, bem como o código de campo de texto, mas acrescentou em um rastreamento de onde o campo de texto costumava ser.
Espero que isso ajude!
// ColorBox.as
package { import flash.display.MovieClip; import flash.display.Sprite; flash.events importação. *;
[Event(name="colorChange")]
public class ColorBox extends MovieClip{
// CONSTANTS
public static const COLOR_CHANGE:String = "colorChange";
public static const DEFAULT_WIDTH:uint = 20;
public static const DEFAULT_HEIGHT:uint = 20;
// PROPERTIES
private var _boxColor:uint = 0xFFFFFF;
public function get boxColor():uint{ return _boxColor; }
private var _lineColor:uint = 0x666666;
// CONSTRUCTOR
public function ColorBox(){
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
// EVENT LISTENERS
private function onAddedToStage(event:Event):void{
stage.addEventListener(MouseEvent.MOUSE_DOWN, setGrey);
stage.addEventListener(MouseEvent.MOUSE_UP, resetColors);
updateDisplay();
addEventListener(MouseEvent.ROLL_OVER, setGrey);
addEventListener(MouseEvent.ROLL_OUT, setDarkGrey);
}
// PRIVATE METHODS
private function resetColors(event:Event=null):void{
_boxColor = 0xFFFFFF;
updateDisplay();
}
private function setGrey(event:MouseEvent):void {
_boxColor = 0xCCCCCC;
updateDisplay();
dispatchEvent(new Event(COLOR_CHANGE));
}
private function setDarkGrey(event:MouseEvent):void {
_boxColor = 0x666666;
updateDisplay();
dispatchEvent(new Event(COLOR_CHANGE));
}
private function updateDisplay():void {
graphics.clear();
graphics.lineStyle(1, _lineColor);
graphics.beginFill(_boxColor, 1);
graphics.drawRect(0,0,20,20);
graphics.endFill();
}
}
}
// ColorBoxRoot.as
package { import flash.events.Event; import flash.display.MovieClip;
/**
* Document root class; Create a new FLA (empty) and set this class as the document root
*/
public class ColorBoxRoot extends MovieClip{
// STAGE OBJECTS
//public var Grey_btn:DisplayObject;
//public var DarkGrey_btn:DisplayObject;
// CONSTRUCTOR
public function ColorBoxRoot(){
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
// EVENT LISTENERS
/**
* Called once the swf stage is ready
*/
private function onAddedToStage(event:Event):void{
initializeUI();
createGrid();
}
// PRIVATE METHODS
/**
* Always try to initialize your UI in a method so you can recall it later to "reset" things, if needed
*/
private function initializeUI():void{
//Grey_btn.buttonMode = true;
//DarkGrey_btn.buttonMode = true;
}
/**
* Creates the ColorBox grid
*/
private function createGrid():void{
var xpos:Number;
var xposStart:Number = 20; // Initial Placement of grid along x axis
var ypos:Number = 100; // Initial Placement of grid along y axis
var xNum:Number = 10; // Size of Grid across in squares
var yNum:Number = 10; // Size of Grid across in squares
var colorBox:ColorBox;
for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
xpos = xposStart;
for (var xaxis:Number = 1; xaxis <= xNum; xaxis++){
// Draw the square
colorBox = new ColorBox();
colorBox.addEventListener(ColorBox.COLOR_CHANGE, onBoxColorChange);
colorBox.name = "box" + xaxis + "_" + yaxis; //jcbii: give it an identifiable name; just for fun
colorBox.x = xpos;
colorBox.y = ypos;
addChild(colorBox);
xpos += ColorBox.DEFAULT_HEIGHT; //jcbii: never hardcode these values; use dynamic values as much as possible
}
ypos += ColorBox.DEFAULT_WIDTH; //jcbii: never hardcode these values; use dynamic values as much as possible
}
}
private function onBoxColorChange(event:Event):void{
trace(event.target.name, ColorBox(event.target).boxColor);
}
}
}
Outras dicas
Não posso dizer que eu já utilizado AS mas .. não deve adicionar o ouvinte dentro do para? Você está substituindo colorBox
com cada iteração para que no final apenas o último será referenciado por ele (isto é onde eu iria reclamar que ele mesmo compila, desde colorbox parece fora acessível do escopo; o programador C em mim está chorando).
Im bastante novo com AS3, mas parece que você problema é quando você inicializar o seu praças. E chamando changeColor () no colorbox. Você só tem uma colorbox que você brincar com, e não 10 como você quer ter (?). Abaixo não é a melhor solução para ele, mas a sua mais próxima de uma solução para a sua base de código atual.
Faça um Array chamado colorboxArray e adicionar seus colorboxes a ele.
var colorBoxArray:Array = new Array();
for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
xpos = xposStart;
for (var xaxis:Number = 1; xaxis <= xNum; xaxis++) {
// Draw the square
var colorBox:Sprite = new Sprite();
colorBoxArray[yaxis] = colorBox;
..
colorBoxArray[yaxis].addEventListener(MouseEvent.CLICK, changeColor);
..
}
E changeColor chamada no colorBoxArray [IdOfTheBoxYouWantToChangeColorOn]
A melhor maneira de fazer isso seria mover todas as suas funções acima para uma classe chamada "Box", e criar instâncias de sua classe Box em seu loop criação acima, adicione ouvintes a todos os seus caixas e seu conjunto. I como matrizes embora; (
Não testado, mas deve estar trabalhando ... uso MouseEvent :: buttonDown, para olhar, se o botão está em baixo ...
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
public class ClassBoxColor extends MovieClip {
public var boxColor = "0xFFFFFF";
public var lineColor = "0x666666";
public function ClassBoxColor() {
// ****Create the Grid****
var xpos:Number;
var xposStart:Number = 20; // Initial Placement of grid along x axis
var ypos:Number = 100; // Initial Placement of grid along y axis
var xNum:Number = 10; // Size of Grid across in squares
var yNum:Number = 10; // Size of Grid across in squares
for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
xpos = xposStart;
for (var xaxis:Number = 1; xaxis <= xNum; xaxis++) {
// Draw the square
var colorBox:Sprite = new Sprite();
colorBox.graphics.beginFill(boxColor, 1 );
colorBox.graphics.lineStyle(1, lineColor);
colorBox.graphics.drawRect(0,0,20,20);
colorBox.x = xpos;
colorBox.y = ypos;
colorBox.buttonMode = true;
addChild(colorBox);
colorBox.addEventListener(MouseEvent.CLICK, changeColor);
colorBox.addEventListener(MouseEvent.ROLL_OVER, changeColor);
xpos += 20;
}
ypos += 20;
}
// LISTENERS
Grey_btn.addEventListener(MouseEvent.CLICK, setGrey); // This button instance is onstage
DarkGrey_btn.addEventListener(MouseEvent.CLICK, setDarkGrey); // This button instance is onstage
// FUNCTIONS & ACTIONS
Grey_btn.buttonMode = true;
DarkGrey_btn.buttonMode = true;
CurrentBoxColor_txt.text = boxColor;// Display the currently selected color in the CurrentBoxColor_txt instance textfield that is onstage
function setGrey(event:MouseEvent):void {
boxColor = "0xCCCCCC";
CurrentBoxColor_txt.text = boxColor;
}
function setDarkGrey(event:MouseEvent):void {
boxColor = "0x666666";
CurrentBoxColor_txt.text = boxColor;
}
function changeColor(event:MouseEvent):void {
if ((event.type == MouseEvent.CLICK) || (event.buttonDown)) {
colorBox.graphics.clear();
colorBox.graphics.lineStyle(1, lineColor);
colorBox.graphics.beginFill(boxColor, 1);
colorBox.graphics.drawRect(0,0,20,20);
colorBox.graphics.endFill();
}
}
}
}
}
Geralmente, eu acho que você se aproxima não é muito limpo ... sua classe tem dependências em algumas Grey_btn e DarkGrey_btn e outras coisas externas ... isso é ruim estilo ... realmente ... também há algumas coisas que eu não compreendo perfeitamente, mas ok ... isso é talvez a minha culpa ...:)
boa sorte de qualquer maneira ...;)
greetz
back2dos