I am making a basic platform game using as3, and am trying to find a way to detect if my player is on the platform so I can allow him to jump if he is on it, but not be able to jump if he's off the platform.Here is my code:
package {
import flash.display.MovieClip
import flash.events.Event
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Main extends MovieClip
{
var _vx = 0
var _vy = 0
var _ay = 0.5
var _isOnGround:Boolean
var canJump:Boolean
var _collisionArea:MovieClip
// Constants:
// Public Properties:
// Private Properties:
// Initialization:
public function Main()
{
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp)
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
_vx = -5;
}
else if (event.keyCode == Keyboard.RIGHT)
{
_vx = 5;
}
else if (event.keyCode == Keyboard.UP )
{
if (canJump)
{
_vy = -10
}
}
}
function onKeyUp(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
_vx = 0;
}
else if (event.keyCode == Keyboard.RIGHT)
{
_vx = 0;
}
}
public function onEnterFrame(event:Event):void
{
if(player1.isOnGround)
{
canJump=true
}
else if (!player1.isOnGround)
{
canJump=false
}
if (_vy > 10)
{
_vy = 10
}
player1.y += _vy
player1.x += _vx
vy += _ay
//Player vs wall collision
for (var i:int = 0; i <= 4; i++)
{
CollisionB.platform_BlockRectangles(player1, this["wall" + i]);
//trace("wall" + i);
}
}
public function set vx(vxValue:Number):void
{
_vx = vxValue;
}
public function get vx():Number
{
return _vx;
}
public function set vy(vyValue:Number):void
{
_vy = vyValue;
}
public function get vy():Number
{
return _vy;
}
public function get isOnGround():Boolean
{
return _isOnGround;
}
public function set isOnGround(onGround:Boolean):void
{
_isOnGround = onGround;
}
public function get collisionArea():MovieClip
{
return _collisionArea;
}
}
}
Im also using another class where the code is:
static public function platform_BlockRectangles(objectA:Object,objectB:Object):void
{
//This function requires the following setter properties in objectA:
// _objectIsOnGround:Boolean, vx:Number, vy:Number
var objectA_Halfwidth=objectA.width/2;
var objectA_Halfheight=objectA.height/2;
var objectB_Halfwidth=objectB.width/2;
var objectB_Halfheight=objectB.height/2;
var dx=objectB.x-objectA.x;
var ox=objectB_Halfwidth+objectA_Halfwidth-Math.abs(dx);
if (0<ox)
{
var dy=objectA.y-objectB.y;
var oy=objectB_Halfheight+objectA_Halfheight-Math.abs(dy);
if (0<oy)
{
if (ox<oy)
{
if (dx<0)
{
ox*=-1;
oy=0;
}
else
{
oy=0;
}
//Dampen horizontal velocity
objectA.vx=0;
}
else
{
if (dy<0)
{
ox=0;
oy*=-1;
objectA.isOnGround=true;
}
else
{
ox=0
}
//Dampen vertical velocity
objectA.vy=0;
}
objectA.x-=ox;
objectA.y+=oy;
}
}
}
Someone please help!!!!!!!
I extremely recommend you to use some library like: Flixel, Citrus
Try to follow this tutorial, will explain all necessary logic to help you with your game
You can use AABB collision detection. Here is a tutorial (the Distance function part).
If you google the term you will get a lot of info in the subject.
But i recomend you to use flixel or flashPunk is you are just starting and want to do games, they take care of these stuff for you and you can get to just make the game.
Related
I'm new here (and also relatively new with AS3 as well), so bear with me.
I've only discovered OOP 2 weeks ago, and before then, I knew only the most rudimentary knowledge of AS3. So I did make a lot of improvement, but one thing's been bugging me.
I can never seem to call functions and methods from parent classes. Even with setters and getters, the child class always gives me an output error. It looks something like this.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Axiom/clicked()
This is an AS3 project that I'm working on right now that is giving me this problem.
Here's some basic background of the project.
I have the main class, called Main, and some other classes, called Axiom and Textbox. Main creates Axiom into a movieclip (background) that's already present on the stage. Axiom creates Textbox when clicked. Axiom calls a method called mouseClick from Main (plays a sound), and Textbox calls some properties from Axiom (text for the textbox).
I have attempted to use
MovieClip(this.parent).mouseClick();
and declaring a new variable in the child class, like this.
private var main:Main;
...
main.mouseClick();
And this leads me to question - what am I doing wrong, and how should I do it properly?
Here are the classes for reference.
Main.as
package {
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Mouse;
import flash.events.MouseEvent;
public class Main extends MovieClip {
// sound
private var music:Music = new Music();
private var clickSound:Click = new Click();
// instructions
private var instructions:Instructions = new Instructions();
// mouse
private var cursor:Cursor = new Cursor();
// player
private var player:Player = new Player();
private var animationState:String = "standing";
private var directionState:String = "right";
// Axiom
private var axiom:Axiom = new Axiom();
// movement
private var rightPressed:Boolean = false;
private var leftPressed:Boolean = false;
private var upPressed:Boolean = false;
private var downPressed:Boolean = false;
private var xMovement:Number = 0;
private var yMovement:Number = 0;
private var speed:Number = 22;
private var friction:Number = 0.9;
private var rDoubleTapCounter:int = 0;
private var lDoubleTapCounter:int = 0;
private var dDoubleTapCounter:int = 0;
private var uDoubleTapCounter:int = 0;
private var doubleTapCounterMax:int = 5;
private var running:Boolean = false;
public function Main() {
// constructor code
// mouse
stage.addChild(cursor);
cursor.mouseEnabled = false;
Mouse.hide();
// instructions
instructions.x = 640;
instructions.y = 120;
stage.addChild(instructions);
// add player
player.x = 642;
player.y = 448.95;
player.gotoAndStop(directionState);
player.right.gotoAndStop(animationState);
addChild(player);
// add Axiom
axiom.x = 300;
axiom.y = -150;
back.addChild(axiom);
// keyboard events
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
// music
music.play(0, int.MAX_VALUE);
// loop
stage.addEventListener(Event.ENTER_FRAME, loop);
}
private function loop(e:Event):void {
// set mouse
cursor.x = stage.mouseX;
cursor.y = stage.mouseY;
// set Movement to speed
if (rightPressed) {
if (upPressed) {
if (running || (rDoubleTapCounter <= doubleTapCounterMax && uDoubleTapCounter <= doubleTapCounterMax)) {
xMovement = speed * 2;
yMovement = speed * -2;
} else {
xMovement = speed;
yMovement = speed * -1;
}
} else if (downPressed) {
if (running || (rDoubleTapCounter <= doubleTapCounterMax && dDoubleTapCounter <= doubleTapCounterMax)) {
xMovement = speed * 2;
yMovement = speed * 2;
} else {
xMovement = speed;
yMovement = speed;
}
} else if (running || rDoubleTapCounter <= doubleTapCounterMax) {
xMovement = speed * 2;
} else {
xMovement = speed;
}
} else if (leftPressed) {
if (upPressed) {
if (running || (lDoubleTapCounter <= doubleTapCounterMax && uDoubleTapCounter <= doubleTapCounterMax)) {
xMovement = speed * -2;
yMovement = speed * -2;
} else {
xMovement = speed * -1;
yMovement = speed * -1;
}
} else if (downPressed) {
if (running || (lDoubleTapCounter <= doubleTapCounterMax && dDoubleTapCounter <= doubleTapCounterMax)) {
xMovement = speed * -2;
yMovement = speed * 2;
} else {
xMovement = speed * -1;
yMovement = speed;
}
} else if (running || lDoubleTapCounter <= doubleTapCounterMax) {
xMovement = speed * -2;
} else {
xMovement = speed * -1;
}
} else if (downPressed) {
if (dDoubleTapCounter <= doubleTapCounterMax || running) {
yMovement = speed * -2;
} else {
yMovement = speed * -1;
}
} else if (upPressed) {
if (uDoubleTapCounter <= doubleTapCounterMax || running) {
yMovement = speed * -2;
} else {
yMovement = speed * -1;
}
}
// double tap counter
if (rightPressed == false) {
rDoubleTapCounter++;
}
if (leftPressed == false) {
lDoubleTapCounter++;
}
if (downPressed == false) {
dDoubleTapCounter++;
}
if (upPressed == false) {
uDoubleTapCounter++;
}
// change labels
if (player.currentLabel != animationState) {
player.right.gotoAndStop(animationState);
}
// friction
xMovement *= friction;
yMovement *= friction;
// animationState and stop
if (Math.abs(xMovement) > 1) {
if (Math.abs(xMovement) > 22) {
animationState = "running";
running = true;
} else {
animationState = "trotting";
running = false;
}
} else {
animationState = "standing";
xMovement = 0;
}
// right or left facing
if (xMovement > 0) {
player.scaleX = 1;
} else if (xMovement < 0) {
player.scaleX = -1;
}
//movement
if (back.x >= back.width / 2 - 50) {
if (player.x >= 642 && xMovement > 0) {
player.x = 642;
back.x -= xMovement;
} else {
if (player.x <= player.width / 2 && xMovement < 0) {
xMovement = 0;
} else {
player.x += xMovement;
}
}
} else if (back.x <= 1280 - back.width / 2 + 50) {
if (player.x <= 642 - 30 && xMovement < 0) {
player.x = 642;
back.x -= xMovement;
} else {
if (player.x >= 1280 + 30 - player.width / 2 && xMovement > 0) {
xMovement = 0;
} else {
player.x += xMovement;
}
}
} else {
back.x -= xMovement;
}
}
private function keyPressed(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.RIGHT) {
rightPressed = true;
} else if (e.keyCode == Keyboard.LEFT) {
leftPressed = true;
} else if (e.keyCode == Keyboard.DOWN) {
downPressed = true;
} else if (e.keyCode == Keyboard.UP) {
upPressed = true;
}
}
private function keyReleased(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.RIGHT) {
rightPressed = false;
rDoubleTapCounter = 0;
} else if (e.keyCode == Keyboard.LEFT) {
leftPressed = false;
lDoubleTapCounter = 0;
} else if (e.keyCode == Keyboard.DOWN) {
downPressed = false;
dDoubleTapCounter = 0;
} else if (e.keyCode == Keyboard.UP) {
upPressed = false;
uDoubleTapCounter = 0;
}
}
public function mouseClick():void {
clickSound.play();
}
}
}
Axiom.as
package {
import flash.events.MouseEvent;
import flash.events.EventDispatcher;
import flash.display.MovieClip;
public class Axiom extends MovieClip {
private var speechBox:Textbox = new Textbox();
private var speech:String = "Something came out of that pop.";
private var main:Main;
public function Axiom() {
// constructor code
this.addEventListener(MouseEvent.CLICK, onClickStage);
this.addEventListener(MouseEvent.CLICK, clicked);
}
private function onClickStage(e:MouseEvent):void {
trace(e.target,e.target.name);
}
private function clicked(e:MouseEvent):void {
main.mouseClick();
stage.addChild(speechBox);
this.removeEventListener(MouseEvent.CLICK, clicked);
}
public function get words():String {
return speech;
}
public function removeThis():void {
this.addEventListener(MouseEvent.CLICK, clicked);
removeChild(speechBox);
}
}
}
Textbox.as
package {
import flash.events.MouseEvent;
import flash.display.MovieClip;
import com.greensock.TweenLite;
public class Textbox extends MovieClip{
private var axiom:Axiom;
private var main:Main;
public function Textbox() {
// constructor code
this.x = 40;
this.y = 360;
this.textBox.text = axiom.words;
TweenLite.from(this, 0.3, {x: "10", alpha: 0});
this.addEventListener(MouseEvent.CLICK, nextPage);
}
private function nextPage(e:MouseEvent):void{
main.mouseClick();
TweenLite.to(this, 0.3, {x: "-10", alpha: 0});
MovieClip(this.parent).removeThis();
}
}
}
Instead of trying to call functions of the parent (rarely a good idea), use Events instead.
In your Axiom Class:
package {
...import statements
public class Axiom extends MovieClip {
private var speechBox:Textbox = new Textbox();
private var speech:String = "Something came out of that pop.";
private var main:Main; //this shouldn't be here, ideally, Axiom knows NOTHING about the main class.
public function Axiom() {
// constructor code
this.addEventListener(MouseEvent.CLICK, onClickStage);
this.addEventListener(MouseEvent.CLICK, clicked);
}
private function onClickStage(e:MouseEvent):void {
trace(e.target,e.target.name);
}
private function clicked(e:MouseEvent):void {
//main.mouseClick(); // unneccesary
dispatchEvent(e); //the event you caught by performing a click will be dispatched again, so that the parent can react to it
stage.addChild(speechBox); //Axiom might not have access to the stage, addChild would suffice
this.removeEventListener(MouseEvent.CLICK, clicked);
}
public function get words():String {
return speech;
}
public function removeThis():void {
this.addEventListener(MouseEvent.CLICK, clicked);
removeChild(speechBox);
}
}
}
and in your Main Class
axiom.addEventListener(MouseEvent.CLICK, onAximClicked);
private function onAxiomClicked(e:MouseEvent):void{
//now you can use the parents (in this case an Object of the Main class) functions
mouseClick();
}
package
{
import flash.display.MovieClip;
import flash.events.*;
public class untitledCode extends MovieClip
{
private var speed:Number = 5;
public function untitledCode()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, whenKey1);
stage.addEventListener(KeyboardEvent.KEY_DOWN, whenKey2);
}
private function whenKey1(event:KeyboardEvent):void
{
if (event.keyCode == 38)
{
mcPlayer1.y -= speed;
}
if (event.keyCode == 40)
{
mcPlayer1.y += speed;
}
if (event.keyCode == 37)
{
mcPlayer1.x -= speed;
}
if (event.keyCode == 39)
{
mcPlayer1.x += speed;
}
if (event.keyCode == 96)
{
mcPlayer1.play();
}
}
private function whenKey2(event:KeyboardEvent):void
{
if (event.keyCode == 87)
{
mcPlayer2.y -= speed;
}
if (event.keyCode == 83)
{
mcPlayer2.y += speed;
}
if (event.keyCode == 65)
{
mcPlayer2.x -= speed;
}
if (event.keyCode == 68)
{
mcPlayer2.x += speed;
}
if (event.keyCode == 90)
{
mcPlayer2.play();
}
}
}
}
There are 2 MovieClips, mcPlayer1 and mcPlayer2. When I hold a key for one MovieClip and then press a key for another, the first MovieClip stops(and vice versa). How do I make them move simultaneously.
Based on the other answer I informed you about that was already on SO, I tested their answer and although it works, there is keyboard lag with their implementation. So I optimized it using the ENTER_FRAME event...
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
public class Main extends MovieClip
{
private var speed:Number = 5;
private var _keyDownStatus:Object = { };
public function Main()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, onDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onUp);
stage.addEventListener(Event.ENTER_FRAME, keyCheck);
}
private function onUp(e:KeyboardEvent):void {
_keyDownStatus[e.keyCode] = false;
}
private function onDown(e:KeyboardEvent):void {
_keyDownStatus[e.keyCode] = true;
}
private function keyCheck(e:Event):void {
// Player 1 Events
if (_keyDownStatus[Keyboard.LEFT]) {
mcPlayer1.x -= speed;
}
if (_keyDownStatus[Keyboard.RIGHT]) {
mcPlayer1.x += speed;
}
if (_keyDownStatus[Keyboard.UP]) {
mcPlayer1.y -= speed;
}
if (_keyDownStatus[Keyboard.DOWN]) {
mcPlayer1.y += speed;
}
if (_keyDownStatus[Keyboard.NUMPAD_0]) {
mcPlayer1.play();
}
//Player 2 Events
if (_keyDownStatus[Keyboard.A]) {
mcPlayer2.x -= speed;
}
if (_keyDownStatus[Keyboard.D]) {
mcPlayer2.x += speed;
}
if (_keyDownStatus[Keyboard.W]) {
mcPlayer2.y -= speed;
}
if (_keyDownStatus[Keyboard.S]) {
mcPlayer2.y += speed;
}
if (_keyDownStatus[Keyboard.Z]) {
mcPlayer2.play();
}
}
}
}
I've tested this in Flash CC 2014 and it works perfectly! I did change the name of the class in my example for my example to work, so please change it to be whatever class name you need it to be.
I do recommend you do add only one key down event listener and save each pushed key and add a key up event listener to remove, so, you can control when only one key is pressed or multiple keys.
I created a simple example (just to explain the main logic), you should adapt and optimize it for your own needs.
private var keyControl:Vector.<uint>;
public function Test()
{
keyControl = new Vector.<uint>();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onDownHandler, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_UP, onUpHandler, false, 0, true);
}
private function onUpHandler(event:KeyboardEvent):void
{
keyControl.splice(keyControl.indexOf(event.keyCode), 1);
}
private function onDownHandler(event:KeyboardEvent):void
{
if(!isKeyPressed(event.keyCode)) keyControl.push(event.keyCode);
/*
to check if some key is being pressed use
if(isKeyPressed(Keyboard.SPACE))
{
// do something
}
if(isKeyPressed(Keyboard.SPACE) && isKeyPressed(Keyboard.A))
{
// do something
}
*/
}
private function isKeyPressed(key:uint):Boolean
{
var returnValue:Boolean;
for (var i:int = 0, numKeys:uint = keyControl.length; i < numKeys; i++)
{
if(keyControl[i] == key)
{
returnValue = true;
break;
}
}
return returnValue;
}
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).
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");
}
}
I am creating a shooting game. I have encountered a problem with my code when I decided to create a method to remove the missile after reaching the top of the stage. I can run the program without any issues only I have realize that the missile was not remove away from the stage, if I hold the shooting button. However, if I tap the shooting button, the missile will removed away with this error #1009 printing out of the output.
Is there any solution to fix the problem?
Here's is the error after the missile flew to the top of the stage with debugging enabled:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Missle/destroyMissle()[E:\Experiment\ExperimentProject\Missle.as:39]
at main/checkMissleOffScreen()[E:\Experiment\ExperimentProject\main.as:63]
at main/eventUpdated()[E:\Experiment\ExperimentProject\main.as:51]
Here's the main's class:
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
/**
* ...
* #author test
*/
public class main extends MovieClip
{
//Objects
public var rect:MovieClip;
public var missle:Missle;
//Array
private var missleArray:Array;
//Keyboard section
var leftKeyIsDown:Boolean;
var rightKeyIsDown:Boolean;
var upKeyIsDown:Boolean;
var downKeyIsDown:Boolean;
var spaceKeyIsDown:Boolean;
//Speed
var characterSpeed:Number = 15;
//Main constructor
public function main()
{
//Array initializer
missleArray = new Array();
missle = new Missle();
//Update events listeners.
stage.addEventListener(Event.ENTER_FRAME, eventUpdated);
//Update keyboard events listeners
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUnpressed);
}
//Events functions
//This functions updated everytime the object is move
private function eventUpdated(e:Event):void
{
playerMoving();
playerClampMoving();
checkMissleOffScreen();
}
private function checkMissleOffScreen():void
{
for (var i = 0; i < missleArray.length; i++ )
{
var currentMissle:Missle = missleArray[i];
if (currentMissle.y < 0)
{
missleArray.splice(i, 1);
missle.destroyMissle();
}
}
}
private function playerClampMoving():void
{
if (rect.x < 0)
{
rect.x = 0;
}
if (rect.x > stage.stageWidth - rect.width)
{
rect.x = stage.stageWidth - rect.width;
}
if (rect.y < 0)
{
rect.y = 0;
}
if (rect.y > stage.stageHeight - rect.height)
{
rect.y = stage.stageHeight - rect.height;
}
}
private function playerMoving():void
{
if (leftKeyIsDown == true)
{
rect.x -= characterSpeed;
}
if (rightKeyIsDown == true)
{
rect.x += characterSpeed;
}
if (upKeyIsDown == true)
{
rect.y -= characterSpeed;
}
if (downKeyIsDown == true)
{
rect.y += characterSpeed;
}
if (spaceKeyIsDown == true)
{
shootingMissle();
}
}
private function shootingMissle():void
{
missle = new Missle();
missle.x = rect.x + (rect.width / 2);
missle.y = rect.y;
missleArray.push(missle);
trace(missleArray.length);
stage.addChild(missle);
}
//Keyboard functions
//Check to see whether the user releases the keyboard
private function keyUnpressed(e:KeyboardEvent):void
{
if (e.keyCode == 37)
{
leftKeyIsDown = false;
}
if (e.keyCode == 39)
{
rightKeyIsDown = false;
}
if (e.keyCode == 40)
{
downKeyIsDown = false;
}
if (e.keyCode == 38)
{
upKeyIsDown = false;
}
if (e.keyCode == 32)
{
spaceKeyIsDown = false;
}
}
//Check to see whether the user presses the keyboard
private function keyPressed(e:KeyboardEvent):void
{
if (e.keyCode == 37)
{
leftKeyIsDown = true;
}
if (e.keyCode == 39)
{
rightKeyIsDown = true;
}
if (e.keyCode == 40)
{
downKeyIsDown = true;
}
if (e.keyCode == 38)
{
upKeyIsDown = true;
}
if (e.keyCode == 32)
{
spaceKeyIsDown = true;
}
}
}
}
Here's the Missle's Class:
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* #author test
*/
public class Missle extends Sprite
{
public function Missle()
{
addEventListener(Event.ADDED_TO_STAGE, onAdd);
}
private function onAdd(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAdd);
//Objects are on the stage
init();
}
private function init():void
{
addEventListener(Event.ENTER_FRAME, missleLaunch);
}
private function missleLaunch(e:Event):void
{
this.y -= 15;
}
public function destroyMissle():void
{
parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME, missleLaunch);
}
}
}
Try this:
public function destroyMissle():void
{
if(parent !== null) parent.removeChild(this);
removeEventListener(Event.ENTER_FRAME, missleLaunch);
}
It is a possibility that you were calling .destroyMissile() more than once meaning parent would be null because you've removed it from the stage and it has no parent.