Action Script 3. Platform game physics glitch (gravity) - actionscript-3

when my player touches the floor, he is unable to move because he is on the floor and being incremented up.
In the main class I have the movement
private function processMovement():void
{
if (touchingGround)
{
if (upKey)
{
character.jumpUp();
}
if (leftKey)
{
character.moveLeft();
}
if (rightKey)
{
character.moveRight();
}
if (!leftKey && !rightKey && !upKey)
{
character.dontMove();
}
}
}
Then in the character class you will see this.
public class player extends OnGround
{
public var canJumpAn:Boolean;
public var attackAn:Boolean;
public var jumpheight:Number = 18;
public function player()
{
addEventListener(Event.ADDED_TO_STAGE, onAdd);
}
private function onAdd(e: Event): void
{
removeEventListener(Event.ADDED_TO_STAGE, onAdd);
}
public function moveLeft():void
{
//decrease VELOCITY
xV -= 2;
if (xV > -7)
{
xV = -7;
}
this.gotoAndStop("run");
//add this to the Mc . x pos baby.
this.x += xV;
this.scaleX = -1;
charIsrunning = true;
}
public function moveRight():void
{
//increase VELOCITY
xV += 2;
if (xV > 7)
{
xV = 7;
}
this.gotoAndStop("run");
//add this to the Mc . x pos baby.
this.x += xV;
this.scaleX = 1;
charIsrunning = true;
}
public function dontMove():void
{
//if no button presses then do this
this.gotoAndStop("stop");
//slowd down ball
xV *= friction;
charIsrunning = false;
isDefending = false;
//stop the ball if you're not moving
if (xV > - 1 && xV < 1)
{
xV = 0;
}
}
override public function positionOnLand():void
{
isJumping = false;
///=gotoAndStop(1);
}
public function defend():void
{
isDefending = true;
this.gotoAndStop("defend");
charIsrunning = false;
}
public function attack():void
{
this.gotoAndStop("attack");
}
public function jumpUp():void
{
if (!isJumping)
{
isJumping = true;
this.gotoAndStop("jump");
//
}
}
}
}
OnGround is another class that player extends, as you can see.
public class OnGround extends MovieClip
{
public var grav:Number;
public var friction:Number;
public var xV:Number;
public var yV:Number;
protected var charIsrunning:Boolean;
protected var isDefending:Boolean;
protected var isJumping:Boolean;
public function OnGround()
{
addEventListener(Event.ADDED_TO_STAGE, init)
charIsrunning = false;
isDefending = false;
//gotoAndStsop("jump");
}
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//gravity
grav = 0.6;
//y velocity
yV = 0;
//x velocity
xV = 0;
//
friction = 0.9;
addEventListener(Event.ENTER_FRAME, fall);
}
private function fall(e:Event):void
{
//add grav to y VELOCITY
yV += grav;
trace(yV);
this.y += yV
}
public function incrementUp():void
{
this.y -= 0.1;
//trace("incrementing");
}
public function keepOnGround():void
{
//trace("onGroundBitch");
grav = 0;
yV = 0;
positionOnLand();
}
public function positionOnLand():void
{
//overide
}
}
}
This is a function that's in the main class
for (var c:int = 0; c < childrenOnStage; c++)
{
if (getChildAt(c).name == "player")
{
if (ground.level1Ground.hitTestPoint(getChildAt(c).x + 13, getChildAt(c).y, true) || ground.level1Ground.hitTestPoint(getChildAt(c).x - 13, getChildAt(c).y, true))
{
getChildAt(c).y --;
//OnGround(getChildAt(c)).incrementUp();
OnGround(getChildAt(c)).keepOnGround();
touchingGround = true;
}
else
{
touchingGround = false;
}
The problem is that when the player touches the ground then it's y position is incremented until it isn't touching the ground and then it's suppose to be kept on the ground by turning grav to = 0 and y velocity to 0.
This means gravity is turned off and the players y position will not shift up (when I jump)
or when go down to be kept on ground.
I would appreciate it if someone can lend me a hand or point me in the correct direction.

I'm not sure why you'd have a gravity value per object unless you really intend to have different object instances have individual gravities.
If not I'd reference a gravity constant instead.
Is anti-gravity a feature of the game? if not then I'd avoid setting gravity to 0. It may 'work' (to an extent) but it's not a good model/abstraction of reality.
Rather, what I would do is seperate the force applied and the current momentum:
The (downward) force of gravity is applied at all times.
When you're standing on the ground an upward force equal and opposite to gravity is applied.
When you jump, add a one-off instance of upward force.
Use the current forces to change the current momentum and use the current momentum to change the position.

Related

How can I change Nested Class in actionscript 3

I'm working off an actionscript 3 code that pulls information from other actionscript 3's. The main code is Herbfight and it references 4 others (Bullets, bugs, Goodbugs and Sprayer). Below I'm trying to combine them all into one actionscript. The reason for this is that I want to pull it in as a symbol rather then having the flash file relate to the class.
The problem is it says I can't have nested classes. Any thoughts on how i can fix this? Below is my attempt to combine the code.
Thanks,
J
package {
import flash.display.;
import flash.events.;
import flash.utils.Timer;
import flash.text.TextField;
import flash.text.*;
import flash.utils.getTimer;
import flash.geom.Point;
public class herbfight_v004 extends MovieClip {
private var aagun:Sprayer;
private var airplanes:Array;
private var goodbug:Array;
private var bullets:Array;
private var upArrow, downArrow:Boolean;
private var nextPlane:Timer;
private var nextGbugs:Timer;
private var shotsLeft:int;
private var shotsHit:int;
private var Sprayer:MovieClip
private var Bullets:MovieClip
private var bugs:MovieClip
private var GooodBugs:MovieClip
public function startherbfight_v004() {
// init score
shotsLeft = 20;
shotsHit = 0;
showGameScore();
// create gun
aagun = new Sprayer();
addChild(aagun);
// create object arrays
airplanes = new Array();
bullets = new Array();
goodbug = new Array();
// listen for keyboard
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
// look for collisions
addEventListener(Event.ENTER_FRAME,checkForHits);
// start planes flying
setNextPlane();
setNextGbugs();
public function Sprayer() {
{
// animation time// initial location of gun
this.x = 410;
this.y = 380;
// movement
addEventListener(Event.ENTER_FRAME,moveGun);
}
public function moveGun(event:Event) {
// get time difference
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
// current position
var newy = this.y;
// move to the left
if (MovieClip(parent).upArrow) {
newy -= speed*timePassed/1000;
}
// move to the right
if (MovieClip(parent).downArrow) {
newy += speed*timePassed/1000;
}
// check boundaries
if (newy < 65) newy = 65;
if (newy > 380) newy = 380;
// reposition
this.y = newy;
}
// remove from screen and remove events
public function deleteGun() {
parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME,moveGun);
}
}
public function bugs(side:String, speed:Number, altitude:Number) {
{
if (side == "left") {
this.x = -50; // start to the left
dx = speed; // fly left to right
this.scaleX = 1; // reverse
} else if (side == "right") {
this.x = -50; // start to the right
dx = -speed; // fly right to left
this.scaleX = 1; // not reverse
}
this.y = altitude; // vertical position
// choose a random plane
this.gotoAndStop(Math.floor(Math.random()*4+1));
// set up animation
addEventListener(Event.ENTER_FRAME,movePlane);
lastTime = getTimer();
}
public function movePlane(event:Event) {
// get time passed
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
// move plane
this.x += dx*timePassed/2000;
// check to see if off screen
if ((dx < 0) && (x < -50)) {
deletePlane();
} else if ((dx > 0) && (x > 350)) {
deletePlane();
}
}
// plane hit, show explosion
public function planeHit() {
removeEventListener(Event.ENTER_FRAME,movePlane);
MovieClip(parent).removePlane(this);
gotoAndPlay("explode");
}
// delete plane from stage and plane list
public function deletePlane() {
removeEventListener(Event.ENTER_FRAME,movePlane);
MovieClip(parent).removePlane(this);
parent.removeChild(this);
}
}
public function Bullets(x,y:Number, speed: Number) {
{
// set start position
this.x = x;
this.y = y;
// get speed
dx = speed;
// set up animation
lastTime = getTimer();
addEventListener(Event.ENTER_FRAME,moveBullet);
}
public function moveBullet(event:Event) {
// get time passed
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
// move bullet
this.x += dx*timePassed/1000;
// bullet past top of screen
if (this.x < 0) {
deleteBullet();
}
}
// delete bullet from stage and plane list
public function deleteBullet() {
MovieClip(parent).removeBullet(this);
parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME,moveBullet);
}
}
public function GoodBugs(side:String, speed:Number, altitude:Number) {
{
if (side == "left") {
this.x = -50; // start to the left
dx = speed; // fly left to right
this.scaleX = -1; // reverse
} else if (side == "right") {
this.x = -50; // start to the right
dx = -speed; // fly right to left
this.scaleX = -1; // not reverse
}
this.y = altitude; // vertical position
// choose a random Gbugs
this.gotoAndStop(Math.floor(Math.random()*2+1));
// set up animation
addEventListener(Event.ENTER_FRAME,moveGbugs);
lastTime = getTimer();
}
public function moveGbugs(event:Event) {
// get time passed
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
// move Gbugs
this.x += dx*timePassed/2000;
// check to see if off screen
if ((dx < 0) && (x < -50)) {
deleteGbugs();
} else if ((dx > 0) && (x > 350)) {
deleteGbugs();
}
}
// Gbugs hit, show explosion
public function GbugsHit() {
removeEventListener(Event.ENTER_FRAME,moveGbugs);
MovieClip(parent).removeGbugs(this);
gotoAndPlay("explode");
}
// delete Gbugs from stage and Gbugs list
public function deleteGbugs() {
removeEventListener(Event.ENTER_FRAME,moveGbugs);
MovieClip(parent).removeGbugs(this);
parent.removeChild(this);
}
}
public function setNextPlane() {
nextPlane = new Timer(1000+Math.random()*1000,1);
nextPlane.addEventListener(TimerEvent.TIMER_COMPLETE,newPlane);
nextPlane.start();
}
public function newPlane(event:TimerEvent) {
// random side, speed and altitude
if (Math.random() > .2) {
var side:String = "left";
} else {
side = "right";
}
var altitude:Number = Math.random()*280+80;
var speed:Number = Math.random()*150+150;
// create plane
var p:bugs = new bugs(side,speed,altitude);
addChild(p);
airplanes.push(p);
// set time for next plane
setNextPlane();
}
public function setNextGbugs() {
nextGbugs = new Timer(1000+Math.random()*1000,1);
nextGbugs.addEventListener(TimerEvent.TIMER_COMPLETE,newGbugs);
nextGbugs.start();
}
public function newGbugs(event:TimerEvent) {
// random side, speed and altitude
if (Math.random() > .2) {
var side:String = "left";
} else {
side = "right";
}
var altitude:Number = Math.random()*280+80;
var speed:Number = Math.random()*150+150;
// create Gbugs
var p:GoodBugs = new GoodBugs(side,speed,altitude);
addChild(p);
goodbug.push(p);
// set time for next Gbugs
setNextGbugs();
}
// check for collisions
public function checkForHits(event:Event) {
for(var bulletNum:int=bullets.length-1;bulletNum>=0;bulletNum--){
for (var airplaneNum:int=airplanes.length-1;airplaneNum>=0;airplaneNum--) {
if (bullets[bulletNum].hitTestObject(airplanes[airplaneNum])) {
airplanes[airplaneNum].planeHit();
bullets[bulletNum].deleteBullet();
shotsHit++;
showGameScore();
break;
}
}
}
for(var bulletNum:int=bullets.length-1;bulletNum>=0;bulletNum--){
for (var GoodBugsNum:int= goodbug.length-1; GoodBugsNum>=0; GoodBugsNum--) {
if (bullets[bulletNum].hitTestObject(goodbug [GoodBugsNum])) {
goodbug [GoodBugsNum]. GbugsHit();
bullets[bulletNum].deleteBullet();
shotsHit--;
showGameScore();
break;
}
}
}
if ((shotsLeft == 0) && (bullets.length == 0)) {
endGame();
}
}
// key pressed
public function keyDownFunction(event:KeyboardEvent) {
if (event.keyCode == 38) {
upArrow = true;
} else if (event.keyCode == 40) {
downArrow = true;
} else if (event.keyCode == 32) {
fireBullet();
}
}
// key lifted
public function keyUpFunction(event:KeyboardEvent) {
if (event.keyCode == 38) {
upArrow = false;
} else if (event.keyCode == 40) {
downArrow = false;
}
}
// new bullet created
public function fireBullet() {
if (shotsLeft <= 0) return;
var b:Bullets = new Bullets(aagun.x,aagun.y,-300);
addChild(b);
bullets.push(b);
shotsLeft--;
showGameScore();
}
public function showGameScore() {
showScore.text = String("Score: "+shotsHit);
showShots.text = String("Shots Left: "+shotsLeft);
}
// take a plane from the array
public function removePlane(plane:bugs) {
for(var i in airplanes) {
if (airplanes[i] == plane) {
airplanes.splice(i,1);
break;
}
}
}
// take a plane from the array
public function removeGbugs(Gbugs:GoodBugs) {
for(var i in goodbug) {
if (goodbug[i] == Gbugs) {
goodbug.splice(i,1);
break;
}
}
}
// take a bullet from the array
public function removeBullet(bullet:Bullets) {
for(var i in bullets) {
if (bullets[i] == bullet) {
bullets.splice(i,1);
break;
}
}
}
// game is over, clear movie clips
public function endGame() {
// remove planes
for(var i:int=airplanes.length-1;i>=0;i--) {
airplanes[i].deletePlane();
}
for(var i:int= goodbug.length-1;i>=0;i--) {
goodbug [i].deleteGbugs();
}
airplanes = null;
goodbug = null
aagun.deleteGun();
aagun = null;
stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.removeEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
removeEventListener(Event.ENTER_FRAME,checkForHits);
nextPlane.stop();
nextPlane = null;
nextGbugs.stop();
nextGbugs = null;
gotoAndStop("gameover");
}
}
}

AS3 - how to remove a child when it reaches a certain point, and re add the child

So first off i'd like to state that i am not very good at AS3, i'm completely self taught so i am sure that there are many things i've done badly, inefficiently or plain wrong and i'm happy for any comments on these if there is things i can improve.
In addition, i have done this with classes, however i am now running into a time problem and have decided to make things work first and sort out the class files properly later, i know this is also very bad practice and makes more work than needed, however as i'm not so confident in their use, i would rather complete the work.
So to my question, i am creating a platform game and so far i've got the movement and jumping from platform to platform down, and i am trying to add the scrolling functionality of the game now, the way i am attempting this is by removing a child when it reaches the bottom of the screen, and then adding that child back in a random position.
on the start function i have this array to add the child and randomize it's position:
for(i=0;i<8;i++) {
PlatformInstance[i] =new Platform();
PlatformInstance[i].y= Math.random()*900;
PlatformInstance[i].x= Math.random() *1500;
stage.addChild(PlatformInstance[i]);
}
the code for my collisions and the scrolling is shown below:
for (i=0; i<8; i++) {
if (PlatformInstance[i].hitTestPoint (Smallclock_hero.x,Smallclock_hero.y+130,true)) {
yescollision = true;
if (keyboard_input.is_up() && yescollision == true)
{
trace ("boop")
Smallclock.y_speed = -40
yescollision = false;
}
else {
Smallclock.y_speed *= 0;
}
}
if (Scrolling == true) {
PlatformInstance[i].y += 1; // this moves the platforms down.
}
}
is there a simple and easy way to remove the PlatformInstance when it reaches a point say (1000) and then add the instance again, with the same randomization code?
thanks in advance.
Adding all of my class files for clarities sake, not sure if you will need them
Start.as
package com {
import flash.display.MovieClip;
import flash.events.Event;
public class Start extends MovieClip {
public var keyboard_input:Keys;
public var Smallclock_hero = new Smallclock;
public var BasePlatformInstance:BasePlatform = new BasePlatform;
public var BackgroundInstance:Background = new Background();
public var PlatformInstance:Platform = new Platform();
public var keyboard_sprite = new MovieClip();
public static var yescollision:Boolean = false
var yScrollSpeed:int = 1;
var Scrolling:Boolean = false;
var i:int =0;
public var Running:Boolean = true;
public function Start () {
trace("Hello")
addChild (BackgroundInstance);
addChild (Smallclock_hero);
addChild (BasePlatformInstance);
BasePlatformInstance.x = 0;
BasePlatformInstance.y = 980;
BackgroundInstance.height = stage.stageHeight +50 ;
BackgroundInstance.width = stage.stageWidth +50 ;
Smallclock_hero.init();
var keyboard_sprite = new MovieClip();
addChild (keyboard_sprite);
keyboard_input = new Keys (keyboard_sprite);
stage.addEventListener(Event.ENTER_FRAME,on_enter);
addEventListener (Event.ENTER_FRAME, collisions);
//addEventListener (Event.ENTER_FRAME,refreshPlatform)
for(i=0;i<8;i++) {
PlatformInstance[i] =new Platform();
PlatformInstance[i].y= Math.random()*900;
PlatformInstance[i].x= Math.random() *1500;
stage.addChild(PlatformInstance[i]);
}
}
public function on_enter(event:Event) {
if (keyboard_input.is_left()){
Smallclock_hero.apply_force(-1,0);
Smallclock_hero.scaleX = -1
}
if (keyboard_input.is_right()) {
Smallclock_hero.apply_force(1,0);
Smallclock_hero.scaleX = 1
}
}
public function collisions (e:Event) {
if (BasePlatformInstance.hitTestPoint (Smallclock_hero.x,Smallclock_hero.y+130, true)) {
//trace ("touching!")
yescollision = true;
if (keyboard_input.is_up())
{
Smallclock.y_speed = -40
Start.yescollision = false;
}
if (Smallclock.y_speed ==-40) {
Scrolling = true;
removeChild(BasePlatformInstance);
}
else {
Smallclock.y_speed *= 0;
}
}
for (i=0; i<8; i++) {
if (PlatformInstance[i].hitTestPoint (Smallclock_hero.x,Smallclock_hero.y+130, true)) {
yescollision = true;
if (keyboard_input.is_up() && yescollision == true)
{
trace ("boop")
Smallclock.y_speed = -40
yescollision = false;
}
else {
Smallclock.y_speed *= 0;
}
}
if (Scrolling == true) {
PlatformInstance[i].y += 1;
}
}
Smallclock.as
package com {
import flash.display.Sprite;
import flash.events.Event;
public class Smallclock extends Sprite {
private var x_speed:Number;
public static var y_speed:Number;
private var power:Number;
public var friction:Number;
public static var gravity:Number;
public static var jumping:Boolean = false;
public static var jumppwr:Number;
public static var jumpSpeedLimit:int = 15;
public function Smallclock() {
addEventListener (Event.ENTER_FRAME, move);
}
private function move (e:Event) {
x+=x_speed;
y+=y_speed;
y_speed += gravity
x_speed *= friction ;
y_speed *= friction ;
if (x < -25) {
x = 1650
}
if (x > 1650) {
x = -25
}
}
public function apply_force (x_force,y_force){
x_speed += (x_force*power);
y_speed += (y_force*power);
}
public function init() {
jumppwr = 2;
gravity = 1.0;
power = 0.8;
friction = 0.9;
x_speed = 0;
y_speed = 0;
x= stage.stageWidth/2;
y = 850;
}
}
}
Keys.as
package com {
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Keys {
private var press_left = false;
private var press_right = false;
private var press_up = false;
private var press_down = false;
private var press_space = false;
public function Keys(movieclip) {
movieclip.stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
movieclip.stage.addEventListener(KeyboardEvent.KEY_UP, key_up);/**/
}
public function is_left() {
return press_left;
}
public function is_right() {
return press_right;
}
public function is_up() {
return press_up;
}
public function is_down() {
return press_down;
}
public function is_space() {
return press_space;
}
public function key_down(event:KeyboardEvent) {
if (event.keyCode == 32) {
press_space = true;
}
if (event.keyCode == 37) {
press_left = true;
}
if (event.keyCode == 38) {
press_up = true;
}
if (event.keyCode == 39) {
press_right = true;
}
if (event.keyCode == 40) {
press_down = true;
}
}
public function key_up(event:KeyboardEvent) {
if (event.keyCode == 32) {
press_space = false;
}
if (event.keyCode == 37) {
press_left = false;
}
if (event.keyCode == 38) {
press_up = false;
}
if (event.keyCode == 39) {
press_right = false;
}
if (event.keyCode == 40) {
press_down = false;
}
}
}
}
I am not going to read thru all your code, sorry.
Of course there is. In the interval/event handler where you are updating your positions, you have to loop through all your platforms and check whether their position is >= 1000. If it is, you don't need to remove it, just randomize it and set its position again with the code you already have:
for(i=0;i<8;i++) {
if(PlatformInstance[i].x >= 1000) {
var inst:Platform = PlatformInstance[i];
inst.y= Math.random() * 900;
inst.x= Math.random() * 1500;
}
That should work just fine. If you really need to remove it (??), you can do so with stage.removeChild(inst) and then stage.addChild(inst) again.
A few tips from that few code I read in your question: do not give instance/variable names with capitalized first letter. That should be a class name (PlatformInstance is obviously an instance of Array or Vector, use platformInstance). Do not add object directly to stage. If possible, add them to your stage owner (which is your document class if you write your code in classes).

To much FPS drop

http://www.fastswf.com/USUAp00
When i scale my procedural generated map based off a perlin noise map to a bigger size, so i can place a character on the map and actually navigate it (moving the map around the player instead of the player around the map), it gets major fps drop.
Test for yourself with the provided link, the higher the scale or map width/height is increased the more it lags while walking. I understand this is allot of data blocks to move
Is there a better way to go about moving my player around?
Would adding the spawned objects to an object pool help? I don't think it would
Is it possible to split the map into segments after generation and load certain segments based off your x,y?
World class: //handles spawning the map
http://pastebin.com/CfMDBWeR
Level class: // handles moving the map around
public class Level extends MovieClip
{
var world:World;
protected var goin:Vector.<int> = new Vector.<int>();
protected var moveSpeed:int;
protected var MAP_SCALE:int;
public function Level()
{
MAP_SCALE = GlobalCode.MAP_SCALE;
trace("level")
for(var i:int = 0; i < 4; i++){
goin[i]=0;
}
world = new World(this);
addEventListener(Event.ENTER_FRAME, update);
addEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.REMOVED_FROM_STAGE, cleanUp);
moveSpeed = 10;
// constructor code
}
protected function init(e:Event)
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
}
protected function cleanUp(e:Event)
{
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.removeEventListener(KeyboardEvent.KEY_UP, keyReleased);
}
protected function keyPressed(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.W)
{
goin[0] = 1;
}
if (k.keyCode == Keyboard.S)
{
goin[1] = 1;
}
if (k.keyCode == Keyboard.A)
{
goin[2] = 1;
}
if (k.keyCode == Keyboard.D)
{
goin[3] = 1;
}
}
protected function MovePlayer(){
if (goin[0] == 1)
{
world.worldTiles.y += moveSpeed;
}
if (goin[1] == 1)
{
world.worldTiles.y -= moveSpeed;
}
if (goin[2] == 1)
{
world.worldTiles.x += moveSpeed;
}
if (goin[3] == 1)
{
world.worldTiles.x -= moveSpeed;
}
}
protected function keyReleased(k:KeyboardEvent)
{
if (k.keyCode == Keyboard.W)
{
goin[0] = 0;
}
if (k.keyCode == Keyboard.S)
{
goin[1] = 0;
}
if (k.keyCode == Keyboard.A)
{
goin[2] = 0;
}
if (k.keyCode == Keyboard.D)
{
goin[3] = 0;
}
}
public function update(e:Event)
{
world.worldTiles.scaleX = MAP_SCALE;
world.worldTiles.scaleY = MAP_SCALE;
MovePlayer();
}
}
Stage Class: The class actually connected to the stage, handles frame switching
public class Stage extends MovieClip {
private var targetFrame:String;
public function Stage() {
targetFrame = "Menu";
// constructor code
}
private function gotoLabel(desiredLabel:String)
{
for (var i=0; i<currentLabels.length; i++)
{
if (currentLabels[i].name == desiredLabel)
{
gotoAndPlay(desiredLabel);
return;
}
}
trace("Requested frame missing!");
}
public function generateMap(m:MouseEvent){
GlobalCode.TILE_SIZE = int(tileSizeText.text);
GlobalCode.MAP_HEIGHT = int(mapHeightText.text);
GlobalCode.MAP_WIDTH = int(mapWidthText.text);
GlobalCode.MAP_SCALE = int(mapScaleText.text);
gotoLabel("Game");
}
private function doneLoading(m:MouseEvent)
{
//set targetFrame
gotoLabel("Menu");
}
}

AS3 - Movie Clip animations (undesirably) bob up and down. [Playable SWF included]

Im making a game where the player controls a movieclip (_character) around the stage with the arrows or WASD. On the stage there are squares/boxes with collision detection. Plus a 50 pixel stage boundary.
_character has five key frames, each with an animation inside, which plays when the four direction buttons are pressed, plus the red stationary animation when no keys are pressed. While moving the characters body and head should be still, with the legs moving. Example below
_character Right Animation
However my problem is that the Movie clip bobs up and down at different areas around the stage, then is fine in others.
In the SWF example below you’ll see the characters mouth and shoulders bobbing up and down around the stage, but strangely enough its back to normal at the bottom of the play area. (Apart from in-between the two boxes to the lower right.)
Rookies Game SWF
This is the embedded SWF featuring all frames. The only thing that should change is the body colour and the eyes and legs moving. The head and shoulders dont bob up and down.
ChAracter Resource SWF
Does anyone have any idea what this is or why its happening? I triple checked my character swf just in case there is a miss-positioned frame to create the bouncing/bobbing animation, but they are all correct, the swf should not be doing that.
If I remove some boxes, the bobbing effect stops in some areas, but comes back in others. Sometimes when it touches a box it bobs and other sides of boxes it doesnt(?) Strangely enough, the bobbing returns when I press down at the bottom of the play area. In the other SWF the bottom of the stage was one of the few areas where the MovieClip didnt bob/bounce.
Rookies Game SWF w/ less boxes
If I remove all the boxes, the bobbing stops except when I press down on the bottom of the playable area. But only that one side causes the bobbing. If I remove the stage boundaries also, the bobbing completely stops presumably because there is nothing for the MovieClip to react to.
Current Code
Rookies game/Application class is used as a level switcher to put levelOne onto the stage.
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
[SWF(width="650", height="450", backgroundColor="#FFFFFF", frameRate="60")]
public class RookiesGame extends Sprite
{
private var _levelOne:LevelOne;
//public static var gameMute:Boolean = false;
public function RookiesGame()
{
_levelOne = new LevelOne(stage);
stage.addChild(_levelOne);
stage.addEventListener("levelOneComplete",levelTwoSwitchHandler);
}
private function levelTwoSwitchHandler(event:Event):void
{
}
}
}
Level One contains most of the code, and majority of the work.
package
{
//import statements
public class LevelOne extends Sprite
{
//Declare the variables to hold the game objects
private var _character:Character = new Character();
private var _background:Background = new Background();
private var _box1:Box = new Box();
//Other box vars
//A variable to store the reference to the stage from the application class
private var _stage:Object;
//Control System
private var _bUp:Boolean = false;
private var _bDown:Boolean = false;
private var _bLeft:Boolean = false;
private var _bRight:Boolean = false;
public function LevelOne(stage:Object)
{
_stage = stage;
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(event:Event):void
{
startGame();
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function startGame():void
{
//Add them to stage.
addGameObjectToLevel(_background, 0, 0);
addGameObjectToLevel(_box1, 300, 200);
//Other boxes added to level
//Add character
this.addChild(_character);
_character.x = 300;
_character.y = 50;
_character.gotoAndStop(1);
playGame();
}
private function playGame():void
{ //EVENT LISTENERS////////////////////////
_stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(event:Event):void
{
_character.accelerationX = 0;
_character.accelerationY = 0;
_character.friction = 0.94;
var _updown:Boolean=Boolean(!(_bUp==_bDown));
var _leftright:Boolean=Boolean(!(_bLeft==_bRight));
if (!_updown && !_leftright)
{ // not moving anywhere
_character.gotoAndStop(1);
_character.accelerationX = 0;
_character.accelerationY = 0;
_character.friction = 0.94;
_character.vy=0;
_character.vx=0;
}
else
{
if (_bUp)
{
_character.accelerationY = -0.5;
_character.gotoAndStop(2);
}
else if (_bDown)
{
_character.accelerationY = 0.5;
_character.gotoAndStop(3);
}
if (_bLeft)
{
_character.accelerationX = -0.5;
_character.gotoAndStop(4);
}
else if (_bRight)
{
_character.accelerationX = 0.5;
_character.gotoAndStop(5);
}
}
//Apply friction
_character.vx *= _character.friction;
_character.vy *= _character.friction;
//Apply acceleration
_character.vx += _character.accelerationX;
_character.vy += _character.accelerationY;
//Limit the speed
if (_character.vx > _character.speedLimit)
{
_character.vx = _character.speedLimit;
}
if (_character.vx < -_character.speedLimit)
{
_character.vx = -_character.speedLimit;
}
if (_character.vy > _character.speedLimit)
{
_character.vy = _character.speedLimit;
}
if (_character.vy < -_character.speedLimit)
{
_character.vy = -_character.speedLimit;
}
//Force the velocity to zero after it falls below 0.1
if (Math.abs(_character.vx) < 0.1)
{
_character.vx = 0;
}
if (Math.abs(_character.vy) < 0.1)
{
_character.vy = 0;
}
//Move the character
_character.x += _character.vx;
_character.y += _character.vy;
checkStageBoundaries(_character);
//Box Collisions
Collision.block(_character,_box1);
Other box collisions
}
private function checkStageBoundaries(gameObject:MovieClip):void
{
if (gameObject.x < 50)
{
gameObject.x = 50;
}
if (gameObject.y < 50)
{
gameObject.y = 50;
}
if (gameObject.x + gameObject.width > _stage.stageWidth - 50)
{
gameObject.x = _stage.stageWidth - gameObject.width - 50;
}
if (gameObject.y + gameObject.height > _stage.stageHeight - 50)
{
gameObject.y = _stage.stageHeight - gameObject.height - 50;
}
}
public function replay():void
{
_stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
_stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
startGame();
}
private function keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == 65 )
{
_bLeft=true;
}
else if (event.keyCode == Keyboard.RIGHT || event.keyCode == 68)
{
_bRight=true;
}
else if (event.keyCode == Keyboard.UP || event.keyCode == 87 )
{
_bUp=true;
}
else if (event.keyCode == Keyboard.DOWN || event.keyCode == 83)
{
_bDown=true;
}
if (event.keyCode == Keyboard.ENTER)
{
replay();
}
}
private function keyUpHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT
|| event.keyCode == 65 || event.keyCode == 68)
{
_bLeft=false;
_bRight=false;
}
else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP
|| event.keyCode == 87 || event.keyCode == 83 )
{
_bUp=false;
_bDown=false;
}
}
private function addGameObjectToLevel(gameObject:Sprite, xPos:int, yPos:int):void
{
this.addChild(gameObject);
gameObject.x = xPos;
gameObject.y = yPos;
}
}
}
_character is an instance of the Character Class.
The SWF has five key frames, each with an animation inside, which plays when the four direction buttons are pressed, plus the red stationary animation when nothing is being pressed.
package
{
import flash.display.MovieClip;
import flash.display.DisplayObject
[Embed(source="../swfs/characterResource.swf", symbol="Character")]
public class Character extends MovieClip
{
//Public properties
public var vx:Number = 0;
public var vy:Number = 0;
public var accelerationX:Number = 0;
public var accelerationY:Number = 0;
public var speedLimit:Number = 4;
public var friction:Number = 0.94;
public function Character()
{
}
}
}
The Box and Background classes are the same, they just show the sprites. Note that the grid background is a single image. The game is not tile based..
The Collision Class. When _character collides with a box, it calls the Collision.block function.
package
{
import flash.display.Sprite;
public class Collision
{
static public var collisionSide:String = "";
public function Collision()
{
}
static public function block(r1:Sprite, r2:Sprite):void
{
//Calculate the distance vector
var vx:Number
= (r1.x + (r1.width / 2))
- (r2.x + (r2.width / 2));
var vy:Number
= (r1.y + (r1.height / 2))
- (r2.y + (r2.height / 2));
//Check whether vx
//is less than the combined half widths
if(Math.abs(vx) < r1.width / 2 + r2.width / 2)
{
//A collision might be occurring! Check
//whether vy is less than the combined half heights
if(Math.abs(vy) < r1.height / 2 + r2.height / 2)
{
//A collision has ocurred!
//Find out the size of the overlap on both the X and Y axes
var overlap_X:Number
= r1.width / 2
+ r2.width / 2
- Math.abs(vx);
var overlap_Y:Number
= r1.height / 2
+ r2.height / 2
- Math.abs(vy);
//The collision has occurred on the axis with the
//*smallest* amount of overlap. Let's figure out which
//axis that is
if(overlap_X >= overlap_Y)
{
//The collision is happening on the X axis
//But on which side? _v0's vy can tell us
if(vy > 0)
{
collisionSide = "Top";
//Move the rectangle out of the collision
r1.y = r1.y + overlap_Y;
}
else
{
collisionSide = "Bottom";
//Move the rectangle out of the collision
r1.y = r1.y - overlap_Y;
}
}
else
{
//The collision is happening on the Y axis
//But on which side? _v0's vx can tell us
if(vx > 0)
{
collisionSide = "Left";
//Move the rectangle out of the collision
r1.x = r1.x + overlap_X;
}
else
{
collisionSide = "Right";
//Move the rectangle out of the collision
r1.x = r1.x - overlap_X;
}
}
}
else
{
//No collision
collisionSide = "No collision";
}
}
else
{
//No collision
collisionSide = "No collision";
}
}
}
}
Any help would be much appreciated.
Im also asking a question about the jump/shudder the Movieclip does when crossing gaps in the maze. If any of that info helps you, or you're smart enough to know the solution to that too, the question is HERE

AS3 Flash: Spawning 2 same objects from 1 class?

I am creating a game in AS3, and in the class file for an enemy's bullet, I have this code.
public class enemy2Bullet extends MovieClip
{
public function enemy2Bullet()
{
stop();
//Setup an event listener to see if the bullet is added to the stage.
addEventListener(Event.ADDED_TO_STAGE, onAdd);
}
private function onAdd(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAdd);
//Now that our object is on the stage, run our custom code.
init();
}
private function init():void
{
if (Math.random() <= 0.5)
{
addEventListener(Event.ENTER_FRAME, bullet2Loop)
}
else
{
addEventListener(Event.ENTER_FRAME, bullet2Loop2)
}
}
private function bullet2Loop(e:Event):void
{
if (currentLabel != "destroyed")
{
this.x += 8;
}
if (currentLabel == "destroyedComplete")
{
destroyEnemy2Bullet();
}
}
private function bullet2Loop2(e:Event):void
{
if (currentLabel != "destroyed")
{
this.x -= 8;
}
if (currentLabel == "destroyedComplete")
{
destroyEnemy2Bullet();
}
}
public function destroyEnemy2Bullet():void
{
{
//Remove the object from stage
stage.removeChild(this);
//Remove any event listeners
removeEventListener(Event.ENTER_FRAME, bullet2Loop);
}
}
}
After compiling, the game runs, but the bullet only shoots in 1 direction.
How can I make it such that the bullets are shot from both left and right, and stay in that direction?
Here's my enemy2 function.
private function enemy2Control():void
{
if (getTimer() - lastSpawnTime2 > 3000 && aEnemy2Array.length < 3)
{
var newEnemy2:MovieClip = new mcEnemy2;
newEnemy2.x = Math.random() * 800;
newEnemy2.y = 0;
aEnemy2Array.push(newEnemy2);
stage.addChild(newEnemy2);
lastSpawnTime2 = getTimer();
}
//Control enemy's bullets
for (var i:int = aEnemy2Array.length - 1; i >= 0; i--)
{
if (enemy2LastFire + 750 / (aEnemy2Array.length) < getTimer())
{
var currentEnemy2:mcEnemy2 = aEnemy2Array[i];
if (Math.random() < 0.06)
{
var newEnemy2Bullet:enemy2Bullet = new enemy2Bullet();
newEnemy2Bullet.x = currentEnemy2.x;
newEnemy2Bullet.y = currentEnemy2.y;
enemy2BulletArray.push(newEnemy2Bullet);
stage.addChild(newEnemy2Bullet);
enemy2LastFire = getTimer();
}
}
for (var j:int = enemy2BulletArray.length - 1; j >= 0; j--)
{
var currentEnemy2Bullet:enemy2Bullet = enemy2BulletArray[j];
if (currentEnemy2Bullet.y >= stage.stageHeight)
{
enemy2BulletArray.splice(j, 1);
currentEnemy2Bullet.destroyEnemy2Bullet();
}
if (currentEnemy2Bullet.hitTestObject(playerCore))
{
playerHP -= 1;
currentEnemy2Bullet.gotoAndPlay(2);
enemy2BulletArray.splice(j, 1);
}
}
}
}
Any help would be appreciated.
A few things:
• You can replace currentEnemy2Bullet with j and just delete the whole var currentEnemy2Bullet:enemy2Bullet = enemy2BulletArray[j]; statement.
• init() is never called. But it's best if you do the direction calculation and use newEnemy2Bullet.addEventListener(Event.ENTER_FRAME, whatever) within the actual initialization of newEnemy2Bullet.
• Truth to be told, your code is fairly messy and can be simplified. For example, you can just determine the direction of the bullet by giving the class a variable, give it a value on initialization, and have the loop update its position based on that variable.