I making a card game and i call some cards from the library randomly.
But i cant use this cards.
Is there any way to make this childs clickable?
And another question please.
If there any chance to use one print array for all the 22 cards i need to show on stage?Or i must to create a new printarray and a new random number for each card?
Note:each card has different points.
var cards:Array = [k1, p1, s1, r1, r3,k4,p4,s4,r4,k5,p5,s5,r5
,k6,p6,s6,r6,k7,p7,s7,r7,k8,p8,s8,r8,k9,p9,s9,r9,k10,p10,s10,r10,
kj,pj,sj,rj,kq,pq,sq,rq,kk,pk,sk,rk];
var printArray:Array = [];
for (var n:int = 1; n <= 1; n++)
{
var randNo:int = int(Math.random() * 51);
printArray.push(randNo);
}
for (var c:int = 0; c < printArray.length; c++)
{
trace(printArray[c]);
var mc:MovieClip = new cards[printArray[c] ];
addChild(mc);
mc.width = 60;
mc.height = 80;
mc.x = 100;
mc.y = 50;
}
var print1Array:Array = [];
for (var n1:int = 1; n1 <= 1; n1++)
{
var rand1No:int = int(Math.random() * 51);
print1Array.push(rand1No);
}
for (var c1:int = 0; c1 < print1Array.length; c1++)
{
trace(print1Array[c1]);
var mc1:MovieClip = new cards[print1Array[c1] ];
addChild(mc1);
mc1.width = 60;
mc1.height = 80;
mc1.x = 70;
mc1.y = 80;
}
stage.addEventListener(Event.ENTER_FRAME,looping);
function looping(event:Event):void
{
//here ia want use the cards.Let say i want to if(mc1 is clicked)
}
mc1.addEventListener(MouseEvent.CLICK, clickCard);
Put that where you have your other mc1's. Then elsewhere, outside any other functions put this:
private function clickCard(e:MouseEvent):void{
//trace(e.target);
}
Related
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);
}
}
The problem is when i have 2 or more balls on stage,some balls are bouncing perfect and some other are sink in floors.
The floors on stage are already on stage.
Is that a drawing problem or its something else?
stop();
//ARRAYS
var ballArray:Array = new Array();
//ADD BALLS
var mediumBall1f2:Ball = new Ball ;
ballArray.push(mediumBall1f2);
this.addChild(mediumBall1f2);
mediumBall1f2.ballX = 3;
mediumBall1f2.ballY = 8;
mediumBall1f2.x = 300;
mediumBall1f2.y = 250;
mediumBall1f2.width = 120;
mediumBall1f2.height = 120;
var mediumBall1f3:Ball = new Ball ;
ballArray.push(mediumBall1f3);
this.addChild(mediumBall1f3);
mediumBall1f3.ballX = -3;
mediumBall1f3.ballY = 8;
mediumBall1f3.x = 200;
mediumBall1f3.y = 350;
mediumBall1f3.width = 140;
mediumBall1f3.height = 140;
var mediumBall1f4:Ball = new Ball ;
ballArray.push(mediumBall1f4);
this.addChild(mediumBall1f4);
mediumBall1f4.ballX = -3;
mediumBall1f4.ballY = 8;
mediumBall1f4.x = 300;
mediumBall1f4.y = 250;
mediumBall1f4.width = 50;
mediumBall1f4.height = 50;
var mediumBall1f5:Ball = new Ball ;
ballArray.push(mediumBall1f5);
this.addChild(mediumBall1f5);
mediumBall1f5.ballX = -3;
mediumBall1f5.ballY = 8;
mediumBall1f5.x = 400;
mediumBall1f5.y = 350;
mediumBall1f5.width = 80;
mediumBall1f5.height = 80;
var mediumBall1f6:Ball = new Ball ;
ballArray.push(mediumBall1f6);
this.addChild(mediumBall1f6);
mediumBall1f6.ballX = 3;
mediumBall1f6.ballY = 8;
mediumBall1f6.x = 400;
mediumBall1f6.y = 320;
mediumBall1f6.width = 30;
mediumBall1f6.height = 30;
var mediumBall1f7:Ball = new Ball ;
ballArray.push(mediumBall1f7);
this.addChild(mediumBall1f7);
mediumBall1f7.ballX = 3;
mediumBall1f7.ballY = 8;
mediumBall1f7.x = 400;
mediumBall1f7.y = 230;
var mediumBall1f8:Ball = new Ball ;
ballArray.push(mediumBall1f8);
this.addChild(mediumBall1f8);
mediumBall1f8.ballX = 3;
mediumBall1f8.ballY = 8;
mediumBall1f8.x = 400;
mediumBall1f8.y = 240;
var mediumBall1f9:Ball = new Ball ;
ballArray.push(mediumBall1f9);
this.addChild(mediumBall1f9);
mediumBall1f9.ballX = 3;
mediumBall1f9.ballY = 8;
mediumBall1f9.x = 400;
mediumBall1f9.y = 110;
//FLOOR
var downArray:Array = new Array();
for (var dA:int = numChildren - 1; dA>= 0; dA--)
{
var childdA:DisplayObject = getChildAt(dA);
if (childdA.name == "downfloor")
{
downArray.push(MovieClip(childdA));
}
}
var upArray:Array = new Array();
for (var uA:int = numChildren - 1; uA>= 0; uA--)
{
var childuA:DisplayObject = getChildAt(uA);
if (childuA.name == "upfloor")
{
upArray.push(MovieClip(childuA));
}
}
var rightArray:Array = new Array();
for (var rA:int = numChildren - 1; rA>= 0; rA--)
{
var childrA:DisplayObject = getChildAt(rA);
if (childrA.name == "rightfloor")
{
rightArray.push(MovieClip(childrA));
}
}
var leftArray:Array = new Array();
for (var lA:int = numChildren - 1; lA>= 0; lA--)
{
var childlA:DisplayObject = getChildAt(lA);
if (childlA.name == "leftfloor")
{
leftArray.push(MovieClip(childlA));
}
}
//USE ONCE
stageclear.visible = false;
stageclear.gotoAndStop(1);
stage.addEventListener(Event.ENTER_FRAME,ballLoop);
function ballLoop(evt:Event)
{
//BALL
for (var j = 0; j<ballArray.length; j++)
{
var ball:Ball = ballArray[j] as Ball;
ball.ballY--;
ball.y -= ball.ballY;
ball.x -= ball.ballX;
if (player.hitTestObject(ball))
{
ball.y = 600;
}
if(ball.x - ball.width/2 < 0)
{
ball.ballX = -3;
}
if(ball.x + ball.width/2 > 800)
{
ball.ballX = 3;
}
if(ball.y + ball.height/2 > 384.45)
{
ball.ballY = 20;
}
if(ball.y - ball.height/2 < 0)
{
ball.ballY = -2;
}
for (var d = 0; d<downArray.length; d++)
{
var down:DownFloor = downArray[d] as DownFloor;
if (ball.hitTestObject(down))
{
ball.ballY = 20;
}
}
for (var r = 0; r<rightArray.length; r++)
{
var right:RightFloor = rightArray[r] as RightFloor;
if (ball.hitTestObject(right))
{
ball.ballX = 3;
}
}
for (var l = 0; l<leftArray.length; l++)
{
var left:LeftFloor = leftArray[l] as LeftFloor;
if (ball.hitTestObject(left))
{
ball.ballX = -3;
}
}
for (var u = 0; u<upArray.length; u++)
{
var up:UpFloor = upArray[u] as UpFloor;
if (ball.hitTestObject(up))
{
ball.ballY = -2;
}
}
if (ball.y >= 600)
{
ball.parent.removeChild(ball);
ballArray.splice(j,1);
}
if (ballArray.length <= 0)
{
stageclear.visible = true;
stageclear.gotoAndPlay(1);
}
}
if(stageclear.currentFrame == stageclear.totalFrames)
{
stage.removeEventListener(Event.ENTER_FRAME,ballLoop);
MovieClip(this.root).gotoAndPlay(1, "Scene 2");
}
}
the reason this is happening
This is happening because hitTest is only true if the MCs overlap. If you could look more closely, you'd see that this happens to all of the balls (it's just more apparent with some than others).
the only fix that I know of
Make your own collision detection.
It could look like this:
function collisionTest (mc1:MovieClip,mc2:MovieClip){
// test if mc1 is going to hit mc2's left side *on the next frame*
if (mc1.x + mc1._xSpeed + mc1.width>= mc2.x){
mc1.x = mc2.x; // this may cause a momentary pause... The ball may seem to stick to the wall for a frame... If this is a problem let me know and I'll show you how to fix that
mc1._xSpeed *= -1;
}
// test if mc1 is going to hit top edge of mc2 *on the next frame*
if (mc1.y + mc1._ySpeed + mc1.height >= mc2.y){
mc1.y = mc2.y; // same possible sticking here
mc1._ySpeed *= -1;
}
}
note
For this to work, the registration point for the MCs should be top-left (which is the default).
Also, my code only works for object 1 moving down, colliding with the top of object2 or object 1 moving right colliding with left side of object 2.
_xSpeed and _ySpeed are things you will need to add as properties to your ball class and use that property to dictate motion of the balls. This is the key: it allows you to look ahead, into the future, and see if the ball is going to hit the wall on the next frame, and if it is, run the result of collision now, instead of after they overlap.
You'll need to add similar code for if the ball is moving left and you want it to detect collision with the right edge of a wall. Also for if the ball is moving up and you want to detect collision with the bottom of a wall
Don't forget to include an adjustment for the width of the wall or the width of the ball (since we are using the registration point which is top left of the bounding box)
Having a bit of a problem. I'm trying to add 10 items to the stage but it is only adding 1. Any insight on what I'm doing wrong?
public var numCells:Array = [];
public function addCell():void
{
var cell:Cell = new Cell();
var i:int = 0;
cell.x = Math.floor(Math.random() * 1366);
cell.y = Math.floor(Math.random() * 768);
for(var i:int = 0; i < 10; i++)
{
numCells.push(cell);
addChild(cell);
}
return;
}
You are only ever instantiating one cell. calling addChild a second time with the same object passed in doesn't make a copy of that object, it just moves it to the top most 'layer'.
You need to instantiate a new cell inside the for loop. Something like this:
private function addCells():void {
for(var i:int = 0; i < 10; i++){
var cell:Cell = new Cell();
cell.x = Math.floor(Math.random() * 1366);
cell.y = Math.floor(Math.random() * 768);
numCells.push(cell);
addChild(cell);
}
}
Newbie question:
If I create several shape objects in a loop, like:
var i:int;
for (i = 0; i < 3; i++) {
var circle:Shape = new Shape();
circle.graphics.beginFill(color);
circle.graphics.drawCircle(100,100, radius);
circle.graphics.endFill();
addChild(circle);
}
How can I then call those different shapes separately, so I could manipulate their properties? It would seem to me they would all have the same name?
You can access them via their index (the order they have been put on the stage).
So something like:
DisplayObject(getChildAt(1)).x = 100; // Where the 1 is the index (starting at 0)
Actually, you can just have an array (or vector) of objects, so you won't depend on current displaylist.
var i:int;
var circleArray:Array = new Array();
for (i = 0; i < 3; i++) {
var circle:Shape = new Shape();
circleArrayList.push(circle);
circle.graphics.beginFill(color);
circle.graphics.drawCircle(100,100, radius);
circle.graphics.endFill();
addChild(circle);
}
//And then access them with
for(i = 0; i < circleArray.length, i++)
{
circleArrayList[i].x = 15 * i;
}
//Or
foreach(var circle:DisplayObject in circleArray)
{
circle.x = 15 * i;
}
for(int i=0;i<3;i++)
{
class x =new class(i);
x.print()
}
I am making a tool which obscures an image with squares. What I want to happen is to have a bouncing ball which hits the squares and makes them disappear. However, the removeChild command isn't working right. I set it up to populate the image with empty movie clips and colorize them. However, when I click the square, I am running into problems with the parent/child. I keep running into this error. "The supplied DisplayObject must be a child of the caller." I cannot think of a good way to assign the eventListeners to each individual squares. I'm sure it is obvious. Here is my code. Thank you in advance
EDIT:If I get it to work, it deletes all instances of the square, not just the one I clicked.
Here is my code
var mc:MovieClip = bgIMG;
var bd:BitmapData = new BitmapData(mc.width,mc.height);
bd.draw(mc);
var _img:Bitmap = new Bitmap(bd);
var _imgNodes:Array = [];
var _tiledImg:MovieClip = container_tiled_img;
var pad:int = 0;
var rows:int = 10;
var cols:int = 10;
var zero:Point = new Point();
createImgNodeGrid(rows, cols, pad);
pixelateNodes(_imgNodes);
function removeMC(e:MouseEvent)
{//removes the movie clip
trace(e.currentTarget.x);
stage.removeChild(e.currentTarget.parent.parent);
}
function pixelateNodes(nodes:Array = null):void
{
for each (var node:Bitmap in nodes)
{
node.bitmapData.fillRect(node.bitmapData.rect, avgColor(node.bitmapData));
}
}
function avgColor(src:BitmapData):uint
{
var A:Number = 0;
var R:Number = 0;
var G:Number = 0;
var B:Number = 0;
var idx:Number = 0;
var px:Number;
for (var x:int = 0; x < src.width; x++)
{
for (var y:int = 0; y < src.height; y++)
{
px = src.getPixel32(x,y);
A += px >> 24 & 0xFF;
R += px >> 16 & 0xFF;
G += px >> 8 & 0xFF;
B += px & 0xFF;
idx++;
}
}
A /= idx;
R /= idx;
G /= idx;
B /= idx;
return A << 24 | R << 16 | G << 8 | B;
}
function createImgNodeGrid(rows:int = 1, cols:int = 1, pad:Number = 0):void
{
var w:Number = _img.width / rows;
var h:Number = _img.height / cols;
var numNodes:int = rows * cols;
_imgNodes = [];
var nodeCount:int = 0;
for (var i:int = 0; i < rows; i++)
{
for (var j:int = 0; j < cols; j++)
{
// get area of current image node
var sourceRect:Rectangle = new Rectangle(i * w, j * h, w, h);
// copy bitmap data of current image node
var tempBd:BitmapData = new BitmapData(w,h,true);
tempBd.copyPixels(_img.bitmapData, sourceRect, zero);
// place image node bitmap data into sprite
var imgNode:Bitmap = new Bitmap(tempBd);
imgNode.x = i * (w + pad);
imgNode.y = j * (h + pad);
// store each image node
//_imgNodes.push(imgNode);
_imgNodes[nodeCount++] = imgNode;
// add each image node to the stage
_tiledImg.addChild(imgNode);
_tiledImg.addEventListener(MouseEvent.CLICK,removeMC);
}
}
}
The problem you have is your are adding the event to the parent of the node(_tiledImg).
function createImgNodeGrid(rows:int = 1, cols:int = 1, pad:Number = 0):void
{
var w:Number = _img.width / rows;
var h:Number = _img.height / cols;
var numNodes:int = rows * cols;
_imgNodes = [];
var nodeCount:int = 0;
for (var i:int = 0; i < rows; i++)
{
for (var j:int = 0; j < cols; j++)
{
// get area of current image node
var sourceRect:Rectangle = new Rectangle(i * w, j * h, w, h);
// copy bitmap data of current image node
var tempBd:BitmapData = new BitmapData(w,h,true);
tempBd.copyPixels(_img.bitmapData, sourceRect, zero);
// place image node bitmap data into sprite
var imgNode:Bitmap = new Bitmap(tempBd);
imgNode.x = i * (w + pad);
imgNode.y = j * (h + pad);
// store each image node
//_imgNodes.push(imgNode);
_imgNodes[nodeCount++] = imgNode;
// you need a container since you can not attach event listeners to a BitMap
var sprite:Sprite = new Sprite()
sprite.mouseChildren = false;
sprite.addEventListener(MouseEvent.CLICK,removeMC);
sprite.addChild(imgNode);
// add each image node to the stage
_tiledImg.addChild(sprite);
// _tiledImg.addEventListener(MouseEvent.CLICK,removeMC);
}
}
}
function removeMC(e:MouseEvent)
{
var target:Sprite = event.currentTarget as Sprite;
target.parent.removeChild(target)
}
If I am following correctly, you are trying to remove an imgNode on MouseClick. If that is the case, you should change removeMC function to this:
function removeMC(e:MouseEvent)
{
//removes the movie clip
trace(e.target);
_tiledImg.removeChild(event.currentTarget);
}
Also, you shouldn't add the listener within the for loop, but instead add it outside of the for loops (since you are just adding the listener to _tiledImg and that doesn't change in the for loops).
A easy way to always remove a child from the right parent is to do as following
function removeMC(e:MouseEvent)
{
//removes the movie clip
var target:Sprite = event.currentTarget as Sprite;
target.parent.removeChild(target)
}