Tweening issue and on labels - actionscript-3

I'm Actually a student in Multimedia Design, and we are having a project to render within 3 weeks called interactive animation.
Well I'M trying to have different effect.
Glowing with easing
Scaling with easing
using alpha
I only use the Adobe manual, and some answer that as been posted here.
This is my code
stop();
import fl.transitions.*;
import fl.transitions.easing.*;
// START :: BULLET Link Glowing ONCLICK- MOUSE EVENT delay declaration //
var glowONColor:Number = 0xFFFFFF;
var glowONAlpha:Number = 0.3;
var glowONBlurX:Number = 20;
var glowONBlurY:Number = 20;
var glowONStrength:Number = 3;
var glowONQuality:Number = BitmapFilterQuality.HIGH;
var glowONInner:Boolean = false;
var glowONKnockout:Boolean = false;
var gfON:GlowFilter = new GlowFilter(glowONColor, glowONAlpha, glowONBlurX, glowONBlurY, glowONStrength, glowONQuality, glowONInner, glowONKnockout);
var glowOFFColor:Number = 0x000000;
var glowOFFAlpha:Number = 0;
var glowOFFBlurX:Number = 0;
var glowOFFBlurY:Number = 0;
var glowOFFStrength:Number = 0;
var glowOFFQuality:Number = BitmapFilterQuality.HIGH;
var glowOFFInner:Boolean = false;
var glowOFFKnockout:Boolean = false;
var gfOFF:GlowFilter = new GlowFilter(glowOFFColor, glowOFFAlpha, glowOFFBlurX, glowOFFBlurY, glowOFFStrength, glowOFFQuality, glowOFFInner, glowOFFKnockout);
mc_bullet_7mm.addEventListener(MouseEvent.CLICK, go_to_item1);
function go_to_item1(event:MouseEvent):void
{
gotoAndStop("Item1");
mc_bullet_7mm.filters = [gfON];
}
mc_bullet_280mm.addEventListener(MouseEvent.CLICK, go_to_item2);
function go_to_item2(event:MouseEvent):void
{
gotoAndStop("Item2");
mc_bullet_280mm.filters = [gfON];
}
mc_bullet_270mm.addEventListener(MouseEvent.CLICK, go_to_item3);
function go_to_item3(event:MouseEvent):void
{
gotoAndStop("Item3");
mc_bullet_270mm.filters = [gfON];
}
mc_bullet_30_06mm.addEventListener(MouseEvent.CLICK, go_to_item4);
function go_to_item4(event:MouseEvent):void
{
gotoAndStop("Item4");
mc_bullet_30_06mm.filters = [gfON];
}
mc_bullet_300_mag.addEventListener(MouseEvent.CLICK, go_to_item5);
function go_to_item5(event:MouseEvent):void
{
gotoAndStop("Item5");
mc_bullet_300_mag.filters = [gfON];
}
mc_bullet_7_64mm.addEventListener(MouseEvent.CLICK, go_to_item6);
function go_to_item6(event:MouseEvent):void
{
gotoAndStop("Item6");
mc_bullet_7_64mm.filters = [gfON];
}
mc_bullet_300mm.addEventListener(MouseEvent.CLICK, go_to_item7);
function go_to_item7(event:MouseEvent):void
{
gotoAndStop("Item7");
mc_bullet_300mm.filters = [gfON];
}
mc_bullet_308mm.addEventListener(MouseEvent.CLICK, go_to_item8);
function go_to_item8(event:MouseEvent):void
{
gotoAndStop("Item8");
mc_bullet_308mm.filters = [gfON];
}
// END:: BULLET OVER Link Glowing - MOUSE EVENT declaration //
//--------------------------------------------------------------------//
// START :: BULLET menu Easing & Rotation - ENTER_FRAME delay declaration //
TransitionManager.start(mc_bullet_7mm, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
TransitionManager.start(mc_bullet_280mm, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
TransitionManager.start(mc_bullet_270mm, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
TransitionManager.start(mc_bullet_30_06mm, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
TransitionManager.start(mc_bullet_300_mag, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
TransitionManager.start(mc_bullet_7_64mm, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
TransitionManager.start(mc_bullet_300mm, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
TransitionManager.start(mc_bullet_308mm, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
function defaultrotate (event:Event)
{
mc_bullet_7mm.rotation += 1;
mc_bullet_280mm.rotation += 1;
mc_bullet_270mm.rotation += 1;
mc_bullet_30_06mm.rotation += 1;
mc_bullet_300_mag.rotation += 1;
mc_bullet_7_64mm.rotation += 1;
mc_bullet_300mm.rotation += 1;
mc_bullet_308mm.rotation += 1;
}
function continuerotate (event:MouseEvent)
{
mc_bullet_7mm.addEventListener(Event.ENTER_FRAME, defaultrotate);
}
mc_bullet_7mm.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
mc_bullet_280mm.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
mc_bullet_270mm.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
mc_bullet_30_06mm.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
mc_bullet_300_mag.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
mc_bullet_7_64mm.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
mc_bullet_300mm.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
mc_bullet_308mm.addEventListener(MouseEvent.MOUSE_OUT, continuerotate);
function stoprotate (event:MouseEvent)
{
mc_bullet_7mm.removeEventListener(Event.ENTER_FRAME, defaultrotate);
}
mc_bullet_7mm.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
mc_bullet_280mm.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
mc_bullet_270mm.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
mc_bullet_30_06mm.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
mc_bullet_300_mag.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
mc_bullet_7_64mm.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
mc_bullet_300mm.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
mc_bullet_308mm.addEventListener(MouseEvent.MOUSE_OVER, stoprotate);
// END:: BULLET menu Easing & Rotation - ENTER_FRAME delay declaration //
//--------------------------------------------------------------------//
// START :: Background Easing in the frame - ENTER_FRAME declaration //
var dest1:Number = 89.95;
addEventListener(Event.ENTER_FRAME, radar_country_enter);
function radar_country_enter(event:Event):void{
if (dest1 != mc_radar_country.y){
var easeNum:Number = 0.9
mc_radar_country.x = mc_radar_country.x * easeNum + dest1 * (1-easeNum);
}
}
var dest2:Number = 89.95;
addEventListener(Event.ENTER_FRAME, radar_rotation_enter);
function radar_rotation_enter(event:Event):void{
if (dest2 != mc_radar_turning.y){
var easeNum:Number = 0.9
mc_radar_turning.x = mc_radar_turning.x * easeNum + dest2 * (1-easeNum);
}
}
import flash.events.Event;
addEventListener(Event.ENTER_FRAME, radar_rotation);
function radar_rotation(event:Event):void
{
mc_radar_turning.rotation +=1;
}
var dest3:Number = 667.85;
addEventListener(Event.ENTER_FRAME, bottom_tween);
function bottom_tween(event:Event):void{
if (dest3 != mc_bottom.y){
var easeNum:Number = 0.9
mc_bottom.y = mc_bottom.y * easeNum + dest3 * (1-easeNum);
}
}
var dest4:Number = 160.2;
addEventListener(Event.ENTER_FRAME, top_tween);
function top_tween(event:Event):void{
if (dest4 != mc_top.y){
var easeNum:Number = 0.8
mc_top.y = mc_top.y * easeNum + dest4 * (1-easeNum);
}
}
var backsound_enter:Sound = new ENTER_FRAME_SONG();
backsound_enter.play();
// END :: Background Easing in the frame - ENTER_FRAME declaration //
The problem is that when i click on another bullet (button) when it goes to LABEL Item1. It doesn't play the scale easing that is located into the LABEL AS3
And also when i click on another bullet (button) it's doesn't glow off
import fl.transitions.Tween;
import fl.transitions.easing.*;
import flash.events.Event;
var tweenGrowX:Tween = new Tween(background_items, "scaleX", Elastic.easeIn, 10, 400, 0.2, true);
var tweenGrowY:Tween = new Tween(background_items, "scaleY", Elastic.easeIn, 10, 400, 0.2, true);
function grow_background_items(event:Event)
{
tweenGrowY.start();
tweenGrowX.start();
}
background_items.addEventListener(Event.ENTER_FRAME, grow_background_items);
stop();
function bullet_glow_off(event:MouseEvent):void
{
mc_bullet_7mm.filters = [gfOFF];
mc_bullet_280mm.filters = [gfOFF];
mc_bullet_270mm.filters = [gfOFF];
mc_bullet_30_06mm.filters = [gfOFF];
mc_bullet_300_mag.filters = [gfOFF];
mc_bullet_7_64mm.filters = [gfOFF];
mc_bullet_300mm.filters = [gfOFF];
mc_bullet_308mm.filters = [gfOFF];
}
mc_bullet_280mm.addEventListener(MouseEvent.CLICK, bullet_glow_off);
mc_bullet_270mm.addEventListener(MouseEvent.CLICK, bullet_glow_off);
mc_bullet_30_06mm.addEventListener(MouseEvent.CLICK, bullet_glow_off);
mc_bullet_300_mag.addEventListener(MouseEvent.CLICK, bullet_glow_off);
mc_bullet_7_64mm.addEventListener(MouseEvent.CLICK, bullet_glow_off);
mc_bullet_300mm.addEventListener(MouseEvent.CLICK, bullet_glow_off);
mc_bullet_308mm.addEventListener(MouseEvent.CLICK, bullet_glow_off);
stop();

I've got the distinct impression you're placing code into various frames on your MainTimeline. This is a headache to be avoided.
As has been recommended before, you don't need multple copies of the same function that perform similar tasks. Rather, you can simplify your code by using variables that reference each object during a loop (thus performing the similar tasks in the loop).
Depending on where in your DisplayList hierarchy your background_items exists, you'll want to change the dot.notation pathing relative to the MainTimeline frame where your code is running. You'll likely want to reset the scaling of background_items every time you reload the animation, otherwise it'd appear not to be doing its transform.
Additionally, I encourage you to collapse "run-once" fragments into a single function. Especially when you begin resetting your stage, having them in one place will be invaluable.
Give this a try...
stop();
init();
import fl.transitions.*;
import fl.transitions.easing.*;
import flash.events.Event;
// Whether the 7mm should be allow the other clips to rotate.
var rotate7mm:Boolean = true;
// This array holds references to the clips we'll handle, and their related goto frames.
var bullets:Array = [
{
"clip":mc_bullet_7mm,
"frame":"Item1"
},
{
"clip":mc_bullet_280mm,
"frame":"Item2"
},
{
"clip":mc_bullet_270mm,
"frame":"Item3"
},
{
"clip":mc_bullet_30_06mm,
"frame":"Item4"
},
{
"clip":mc_bullet_300_mag,
"frame":"Item5"
},
{
"clip":mc_bullet_7_64mm,
"frame":"Item6"
},
{
"clip":mc_bullet_300mm,
"frame":"Item7"
},
{
"clip":mc_bullet_308mm,
"frame":"Item8"
}
]
function init():void {
// Everything that should happen once
var backsound_enter:Sound = new ENTER_FRAME_SONG();
backsound_enter.play();
addEventListener(Event.ENTER_FRAME, tick);
for each {var entry:Object in bullets} {
entry.clip.addEventListener(MouseEvent.CLICK, go_to_item)
entry.clip.addEventListener(MouseEvent.MOUSE_OUT, toggleRotation);
entry.clip.addEventListener(MouseEvent.MOUSE_OVER, toggleRotation);
TransitionManager.start(entry.clip, {type:Fade, direction:Transition.IN, duration:9, easing:Strong.easeOut});
}
}
function go_to_item(e:MouseEvent):void {
// Handles glowing the clicked button, and turning off the glow to the ones not selected.
var gfON:GlowFilter = new GlowFilter(
0xFFFFFF, // Color
0.3, // Alpha
20, // BlurX
20, // BlurY
3, // Strength
BitmapFilterQuality.HIGH, // Quality
false, // Inner
false // Knockout
);
var gfOFF:GlowFilter = new GlowFilter(
0x000000, // Color
0, // Alpha
0, // BlurX
0, // BlurY
0, // Strength
BitmapFilterQuality.HIGH, // Quality
false, // Inner
false // Knockout
);
for each (var entry:Object in bullets) {
if (e.currentTarget == entry.clip) {
gotoAndStop(entry.frame)
entry.clip.filters = [gfON];
// Animate the background in
var tweenGrowX:Tween = new Tween(background_items, "scaleX", Elastic.easeIn, 10, 400, 0.2, true);
tweenGrowX.start();
var tweenGrowY:Tween = new Tween(background_items, "scaleY", Elastic.easeIn, 10, 400, 0.2, true);
tweenGrowY.start();
} else {
entry.clip.filters = [gfOFF]
}
}
}
function toggleRotation(e:Event):void {
// Rather than registering another function for enterframe events, we simply set a boolean which tells the existing tick() function to run the rotation transforms.
switch (e.type) {
case "mouseOut":
rotate7mm = true;
break;
case "mouseOver":
rotate7mm = false;
break;
}
}
function tick(e:Event):void {
// Anything that needs to happen in a frame update occurs in this function.
mc_radar_turning.rotation +=1;
var radarDest:Number = 89.95; // Radar Dest
var bottomDest:Number = 667.85; // Bottom Dest
var topDest:Number = 160.2; // Top Dest
var easeNumSlow:Number = 0.9
var easeNumFast:Number = 0.8
// Country Enter
if (radarDest != mc_radar_country.y) {
mc_radar_country.x = mc_radar_country.x * easeNumSlow + radarDest * (1-easeNumSlow);
}
// Radar Rotation
if (radarDest != mc_radar_turning.y) {
mc_radar_turning.x = mc_radar_turning.x * easeNumSlow + radarDest * (1-easeNumSlow);
}
// Bottom Tween
if (dest3 != mc_bottom.y) {
mc_bottom.y = mc_bottom.y * easeNumSlow + dest3 * (1-easeNumSlow);
}
// Top Tween
if (topDest != mc_top.y) {
mc_top.y = mc_top.y * easeNumFast + topDest * (1-easeNumFast);
}
// 7mm Rotation
if (rotate7mm) {
for each (var entry:Object in bullets) {
entry.clip.rotation += 1;
}
}
}

Related

AS3 Frogger Pixel Perfect Collision

I have created a simple AS3 frogger game and used .hitTestObject to test if the frog hits any of the obstacles. This is not effective as the frog hits objects that aren't touching it at all. I am new to AS3 and have no idea where to start with coding for this. Any help would be appreciated!
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.ui.*;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.utils.Timer;
import flash.display.BitmapData;
import flash.display.Bitmap;
public class Main extends MovieClip
{
//set variables
public var frog_spriteInstance:frog_sprite;
public var safeZoneInstance1 : safeZone;
public var safeZoneInstance2: safeZone;
public var safeZoneInstance3 : safeZone;
public var whitecar : car1;
public var whitecar1 : car1;
public var whitecar2 : car1;
public var truck1 : truck_sprite;
public var truck2: truck_sprite;
public var redcar : car_sprite;
public var redcar2 : car_sprite;
public var redcar3 : car_sprite;
public var log1 : log_sprite;
public var log2 : log_sprite;
public var log3 : log_sprite;
public var letters : Letters;
public var letters2 : Letters_2;
public var letters3 : Letters_3;
public var letters4 : Letters_4;
public var health : HealthBar;
public var firstletter : firstLetter;
public var secondletter : secondLetter;
public var thirdletter : thirdLetter;
public var fourthletter : fourthLetter;
var mysound:Sound = new (mySound);
public function Main()
{
// constructor code
safeZoneInstance1 = new safeZone();
stage.addChild(safeZoneInstance1);
safeZoneInstance1.x = 300;
safeZoneInstance1.y=545
safeZoneInstance2 = new safeZone();
stage.addChild(safeZoneInstance2);
safeZoneInstance2.x = 300;
safeZoneInstance2.y=300
safeZoneInstance3 = new safeZone();
stage.addChild(safeZoneInstance3);
safeZoneInstance3.x = 300;
safeZoneInstance3.y=100
whitecar = new car1();
stage.addChild(whitecar);
whitecar.x = 300;
whitecar.y = 500
whitecar1 = new car1();
stage.addChild(whitecar1);
whitecar1.x = 550;
whitecar1.y = 480
whitecar2 = new car1();
stage.addChild(whitecar2);
whitecar2.x = 50;
whitecar2.y = 480
truck1 = new truck_sprite();
stage.addChild (truck1);
truck1.x = 1000;
truck1.y = 430
truck2 = new truck_sprite();
stage.addChild (truck2);
truck2.x = 300;
truck2.y = 430
redcar = new car_sprite();
stage.addChild (redcar);
redcar.x = 300;
redcar.y = 340
redcar2 = new car_sprite();
stage.addChild (redcar2);
redcar2.x = 100;
redcar2.y = 375
redcar3 = new car_sprite();
stage.addChild (redcar3);
redcar3.x = 500;
redcar3.y = 375
log1 = new log_sprite();
stage.addChild(log1);
log1.x = 300;
log1.y = 230
log2 = new log_sprite();
stage.addChild(log2);
log2.x = 100;
log2.y = 150
log3 = new log_sprite();
stage.addChild(log3);
log3.x = 500;
log3.y = 150
letters = new Letters();
letters.x = randomRange(100,500) ;
letters.y = randomRange(100,500);
stage.addChild(letters);
letters2 = new Letters_2();
letters2.x = randomRange(100,500) ;
letters2.y = randomRange(100,500);
stage.addChild(letters2);
letters3 = new Letters_3();
letters3.x = randomRange(100,500) ;
letters3.y = randomRange(100,500);
stage.addChild(letters3);
letters4 = new Letters_4();
letters4.x = randomRange(100,500) ;
letters4.y = randomRange(100,500);
stage.addChild(letters4);
frog_spriteInstance = new frog_sprite();
stage.addChild(frog_spriteInstance);
frog_spriteInstance.x=300;
frog_spriteInstance.y=550;
health = new HealthBar();
stage.addChild(health);
health.x = 130;
health.y = 20;
health.width = 100;
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveFrog);
stage.addEventListener(Event.ENTER_FRAME, movecars);
stage.addEventListener(Event.ENTER_FRAME, movetrucks);
stage.addEventListener(Event.ENTER_FRAME, moveredcars);
stage.addEventListener(Event.ENTER_FRAME, movelogs);
stage.addEventListener(Event.ENTER_FRAME,checkforcollision);
mysound.play();
}
public function moveFrog(e:KeyboardEvent)
{
// get the key pressed and then move the player
{
if (e.keyCode == Keyboard.UP)
{
frog_spriteInstance.rotation = 0;
frog_spriteInstance.y -= 50;
}
if (e.keyCode == Keyboard.DOWN)
{
frog_spriteInstance.rotation = 180;
frog_spriteInstance.y += 50;
}
if (e.keyCode == Keyboard.LEFT)
{
frog_spriteInstance.rotation = -90;
frog_spriteInstance.x -= 50;
}
if (e.keyCode == Keyboard.RIGHT)
{
frog_spriteInstance.rotation = 90;
frog_spriteInstance.x += 50;
}
}
}
function movecars(event:Event)
{
//move cars across screen and when they disappear, reappear at the other side
whitecar.x -= 3;
if (whitecar.x<-100){
whitecar.x=650;
}
whitecar1.x -= 3;
if (whitecar1.x<-100){
whitecar1.x=650;
}
whitecar2.x -= 3;
if (whitecar2.x<-100){
whitecar2.x=650;
}
}
function movelogs(event:Event)
{
//move logs across screen and when they disappear, reappear at the other side
log1.x -= 5;
if (log1.x<-100){
log1.x=650;
}
log2.x -= 5;
if (log2.x<-100){
log2.x=650;
}
log3.x -= 5;
if (log3.x<-100){
log3.x=650;
}
}
function movetrucks(event:Event)
{
//move trucks across screen and when they disappear, reappear at the other side
truck1.x +=3;
if (truck1.x>650){
truck1.x=-100;
}
truck2.x +=3;
if (truck2.x>650){
truck2.x=-100;
}
}
function moveredcars(event:Event)
{
//move red cars across screen and when they disappear, reappear at the other side
redcar.x +=3;
if (redcar.x>650){
redcar.x=-100;
}
redcar2.x +=3;
if (redcar2.x>650){
redcar2.x=-100;
}
redcar3.x +=3;
if (redcar3.x>650){
redcar3.x=-100;
}
}
function checkforcollision(event:Event)
{
//check for collisions
if (frog_spriteInstance.hitTestObject(log1) || (frog_spriteInstance.hitTestObject(log2) || (frog_spriteInstance.hitTestObject(log3) || (frog_spriteInstance.hitTestObject(whitecar) || (frog_spriteInstance.hitTestObject(whitecar1) || (frog_spriteInstance.hitTestObject(whitecar2) || (frog_spriteInstance.hitTestObject(log2) || (frog_spriteInstance.hitTestObject(truck1) || (frog_spriteInstance.hitTestObject(truck2) || (frog_spriteInstance.hitTestObject(redcar) || (frog_spriteInstance.hitTestObject(redcar2) || (frog_spriteInstance.hitTestObject(redcar3))))))))))))){
//reset frog if hits an obstacle
stage.addChild(frog_spriteInstance);
frog_spriteInstance.x=300;
frog_spriteInstance.y=550;
//reduce health bar
health.width -= 10;
}
//remove event listeners when health is empty
if (health.width == 0){
stage.removeEventListener(Event.ENTER_FRAME, movecars);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, moveFrog);
stage.removeEventListener(Event.ENTER_FRAME, movetrucks);
stage.removeEventListener(Event.ENTER_FRAME, moveredcars);
stage.removeEventListener(Event.ENTER_FRAME, movelogs);
}
//add letters to bottom of screen when hit correctly
if (frog_spriteInstance.hitTestObject(letters)){
stage.addChild(frog_spriteInstance);
frog_spriteInstance.x=300;
frog_spriteInstance.y=550;
stage.removeChild(letters);
firstletter = new firstLetter();
stage.addChild(firstletter);
firstletter.x=345;
firstletter.y=600;
}
if (frog_spriteInstance.hitTestObject(letters2)){
stage.addChild(frog_spriteInstance);
frog_spriteInstance.x=300;
frog_spriteInstance.y=550;
stage.removeChild(letters2);
secondletter = new secondLetter();
stage.addChild(secondletter);
secondletter.x=206;
secondletter.y=600;
}
if (frog_spriteInstance.hitTestObject(letters3)){
stage.addChild(frog_spriteInstance);
frog_spriteInstance.x=300;
frog_spriteInstance.y=550;
stage.removeChild(letters3);
thirdletter = new thirdLetter();
stage.addChild(thirdletter);
thirdletter.x=273;
thirdletter.y=600;
}
if (frog_spriteInstance.hitTestObject(letters4)){
stage.addChild(frog_spriteInstance);
frog_spriteInstance.x=300;
frog_spriteInstance.y=550;
stage.removeChild(letters4);
health.width -= 10;
fourthletter = new fourthLetter();
stage.addChild(fourthletter);
fourthletter.x=25;
fourthletter.y=620;
}
}
function randomRange(minNum:Number, maxNum:Number):Number
{
//random generator for letter positioning
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
}
}
Also my code is pretty dodgy so any suggestions on improvement are very welcome.
To perform pixel perfect hit test from two arbitrary display objects you have to draw them to bitmaps and use BitmapData/hitTest().
Here is a generalized function that does this:
function hitTestShapes(object1:DisplayObject, object2:DisplayObject, threshold:uint = 1):Boolean {
var bounds1:Rectangle = object1.getBounds(object1.parent);
var matrix1:Matrix = object1.transform.matrix;
matrix1.tx = object1.x - bounds1.x;
matrix1.ty = object1.y - bounds1.y;
var bmp1:BitmapData = new BitmapData(bounds1.width, bounds1.height, true, 0);
bmp1.draw(object1, matrix1);
var bounds2:Rectangle = object2.getBounds(object2.parent);
var matrix2:Matrix = object2.transform.matrix;
matrix2.tx = object2.x - bounds2.x;
matrix2.ty = object2.y - bounds2.y;
var bmp2:BitmapData = new BitmapData(bounds2.width, bounds2.height, true, 0);
bmp2.draw(object2, matrix2);
return bmp1.hitTest(bounds1.topLeft, threshold, bmp2, bounds2.topLeft, threshold);
}
Note, though, that drawing to bitmaps is rather slow, so be careful not to over-use this kind of function or you will have performance issues. In fact, it would be a good idea to use hitTestObject() first, which is very fast and detects bounding box intersections, then only call hitTestShapes() to refine your check. In other words:
if (frog_spriteInstance.hitTestObject(log1) && hitTestShapes(frog_spriteInstance, log1)) { }
As for suggestions on your code, there's a lot of potential for de-duplicating by way of arrays, loops, and functions. For example, instead of defining all your objects as separate variables, just store them all in an array (or vector):
public var safeZones:Array = [];
public var obstacles:Array = [];
public var letters:Array = [];
To populate the arrays, you can push values into them and use a function to consolidate all your duplicate object setup code:
(Code convention note: use "UpperCamelCase" for class names.)
public function Main(){
addSafeZone(300, 545);
addSafeZone(300, 300);
addSafeZone(300, 100);
addObstacle(WhiteCar, 300, 500);
addObstacle(WhiteCar, 550, 480);
addObstacle(WhiteCar, 50, 480);
addObstacle(Truck, 1000, 430);
addObstacle(Truck, 300, 430);
addObstacle(RedCar, 300, 340);
addObstacle(RedCar, 100, 375);
addObstacle(RedCar, 500, 375);
addObstacle(Log, 300, 230);
addObstacle(Log, 100, 150);
addObstacle(Log, 500, 150);
addRandomLetters(Letters_1);
addRandomLetters(Letters_2);
addRandomLetters(Letters_3);
addRandomLetters(Letters_4);
}
private function addSafeZone(x:Number, y:Number):void {
var safeZone:SafeZone = new SafeZone();
stage.addChild(safeZone);
safeZone.x = x;
safeZone.y = y
safeZones.push(safeZone);
}
private function addObstacle(spriteClass:Class, x:Number, y:Number):void {
var obstacle:Sprite = new spriteClass();
stage.addChild(obstacle);
obstacle.x = x;
obstacle.y = y
obstacles.push(obstacle);
}
private function addRandomLetters(lettersClass:Class):void {
var lettersSprite:Sprite = new lettersClass();
lettersSprite.x = randomRange(100, 500);
lettersSprite.y = randomRange(100, 500);
stage.addChild(lettersSprite);
letters.push(lettersSprite);
}
Now you can loop over the arrays to perform all your actions. For example, to check for a hit against any obstacle:
for each(var obstacle:DisplayObject in obstacles){
if(frog.hitTestObject(obstacle) && hitTestShapes(frog, obstacle)){
// The frog hit an obstacle!
}
}
You could also combine all our "move" functions into one, which moves each obstacle based on their type:
private function moveObstacles(e:Event):void {
for each(var obstacle in obstacles){
if(obstacle is WhiteCar){
obstacle.x -= 3;
}
else if(obstacle is RedCar){
obstacle.x += 3;
}
else if(obstacle is Truck){
obstacle.x += 3;
}
else if(obstacle is Log){
obstacle.x -= 5;
}
if(obstacle.x < -100){
obstacle.x = 650;
}
else if(obstacle.x > 650){
obstacle.x = -100;
}
}
}
Lastly, you really should only need a single ENTER_FRAME handler. Just call whatever functions you want from in there. Adding multiple ENTER_FRAME handlers can get troublesome to manage. For example, just do this:
addEventListener(Event.ENTER_FRAME, update);
private function update(e:Event):void {
moveObstacles();
doOtherStuff();
anythingYouNeedToDo();
}
This way you only need to removeEventListener(Event.ENTER_FRAME, update) to stop the game, not a whole bunch of ENTER_FRAME handlers.
I haven't tested any of this code, but you get the general idea. Let me know if you have any issues with it and I can help.

User interaction with Leapmotion AS3 library

I can connect the device and attach a custom cursor to one finger, but I can´t use any of the gestures to over/click a button or drag a sprite around, etc.
I´m using Starling in the project. To run this sample just create a Main.as, setup it with Starling and call this class.
My basic code:
package
{
import com.leapmotion.leap.Controller;
import com.leapmotion.leap.events.LeapEvent;
import com.leapmotion.leap.Finger;
import com.leapmotion.leap.Frame;
import com.leapmotion.leap.Gesture;
import com.leapmotion.leap.Hand;
import com.leapmotion.leap.InteractionBox;
import com.leapmotion.leap.Pointable;
import com.leapmotion.leap.ScreenTapGesture;
import com.leapmotion.leap.Vector3;
import starling.display.Shape;
import starling.display.Sprite;
import starling.events.Event;
import starling.events.TouchEvent;
/**
* ...
* #author miau
*/
public class LeapController extends Sprite
{
private var _controller:Controller;
private var _cursor:Shape;
private var _screenTap:ScreenTapGesture;
private var _displayWidth:uint = 800;
private var _displayHeight:uint = 600;
public function LeapController()
{
addEventListener(Event.ADDED_TO_STAGE, _startController);
}
private function _startController(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, _startController);
//adding controller
_controller = new Controller();
_controller.addEventListener( LeapEvent.LEAPMOTION_INIT, onInit );
_controller.addEventListener( LeapEvent.LEAPMOTION_CONNECTED, onConnect );
_controller.addEventListener( LeapEvent.LEAPMOTION_DISCONNECTED, onDisconnect );
_controller.addEventListener( LeapEvent.LEAPMOTION_EXIT, onExit );
_controller.addEventListener( LeapEvent.LEAPMOTION_FRAME, onFrame );
//add test button
_testButton.x = stage.stageWidth / 2 - _testButton.width / 2;
_testButton.y = stage.stageHeight / 2 - _testButton.height / 2;
addChild(_testButton);
_testButton.touchable = true;
_testButton.addEventListener(TouchEvent.TOUCH, doSomething);
//draw ellipse as a cursor
_cursor = new Shape();
_cursor.graphics.lineStyle(6, 0xFFE24F);
_cursor.graphics.drawEllipse(0, 0, 80, 80);
addChild(_cursor);
}
private function onFrame(e:LeapEvent):void
{
trace("ON FRAME STARTED");
var frame:Frame = e.frame;
var interactionBox:InteractionBox = frame.interactionBox;
// Get the first hand
if(frame.hands.length > 0){
var hand:Hand = frame.hands[0];
var numpointables:int = e.frame.pointables.length;
var pointablesArray:Array = new Array();
if(frame.pointables.length > 0 && frame.pointables.length < 2){
//trace("number of pointables: "+frame.pointables[0]);
for(var j:int = 0; j < frame.pointables.length; j++){
//var pointer:DisplayObject = pointablesArray[j];
if(j < numpointables){
var pointable:Pointable = frame.pointables[j];
var normal:Vector3 = pointable.tipPosition;
var normalized:Vector3 = interactionBox.normalizePoint(normal);
//pointable.isFinger = true;
_cursor.x = normalized.x * _displayWidth;
_cursor.y = _displayHeight - (normalized.y * _displayHeight);
_cursor.visible = true;
}else if (j == 0) {
_cursor.visible = false;
}
}
}
}
}
private function onExit(e:LeapEvent):void
{
trace("ON EXIT STARTED");
}
private function onDisconnect(e:LeapEvent):void
{
trace("ON DISCONNECT STARTED");
}
private function onConnect(e:LeapEvent):void
{
trace("ON CONNECT STARTED");
_controller.enableGesture( Gesture.TYPE_SWIPE );
_controller.enableGesture( Gesture.TYPE_CIRCLE );
_controller.enableGesture( Gesture.TYPE_SCREEN_TAP );
_controller.enableGesture( Gesture.TYPE_KEY_TAP );
}
private function onInit(e:LeapEvent):void
{
trace("ON INIT STARTED");
}
private function doSomething(e:TouchEvent):void
{
trace("I WAS TOUCHED!!!");
}
}
}
If a good code Samaritan can update this code to perform a screen tap gesture (or any interacion with any object), I will really appreciate this a lot.
Regards!
controller.enableGesture(Gesture.TYPE_SWIPE);
controller.enableGesture(Gesture.TYPE_SCREEN_TAP);
if(controller.config().setFloat("Gesture.Swipe.MinLength", 200.0) && controller.config().setFloat("Gesture.Swipe.MinVelocity", 500)) controller.config().save();
if(controller.config().setFloat("Gesture.ScreenTap.MinForwardVelocity", 30.0) && controller.config().setFloat("Gesture.ScreenTap.HistorySeconds", .5) && controller.config().setFloat("Gesture.ScreenTap.MinDistance", 1.0)) controller.config().save();
//etc...
Then catch it in the frame event listener:
private function onFrame( event:LeapEvent ):void
{
var frame:Frame = event.frame;
var gestures:Vector.<Gesture> = frame.gestures();
for ( var i:int = 0; i < gestures.length; i++ )
{
var gesture:Gesture = gestures[ i ];
switch ( gesture.type )
{
case Gesture.TYPE_SCREEN_TAP:
var screentap:ScreenTapGesture = ScreenTapGesture ( gesture);
trace ("ScreenTapGesture-> x: " + Math.round(screentap.position.x ) + ", y: "+ Math.round( screentap.position.y));
break;
case Gesture.TYPE_SWIPE:
var screenSwipe:SwipeGesture = SwipeGesture(gesture);
if(gesture.state == Gesture.STATE_START) {
//
}
else if(gesture.state == Gesture.STATE_STOP) {
//
trace("SwipeGesture-> direction: "+screenSwipe.direction + ", duration: " + screenSwipe.duration);
}
break;
default:
trace( "Unknown gesture type." )
}
}
}
When the event occurs, check the coordinates translated to the stage/screen and whether a hit test returns true.
EDIT: Considering I have no idea how to reliable get the touch point x/y (or better: how to translate them to the correct screen coordinates), I would probably do something like this in my onFrame event:
private function onFrame(event:LeapEvent):void {
var frame:Frame = event.frame;
var gestures:Vector.<Gesture> = frame.gestures();
var posX:Number;
var posY:Number;
var s:Shape;
if(frame.pointables.length > 0) {
var currentVector:Vector3 = screen.intersectPointable(frame.pointables[0], true); //get normalized vector
posX = 1920 * currentVector.x - stage.x; //NOTE: I hardcoded the screen res value, you can get it like var w:int = leap.locatedScreens()[0].widthPixels();
posY = 1080 * ( 1 - currentVector.y ) - stage.y; //NOTE: I hardcoded the screen res value, you can get it like var h:int = leap.locatedScreens()[0].heightPixels();
}
for(var i:int = 0; i < gestures.length; i++) {
var gesture:Gesture = gestures[i];
if(gesture.type == Gesture.TYPE_SCREEN_TAP) {
if(posX >= _button1.x &&
posX <= _button1.x + _button1.width &&
posY >= _button1.y &&
posY <= _button1.y + _button1.height) {
s = new Shape();
s.graphics.beginFill(0x00FF00);
s.graphics.drawCircle(0, 0, 10);
s.graphics.endFill();
s.x = posX;
s.y = posY;
stage.addChild(s);
trace("Lisa tocada!");
}
else {
s = new Shape();
s.graphics.beginFill(0xFF0000);
s.graphics.drawCircle(0, 0, 10);
s.graphics.endFill();
s.x = posX;
s.y = posY;
stage.addChild(s);
trace("Fallaste! Intentalo otra vez, tiempo: "+new Date().getTime());
}
}
}
}

Error 2025 when trying to removeChild, child not contained where it was added?

I am trying to code a tile-based level editor, in which the Main class adds Tile class instances as children of the 'tiles' movieclip when clicking/dragging the mouse.
I am able to add tiles to the container, and they show on stage, however I cannot remove any tiles when erasing them is enabled. It gives me the following error
Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at Main/Draw()
at Main/::Go()
Also, when I check if the tile is inside the tiles container, it tells me that the parent is null.
So, a little help? I tried checking other questions with similar issues but none seemed to be close to mine.
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
//import flash.events.TimerEvent.updateAfterEvent;
public class Main extends MovieClip {
//containers
var lines:Sprite = new Sprite();
var tiles:Sprite = new Sprite();
// Grid data
var tileW:int = 20;
var tileH:int = 20;
var gridW:int = 20;//(inputWidth);
var gridH:int = 20;//(inputHeight);
var gridX:int = 50;
var grixY:int = 50;
var level:Array;
//Drawing variables
var go:Boolean = false;
var erase:Boolean = false;
var default_tile:int = 1;
var type:int;
var rect:Object = {x:100, y:50, width:(gridW * tileW)/100, height:(gridH * tileH)/100};
//menus
var sizeMenu:SizeMenu = new SizeMenu();
var current:Tile = new Tile();
public function Main():void {
//Flash alignment and resizing
stage.scaleMode=StageScaleMode.NO_SCALE;
stage.align=StageAlign.TOP_LEFT;
stage.addChild(lines);
lines.x = rect.x;
lines.y = rect.y;
stage.addChild(tiles);
tiles.x = rect.x;
tiles.y = rect.y;
stage.addChild(sizeMenu);
stage.addChild(current);
current.x = 50;
current.gotoAndStop(default_tile);
stage.addEventListener(MouseEvent.MOUSE_DOWN, Go);
stage.addEventListener(MouseEvent.MOUSE_UP, Go);
stage.addEventListener(MouseEvent.MOUSE_MOVE, Go);
stage.addEventListener(KeyboardEvent.KEY_DOWN, ToggleErase);
stage.addEventListener(KeyboardEvent.KEY_UP, ToggleErase);
Setup();
}
//Draws grid lines
private function Setup():void {
trace("Drawing Grid...");
// create an empty array
level = new Array(gridH);
for (var i=0; i < gridW; i++) {
level[i] = new Array(gridW);
}
// attach lines to create a grid
for (var k=0; k <= gridH; k++) {
var line = new Line();
line.name = "line"+k;
line.scaleX = rect.width;
line.y = tileH * k;
lines.addChild(line);
for (var j=0; j <= gridW; j++) {
line = new Line();
line.name = "line"+j+"_"+k;
line.scaleX = rect.height;
line.x = tileW * j;
line.rotation = 90;
lines.addChild(line);
}
}
type = default_tile;
trace("Done drawing grid!");
}
//Decided if drawing is possible
private function Go(e:MouseEvent):void {
if (e.type == "mouseDown") {
go = true;
Draw(e);
}
if (e.type == "mouseUp") {
go = false;
}
if (e.type == "mouseMove") {
if (go) {
Draw(e);
}
//e.updateAfterEvent();
}
}
//Toggles erase
private function ToggleErase(e:KeyboardEvent):void{
if (e.shiftKey){
erase = true;
}
if (e.type == "keyUp"){
erase = false;
}
}
// attaches the tiles when drawn on the grid
public function Draw(e:MouseEvent) {
var x = mouseX;
var y = mouseY;
var cx = Math.floor((x - rect.x) / tileW);
var cy = Math.floor((y - rect.y) / tileH);
if (cx >= 0 && cx < gridW && cy >= 0 && cy < gridH) {
var target = e.currentTarget;
if (!erase) {
if (tiles.contains(target)){
trace("Contained!");
tiles.removeChild(target);
}
var tile = new Tile();
tiles.addChild(tile);
tile.name = ("t_" + cy + "_" + cx);
tile.x = (tileW * cx);
tile.y = (tileH * cy);
tile.gotoAndStop(type);
level[cy][cx] = type;
} else {
if (tiles.contains(target)){
trace("Contained!");
tiles.removeChild(target);
}
level[cy][cx] = default_tile - 1;
}
}
}
//Cleans the grid and redraws it
private function ResetGrid():void {
level = null;
//Delete tiles
while (tiles.numChildren) {
tiles.removeChildAt(0);
}
//Delete lines
while (lines.numChildren) {
lines.removeChildAt(0);
}
gridW=20;
gridH=20;
rect.width = (gridW * tileW)/100;
rect.height = (gridH * tileH)/100;
}
// updates the current-clip
private function update() {
current.gotoAndStop(type);
}
}
}
The following code is causing the problem, basically you are calling removeChild twice for the same object.
if (tiles.contains(target)){
trace("Contained!");
tiles.removeChild(target);
}
tiles.removeChild(target);
In your code, I notice that you have the ability for the tile to be removed, and then try to remove it again at the end of this block :
if (!erase) {
if (tiles.contains(target)){
trace("Contained!");
tiles.removeChild(target);
}
var tile = new Tile();
tiles.addChild(tile);
tile.name = ("t_" + cy + "_" + cx);
tile.x = (tileW * cx);
tile.y = (tileH * cy);
tile.gotoAndStop(type);
level[cy][cx] = type;
} else {
if (tiles.contains(target)){
trace("Contained!");
tiles.removeChild(target);
}
// this is going to throw an error
tiles.removeChild(target);
Make it easy on yourself and create a class for Tile with a remove method. Something like this:
class Tile extends Sprite
{
public function remove():void
{
if(parent) parent.removeChild(this);
}
}
This way, you can simply do:
tile.remove();
I have resolved my issue! All tile instances are given a name based on their position on the grid when added. Instead of making target the object the mouse was pointing at, I used getChildByName(); to search if there was already an object with a specific name, and to erase it if it did.
if (cx >= 0 && cx < gridW && cy >= 0 && cy < gridH) {
var target = tiles.getChildByName("t_" + cy + "_" + cx);
if (!erase) {
if (target){
tiles.removeChild(target);
}
var tile = new Tile();
tiles.addChild(tile);
tile.name = ("t_" + cy + "_" + cx);
tile.x = (tileW * cx);
tile.y = (tileH * cy);
tile.gotoAndStop(type);
level[cy][cx] = type;
} else {
if (target){
tiles.removeChild(target);
}
level[cy][cx] = default_tile - 1;
}
}

AS3 - Game Timer not calculating start time properly

I'm building a game in AS3 based off of Gary Rosenzweig's latest Actionscript 3 book. It has a game timer issue, not just mine but his demo too, that I can't figure out.
The game is like Asteroids where four rocks are placed in the corners of the stage at the beginning and then start moving randomly around the stage. The problem is the timer used is started the moment that the flash file starts not the moment the player clicks the start button. So if you are on the start screen for 5 seconds before you click play when the game actually begins the rocks are where they would be after 5 seconds of play, which could be right over the player.
I've posted the parts of the code that I think apply. Could someone please tell me how to modify this so that when the player actually starts the game the rocks start in their proper places. I'm pretty sure it's the last function that I've included that is the problem but I've included other related parts to give you a more complete picture.
package {
import flash.display.*;
import flash.events.*;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.text.*;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.geom.Point;
import flash.net.SharedObject;
import flash.media.Sound;
import flash.media.SoundMixer;
import flash.media.SoundTransform;
import flash.media.SoundChannel;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
public class VirusDefender extends MovieClip {
static const shipRotationSpeed:Number = .1;
static const rockSpeedStart:Number = .03;
static const rockSpeedIncrease:Number = .01;
static const missileSpeed:Number = .2;
static const thrustPower:Number = .15;
static const shipRadius:Number = 20;
static const startingShips:uint = 3;
// game objects
private var ship:Ship;
private var rocks:Array;
private var missiles:Array;
// animation timer
private var lastTime:uint;
// arrow keys
private var rightArrow:Boolean = false;
private var leftArrow:Boolean = false;
private var upArrow:Boolean = false;
// ship velocity
private var shipMoveX:Number;
private var shipMoveY:Number;
// timers
private var delayTimer:Timer;
private var shieldTimer:Timer;
// game mode
private var gameMode:String;
private var shieldOn:Boolean;
// ships and shields
private var shipsLeft:uint;
private var shieldsLeft:uint;
private var shipIcons:Array;
private var shieldIcons:Array;
private var scoreDisplay:TextField;
// score and level
private var gameScore:Number;
private var gameLevel:uint;
// sprites
private var gameObjects:Sprite;
private var scoreObjects:Sprite;
var gameBackground:GameBackground = new GameBackground();
// sounds
var sndFire:fire_sound;
var sndFireChannel:SoundChannel;
var sndThruster:thruster_sound;
var sndThrusterChannel:SoundChannel;
var sndShield:shield_sound;
var sndShieldChannel:SoundChannel;
var sndExplosion:explosion_sound;
var sndExplosionChannel:SoundChannel;
var sndBubble:bubble_sound;
var sndBubbleChannel:SoundChannel;
// start the game
public function startSpaceRocks() {
// set up sprites
addChild(gameBackground);
setChildIndex(gameBackground,0); // I added this
gameObjects = new Sprite();
addChild(gameObjects);
scoreObjects = new Sprite();
addChild(scoreObjects);
// reset score objects
gameLevel = 1;
shipsLeft = startingShips;
gameScore = 0;
createShipIcons();
createScoreDisplay();
// set up listeners
trace("add moveGameObjects event listener");
addEventListener(Event.ENTER_FRAME,moveGameObjects);
leftButton.addEventListener(TouchEvent.TOUCH_OVER,leftPress);
leftButton.addEventListener(TouchEvent.TOUCH_OUT,leftRelease);
rightButton.addEventListener(TouchEvent.TOUCH_OVER,rightPress);
rightButton.addEventListener(TouchEvent.TOUCH_OUT,rightRelease);
thrusterButton.addEventListener(TouchEvent.TOUCH_OVER,thrusterPress);
thrusterButton.addEventListener(TouchEvent.TOUCH_OUT,thrusterRelease);
shieldButton.addEventListener(TouchEvent.TOUCH_OVER,shieldPress);
fireButton.addEventListener(TouchEvent.TOUCH_OVER,firePress);
// Left Button
function leftPress(event:TouchEvent):void{
leftArrow = true;
}
function leftRelease(event:TouchEvent):void{
leftArrow = false;
}
// Right button
function rightPress(event:TouchEvent):void{
rightArrow = true;
}
function rightRelease(event:TouchEvent):void{
rightArrow = false;
}
// Thruster button
function thrusterPress(event:TouchEvent):void{
sndThruster=new thruster_sound();
sndThrusterChannel=sndThruster.play();
upArrow = true;
if (gameMode == "play") ship.gotoAndStop(2);
}
function thrusterRelease(event:TouchEvent):void{
sndThrusterChannel.stop();
upArrow = false;
if (gameMode == "play") ship.gotoAndStop(1);
}
// Fire button
function firePress(event:TouchEvent):void{
sndFire=new fire_sound();
sndFireChannel=sndFire.play();
newMissile();
}
// Shield button
function shieldPress(event:TouchEvent):void{
startShield(false);
}
// start
gameMode = "delay";
trace("gameMode - delay");
shieldOn = false;
missiles = new Array();
trace("nextRockWave fired");
nextRockWave(null);
newShip(null);
}
// SCORE OBJECTS
// draw number of ships left
public function createShipIcons() {
shipIcons = new Array();
for(var i:uint=0;i<shipsLeft;i++) {
var newShip:ShipIcon = new ShipIcon();
newShip.x = 165+i*25; //165
newShip.y = 273; //273
scoreObjects.addChild(newShip);
shipIcons.push(newShip);
}
}
// draw number of shields left
public function createShieldIcons() {
shieldIcons = new Array();
for(var i:uint=0;i<shieldsLeft;i++) {
var newShield:ShieldIcon = new ShieldIcon();
newShield.x = 310-i*25; //530
newShield.y = 273; //15
scoreObjects.addChild(newShield);
shieldIcons.push(newShield);
}
}
// put the numerical score at the upper right
public function createScoreDisplay() {
updateScore();
}
// new score to show
public function updateScore() {
score.text = addCommaInNumber(gameScore);
}
// remove a ship icon
public function removeShipIcon() {
scoreObjects.removeChild(shipIcons.pop());
}
// remove a shield icon
public function removeShieldIcon() {
scoreObjects.removeChild(shieldIcons.pop());
}
// remove the rest of the ship icons
public function removeAllShipIcons() {
while (shipIcons.length > 0) {
removeShipIcon();
}
}
// remove the rest of the shield icons
public function removeAllShieldIcons() {
while (shieldIcons.length > 0) {
removeShieldIcon();
}
}
// SHIP CREATION AND MOVEMENT
// create a new ship
public function newShip(event:TimerEvent) {
// if ship exists, remove it
if (ship != null) {
gameObjects.removeChild(ship);
ship = null;
}
// no more ships
if (shipsLeft < 1) {
endGame();
return;
}
// create, position, and add new ship
ship = new Ship();
ship.gotoAndStop(1);
ship.x = 240; //275
ship.y = 160; //200
ship.rotation = -90;
ship.shield.visible = false;
gameObjects.addChild(ship);
// set up ship properties
shipMoveX = 0.0;
shipMoveY = 0.0;
gameMode = "play";
// set up shields
shieldsLeft = 3;
createShieldIcons();
// all lives but the first start with a free shield
if (shipsLeft != startingShips) {
startShield(true);
sndShield=new shield_sound();
sndShieldChannel=sndShield.play();
}
}
// animate ship
public function moveShip(timeDiff:uint) {
// rotate and thrust
if (leftArrow) {
ship.rotation -= shipRotationSpeed*timeDiff;
} else if (rightArrow) {
ship.rotation += shipRotationSpeed*timeDiff;
} else if (upArrow) {
shipMoveX += Math.cos(Math.PI*ship.rotation/180)*thrustPower;
shipMoveY += Math.sin(Math.PI*ship.rotation/180)*thrustPower;
}
// move
ship.x += shipMoveX;
ship.y += shipMoveY;
// wrap around screen
if ((shipMoveX > 0) && (ship.x > 470)) {
ship.x -= 490;
}
if ((shipMoveX < 0) && (ship.x < -20)) {
ship.x += 500;
}
if ((shipMoveY > 0) && (ship.y > 320)) {
ship.y -= 340;
}
if ((shipMoveY < 0) && (ship.y < -20)) {
ship.y += 340;
}
}
// remove ship
public function shipHit() {
gameMode = "delay";
ship.gotoAndPlay("explode");
sndExplosion=new explosion_sound();
sndExplosionChannel=sndExplosion.play();
removeAllShieldIcons();
delayTimer = new Timer(2000,1);
delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,newShip);
delayTimer.start();
removeShipIcon();
shipsLeft--;
}
// turn on shield for 3 seconds
public function startShield(freeShield:Boolean) {
if (shieldsLeft < 1) return; // no shields left
if (shieldOn) return; // shield already on
// turn on shield and set timer to turn off
ship.shield.visible = true;
sndShield=new shield_sound();
sndShieldChannel=sndShield.play();
shieldTimer = new Timer(3000,1);
shieldTimer.addEventListener(TimerEvent.TIMER_COMPLETE,endShield);
shieldTimer.start();
// update shields remaining
if (!freeShield) {
removeShieldIcon();
shieldsLeft--;
}
shieldOn = true;
}
// turn off shield
public function endShield(event:TimerEvent) {
ship.shield.visible = false;
shieldOn = false;
}
// ROCKS
// create a single rock of a specific size
public function newRock(x,y:int, rockType:String) {
trace("newRock fired");
// create appropriate new class
var newRock:MovieClip;
var rockRadius:Number;
if (rockType == "Big") {
newRock = new Rock_Big();
rockRadius = 35;
} else if (rockType == "Medium") {
newRock = new Rock_Medium();
rockRadius = 20;
} else if (rockType == "Small") {
newRock = new Rock_Small();
rockRadius = 10;
}
// choose a random look
newRock.gotoAndStop(Math.ceil(Math.random()*3));
// set start position
newRock.x = x;
newRock.y = y;
// set random movement and rotation
var dx:Number = Math.random()*2.0-1.0;
var dy:Number = Math.random()*2.0-1.0;
var dr:Number = Math.random();
// add to stage and to rocks list
gameObjects.addChild(newRock);
setChildIndex(gameObjects,1); // I added this
rocks.push({rock:newRock, dx:dx, dy:dy, dr:dr, rockType:rockType, rockRadius: rockRadius});
}
// create four rocks
public function nextRockWave(event:TimerEvent) {
rocks = new Array();
newRock(30,30,"Big"); //100 100
newRock(30,290,"Big"); // 100 300
newRock(450,30,"Big"); // 450 100
newRock(450,290,"Big"); // 450 300
gameMode = "play";
}
// animate all rocks
public function moveRocks(timeDiff:uint) {
for(var i:int=rocks.length-1;i>=0;i--) {
// move the rocks
var rockSpeed:Number = rockSpeedStart + rockSpeedIncrease*gameLevel;
rocks[i].rock.x += rocks[i].dx*timeDiff*rockSpeed;
rocks[i].rock.y += rocks[i].dy*timeDiff*rockSpeed;
// rotate rocks
rocks[i].rock.rotation += rocks[i].dr*timeDiff*rockSpeed;
// wrap rocks
if ((rocks[i].dx > 0) && (rocks[i].rock.x > 470)) {
rocks[i].rock.x -= 490;
}
if ((rocks[i].dx < 0) && (rocks[i].rock.x < -20)) {
rocks[i].rock.x += 490;
}
if ((rocks[i].dy > 0) && (rocks[i].rock.y > 325)) {
rocks[i].rock.y -= 345;
}
if ((rocks[i].dy < 0) && (rocks[i].rock.y < -25)) {
rocks[i].rock.y += 345;
}
}
}
public function rockHit(rockNum:uint) {
// create two smaller rocks
sndBubble=new bubble_sound();
sndBubbleChannel=sndBubble.play();
if (rocks[rockNum].rockType == "Big") {
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium");
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium");
} else if (rocks[rockNum].rockType == "Medium") {
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small");
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small");
}
// remove original rock
gameObjects.removeChild(rocks[rockNum].rock);
rocks.splice(rockNum,1);
}
// MISSILES
// create a new Missile
public function newMissile() {
// create
var newMissile:Missile = new Missile();
// set direction
newMissile.dx = Math.cos(Math.PI*ship.rotation/180);
newMissile.dy = Math.sin(Math.PI*ship.rotation/180);
// placement
newMissile.x = ship.x + newMissile.dx*shipRadius;
newMissile.y = ship.y + newMissile.dy*shipRadius;
// add to stage and array
gameObjects.addChild(newMissile);
missiles.push(newMissile);
}
// animate missiles
public function moveMissiles(timeDiff:uint) {
for(var i:int=missiles.length-1;i>=0;i--) {
// move
missiles[i].x += missiles[i].dx*missileSpeed*timeDiff;
missiles[i].y += missiles[i].dy*missileSpeed*timeDiff;
// moved off screen
if ((missiles[i].x < 0) || (missiles[i].x > 485) || (missiles[i].y < 0) || (missiles[i].y > 325)) {
gameObjects.removeChild(missiles[i]);
delete missiles[i];
missiles.splice(i,1);
}
}
}
// remove a missile
public function missileHit(missileNum:uint) {
gameObjects.removeChild(missiles[missileNum]);
missiles.splice(missileNum,1);
}
// GAME INTERACTION AND CONTROL
public function moveGameObjects(event:Event) {
// get timer difference and animate
var timePassed:uint = getTimer() - lastTime;
lastTime += timePassed;
moveRocks(timePassed);
if (gameMode != "delay") {
moveShip(timePassed);
}
moveMissiles(timePassed);
checkCollisions();
}
// look for missiles colliding with rocks
public function checkCollisions() {
// loop through rocks
rockloop: for(var j:int=rocks.length-1;j>=0;j--) {
// loop through missiles
missileloop: for(var i:int=missiles.length-1;i>=0;i--) {
// collision detection
if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y),
new Point(missiles[i].x,missiles[i].y))
< rocks[j].rockRadius) {
// remove rock and missile
rockHit(j);
missileHit(i);
// add score
gameScore += 10;
updateScore();
// break out of this loop and continue next one
continue rockloop;
}
}
// check for rock hitting ship
if (gameMode == "play") {
if (shieldOn == false) { // only if shield is off
if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y),
new Point(ship.x,ship.y))
< rocks[j].rockRadius+shipRadius) {
// remove ship and rock
shipHit();
rockHit(j);
}
}
}
}
// all out of rocks, change game mode and trigger more
if ((rocks.length == 0) && (gameMode == "play")) {
gameMode = "betweenlevels";
gameLevel++; // advance a level
levelTextBox.text = "Infection: " + gameLevel;
delayTimer = new Timer(2000,1);
delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,nextRockWave);
delayTimer.start();
}
}
public function endGame() {
// remove all objects and listeners
removeChild(gameObjects);
removeChild(scoreObjects);
removeChild(gameBackground);
gameObjects = null;
scoreObjects = null;
removeEventListener(Event.ENTER_FRAME,moveGameObjects);
gameMode = "gameOver";
gotoAndStop("gameover");
}
/***** ADD COMMAS TO NUMBERS *******/
function addCommaInNumber (number : Number) : String
{
var integer : String = "" ;
var fraction : String = "" ;
var string : String = number.toString();
var array : Array = string.split(".");
var regex : RegExp = /(\d+)(\d{3})/;
integer = array[0];
while( regex.test(integer) )
{
integer = integer.replace(regex,'$1' + ',' + '$2');
}
if (array[1])
{ fraction = integer.length > 0 ? '.' + array[1] : ''; }
return integer + fraction;
}
}
}
The part of code you thought applied to your problem is incorrect.
A timer can be started along with it's declaration as :
private var myTimer:Timer = new Timer(delay, repeat);
But since you are not initiating the timer at the time of declaration (as seen in you snippet)
// timers
private var delayTimer:Timer;
private var shieldTimer:Timer;
There must be some other function where it would be initiated. Move the action of initiating the timer to whichever place you want to start the timer. For eg : into startspacerocks() function
If that is not the problem, please post the relevant code that applies to your problem.
EDIT:
Well I think your answer lies in the moveGameObjects function.
Try modifying the function as follows:
// GAME INTERACTION AND CONTROL
public function moveGameObjects(event:Event) {
//Current Time
var currentTime:uint = getTimer();
//Initiate lastTime
if(lastTime == 0) lastTime = currentTime;
// get timer difference and animate
var timePassed:uint = currentTime - lastTime;
lastTime += timePassed;
moveRocks(timePassed);
if (gameMode != "delay") {
moveShip(timePassed);
}
moveMissiles(timePassed);
checkCollisions();
}
From the code you've posted, I can't answer your question safely, but you should check, when startSpaceRocks() is called the first time. This should be in the click handler of your start button.
Beside that, your question title does not reflect the problem. There is no problem with a timer at all, there is a problem, when the "timer" is started.

how can i make this papervision3d code work?

This code works but it does display the cube as the first code and the view, zoom and interactivity is different, so i wanted the cube to be displayed as in the first code with the same features.
first code is here: http://papervision2.com/10-advanced-interactivity/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.view.BasicView;
public class Main extends BasicView
{
protected var cube:Cube;
protected var interactiveMats:Array;
protected var materialsList:MaterialsList;
protected var targetrotationX:Number;
protected var targetrotationY:Number;
protected var targetrotationZ:Number;
protected var tweening:Boolean;
public function Main():void
{
super();
init();
}
protected function init():void
{
createChildren();
startRendering();
}
protected function createChildren():void
{
//Set the viewport to interactive
viewport.interactive = true;
//Create Materials:
materialsList = new MaterialsList();
interactiveMats = ["front", "back", "left", "right", "bottom", "top"];
var colorsArray:Array = [0x76b6f8, 0x4291e1, 0x1f73c8, 0xe77111, 0xe8914c, 0xfad2b2];
for (var i:int = 0; i < interactiveMats.length; i++)
{
//Create a color box so we can use our MouseEvents
var colorBox:Sprite = new Sprite();
colorBox.graphics.beginFill(colorsArray[i]);
colorBox.graphics.drawRect(0, 0, 100, 100);
colorBox.graphics.endFill();
colorBox.name = interactiveMats[i];
//Add a textField for reference
var textField:TextField = new TextField()
colorBox.addChild(textField)
textField.text = interactiveMats[i];
//Add a MouseEvent to the Sprite
colorBox.mouseChildren = false;
colorBox.addEventListener(MouseEvent.CLICK, onMovieMatClicked);
//Create the MovieMat
var movieMat:MovieMaterial = new MovieMaterial(colorBox, true, true);
movieMat.interactive = true;
movieMat.smooth = true;
materialsList.addMaterial(movieMat, interactiveMats[i]);
}
//Create Cube
cube = new Cube(materialsList, 100, 100, 100);
//Add cube to the scene
scene.addChild(cube);
}
protected function onMovieMatClicked(evt:MouseEvent):void
{
if (tweening)
{
// Let it rotate again
tweening = false;
}
else
{
switch(evt.target.name) {
case "front":
targetrotationX = 0;
targetrotationY = 180;
targetrotationZ = 0;
tweening = true;
break;
case "back":
targetrotationX = 0;
targetrotationY = 0;
targetrotationZ = 0;
tweening = true;
break;
case "left":
targetrotationX = 0;
targetrotationY = -90;
targetrotationZ = 0;
tweening = true;
break;
case "right":
targetrotationX = 0;
targetrotationY = 90;
targetrotationZ = 0;
tweening = true;
break;
case "top":
targetrotationX = -90;
targetrotationY = 0;
targetrotationZ = 0;
tweening = true;
break;
case "bottom":
targetrotationX = 90;
targetrotationY = 0;
targetrotationZ = 180;
tweening = true;
break;
}
}
}
override protected function onRenderTick(event:Event = null):void
{
super.onRenderTick(event);
if (tweening) {
// If a face has been clicked
if (camera.zoom <230) {
// If the camera isn't zoomed enough then zoom in a bit more:
camera.zoom += Math.sqrt(230-camera.zoom)/5;
}
// Test each rotation and rotate it towards the target rotation:
// X axis:
if (cube.rotationX < targetrotationX)
{
cube.rotationX += Math.sqrt(targetrotationX-cube.rotationX);
cube.rotationX = Math.round(cube.rotationX);
}
else if (cube.rotationX > targetrotationX)
{
cube.rotationX -= Math.sqrt(cube.rotationX-targetrotationX);
cube.rotationX = Math.round(cube.rotationX);
}
// Y axis:
if (cube.rotationY < targetrotationY)
{
cube.rotationY += Math.sqrt(targetrotationY-cube.rotationY);
cube.rotationY = Math.round(cube.rotationY);
}
else if (cube.rotationY > targetrotationY)
{
cube.rotationY -= Math.sqrt(cube.rotationY-targetrotationY);
cube.rotationY = Math.round(cube.rotationY);
}
// Z axis:
if (cube.rotationZ < targetrotationZ)
{
cube.rotationZ += Math.sqrt(targetrotationZ-cube.rotationZ);
cube.rotationZ = Math.round(cube.rotationZ);
}
else if (cube.rotationZ > targetrotationZ)
{
cube.rotationZ -= Math.sqrt(cube.rotationZ-targetrotationZ);
cube.rotationZ = Math.round(cube.rotationZ);
}
}
else
{
// If the camera is zoomed in, it shouldn't be now
if (camera.zoom > 200)
{
// So zoom out a bit.
camera.zoom -= Math.sqrt(camera.zoom-2)/5;
}
// Rotate the cube a bit:
cube.rotationX += 2;
cube.rotationY += 2;
// Make sure that we dont "wind up" the rotation
if (cube.rotationX>= 360) cube.rotationX = 0;
if (cube.rotationY>= 360) cube.rotationY = 0;
}
}
}
}
code2 taken from: http://papervision2.com/advanced-interactivity/
However the article was submitted, it parsed < to < and > to >.
Do a find/replace for each of those and the bulk of the errors should go away.