handling position of multiple movieclips in relation to each other - actionscript-3

I'm not that new to using Flash, but I mostly used it for making animations and I don't really use actionscript much but this time I wanted to try making layouts by code.
I'm trying to position square movieclips to form a grid like menu.
I positioned the each of the movieclips all in code but I think perhaps there's a better and more efficient way of doing this.
The code is very basic but I'll post it anyway so you have an image of what I'm trying to make it look like. I'm not really good at explaining so, I apologize.
//1st row//
var btn1:MovieClip = new dBtn();
btn1.x = -210;
btn1.y = -90;
addChild(btn1);
var btn2:MovieClip = new dBtn();
btn2.x = btn1.x+70;
btn2.y = btn1.y;
addChild(btn2);
var btn3:MovieClip = new dBtn();
btn3.x = btn2.x+70;
btn3.y = btn2.y;
addChild(btn3);
//2nd row//
var btn4:MovieClip = new dBtn();
btn4.x = btn1.x;
btn4.y = btn1.y+70;
addChild(btn4);
var btn5:MovieClip = new dBtn();
btn5.x = btn4.x+70;
btn5.y = btn4.y;
addChild(btn5);
var btn6:MovieClip = new dBtn();
btn6.x = btn5.x+70;
btn6.y = btn5.y;
addChild(btn6);
//3rd row//
var btn7:MovieClip = new dBtn();
btn7.x = btn4.x;
btn7.y = btn4.y+70;
addChild(btn7);
var btn8:MovieClip = new dBtn();
btn8.x = btn7.x+70;
btn8.y = btn7.y;
addChild(btn8);
var btn9:MovieClip = new dBtn();
btn9.x = btn8.x+70;
btn9.y = btn8.y;
addChild(btn9);

Loops + simple math.
var buttonsList:Array = new Array;
for (var i:int = 0; i < 9; i++)
{
// You can omit () with "new" operator if there are no arguments.
var aBut:MovieClip = new dBtn;
// Value of i % 3 goes 0 1 2 0 1 2 0 1 2.
aBut.x = -210 + 70 * (i % 3);
// Value of int(i / 3) goes 0 0 0 1 1 1 2 2 2.
aBut.y = -90 + 70 * int(i / 3);
addChild(aBut);
buttonsList[i] = aBut;
}
Then to address each one of them you can use their indices from 0 to 8 respectively:
// Make the central one semi-transparent.
buttonsList[4].alpha = 0.5;

Related

object HTMLImageElement apeearing from jQuery when trying to insert images

So here is what I'm trying to do:
Display a pattern that is randomly created with images, but keep getting the [object HTML Image Element] box appearing
var s1 = [];
s1[0] = new Image();
s1[0].src = '11.jpg';
s1[1] = new Image();
s1[1].src = '12.jpg';
s1[2] = new Image();
s1[2].src = '13.jpg';
s1[3] = new Image();
s1[3].src = '14.png';
s1[4] = new Image();
s1[4].src = '15.png';
var s2 = [];
s2[0] = new Image();
s2[0].src = '21.jpg';
s2[1] = new Image();
s2[1].src = '22.jpg';
s2[2] = new Image();
s2[2].src = '23.jpg';
s2[3] = new Image();
s2[3].src = '24.png';
s2[4] = new Image();
s2[4].src = '25.jpg';
var s3 = [];
s3[0] = new Image();
s3[0].src = '31.jpg';
s3[1] = new Image();
s3[1].src = '32.jpg';
s3[2] = new Image();
s3[2].src = '33.jepg';
s3[3] = new Image();
s3[3].src = '34.jpg';
s3[4] = new Image();
s3[4].src = '35.gif';
The arrays are now created, I want it to randomly pick 1 of the 5 to use, which seems to be working fine
p1 = Math.floor(Math.random() * 5 + 1);
p2 = Math.floor(Math.random() * 5 + 1);
p3 = Math.floor(Math.random() * 5 + 1);
if(p1 == 1) {
p1 = s1[0];
} else if (p1 == 2) {
p1 = s1[1];
} else if (p1 == 3) {
p1 = s1[2];
} else if (p1 == 4) {
p1 = s1[3];
} else if (p1 == 5) {
p1 = s1[4];
}
This exact same if/ else if structure is done for p2 and p3, I wont copy and paste it in to save space, now I want to output the final pattern, which is when i'm getting the object HTML image element appearing
while(repeat > 0){
pattern = p1 + p2 + p3 + pattern;
repeat --;
}
correctAnswer = 1;
$("#patternSpan").html(pattern)
Probelm
What does it mean to add images to each other?
Should all the rgb values for each pixel be added together? Should it create a new image with the pixels appended? appended to which side?
Neither of these things make sense for a language to automatically do, so whats happening here:
pattern = p1 + p2 + p3 + pattern;
Is that javascript is trying to decide if + means numeric addition or string concatenation.
Because the values aren't numbers, JS defaults to string concatenation.
What happens to a non-string when you attempt string concatenation?
JS calls .toString() on the value first
Turns out the string value for an image is [object HTML Image Element]
Solution
So what you want to do is append the images to #patternSpan. So instead of adding the images together, append them to the span:
$("#patternSpan").append(p1, p2, p3)
Side note
The section where you randomly pick the images can be cleaned up a lot by doing this instead:
idx1 = Math.floor(Math.random() * 5 + 1);
idx2 = Math.floor(Math.random() * 5 + 1);
idx3 = Math.floor(Math.random() * 5 + 1);
p1 = s1[idx1];
p2 = s2[idx2];
p3 = s3[idx3];
You should also avoid re-using variables like p1 for different types of things, ie storing a random number and storing an image.
You are more likely to run into type related bugs if a variable can contain multiple possible types.

How to Save positions for 3 objects in Array to make random position between each other by AS3?

How to Save positions for 3 objects in Array to make random position between each other by AS3?
import flash.geom.Point;
var arry:Point = new Point();
arry[0] = arry[78,200];
arry[1] = arry[217,200];
arry[2] = arry[356,200];
//object called b1
b1.x = arry[0][0];
b1.y = arry[0][1];
//object called b2
b2.x = arry[1][0];
b2.y = arry[1][1];
//object called b3
b3.x = arry[2][0];
b3.y = arry[2][1];
//make objects swap positions between each other
var rand:Number = (Math.random()*arry.length);
//output to see random position [[78,200],[217,200],[356,200]]
trace(arry);
to get random with tween like this... https://www.youtube.com/watch?v=8m_m64plQ6E
At compile time you should get this Error I suppose : "ReferenceError: Error #1069"
Here is a way to store the positions (like in the link you provided from youtube) :
import flash.geom.Point;
var squareWidth:uint = 40;
var squareHeight:uint = 40;
var marginX:uint = 100;
var marginY:uint = 75;
var spacer:uint = 10;
var positions:Vector.<Point > = new Vector.<Point > (9);
function setPositions(v:Vector.<Point>):void {
var count:uint = 0;
var posx:uint;
var posy:uint;
for (var i = 0; i < 3; i ++)
{
for (var j = 0; j < 3; j ++)
{
posx = (j * squareWidth) + (spacer * j) + marginX;
posy = (i * squareHeight) + (spacer * i) + marginY;
v[count] = new Point(posx,posy);
count++;
}
}
}
setPositions(positions);
trace(positions);
// output :
// (x=100, y=75),(x=150, y=75),(x=200, y=75),(x=100, y=125),(x=150, y=125),(x=200, y=125),(x=100, y=175),(x=150, y=175),(x=200, y=175)
So here you have nine Points to place the clips like in the video.
You just have to add a function to swap the nine boxes stored in another Vector.
In your case.
For 3 positions do the following if I understand your question.
import flash.geom.Point;
var positions:Vector.<Point> = new Vector.<Point>(3);
var p1:Point = new Point(78,200);
var p2:Point = new Point(217,200);
var p3:Point = new Point(356,200);
positions[0] = p1;
positions[1] = p2;
positions[2] = p3;
trace(positions);
// output : (x=78, y=200),(x=217, y=200),(x=356, y=200)
So, you're still unclear!
Your issue is to find a random position?
This may help you if this is the problem you're facing :
import flash.geom.Point;
var positions:Vector.<Point > = new Vector.<Point > (3);
var numbers:Vector.<uint> = new Vector.<uint>();
var numbersAllowed:uint = 3;
var rndNmbrs:Vector.<uint> = new Vector.<uint>(3);;
var p1:Point = new Point(78,200);
var p2:Point = new Point(217,200);
var p3:Point = new Point(356,200);
positions[0] = p1;
positions[1] = p2;
positions[2] = p3;
trace(positions);
function populateRndNmbrs(n:uint):void {
for (var i:uint = 0; i < n; i++)
{
numbers[i] = i;
}
}
populateRndNmbrs(numbersAllowed);
function populateRandomNumbers(n:uint):void
{
var rnd:uint;
for (var i:uint = 0; i < n; i++)
{
rnd = numbers[Math.floor(Math.random() * numbers.length)];
for (var j:uint = 0; j < numbers.length; j++)
{
if (rnd == numbers[j])
{
numbers.splice(j,1);
}
}
rndNmbrs[i] = rnd;
}
}
populateRandomNumbers(numbersAllowed);
trace("rndNmbrs = " + rndNmbrs);
for (var i:uint = 0; i < numbersAllowed; i++)
{
trace("b"+ (i+1) + ".x = " + positions[rndNmbrs[i]].x);
trace("b"+ (i+1) + ".y = " + positions[rndNmbrs[i]].y);
// In place of trace, you should place the boxes at those random positions.;
}
//output:
//(x=78, y=200),(x=217, y=200),(x=356, y=200)
//rndNmbrs = 2,0,1
//b1.x = 356
//b1.y = 200
//b2.x = 78
//b2.y = 200
//b3.x = 217
//b3.y = 200
Is that what you want? Or do you want to know how to create a motion effect?
I'm not sure about what you really need...
This will help you to place all the boxes in a random position.
You may do this like here bellow, and add a function to check if the random positions are not the same.
With only 3 MovieClips, you will often have the same random positions as long they're stored in the "positions Vector"
var squares:Vector.<MovieClip> = new Vector.<MovieClip>(3);
function populateMCs(target:DisplayObjectContainer,n:uint):void{
for (var i:uint = 0; i < n; i++){
squares[i] = target["b"+(i+1)];
}
}
function swapMCs():void{
for (var i:uint=0; i<squares.length; i++){
squares[i].x = positions[rndNmbrs[i]].x;
squares[i].y = positions[rndNmbrs[i]].y;
}
}
populateMCs(this,numbersAllowed);
swapMCs();
I give you a last example to get a motion effect in AS3.
I'm not a translator AS2 -> AS3 and a video is not the best way to show your code :(
This will make your boxes move smoothly, but not the way you want.
Now, you have to learn AS3 and try to make the job by yourself.
Then, if you have another issue, just ask clearly what you want.
var friction:Number = 0.15;
setDestination(squares[0],squares[0].x,350,friction);
setDestination(squares[1],squares[1].x,350,friction);
setDestination(squares[2],squares[2].x,350,friction);
squares[0].addEventListener(Event.ENTER_FRAME,moveClip);
squares[1].addEventListener(Event.ENTER_FRAME,moveClip);
squares[2].addEventListener(Event.ENTER_FRAME,moveClip);
function setDestination(mc:MovieClip,x:uint,y:uint,friction:Number):void{
mc.destinx = x;
mc.destiny = y;
mc.f = friction;
}
function moveClip(e:Event):void{
var mc:MovieClip = e.target as MovieClip;
trace(mc.name)
mc.speedx = (mc.destinx - mc.x);
mc.speedy = (mc.destiny - mc.y);
mc.x += mc.speedx*mc.f;
mc.y += mc.speedy*mc.f;
if((Math.floor(mc.speedx)<1) && (Math.floor(mc.speedy)<1)){
mc.removeEventListener(Event.ENTER_FRAME,moveClip);
trace("STOP MOVE FOR " + mc.name);
}
}

New at action script and finding issues at my 3x3 tile puzzle game

This code is for a 3x3 tile puzzle game. I'm in school designing a game for my coursework and I have tried my best but this is all I can do.
The issue I think is that I'm not sure how to make it so that when the tile next to the blank tile is clicked it will swap, but not any others if they are not next to the blank tile.
Also I haven't prepared the win sequence for when they are all in order and its not random at the start where the tiles start as I was unsure how to make it random. It also says that the issue is that it expected 2, got 1. Ihave no idea what that means.
var blank:Blank = new Blank();
var one:One = new One();
var two:Two = new Two();
var three:Three = new Three();
var four:Four = new Four();
var five:Five = new Five();
var six:Six = new Six();
var seven:Seven = new Seven();
var eight:Eight = new Eight();
var tile = String
function swapBlank(tile):void
{
var m = int
var n = int
m = tile.x
n = tile.y
tile.x = blank.x
tile.y = blank.y
blank.x = m
blank.y = n
}
function swap(tile,e:MouseEvent):void
{
if (tile.x == blank.x)
{
if (tile.y == blank.y + 110)
{
swapBlank(tile);
}
else if (tile.y == blank.y - 110)
{
swapBlank(tile);
}
}
else if (tile.y == blank.y)
{
if (tile.x == blank.x + 110)
{
swapBlank(tile);
}
else if (tile.x == blank.x - 110)
{
swapBlank(tile);
}
}
}
//expected 2, got 1//
addChild(blank);
addChild(one);
addChild(two);
addChild(three);
addChild(four);
addChild(five);
addChild(six);
addChild(seven);
addChild(eight);
three.x = 10
three.y = 10
eight.x = 120
eight.y = 10
seven.x = 230
seven.y = 10
one.x = 10
one.y = 120
four.x = 120
four.y = 120
six.x = 230
six.y = 120
two.x = 10
two.y = 230
five.x = 120
five.y = 230
blank.x = 230
blank.y = 230
one.addEventListener(MouseEvent.CLICK, swap);
two.addEventListener(MouseEvent.CLICK, swap);
three.addEventListener(MouseEvent.CLICK,swap);
four.addEventListener(MouseEvent.CLICK, swap);
five.addEventListener(MouseEvent.CLICK, swap);
six.addEventListener(MouseEvent.CLICK, swap);
seven.addEventListener(MouseEvent.CLICK, swap);
eight.addEventListener(MouseEvent.CLICK, swap);
The error that you get on your swap function call is because Event Listeners always have only one parameter: the Event. So swap() should look like
function swap(event:MouseEvent):void.
The event will have a reference to the tile that was clicked so you can get it roughly like this:
tile = event.target;
Then you can check if tile is next to the blank one, and the rest.
But Stack Overflow is not meant to tell you how to do your assignments so that one is for you to solve.

How do I rasterize a graphic that contains path data?

I am trying to rasterize some SVG data to a PNG and it is not working. Could someone please tell me what I am doing wrong?
This code does not seem to have any data in the BitmapData object.
var color:uint = Math.floor( (Math.random() * 0xFFFF00) + 0x0000FF);
var graphic:Graphic = new Graphic();
graphic.graphics.beginFill(color);
var pathData:String = "M 0 0 L 0 40 L 40 40 L 40 40 Z";
var path:Path = new Path();
path.data = pathData;
path.x =0;
path.y=0;
path.width = 40;
path.height = 40;
path.stroke=new SolidColorStroke(100);
path.fill=new SolidColor(100);
path.winding = GraphicsPathWinding.EVEN_ODD;
graphic.addElement(path);
graphic.width = 40;
graphic.height = 40;
graphic.validateNow();
var FillColor = 0x00000000;
var bitMapData:BitmapData = new BitmapData(graphic.width,graphic.height, true, FillColor);
bitMapData.draw(graphic);
But this code does:
var graphic:Graphic = new Graphic();
graphic.graphics.beginFill(color);
var width:Number = Math.floor(Math.random() * (MAXWIDTH-MINWIDTH)) + MINWIDTH;
var height:Number = Math.floor(Math.random() * (MAXHEIGHT-MINHIEGHT)) + MINHIEGHT;
var radius:Number = Math.floor( (Math.random()*(MAXRADIUS-MINRADIUS)))+MINRADIUS;
width = height = radius*2;
graphic.graphics.drawCircle(radius, radius,radius );
graphic.graphics.endFill();
var FillColor = 0x00000000;
var bitMapData:BitmapData = new BitmapData(graphic.width,graphic.height, true, FillColor);
bitMapData.draw(graphic);
if I do:
var temp:Graphic = new Graphic();
temp.graphics.beginFill(0x000000);
temp.graphics.drawRect(0,0,width/2, height/2);
temp.graphics.endFill();
sprite.graphics.drawRect(0,0,width, height);
sprite.addElement(temp);
both rectangles draw on canvas, but
BitMapData.draw(sprite);
only shows the toplevel sprite.
So I figured it out. Paths use BeforeDraw(), Draw(), and EndDraw(), which performs the fill and stroke operations. The problem is that these functions dont get called until the path gets rendered on the canvas. So, I extended my path class and over-rode the EndDraw() function. In this function I dispatched an event. Then, when I catch the event I can get the DisplayObject from the path (which is now filled in) and pass that object into BitmapData().

How to get Text Input In Adobe AIR

I'm new to Adobe AIR and here is what i'm doing, (please note that i'm doing this by AS3 code:
Adding a VGroup to the Canvas control.
var vIncomeHeader:VGroup = new VGroup();
vIncomeHeader.width = 1326;
vIncomeHeader.height = 29;
vIncomeHeader.id = "vIncomeHeader";
canvasIncome.addChild(vIncomeHeader);
Creating and adding a HGroup to the VGroup created in step one.
Creating 5 TextInput and adding it to HGroup. First textbox is editable and rest are not editable.
var hfIncomeHeader:HGroup = new HGroup();
var txt:TextInput = new TextInput();
vIncomeHeader.addElement(hfIncomeHeader);
var lp:int =0;
var lp-inner:int =0;
for (lp=0; lp<10; lp++)
{
hfIncomeHeader = new HGroup();
hfIncomeHeader.width = 1326;
hfIncomeHeader.height = 29;
//Amount
txt = new TextInput();
txt.id = "txtAmount_" + lp;
txt.width = 120;
txt.height = 22;
txt.restrict = "0-9.\\";
txt.addEventListener(Event.CHANGE, txtChangeIncomeAmount);
hfIncomeHeader.addElement(txt);
for (lp-inner=0; lp-inner<4; lp-inner++)
{
//Income Type
txt = new TextInput();
txt.id = "txt_" + lp + "_" + lp-inner;
txt.width = 120;
txt.height = 22;
hfIncomeHeader.addElement(txt);
}
}
//txtChangeIncomeAmount
protected function txtChangeIncomeAmount(event:Object):void
{
// HOW TO Do IT
}
[Second and third steps are part of a for loop from 0 to 10]
Now, what I want to do is to write the number in first textbox and automatically fill the same number to other 4 textboxes of that HGroup.
You can set names to your TextInput and then get them by names. Something like that:
...
txt.name = "txt_" + lp-inner;
...
protected function txtChangeIncomeAmount(event:Event):void
{
var txt:TextInput;
for (var i:uint = 0; i < 4; i++)
{
txt = hfIncomeHeader.getChildByName("txt_" + i) as TextInput;
txt.text = (event.currentTarget as TextInput).text;
}
}