Hey everyone so I have been at this for awhile now and I'm trying to figure out the best way to go about this. So I have an array of Movie Clip Objects calledouterPlanets and they are added to an array called aPlanetArray so these planets in the array are added to the stage and have spacing between them all. When the Player touches the screen the character jumps on another planet and the planets scroll down on the +y axis to keep the character positioned to the center.
I add 10 planets to the stage because for performance Issues I don't want to add a lot and lose FPS so my idea was when the array is getting low such as the planet array is <= 5 then add more planets to the top position of the last last planet. Hope I am making sense. Think of it like a stack of blocks the blocks fall down one by one and more is added to the top of them as more fall down so its never ending.
Here is how I add them to the stage:
//Instantiate Arrays
aPlanetArray = new Array();
//Numbers
xSpacing = 100;
ySpacing = 200;
startPoint = new Point((stage.stageWidth / 2), (stage.stageHeight / 2) );
addOuterPlanets();
private function addOuterPlanets():void
{
for (var i:int = 0; i < nPlanets; i++)
{
outerPlanets = new mcOuterPlanets();
outerPlanets.x = startPoint.x + (xSpacing * i);
outerPlanets.y = startPoint.y - (ySpacing * i);
stage.addChild(outerPlanets);
aPlanetArray.push(outerPlanets);
}
}
The only thing I can come up with at the moment is this:
if (aPlanetArray.length <= 5)
{
addOuterPlanets();
}
This adds a new set of planets but of course just adds them to the center of the stage and not on top of the other planets. Any idea how to accomplish this?
Current Progress:
private function collisionPlanetHandler():void
{
for (var i:int = 0; i < aPlanetArray.length; i++)
{
var currentPlanet:mcOuterPlanets = aPlanetArray[i];
planetContainer.addChild(aPlanetArray[i]);
if (character.hitTestObject(currentPlanet) && !nextlevel)
{
trace("HIT");
yDown = (stage.stageHeight / 2) - (currentPlanet.y - 200); //have object tween to center of stage or where was last positioned
//tap back to false
tap = false;
nextlevel = true;
if (!bNullObject) // have null object so doesnt loop again and cause error for planet == null
{
planet.destroy();
planet = null;
}
bNullObject = true;
planetHit = currentPlanet; // to land on correct planet
aPlanetArray.splice(i, 1);
randomRotation = randomNumber(1, 2); //Stop in random rotation for next planet
TweenLite.to(planetContainer, 2.0, { y:yDown, ease:Elastic.easeOut } );
planetIncrement -= 300;
addPlanet(randomNumber((stage.stageWidth/2) - 220, ((stage.stageWidth/2)) + 220), planetIncrement);
}
}
}
example code
function gameSetup():void{
setupUsers();
loadSounds();
createLevel(_level1);
addInitialPlanets();
addCharacter();
}
private function addInitialPlanets():void{
for (var i:int = 0; i < nPlanets; i++){
addPlanet(startPoint.x + xSpacing * i, startPoint.y + ySpacing * i);
}
}
private function addPlanet(xPos:Number, yPos:Number):void{
p = new mcOuterPlanets();
// var p:mcOuterPlanets = new mcOuterPlanets(); // this is preferred method
p.x = xPos;
p.y = yPos;
stage.addChild(p);
// addChild(p); // this is preferred method
aPlanetArray.push(p);
}
Now when you need to add another planet above the others do
addPlanet(xPos, yPos);
// where xPos is desired X and yPos is desired y
You see what is happening here? I'm positioning the planet by using a separate function. You can offload other tasks related to add a planet as well. Imagine something like this:
addPlanet(xPos, yPos, color, size, speed, ringCount);
Get the idea?
Also you'll want to remove the planets that are far below the player to prevent slowdown. Or you could simply move the ones far below up to the top to recycle them instead of creating new planets all the time.
Draft example...
#Nathan , Neal Davis is right as usual, but I'd push the Vector, then addChild at its current index... Avoid the Arrays if You can. (if the instances are made by the same Class).
var aPlanetArray:<Vector>.MovieClip = new <Vector>.MovieClip(10);
// or new <Vector>.MovieClip(); if You don't want to restrict the amount of items in the Vector.
// or new <Vector>.McOuterPlanets() if McOuterPlanets is a Class.
private function addOuterPlanets():void {
for (var i:int = 0; i < nPlanets; i++){
aPlanetArray.push(new mcOuterPlanets());
aPlanetArray[i].x = startPoint.x + (xSpacing * i);
aPlanetArray[i].y = startPoint.y - (ySpacing * i);
addChild(aPlanetArray[i]);
};
[EDIT]
If you choose to make a Vector of MovieClip (var aPlanetArray:<Vector>.MovieClip = new <Vector>.MovieClip(10)),
You must use aPlanetArray[i] as McOuterPlanets to get the methods of
Your McOuterPlanets methods!
So, in the case of a Vector of MovieClip (aPlanetArray == .MovieClip), if You want to use the methods of McOuterPlanets methods You have to do :
var outerP : McOuterPlanets = aPlanetArray[someIndex] as McOuterPlanets;.
Then You may call outerP.someMethodOfMcOuterPlanets();
Just because McOuterPlanets extends the MovieClip Class.
Never use Vectors if You have to add different types of datas in Your Vector, use the Array Class instead.
This will works but this is tricky an total nonsense!
Example :
var vectorOfStrings:Vector.<String> = Vector.<String>([["a","b","c"],["d","e","f"]]);
// this works and Your Vector contains only Strings so OK.
trace("");
trace("length of the Vector = " + vectorOfStrings.length);
trace("vectorOfStrings.toString() = " + vectorOfStrings.toString());
trace("vectorOfStrings[0] = " + vectorOfStrings[0]);
trace("vectorOfStrings[1] = " + vectorOfStrings[1]);
var vectorOfArrays:Vector.<Array> = Vector.<Array>([["a","b","c"],[1,2,3]]);
// this works but this is tricky an total nonsense
// use the Array Class instead!
trace("\n NEVER DO THIS! Use the Array Class instead!");
trace(" NONSENSE!");
trace("length of the Vector = " + vectorOfArrays.length);
trace("vectorOfArrays.toString() = " + vectorOfArrays.toString());
trace("vectorOfArrays[0] = " + vectorOfArrays[0]);
trace("vectorOfArrays[1] = " + vectorOfArrays[1]);
[/EDIT]
I hope this may help.
Check to the reference for :
ActionScript 3 fundamentals: Arrays
ActionScript 3 fundamentals: Associative arrays, maps, and dictionaries
ActionScript 3 fundamentals: Vectors and ByteArrays
Related
The intention of the following ActionScript script is to allow a player to move by clicking a button, wherein myarray represents places they are allowed to move to.
I'm having trouble making my click event handler work properly. For example, how can I extract the (x, y) coordinates of the click from the MouseEvent event in order to perform further processing?
a.addEventListener(MouseEvent.CLICK, bergerak);
b.addEventListener(MouseEvent.CLICK, bergerak);
c.addEventListener(MouseEvent.CLICK, bergerak);
d.addEventListener(MouseEvent.CLICK, bergerak);
function bergerak (Event:MouseEvent) {
var namatombol:String = Event.currentTarget.name;
var myarray:Array = [];
for (var i:int = 0; i < 3; i++) {
myarray[i] = this["kotak" + i];
if (namatombol == "a") {
MovieClip(root).pemain.x = MovieClip(root).myarray[i].x;
MovieClip(root).pemain.y = MovieClip(root).myarray[i].y;
}
}
}
I understood that you're willing to move a player display object (like a MovieClip) to the clicked button position on stage. In this case, your function will be as follows:
function bergerak(event:MouseEvent):void
{
MovieClip(root).pemain.x = event.target.x;
MovieClip(root).pemain.y = event.target.y;
}
Hey everyone so in my game I am creating I add all my interactive objects to the stage by simply dragging from the library and placing them on the stage. Then in Flash Develop in my Engine Class I place them inside an array like so:
private var aZebraArray:Array;
In my constructor I add the elements on the stage through their instance names I gave them Like so:
aZebraArray = [startScreen.zebra_Front, startScreen.zebra_Middle, startScreen.zebra_Back, startScreen.zebra_Far];
Then in my Enter_Frame Listener I loop through the objects on stage like so for the Hit Test:
private function Round_1Controls():void
{
trace(aZebraArray.length);
for (var i:int = 0; i < aZebraArray.length; i++)
{
var currentZebra = aZebraArray[i];
if (crosshair.bullet.hitTestObject(currentZebra) && shotGun)
{
trace("HIT");
aZebraArray.splice(i, 1);
currentZebra.gotoAndPlay("DIE");
shotGun = false;
//Add points
nPoints += 50;
updatePointsText();
//Animals hit for stars
animalsHit ++;
}
}
Now in my game if the player doesn't get 3 stars he is able to Retry and restart that round over. The PROBLEM That I have run into is that I don't quite know how I would go about having the objects that are on stage placed back where they first started from because when the round starts the "Zebras" run across the stage through a custom tween I made in each of them. Also I believe I could just create a new array like so:
aZebraArray = new Array();
aZebraArray = [startScreen.zebra_Front, startScreen.zebra_Middle, startScreen.zebra_Back, startScreen.zebra_Far];
but then how could i restart all their animations so they can run across the stage again? I know I can just create their own class and add them in array then control them through a timer object but I add them manually on stage because their are a lot of bushes that they need to hide behind or be in front of and to code that would be exhausting. If anyone can help I would Appreciate it thanks!
Here is what I have in my retry Function but it is only adding 1 or 2 of the objects in the array back to the stage.
private function replayRound_1(e:MouseEvent):void
{
continueScreen.mcRetry.removeEventListener(MouseEvent.CLICK, replayRound_1);
continueScreen.destroyContinueScreen();
round1 = true;
nAmmo = 0;
nAmmo += 5;
updateAmmoText();
animalsHit = 0;
hasAmmo = true;
gameChannel = gameSound.play(0, 999);
//aZebraArray = [];
aZebraArray = new Array();
aZebraArray = [startScreen.zebra_Front, startScreen.zebra_Middle, startScreen.zebra_Back, startScreen.zebra_Far];
for (var i:int = 0; i < aZebraArray.length; i++)
{
var currentZebra = aZebraArray[i];
currentZebra.gotoAndStop("RUN");
}
}
Hey everyone so I am having some trouble displaying the player Vector lives in a Array added to the stage. When I first start my game the lives are added correctly and when an enemy hits the player they are removed correctly but when I added a store where you can purchase an extra life I am getting a bug to where the vector lives are added to the stage but they dont remove when an enemy hits the player and they just are there.
in the constructor I have nLives = 2;
addPlayerLivesToStage();
Here is the addPlayerLivesToStage(); function as well as the removePlayerLives();
private function addPlayerLivesToStage():void
{
var startPoint:Point = new Point((stage.stageWidth / 2) + 240, (stage.stageHeight / 2) - 180);
var xSpacing:Number = 30;
lives = new Vector.<Sprite>();
for (var i:int = 0; i < nLives; i++)
{
var playerLives:mcPlayerLives = new mcPlayerLives();
playerLives.x = startPoint.x + (xSpacing * i);
playerLives.y = startPoint.y;
addChild(playerLives);
lives.push(playerLives);
//aPlayerLivesArray.push(playerLives);
}
}
private function removePlayerLive():void
{
//Remove live from screen
removeChild(lives[lives.length - 1]);
lives[lives.length - 1] = null;
lives.splice(lives.length - 1, 1);
}
Now in my games ENTER.FRAME Loop I have the function purchaseExtraLifeFunc(); that controls the Purchase and is supposed to add 1 life to the stage.
Like So:
private function purchaseExtraLifeFunc():void
{
if (nCoins >= 5 && purchaseItem)
{
trace("purchase life");
//remove coins from cost of purchase
nCoins -= 5;
updatecoinsTextScore();
//add extra life
nLives += 1;
addPlayerLivesToStage();
}
else
{
purchaseItem = false;
}
}
as you can say I add 1 Live and call the addPlayerLivesToStage function.
THis is not working correctly and I'm all out of ideas if anyone could help me with this I would really aprreciate it
I can see a few logic problems that could be the cause.
It looks like your addPlayerLivesToStage method ignores the fact that it could have been called before, and there could already be lives Sprites added to the stage. You then overwrite the lives Vector with a new Vector. So you don't have access to the previously added Sprites anymore.
I bet if you made the lives Sprites slightly transparent, you would see them stack over each other as you purchase more lives. Or to test, you could store a number that you increment every time you add a lives Sprite in your loop. And set the Y of the new sprite to this number. That way you would see all the Sprites you are adding.
To fix this, you want to remove all the lives Sprites at the beginning of your addPlayerLivesToStage function, because you are recreating them later in that function anyway.
EDIT*
The problem is still that the Sprites are not being cleaned up between addPlayerLivesToStage calls.
It is easier if you first use a container Spirte to hold all you life sprites. So add a private property to your class:
private var livesContainer:Sprite;
Then in you constructor, just set it up:
livesContainer = new Sprite();
livesContainer.x = (stage.stageWidth / 2) + 240;
livesContainer.y = (stage.stageHeight / 2) - 180;
addChild(livesContainer);
The you can just add all the lives into this container.
I modified your addPlayerLivesToStage function to remove any left over life sprites at the end, and cleaned up the adding, so it does not add a life that is already added.
private function addPlayerLivesToStage():void
{
var xSpacing:Number = 30;
// Add new life sprites if we need to.
for (var i:int = lives.length; i < nLives; i++)
{
var playerLives:mcPlayerLives = new mcPlayerLives();
playerLives.x = xSpacing * i;
livesContainer.addChild(playerLives);
lives.push(playerLives);
}
// Remove any life Sprites that are left over from last time.
for (var j:int = lives.length - 1; j > nLives; j--)
{
var life:Sprite = lives[j]
livesContainer.removeChild(life);
lives.splice(j, 1);
}
}
I import a model using the Helix3d toolkit. Next, I perform a hit-test on the 3Dmodel. ThenI get the MeshGeometry3D information from rayMeshResult.Meshit. Finally I get the vertex position information, and triangleIndices from the MeshGeometry3D. Now I clone the points from LinesVisual3D, and then I feed the triangleIndices/vertex info into the clone. Finally, I copy the clone's point data into LinesVisual3D.Points, and add the lines to my viewport.
As you can see from the picture at the link, not all of the edges of the cube are drawn, yet all of the points are there.
http://www.freeimagehosting.net/fhws5
GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;
MeshGeometry3D newGeom = rayMeshResult.MeshHit as MeshGeometry3D;
Point3DCollection srtpnt = modelLines.Points.Clone();
for (int i = 0; i < newGeom.TriangleIndices.Count; i ++)
{
srtpnt.Add(newGeom.Positions[newGeom.TriangleIndices[i]]);
textBlock4.Text += newGeom.Positions[newGeom.TriangleIndices[i]].ToString() + "\n";
}
modelLines.Points = srtpnt;
modelPoints.Points = srtpnt;
modelPoints.Color = Colors.Red;
modelPoints.Size = 15;
modelLines.Thickness = 6;
modelLines.Color = Colors.Blue;
MainViewport.ClearChildren();
MainViewport.Children.Add(modelLines);
MainViewport.Children.Add(modelPoints);
UpdateResultInfo(rayMeshResult);
I am using the OrbitTools library to develop a satellite tracking system using the Bing Maps Silverlight control similar to http://karhukoti.com.
I am not knowledgeable in this domain and lack a lot of the information related to satellite tracking but have started teaching myself as this particular project was chosen by my supervisor as a graduation project.
However, i faced numerous difficulties, a major one is how to convert Two Line Elements (TLE) information to longitude latitude and altitude to display the satellite and satellite path on the map.
I tried the following C# code:
protected void DisplaySatellitePath(List<Eci> Pos)
{
MapLayer myRouteLayer = new MapLayer();
myMap.Children.Add(myRouteLayer);
foreach (Eci e in Pos)
{
CoordGeo coordinates = e.toGeo();
Ellipse point = new Ellipse();
point.Width = 10;
point.Height = 10;
point.Fill = new SolidColorBrush(Colors.Orange);
point.Opacity = 0.65;
//Location location = new Location(e.Position.X, e.Position.X);
Location location = new Location(coordinates.Latitude, coordinates.Longitude);
MapLayer.SetPosition(point, location);
MapLayer.SetPositionOrigin(point, PositionOrigin.Center);
myRouteLayer.Children.Add(point);
}
}
and also tried
protected void DisplaySatellitePathSecondGo(List<Eci> Pos)
{
MapLayer myRouteLayer = new MapLayer();
myMap.Children.Add(myRouteLayer);
foreach (Eci e in Pos)
{
Ellipse point = new Ellipse();
point.Width = 10;
point.Height = 10;
point.Fill = new SolidColorBrush(Colors.Yellow);
point.Opacity = 0.65;
Site siteEquator = new Site(e.Position.X, e.Position.Y, e.Position.Z);
Location location = new Location(siteEquator.Latitude, siteEquator.Longitude);
MapLayer.SetPosition(point, location);
MapLayer.SetPositionOrigin(point, PositionOrigin.Center);
myRouteLayer.Children.Add(point);
}
}
Can you please tell me what i'm doing wrong here? I searched the net for examples or documention about OrbitTools but with no luck.
I really hope that someone using this library could help me or suggest a better .NET library.
Thank you very much.
Is this still something you are struggling with? I noticed when I pulled down the code that they have a demo that they provide along with the library. In it they show the following method which I'm sure you must have looked at:
static void PrintPosVel(Tle tle)
{
Orbit orbit = new Orbit(tle);
ArrayList Pos = new ArrayList();
// Calculate position, velocity
// mpe = "minutes past epoch"
for (int mpe = 0; mpe <= (360 * 4); mpe += 360)
{
// Get the position of the satellite at time "mpe".
// The coordinates are placed into the variable "eci".
Eci eci = orbit.getPosition(mpe);
// Push the coordinates object onto the end of the array
Pos.Add(eci);
}
// Print TLE data
Console.Write("{0}\n", tle.Name);
Console.Write("{0}\n", tle.Line1);
Console.Write("{0}\n", tle.Line2);
// Header
Console.Write("\n TSINCE X Y Z\n\n");
// Iterate over each of the ECI position objects pushed onto the
// position vector, above, printing the ECI position information
// as we go.
for (int i = 0; i < Pos.Count; i++)
{
Eci e = Pos[i] as Eci;
Console.Write("{0,4}.00 {1,16:f8} {2,16:f8} {3,16:f8}\n",
i * 360,
e.Position.X,
e.Position.Y,
e.Position.Z);
}
Console.Write("\n XDOT YDOT ZDOT\n\n");
// Iterate over each of the ECI position objects in the position
// vector again, but this time print the velocity information.
for (int i = 0; i < Pos.Count; i++)
{
Eci e = Pos[i] as Eci;
Console.Write("{0,24:f8} {1,16:f8} {2,16:f8}\n",
e.Velocity.X,
e.Velocity.Y,
e.Velocity.Z);
}
}
In this it seems that they are making the conversion that you are looking for. Am I missing something as to what the problem is that you are actually having?