AS3: FPS get down - actionscript-3

Ahoy. When i want update information with ENTER_FRAME like this:
import flash.events.Event;
var ticks:uint = 0;
var last:uint = getTimer();
var food:uint = 10;
var wood:uint = 10;
var stone:uint = 10;
stage.addEventListener(Event.ENTER_FRAME, update); // getFPS
stage.addEventListener(Event.ENTER_FRAME, list); //get Materials Info
function update(e:Event){
ticks++;
var now:uint = getTimer();
var delta:uint = now - last;
if (delta >= 1000) {
var fps:int = ticks / delta * 1000;
fpsText.text = String(fps+"fps");
ticks = 0;
last = now;
}
}//
function list(e:Event){
foodText.text = String(food+"food");
woodText.text = String(wood+"wood");
stoneText.text = String(stone+"stone");
}//
fps drop down.
When i change code like this:
import flash.events.Event;
var ticks:uint = 0;
var last:uint = getTimer();
var food:uint = 10;
var wood:uint = 10;
var stone:uint = 10;
stage.addEventListener(Event.ENTER_FRAME, update); // getFPS
function update(e:Event){
ticks++;
var now:uint = getTimer();
var delta:uint = now - last;
if (delta >= 1000) {
var fps:int = ticks / delta * 1000;
fpsText.text = String(fps+"fps");
list();
ticks = 0;
last = now;
}
}//
function list(){
foodText.text = String(food+"food");
woodText.text = String(wood+"wood");
stoneText.text = String(stone+"stone");
}//
fps drop down after 15 minutes.
I know problem is in function list(), but how I list materials quick without slowing fps.
How i change this for clean run?
Thx for hlp.

I'm assuming there is more code somewhere else that will change the values of food, wood, and stone. No need to update the values on enterframe if they aren't changing. Perhaps you could update the UI only when you change the values? So remove list() from the enter frame and do something like this when you change the values?
function getWood(){
wood++;
list();
}
function useWood(){
wood--;
list();
}

Related

How to stop player from walking on walls

I'm building a test avatar chat... thingy in ActionScript3, but I've come across a problem, whenever I click the chatbar to say something, my avatar (which is currently a penguin) walks to it -- how can I prevent this from happening? In other words, how do I build a wall and keep the penguins out?
This is the code I'm using to make my penguin move.
stage.addEventListener(MouseEvent.CLICK, myClickReaction);
// speeds ALONG NYPOTENUSE
var v:Number = 7;
// vector of movement
var dir:int = 100;
// mouse click point
var clickPoint:Point = new Point();
// angle doesn't change metween clicks - so it can be global
var angle:Number;
function myClickReaction (e:MouseEvent):void {
clickPoint = new Point(mouseX, mouseY);
angle = Math.atan2(clickPoint.y - penguin.y, clickPoint.x - penguin.x);
dir = angle >= 0 ? -1 : 1;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onEnterFrame(e:Event):void {
var projectedX:Number = penguin.x + v * Math.cos(angle);
var projectedY:Number = penguin.y + v * Math.sin(angle);
var diff:Number = clickPoint.y - projectedY;
if (diff / Math.abs(diff) == dir) {
penguin.x = clickPoint.x;
penguin.y = clickPoint.y;
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
else {
penguin.x = projectedX;
penguin.y = projectedY;
}
}

NaN from speed test

I'm trying to test the time it takes to calculate and create a certain matrix. The code being used is below.
import flash.geom.Matrix;
import flash.utils.getTimer;
var iter:int = 0;
var titer:int = 10000;
var time:Number;
var ttime:Number;
var zm:Number = 1.5;
var sx:Number = 0, sy:Number = 0.5;
var rot:Number = Math.PI/6;
var tx:Number = 10, ty:Number = 0;
var w:Number = 50, h:Number = 50;
var cr:Number = Math.cos(rot), sr:Number = Math.sin(rot);
var m3:Matrix, mt:Matrix;
for(iter; iter<titer; iter++) {
time = getTimer();
m3 = new Matrix(cr*(sx+zm), -sr*(sx+zm), sr*(sy+zm), cr*(sy+zm), tx+w-cr*w*(sx+zm)-sr*h*(sy+zm), ty+h+sr*w*(sx+zm)-cr*h*(sy+zm));
ttime += getTimer() - time;
}
trace('total:', ttime, 'avg:', Number(ttime)/Number(titer));
I'm SURE I set this up properly, but the trace is returning 'NaN'. What could cause this?
It will be very short and simple response: var ttime: Number = 0; ;) It's a good programming practice to initialise variables.
Also, I don't understand your construction for for performance testing. What do you think about such construction?
var time:uint = getTimer();
//your 'for' with Matrix
time = getTimer() - time;
//trace results...

error while converting AS2 starfield code to AS3

I've tried to convert a nice AS2 script for starfirld effect to AS3 But i'm still getting strange errors
would really appreciate if any one could help me understand what am i doing wrong
here is the original AS2 code:
var stars = 100;
var maxSpeed = 16;
var minSpeed = 2;
var i = 0;
while (i < stars)
{
var mc = this.attachMovie("star", "star" + i, i);
mc._x = random(Stage.width);
mc._y = random(Stage.height);
mc.speed = random(maxSpeed - minSpeed) + minSpeed;
var size = random(2) + 6.000000E-001 * random(4);
mc._width = size;
mc._height = size;
++i;
} // end while
this.onEnterFrame = function ()
{
for (var _loc3 = 0; _loc3 < stars; ++_loc3)
{
var _loc2 = this["star" + _loc3];
if (_loc2._y > 0)
{
_loc2._y = _loc2._y - _loc2.speed;
continue;
} // end if
_loc2._y = Stage.height;
_loc2.speed = random(maxSpeed - minSpeed) + minSpeed;
_loc2._x = random(Stage.width);
} // end of for
};
and here is my AS3 version:
import flash.events.Event;
import flash.events.MouseEvent;
function starField():void
{
var stars:int = 100;
var maxSpeed:int = 16;
var minSpeed:int = 2;
var i:int = 0;
while (i < stars)
{
var mc = new Star();
addChild(mc)
mc._x = Math.random()(stage.stageWidth);
mc._y = Math.random()(stage.stageHeight);
mc.speed = Math.random()(maxSpeed - minSpeed) + minSpeed;
var size = Math.random()(2) + 6.000000E-001 * Math.random()(4);
mc._width = size;
mc._height = size;
++i;
} // end while
}
addEventListener(Event.ENTER_FRAME, update);
function update(_e:Event):void
{
for (var _loc3 = 0; _loc3 < 100; ++_loc3)
{
var _loc2 = this["star" + _loc3];
if (_loc2._y > 0)
{
_loc2._y = _loc2._y - _loc2.speed;
continue;
} // end if
_loc2._y = stage.stageHeight;
_loc2.speed = Math.random()(maxSpeed - minSpeed) + minSpeed;
_loc2._x = Math.random()(stage.stageWidth);
} // end of for
};
the error message I'm getting is: "TypeError: Error #1010: A term is undefined and has no properties. at _fla::MainTimeline/update()"
I understand it has a problem with the 'update' function but I'm net sure which term it refer to?
I'll bet a can of juice here is your problem:
var _loc2 = this["star" + _loc3];
put these into an associative array and access them from there.
#Discipol is right.
Just wanted to add a few more notes:
You can also use the display list to get the movie clip by name:
var _loc2:MovieClip = MovieClip(getChildByName("star" + _loc3));
You've got untyped variables and your are relying on MovieClip as a dynamic class to add properties (such as speed) at runtime. For a really simple project the impact is barely noticeable, but on the long run, for bigger projects, it's worth extending Sprite if you don't use the timeline and add the properties you need:
package {
import flash.display.Sprite;
import flash.events.Event;
public class Star extends Sprite {
private var speed:Number;
private var minSpeed:Number;
private var maxSpeed:Number;
public function Star(min:Number,max:Number) {
minSpeed = min;
maxSpeed = max;
var size = (Math.random()*2) + 1.82211880039 * (Math.random()*4);
width = size;
height = size;
this.addEventListener(Event.ADDED_TO_STAGE,reset);
}
private function reset(e:Event = null):void{
speed = (Math.random() * (maxSpeed-minSpeed)) + minSpeed;
x = Math.random() * stage.stageWidth;
if(e != null) y = Math.random() * stage.stageHeight;//initialized from added to stage event
else y = stage.stageHeight;//otherwise reset while updating
}
public function update():void{
if (y > 0) y -= speed;
else reset();
}
}
}
and the rest of the code would be as simple as:
var stars:int = 100;
var starClips:Vector.<Star> = new Vector.<Star>(stars,true);//a typed fixed vector is faster than a dynamically resizable untyped Array
for(var i:int = 0 ; i < stars; i++) starClips[i] = addChild(new Star(16,2)) as Star;
this.addEventListener(Event.ENTER_FRAME,updateStars);
function updateStars(e:Event):void{
for(var i:int = 0 ; i < stars; i++) starClips[i].update();
}

elastic string script makes flash crash

I'm in over my head in this AS3 project.
I'm no expert in actionscript and certainly not in AS3 but I managed to create (with help from this: http://swamy-techtalk.blogspot.com/2011/07/elastic-string-to-mouse-pointer-effect.html) a eleastic string effect from a point to a draggable movieclip.
Problem is the script seems to crash flash or the browser when I test it. (Not right away just when I'm playing around with the movieclip)
Sinse I'm in over my head in the script I compiled I'm not exactly sure whats wrong.
A bit of google research hinted that it might have something to do with removeChildAt() wich I changed from removeChildAt(0) to removeChildAt(1) to prevent it from removing my movieclip.
Hope somebody has the patience to read through my script to see what I did wrong.
Example here: http://www.madsringblom.dk/flash/pullstring.html (beware it might crash your browser)
Code below:
Object(this).leaf_mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
var origX:int = Object(this).leaf_mc.x + 1;
var origY:int = Object(this).leaf_mc.y + 2;
var pullbackX:int = Object(this).leaf_mc.x;
var pullbackY:int = Object(this).leaf_mc.y;
var dragging:Boolean = false;
//speed of pulling and rotating back when stop dragging.
var speed:int = 15;
var addX:int = 2
var addY:int = 3
function mouseDownHandler(e:MouseEvent):void
{
var obj = e.target;
obj.startDrag();
dragging = true;
}
function mouseUpHandler(e:MouseEvent):void
{
var obj = e.target;
Object(this).leaf_mc.stopDrag();
dragging = false;
}
import flash.display.*;
import flash.events.MouseEvent;
import flash.events.Event;
var haschild:Boolean = false;
var gotonodes:Array = new Array();
var currentnodes:Array = new Array();
var posX:int = Object(this).leaf_mc.x + addX;
var posY:int = Object(this).leaf_mc.y + addY;
gotonodes = Interpolate(posX,posY,origX,origY,25);
currentnodes = gotonodes;
stage.addEventListener(Event.ENTER_FRAME, onmove1);
function onmove1(e:Event)
{
for (var node = 0; node < gotonodes.length - 1; node++)
{
currentnodes[node].xco=currentnodes[node].xco+(gotonodes[node].xco-currentnodes[node].xco)/(node*node/30+1);
currentnodes[node].yco=currentnodes[node].yco+(gotonodes[node].yco-currentnodes[node].yco)/(node*node/30+1);
}
var posX:int = Object(this).leaf_mc.x + addX;
var posY:int = Object(this).leaf_mc.y + addY;
gotonodes=Interpolate(posX,posY,origX,origY,25);
// pull leaf_mc back to starting point when released. And rotate back.
if (dragging == false)
{
Object(this).leaf_mc.x-=(Object(this).leaf_mc.x-pullbackX)/speed;
Object(this).leaf_mc.y-=(Object(this).leaf_mc.y-pullbackY)/speed;
Object(this).leaf_mc.rotation+=Object(this).leaf_mc.rotation/speed;
}
// rotating the leaf_mc according to the point (origX,origY)
var theX:int = origX - Object(this).leaf_mc.x;
var theY:int = (origY - Object(this).leaf_mc.y) * -1;
var angle = Math.atan(theY/theX)/(Math.PI/180);
Math.atan( -5 / 10) / (Math.PI / 180);
if (theX < 0)
{
angle += 180;
}
if (theX >= 0 && theY < 0)
{
angle += 360;
}
Object(this).leaf_mc.rotation = (angle*-1) + 90;
DrawNodes(currentnodes);
}
function FindAngle(x1, x2, y1, y2):Number
{
return Math.atan2(y2-y1, x2-x1);
};
function Distance(x1, x2, y1, y2):Number
{
return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
}
function Interpolate(x1, y1, x2, y2, n):Array
{
var dist= Distance(x1,x2,y1,y2);
var ang = FindAngle(x1,x2,y1,y2);
var points = [];
for (var l = 0; l <= dist; l += dist / n)
{
var x3 =x1+l*Math.cos(ang);
var y3 = y1+l*Math.sin(ang);
points.push({xco:x3,yco:y3});
}
points.push( { xco:x1, yco:y1 } );
return points;
}
function DrawNodes(array):void
{
if(haschild)
{
this.removeChildAt(1);
haschild=false;
}
var shape:Shape = new Shape();
shape.graphics.lineStyle(1,0x331100,40);
shape.graphics.moveTo(array[0].xco, array[0].yco);
for (var i = 0; i < array.length - 1; i++)
{
shape.graphics.lineTo(array[i].xco,array[i].yco);
}
shape.graphics.beginFill(0xFBFFA4,1);
shape.graphics.drawCircle(array[0].xco,array[0].yco,1);
shape.graphics.endFill();
this.addChild(shape);
haschild = true;
}
Where is this code placed? From what you pasted, I'm thinking on the stage.
A stop(); somewhere in the script might be a start and help quite a bit - otherwise the Flash movie will loop, and every time it hits this frame (every frame if you only have one), you'll add new event handlers etc. Eventually you'll run out of memory, and the onmove1 event handler will eat up your CPU, running 50 times per frame after 50 frames, 200 times after 200 frames etc.

Intermittent/staggered loading of an object

I've just recently tried my hand at actionscript 3 and have come across a road block.
How do I go about rendering the cubes (cube1) intermittently, ie. staggered loading. I need the cubes to load a split second from each other.
Below is a snippet of what I have so far:
var rows:int = 5;
var cols:int = 3;
var spacery:int = 100;
var spacerx:int = 120;
var box_count:int = 8;
for(var i:int; i < box_count; i++) {
cube1 = new Cube(ml,100,10,80,1,1,1);
cube1.y = ((i % rows)) * (cube1.x + spacery);
cube1.x = Math.floor(i/rows) * (cube1.x +spacerx);
cube1.z = 0;
bigBox.addChild(cube1);
}
//Create an array out side the function; as a global (instance) variable:
var cubes:Array = [];
//instead of bigBox.addChild(cube1), store them in the array:
cubes.push(cube1);
//initialize a timer outside after for loop
//Fire every 100 milliseconds, box_count times
var timer:Timer = new Timer(100, box_count);
timer.addEventListener(TimerEvent.TIMER, onTick);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTickDone);
function onTick(e:Event):void
{
bigBox.addChild(cubes[timer.currentCount]);
}
function onTickDone(e:Event):void
{
cubes = null;
timer.removeEventListener(TimerEvent.TIMER, onTick);
timer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTickDone);
timer = null;
}