as3 - Moving objects through different positions - actionscript-3

I am coding a simple video game in adobe animate with as3. I am trying to move my objects through a swipe action through 3 different positions e.g:
Swipe 1: mc1 moves to 1st position (x = 600; y = 300).
Swipe 2: mc2 moves to 1st position (x = 600; y = 300) and mc1 move to 2nd position (x = 300, y = 300).
Swipe 3: mc3 moves to 1st position (x = 600; y = 300) and mc2 move to 2nd position (x = 300, y = 300) and mc1 moved to 3rd position ((x = -100, y = -100).
Swipe 4: mc4 moves to 1st position (x = 600; y = 300) and mc3 move to 2nd position (x = 300, y = 300) and mc2 moved to 3rd position ((x = -100, y = -100)...and so on.
I would also like to be able to return to the start of the loop (Swipe 1) through a click to repeat the whole process at any point.
I am using arrays for my objects e.g.
var A:Array =
[
mc1,
mc2,
mc3,...mc50
];
I have tried this:
var anObject:DisplayObject;
//move object through swipe action
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeHandler_1);
function fl_SwipeHandler_1(event:TransformGestureEvent):void
{
switch(event.offsetX)
{
case -1:
{for each (anObject in A) {
for (var n:int = 0; n < A.length; n++){
A[n].x = 600 // how do I get this right?
A[n].y = 300
A[n-1].x = 300
A[n-1].y = 300
A[n-2].x = -100
A[n-2].y = -100
}}
} break;
}
}
//return to beginning of loop (Swipe 1)
mc_return_to_A0.addEventListener(MouseEvent.CLICK, return_to_A0);
function return_to_A0 (event:MouseEvent):void
{n==0} //how do I get this right? ```
Any help would be much appreciated!
Thanks

I cannot help you with gestures for I never worked with them directly, but positioning is logically... not difficult.
You have an Array of objects and an Array of positions. After the 1-st swipe you want only the first object go to the first given position:
Positions: ... (6) (5) (4) (3) (2) (1)
Objects: (1) (2) (3) (4) (5) (6) ...
After the 2-nd swipe:
Positions: ... (6) (5) (4) (3) (2) (1)
Objects: (1) (2) (3) (4) (5) (6) ...
After the 5-th swipe:
Positions: ... (6) (5) (4) (3) (2) (1)
Objects: (1) (2) (3) (4) (5) (6) ...
So, the script should go as the following (sort of):
// A list of your objects here.
var A:Array = [mc1, mc2, ... , mc50];
// A list of designated points here. I kinda advise to design
// these on stage with empty MovieClips appropriately named.
// This way you will have a visual representation of these
// positions, not just lots of numbers on your code.
var P:Array = [p1, p2, ... , p50];
// You need to keep a number of successful swipes, it is,
// literally, the number of objects you need to re-position.
var N:int = 0;
// So, after you successfully register a new swipe,
// you call this method to apply the re-positioning.
function arrangeThings():void
{
// So we take first N objects, one by one.
for (var i:int = 0; i < N; i++)
{
// Figure the index of the P for the current designated position.
var anIndex:int = N - i - 1;
// Get the position object itself.
var aPos:DisplayObject = P[anIndex];
// Get the object to position.
var anObject:DisplayObject = A[i];
// Assume the designated position.
anObject.x = aPos.x;
anObject.y = aPos.y;
}
}
Then, I've already explained you how to reset things in the comment here. Plainly, you just store the initial coordinates at the start and then assign them back upon need.

Related

Define rectangle how to

I 'm trying to develop a game.In my project i have a movieclip which is the character for the game.I also have 5 buttons(left right down up and stop) so the user can move.The game is for android.In my library i have a square with dimnesions 50 x 50.I have filled the stage with copies of this square with different instances so the character can move on them.The point of the game is that the user moves the character and with HitTestObject() function he removes the square that he is walking on.I used a timer so if 5 seconds are over and the player hasn't completed a rectangle of missing squares the squares appear again.But if he makes a rectangle(lets say that he makes it by removing 8 squares) the squares that are inside this rectangle must dissapear also.I need to find a way to see when the player completes this rectangle.I also think that my aproach to what i want to do is draft and there is a much better one.
Thanks in advance!
i think i may haven't explained my problem well..sorry for this its my mistake!everytime the character touches on a square it disapears.if in 5 seconds the character hasn't completed a "rectangle" of missing squares they appear again.When i say rectangle i mean rectangle of squares.For example if 4 squares missing(not in a row) its a rectangle,or if 8 squares or 12 etc...
import flash.utils.Timer;
stop();
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
var hunterxspeed:Number=0;
var hunteryspeed:Number=0;
var timerformove:Timer=new Timer(30);
var timerforblocks:Number=0;
var simpletimer:Number=0;
var rectanglearray:Array = new Array();
var sumvertical:int=0;
var sumhorizontal:int=0;
var i:int=0;
moveup.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler_2);
function fl_TapHandler_2(event:TouchEvent):void
{
hunteryspeed = -4;
hunterxspeed = 0;
rectanglearray[0] = 0;
rectanglearray[1] = -1;
sumvertical+=rectanglearray[0]+rectanglearray[1];
i++;
}
movedown.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler_3);
function fl_TapHandler_3(event:TouchEvent):void
{
hunteryspeed = 4;
hunterxspeed = 0;
rectanglearray[0] = 0;
rectanglearray[1] = 1;
sumvertical+=rectanglearray[0]+rectanglearray[1];
i++;
}
moveright.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler_4);
function fl_TapHandler_4(event:TouchEvent):void
{
hunterxspeed = 4;
hunteryspeed = 0;
hunter.scaleX = 2/4;
rectanglearray[2] = 1;
rectanglearray[3] = 0;
sumhorizontal+= rectanglearray[2] +rectanglearray[3];
i++;
}
moveleft.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler_5);
function fl_TapHandler_5(event:TouchEvent):void
{
hunterxspeed = -4;
hunteryspeed = 0;
hunter.scaleX = -(2/4);
rectanglearray[2] = -1;
rectanglearray[3] = 0;
sumhorizontal+= rectanglearray[2] + rectanglearray[3];
i++;
}
stopmove.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler_6);
function fl_TapHandler_6(event:TouchEvent):void
{
hunterxspeed = 0;
hunteryspeed = 0;
}
timerformove.addEventListener(TimerEvent.TIMER,huntermove);
function huntermove(e:TimerEvent) :void
{
if (hunter.y > stage.stageHeight-160)
{
hunter.y = stage.stageHeight-161;
hunteryspeed = 0;
}
if (hunter.y < 20)
{
hunter.y = 21;
hunteryspeed = 0;
}
if (hunter.x > stage.stageWidth-30)
{
hunter.x = stage.stageWidth-31;
hunterxspeed = 0;
}
if (hunter.x < 30)
{
hunter.x = 31;
hunterxspeed = 0;
}
hunterlegs.y = hunter.y+20;
hunterlegs.x = hunter.x;
hunter.y += hunteryspeed;
hunter.x += hunterxspeed;
if(timerforblocks==5000)
{
simpletimer+=50;
}
if(simpletimer>timerforblocks)
{
simpletimer=0;
timerforblocks=0;
}
if(hunterlegs.hitTestObject(grass))
{
timerforblocks=5000;
grass.x=grass.x-100;
}
if(hunterlegs.hitTestObject(grass1))
{
timerforblocks=5000;
grass1.x=grass1.x-100;
}
if(hunterlegs.hitTestObject(grass2))
{
timerforblocks=5000;
grass2.x=grass2.x-200;
}
if(hunterlegs.hitTestObject(grass12))
{
timerforblocks=5000;
grass12.x=grass12.x-300;
}
if(hunterlegs.hitTestObject(grass22))
{
timerforblocks=5000;
grass22.x=grass22.x-300;
}
if(hunterlegs.hitTestObject(grass21))
{
timerforblocks=5000;
grass21.x=grass21.x-300;
}
if(hunterlegs.hitTestObject(grass20))
{
timerforblocks=5000;
grass20.x=grass20.x-300;
}
if(hunterlegs.hitTestObject(grass10))
{
timerforblocks=5000;
grass10.x=grass10.x-300;
}
if(sumvertical==0 && sumhorizontal==0 && i==4)
{
grass.x=2000;
grass1.x=2000;
grass2.x=2000;
grass12.x=2000;
grass22.x=2000;
grass21.x=2000;
grass20.x=2000;
grass10.x=2000;
}
}
timerformove.start();
All objects are in the first frame.
I named grass the first square and i copied it to 100 more or less with different instances.
Hunter is my character.
A rectangle has 4 corners, and the character ends up at the origin square.
What you could try is to keep an array where you store the movement of the character. For instance, if the character moves upward, store {x: 0, y: -1} and if it moves left, store {x: 1, y: 0}.
Then, when it's time to check for valid rectangles, step through the list of movements and keep track of corners (where the direction changes) and check to see if the following criteria is fulfilled:
The sum of all horizontal movements is 0
The sum of all vertical movements is 0
The sum of corners is 4
This will check to see if the character ended up in the same position it originally started in and if it's movements formed a valid rectangle.
If the criteria isn't met, do the same check of the array, but start on position number 2. Etc.
This way, you will check if a valid rectangle has been formed at any stage during the character's movements (even if a rectangle was only part of the character's total moves). It will also validate for a rectangle of any size.
Here's an illustration that could perhaps clear things up:
In the first case, when the horizontal and vertical counters both sums 0, the corner count is 4. This is a valid rectangle.
In the second case, when the horizontal and vertical counters both sums 0, the corner count is 6. This is not a rectangle.
Edit to respond to follow-up question:
It's a bit tricky since it appears like the character is able to move around freely. The system described above becomes trivial if you have a game where the character moves across the grid one step at a time.
The system still applies though, but you need to look at the order of which the "squares" are being eaten. You can still make the same array of movement by keeping track of the last square to be hit and what place it had in the grid.
For example, if we follow the pattern of the first example the squares are eaten in the following order:
Square 1: [2, 4]
Square 2: [1, 4] -> subtract from last position: [1-2, 4-4] = [-1, 0] <- add this to the movement array
Square 3: [1, 3] -> subtract from last position: [1-1, 3-4] = [0, -1] <- add this to the movement array
Square 4: [1, 2] -> subtract from last position: [1-1, 2-3] = [0, -1] <- add this to the movement array
...
Square 12: [3, 4] -> subtract from last position: [3-4, 4-4] = [-1, 0] <- add this to the movement array
Square 13: [2, 4] -> subtract from last position: [2-3, 4-4] = [-1, 0] <- add this to the movement array
You will now have the same movement array as in the example above.

How to draw dashed lines with using rectangles in AS3?

I'm using starling framework for my game project and it hasn't got any draw dashed line method. Because of this they suggest me to draw dashed lines with using small rectangles which is called quads.
My math is not enough for it, could you give a sample method for rectangles with dashed lines occurring.
Thanks..
This class by Andy Woodruff draws dashed lines
/*
DashedLine class
by Andy Woodruff (http://cartogrammar.com/blog || awoodruff#gmail.com)
May 2008
Still in progress; I'll get a more perfected version eventually. For now take it as is.
This is a Sprite with the capability to do basic lineTo drawing with dashed lines.
Example:
var dashy:DashedLine = new DashedLine(2,0x333333,new Array(3,3,10,3,5,8,7,13));
dashy.moveTo(120,120);
dashy.beginFill(0xcccccc);
dashy.lineTo(220,120);
dashy.lineTo(220,220);
dashy.lineTo(120,220);
dashy.lineTo(120,120);
dashy.endFill();
*/
package com.cartogrammar.drawing {
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Point;
import flash.display.CapsStyle;
public class DashedLine extends Sprite {
var lengthsArray:Array = new Array(); // array of dash and gap lengths (dash,gap,dash,gap....)
var lineColor:uint; // line color
var lineWeight:Number; // line weight
var lineAlpha:Number = 1; // line alpha
var curX:Number = 0; // stores current x as it changes with lineTo and moveTo calls
var curY:Number = 0; // same as above, but for y
var remainingDist:Number = 0; // stores distance between the end of the last full dash or gap and the end coordinates specified in lineTo
var curIndex = null; // current index in the length array, so we know which dash or gap to draw
var arraySum:Number = 0; // total length of the dashes and gaps... not currently being used for anything, but maybe useful?
var startIndex:int = 0; // array index (the particular dash or gap) to start with in a lineTo--based on the last dash or gap drawn in the previous lineTo (along with remainingDist, this is so our line can properly continue around corners!)
var fill:Shape = new Shape(); // shappe in the background to be used for fill (if any)
var stroke:Shape = new Shape(); // shape in the foreground to be used for the dashed line
public function DashedLine(weight:Number = 0, color:Number = 0, lengthsArray:Array = null){
if (lengthsArray != null){ // if lengths array was specified, use it
this.lengthsArray = lengthsArray;
} else { // if unspecified, use a default 5-5 line
this.lengthsArray = [5,5];
}
if (this.lengthsArray.length % 2 != 0){ // if array has more dashes than gaps (i.e. an odd number of values), add a 5 gap to the end
lengthsArray.push(5);
}
// sum the dash and gap lengths
for (var i:int in lengthsArray){
arraySum += lengthsArray[i];
}
// set line weight and color properties from constructor arguments
lineWeight = weight;
lineColor = color;
// set the lineStyle according to specified properties - beyond weight and color, we use the defaults EXCEPT no line caps, as they interfere with the desired gaps
stroke.graphics.lineStyle(lineWeight,lineColor,lineAlpha,false,"none",CapsStyle.NONE);
// add fill and stroke shapes
addChild(fill);
addChild(stroke);
}
// basic moveTo method
public function moveTo(x:Number,y:Number):void{
stroke.graphics.moveTo(x,y); // move to specified x and y
fill.graphics.moveTo(x,y);
// keep track of x and y
curX = x;
curY = y;
// reset remainingDist and startIndex - if we are moving away from last line segment, the next one will start at the beginning of the dash-gap sequence
remainingDist = 0;
startIndex = 0;
}
// lineTo method
public function lineTo(x:Number,y:Number):void{
var slope:Number = (y - curY)/(x - curX); // get slope of segment to be drawn
// record beginning x and y
var startX:Number = curX;
var startY:Number = curY;
// positive or negative direction for each x and y?
var xDir:int = (x < startX) ? -1 : 1;
var yDir:int = (y < startY) ? -1 : 1;
// keep drawing dashes and gaps as long as either the current x or y is not beyond the destination x or y
outerLoop : while (Math.abs(startX-curX) < Math.abs(startX-x) || Math.abs(startY-curY) < Math.abs(startY-y)){
// loop through the array to draw the appropriate dash or gap, beginning with startIndex (either 0 or determined by the end of the last lineTo)
for (var i:int = startIndex; i < lengthsArray.length; i++){
var dist:Number = (remainingDist == 0) ? lengthsArray[i] : remainingDist; // distance to draw is either the dash/gap length from the array or remainingDist left over from the last lineTo if there is any
// get increments of x and y based on distance, slope, and direction - see getCoords()
var xInc:Number = getCoords(dist,slope).x * xDir;
var yInc:Number = getCoords(dist,slope).y * yDir;
// if the length of the dash or gap will not go beyond the destination x or y of the lineTo, draw the dash or gap
if (Math.abs(startX-curX) + Math.abs(xInc) < Math.abs(startX-x) || Math.abs(startY-curY) + Math.abs(yInc) < Math.abs(startY-y)){
if (i % 2 == 0){ // if even index in the array, it is a dash, hence lineTo
stroke.graphics.lineTo(curX + xInc,curY + yInc);
} else { // if odd, it's a gap, so moveTo
stroke.graphics.moveTo(curX + xInc,curY + yInc);
}
// keep track of the new x and y
curX += xInc;
curY += yInc;
curIndex = i; // store the current dash or gap (array index)
// reset startIndex and remainingDist, as these will only be non-zero for the first loop (through the array) of the lineTo
startIndex = 0;
remainingDist = 0;
} else { // if the dash or gap can't fit, break out of the loop
remainingDist = getDistance(curX,curY,x,y); // get the distance between the end of the last dash or gap and the destination x/y
curIndex = i; // store the current index
break outerLoop; // break out of the while loop
}
}
}
startIndex = curIndex; // for next time, the start index is the last index used in the loop
if (remainingDist != 0){ // if there is a remaining distance, line or move from current x/y to the destination x/y
if (curIndex % 2 == 0){ // even = dash
stroke.graphics.lineTo(x,y);
} else { // odd = gap
stroke.graphics.moveTo(x,y);
}
remainingDist = lengthsArray[curIndex] - remainingDist; // remaining distance (which will be used at the beginning of the next lineTo) is now however much is left in the current dash or gap after that final lineTo/moveTo above
} else { // if there is no remaining distance (i.e. the final dash or gap fits perfectly), we're done with the current dash or gap, so increment the start index for next time
if (startIndex == lengthsArray.length - 1){ // go to the beginning of the array if we're at the end
startIndex = 0;
} else {
startIndex++;
}
}
// at last, the current x and y are the destination x and y
curX = x;
curY = y;
fill.graphics.lineTo(x,y); // simple lineTo (invisible line) on the fill shape so that the fill (if one was started via beginFill below) follows along with the dashed line
}
// returns a point with the vertical and horizontal components of a diagonal given the distance and slope
private function getCoords(distance:Number,slope:Number):Point {
var angle:Number = Math.atan(slope); // get the angle from the slope
var vertical:Number = Math.abs(Math.sin(angle)*distance); // vertical from sine of angle and length of hypotenuse - using absolute value here and applying negative as needed in lineTo, because this number doesn't always turn out to be negative or positive exactly when I want it to (haven't thought through the math enough yet to figure out why)
var horizontal:Number = Math.abs(Math.cos(angle)*distance); // horizontal from cosine
return new Point(horizontal,vertical); // return the point
}
// basic Euclidean distance
private function getDistance(startX:Number,startY:Number,endX:Number,endY:Number):Number{
var distance:Number = Math.sqrt(Math.pow((endX-startX),2) + Math.pow((endY-startY),2));
return distance;
}
// clear everything and reset the lineStyle
public function clear():void{
stroke.graphics.clear();
stroke.graphics.lineStyle(lineWeight,lineColor,lineAlpha,false,"none",CapsStyle.NONE);
fill.graphics.clear();
moveTo(0,0);
}
// set lineStyle with specified weight, color, and alpha
public function lineStyle(w:Number=0,c:Number=0,a:Number=1):void{
lineWeight = w;
lineColor = c;
lineAlpha = a;
stroke.graphics.lineStyle(lineWeight,lineColor,lineAlpha,false,"none",CapsStyle.NONE);
}
// basic beginFill
public function beginFill(c:uint,a:Number=1):void{
fill.graphics.beginFill(c,a);
}
// basic endFill
public function endFill():void{
fill.graphics.endFill();
}
}
}
Thanks For Your Replies, I Wrote My Own Class Which Draws Rectangles To Create A Dashed Lines.
Thanks..

How to have an object hover back and forth constrained within a specific radius?

I have a sprite in a movie symbol that I would like to hover back and forth within a 360 radius. I was hoping to make it smooth and random. Never really venturing from its original xy cordinates.
I've tried to create some stipulations with if statements and a starting momentum. Like this:
var num = 2;
stage.addEventListener(Event.ENTER_FRAME, hover);
function hover(evt:Event):void{
//start it moving
cloudWhite.y += num;
cloudWhite.x += num;
//declare these variables
var cX = cloudWhite.x;
var cY = cloudWhite.y;
// object travels 10 pixels
var cXP = cX + 10;
var cXN = cX - 10;
var cYP = cY + 10;
var cYN = cY - 10;
// if object goes 10 pixels reverse direction of momentum (maybe)
if (cX >= cXP) {
num = -2;
}
if (cX <= cXN){
num = 2;
}
if (cY >= cYP) {
num = 2;
}
if (cY <= cYN){
num = 2;
}
Clearly this is super wrong because when it runs the object just either goes to 0,0 or to some place that only the math gods know of.
I am clearly a noob at this kind of math so i apologize but I am very excited to learn the trig behind this.
Thank you for your help and thank you for reading.
You are setting all your variables inside the ENTER_FRAME loop, so none of your conditions ever evaluates to true. On every single frame you are doing this:
cloudWhite.x += 2;
cX = cloudWhite.x;
cXP = cX + 10; // Must == cloudWhite's previous x + 10 + 2;
cXN = cX - 10; // Must == cloudWite's previous x -10 + 2;
if(cX > cXP)... // Can never be true.
if(cX < cXN)... // Can never be true.
What you need to do is:
1) Store the original position of cloudWhite somewhere outside the loop, and store it before the loop begins.
2) Define your bounds relative to the original position of cloudWhite, again before your loop begins. Also define the amount you are going to change the position with each iteration.
3) Start your loop.
4) Increment the current position of cloudWhite on each iteration. Add a little random in here if you want the shape to move in a random manner.
5) Check if the new position of cW is outside your bounds and adjust the direction if it is.
The sample below is crude and jerky but I don't know exactly what effect you're looking for. If you want smoother, longer movements in each direction, consider using the Tween class or a Tween library such as the popular Greensock one, instead of incrementing / decrementing the position manually. There's a useful discussion of this here: http://www.actionscript.org/forums/archive/index.php3/t-163836.html
import flash.display.MovieClip;
import flash.events.Event;
// Set up your variables
var original_x:Number = 100; // Original x
var original_y:Number = 100; // Original y
var x_inc:Number = 5; // X Movement
var y_inc:Number = 5; // Y Movenent
var bounds:Number = 50; // Distance from origin allowed
// Doesn't take into account width of object so is distance to nearest point.
// Create an MC to show the bounds:
var display:MovieClip = addChild(new MovieClip()) as MovieClip;
display.graphics.lineStyle(1, 0x0000FF);
display.graphics.beginFill(0x0000FF, 0.5);
display.graphics.drawRect(0-bounds, 0-bounds, bounds * 2, bounds *2);
display.x = original_x;
display.y = original_y;
addChild(display);
// Create our moving mc:
var mc:MovieClip = addChild(new MovieClip()) as MovieClip;
mc.graphics.beginFill(0xFF0000, 1);
mc.graphics.drawCircle(-10, -10, 20);
// Position it:
mc.x = original_x;
mc.y = original_y;
addChild(mc);
// Loop:
function iterate($e:Event = null):void
{
// Move the mc by a random amount related to x/y inc
mc.x += (Math.random() * (2 * x_inc))/2;
mc.y += (Math.random() * (2 * y_inc))/2;
// If the distance from the origin is greater than bounds:
if((Math.abs(mc.x - original_x)) > bounds)
{
// Reverse the direction of travel:
x_inc == 5 ? x_inc = -5 : x_inc = 5;
}
// Ditto on the y axis:
if((Math.abs(mc.y - original_y)) > bounds)
{
y_inc == 5 ? y_inc = -5 : y_inc = 5;
}
}
// Start the loop:
addEventListener(Event.ENTER_FRAME, iterate);
This should get you started. I'm sure there are any number of other ways to do this with formal trig, but this has the benefit of being very simple, and just an extension of your existing method.

How to re-position the children of a MovieClip?

I am having a container mc with 5 children mcs.
children names mc0,mc1....mc4.
cont.getChildByName("mc"+Number(cont.numChildren-1)).x =
cont.getChildByName("mc0").x - 20 *1.2;
after this re-position process.. I want to set the last item position as 0 and so on. How can I do this?
My target is to attain a circular movement.
like
[mc0][mc1][mc2]
[mc2][mc0][mc1]
[mc1][mc2][mc0]
[mc0][mc1][mc2]
//Of course, you don't necessarily have to create absolute positions,
//this is a simple example...
var positions:Array = [{x:0,y:0} , {x:20, y:20} etc....];
var children:Array = [mc0 , mc1 ... mcN];
//Provided that positions & children have the same length
private function rotate():void
{
//remove the last element of the Array
var lastChild:MovieClip = children.pop();
//Add it to the beginning of the Array
children.unshift(lastChild );
//Assign new positions
//Here you could tween for smoother effect
for( var i:int ; i < positions.length ; ++i )
{
children[i].x = positions[i].x;
children[i].y = positions[i].y;
}
}
Let's introduce an offset variable simulating the rotation's progression:
var offset:uint = 0;
Now we must define each clip's position depending on this variable. I will introduce a gap constant for the distance between two items.
const GAP:uint = 20;
for (var iMc:int=0; iMc < cont.numChildren; iMc++)
{
mc = cont.getChildByName("mc" + iMc.toString()) as Sprite;
mc.x = GAP * ((iMc + offset) % cont.numChildren);
}
The % operator (modulo) allows you to get a number between 0 and the second operand-1

Dual fire and positioning problems

I'm working on a space shooter and have this problem:
My space ship fires bullets. The bullets are centered in reference to the ship. Currently all bullets are single shots.
Now what I'd like to have is dual fire for the ship. Basically that means I have to double the shots and place them at the left and right
side of the ship, right? But I don't know how to do it exactly.
The other problem I have is that when I change the x and y-coordinates of the bullet in order to move the bullets from the center of the ship to the left (or right) and rotate the ship and fire I get a strange behavior of the bullets. In this case they move from the left to the center and vice versa referring to the ship (while rotating and firing).
Please - has anyone any idea where the problems might be and how to do it? I appreciate very much any help. TIA!:)
private function autoShoot(step:Number):void {
projectileManager.projectilePoolCount = projectileManager.projectilePool.length - 1;
asteroidManager.asteroidCount = asteroidManager.asteroids.length;
if (projectileManager.lastProjectileShot > projectileOffset && projectileManager.projectilePoolCount > 0 &&
playerStarted && asteroidManager.asteroidCount > 0 && projNumber < projectileNumber)
{
dispatchEvent(new CustomEventSound(CustomEventSound.PLAY_SOUND, Main.SOUND_PLAYER_SHOOT,
false, 0, 8, 1));
tempProjectile = projectileManager.projectilePool.pop();
tempProjectile.projectileDelayCount = 0;
var projectileRadians:Number = (player.frame / 360) * 6.28;
projShots++;
projNumber++;
if (projNumber >= projectileNumber)
{
player.startDelay = true;
}
tempProjectile.x = (player.point.x) + Math.cos(projectileRadians);
tempProjectile.y = (player.point.y) + Math.sin(projectileRadians);
tempProjectile.x = player.x + 13;
tempProjectile.y = player.y + 13;
tempProjectile.nextX = tempProjectile.x;
tempProjectile.nextY = tempProjectile.y;
tempProjectile.dx = rotationVectorList[player.frame].x;
tempProjectile.dy = rotationVectorList[player.frame].y;
tempProjectile.speed = projectileSpeed;
tempProjectile.frame = 0;
tempProjectile.bitmapData = tempProjectile.animationList[0];
tempProjectile.projectileDelay = 10;
projectileManager.projectiles.push(tempProjectile);
projectileManager.lastProjectileShot = 0;
} else {
projectileManager.lastProjectileShot += step;
}
}
The autoShoot function only fires one projectile each time it is called. There is only one tempProjectile per call to push to the projectiles list.
So one fix can be to add a tempProjectile2 (in the same place tempProjectile is defined) as a variable that can be used. Now in each call the projectile pool gets depleted by two, as long an adequate number of projectiles are popped
tempProjectile = projectileManager.projectilePool.pop();
tempProjectile2 = projectileManager.projectilePool.pop();
then adjust the offset accordingly
tempProjectile.x
tempProjectile.y
tempProjectile2.x
tempProjectile2.y
And so on with the rest of the code. The only thing I am unclear about is why tempProjectile.x and y are assigned twice.
tempProjectile.x = (player.point.x) + Math.cos(projectileRadians);
tempProjectile.y = (player.point.y) + Math.sin(projectileRadians);
tempProjectile.x = player.x + 13;
tempProjectile.y = player.y + 13;
only the second pair will be used, I think.
Hopefully the rest of the functions should not change because at the end the projectiles are pushed to the projectiles list
projectileManager.projectiles.push(tempProjectile);
projectileManager.projectiles.push(tempProjectile2);
So the whatever function used to update and render should remain the same, assuming tempProjectile is not tied down elsewhere in the program.