I have got this error
"TypeError: Error #1009: Cannot access a property or method of a null object reference.
at sole_fla::MainTimeline/game()"
I just can't seems to display my score on the dynamic text box that I created that I named as "scoretext"
this is my code
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.display.MovieClip;
addEventListener(Event.ENTER_FRAME, game);
addEventListener(MouseEvent.CLICK, onClick);
var score:int = 0;
var high:int = 0;
const gravity:Number = 2;
const force: Number = 30;
const lyfe: Number = 100;
var yspeed: Number = 249;
var life: Number = 0;
function onClick(event:MouseEvent):void
{
//just testing if mouse input is detected
trace("The event handler works!");
}
//game main loop
function game(event: Event) {
score = 0;
life = lyfe;
yspeed = yspeed + gravity;
player.y = yspeed;
if(player.y - player.height/2 < 0)
player.y = player.height/2;
for (var i = 0; i < numChildren; i++) {
//test if mons hit player
if (mons.hitTestObject(player)){
life = life - 10;
trace("hit");
}
//test if starz hit player
if (starz.hitTestObject(player)){
//I believe this is the part where it gets the error
//this is my scoretext dynamic text box to display the score
scoretext.text = score.toString();
++score;
}
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_KeyboardDownHandler_2);
function fl_KeyboardDownHandler_2(event:KeyboardEvent):void
{
if(event.keyCode == 32){
yspeed = yspeed - force;
trace("Key Code Pressed: " + event.keyCode);
player.gotoAndPlay(41);
}
}
Changing frames does not go together well with persistent event listeners.
The listener is executed, but references to objects are null if the object is not present on the current frame.
When switching states in your application, terminate previous states properly by removing event listeners.
Related
I am making a minions game. My minion's instance name is sideMinion. The bananas are falling and everything works fine, but my removeChild() doesn't work properly. The error I'm getting is
Error #2025: The supplied DisplayObject must be a child of the caller.
The removeChild() or the hitTestObject doesn't work properly.
This is what I have in my banana as. class:
package {
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.Event;
public class banana extends MovieClip {
var velX: Number = 0;
var velY: Number = 0;
var falling: Boolean = false;
var gravity: Number = 0;
public function banana() {
var timing: Timer = new Timer(25, 0);
timing.addEventListener(TimerEvent.TIMER, moveMe);
timing.start();
}
private function moveMe(event: TimerEvent)
{
x += velX;
y += velY;
if (falling) velY += gravity;
/* trace("[BANANA] position:", x, y, "speed:", velX, velY);*/
}
public function setSpeed(dx,dy) {
velX = dx;
velY = dy;
}
public function setSpot(atX,atY){
this.x=atX;
this.y=atY;
}
public function makeItFall (){
falling=true;
}
}
}
And in my main program:
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
var leftKey:Boolean;
var rightKey:Boolean;
var upKey:Boolean;
var downKey:Boolean;
var jump:Boolean = false;
var xvelocity:int = 9;
var yvelocity:int = 3;
var gravity:Number = 7;
stage.addEventListener(Event.ENTER_FRAME, changeVelocity);
stage.addEventListener(KeyboardEvent.KEY_UP, checkKeyUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeyDown);
function changeVelocity(evt:Event){
moveMinion();
yvelocity += gravity;
}
function moveMinion(){
if (leftKey == true){
sideMinion.x -= xvelocity;
sideMinion.left();
}
if (rightKey == true){
sideMinion.x += xvelocity;
sideMinion.right();
}
}
function checkKeyDown(e:KeyboardEvent){
if (e.keyCode == Keyboard.LEFT){
leftKey = true;
}
else if (e.keyCode == Keyboard.RIGHT){
rightKey = true;
}
}
function checkKeyUp(e:KeyboardEvent){
if (e.keyCode == Keyboard.LEFT){
leftKey = false;
}
else if (e.keyCode == Keyboard.RIGHT){
rightKey = false;
}
}
btnStart.addEventListener(MouseEvent.CLICK, makeItFall);
function makeItFall(e:MouseEvent){
var numBananas = 6;
var theBananas: Array = new Array();
theBananas = [];
for (var i = 0; i < numBananas; i++) {
var aBanana: banana = new banana();
theBananas.push(aBanana);
btnStart.visible=false;
aBanana.y=30;
theBananas[i].setSpot(Math.random()*450+50,Math.random()*200+20);
theBananas[i].setSpeed((Math.random()), 1);
stage.addChild(aBanana);
}
var health: uint= 1;
addEventListener(Event.ENTER_FRAME, pickUpBananas);
function pickUpBananas(event:Event){
for( var i= 0; i<theBananas.length; ++i){
if (sideMinion.hitTestObject(theBananas[i])){
removeChild(theBananas[i]);
health=health+1;
trace(health);
}
}
}
}
stop();
Edit : format code
As you are adding child to stage, you'll have to remove it also from stage:
stage.removeChild(theBananas[i]);
For future, in some situations you can also use parent property if you don't know the actual parent:
theBananas[i].parent.removeChild(theBananas[i]);
In your game, I assume you want also to remove the bananas from theBananas-array when you remove bananas from stage, so that your array wont end up having already deleted bananas. So, here's couple modifications:
for(var i:int = theBananas.length-1; i>-1; i--){ //inverted loop
if (sideMinion.hitTestObject(theBananas[i])){
stage.removeChild(theBananas[i]);
theBananas.splice(i,1); //removing it from the array
health=health+1;
trace(health);
}
}
Inverted loop obviously loops from last element all the way to the first one, becouse if you'd remove the first element from the array, then second element would 'jump' into its place and loop would skip it.
I hope we all will soon get to see your game! :)
I have been making this game in AS3 and the basics work. The thing i am having trouble with is making a 'start' menu appear when the game starts but also when the player dies. I have been trying the .visible code but that didn't seem to work.
Question: What code do i add to my game that makes the start button appear when the game starts but also when the player dies. Code:
package{
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.Event; //used for ENTER_FRAME event
public class Main extends MovieClip{
//constants
const gravity:Number = 1.5; //gravity of the game
const dist_btw_obstacles:Number = 300; //distance between two obstacles
const ob_speed:Number = 8; //speed of the obstacle
const jump_force:Number = 15; //force with which it jumps
//variables
var player:Player = new Player();
var lastob:Obstacle = new Obstacle(); //varible to store the last obstacle in the obstacle array
var obstacles:Array = new Array(); //an array to store all the obstacles
var yspeed:Number = 0; //A variable representing the vertical speed of the bird
var score:Number = 0; //A variable representing the score
public function Main(){
init();
}
function init():void {
//initialize all the variables
player = new Player();
lastob = new Obstacle();
obstacles = new Array();
yspeed = 0;
score = 0;
//add player to center of the stage the stage
player.x = stage.stageWidth/2;
player.y = stage.stageHeight/2;
addChild(player);
//create 3 obstacles ()
createObstacle();
createObstacle();
createObstacle();
//Add EnterFrame EventListeners (which is called every frame) and KeyBoard EventListeners
addEventListener(Event.ENTER_FRAME,onEnterFrameHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, key_up);
}
private function key_up(event:KeyboardEvent){
if(event.keyCode == Keyboard.SPACE){
//If space is pressed then make the bird
yspeed = -jump_force;
}
}
function restart(){
if(contains(player))
removeChild(player);
for(var i:int = 0; i < obstacles.length; ++i){
if(contains(obstacles[i]) && obstacles[i] != null)
removeChild(obstacles[i]);
obstacles[i] = null;
}
obstacles.slice(0);
init();
}
function onEnterFrameHandler(event:Event){
//update player
yspeed += gravity;
player.y += yspeed;
//restart if the player touches the ground
if(player.y + player.height/2 > stage.stageHeight){
restart();
}
//Don't allow the bird to go above the screen
if(player.y - player.height/2 < 0){
player.y = player.height/2;
}
//update obstacles
for(var i:int = 0;i<obstacles.length;++i){
updateObstacle(i);
}
//display the score
scoretxt.text = String(score);
}
//This functions update the obstacle
function updateObstacle(i:int){
var ob:Obstacle = obstacles[i];
if(ob == null)
return;
ob.x -= ob_speed;
if(ob.x < -ob.width){
//if an obstacle reaches left of the stage then change its position to the back of the last obstacle
changeObstacle(ob);
}
//If the bird hits an obstacle then restart the game
if(ob.hitTestPoint(player.x + player.width/2,player.y + player.height/2,true)
|| ob.hitTestPoint(player.x + player.width/2,player.y - player.height/2,true)
|| ob.hitTestPoint(player.x - player.width/2,player.y + player.height/2,true)
|| ob.hitTestPoint(player.x - player.width/2,player.y - player.height/2,true)){
restart();
}
//If the bird got through the obstacle without hitting it then increase the score
if((player.x - player.width/2 > ob.x + ob.width/2) && !ob.covered){
++score;
ob.covered = true;
}
}
//This function changes the position of the obstacle such that it will be the last obstacle and it also randomizes its y position
function changeObstacle(ob:Obstacle){
ob.x = lastob.x + dist_btw_obstacles;
ob.y = 100+Math.random()*(stage.stageHeight-200);
lastob = ob;
ob.covered = false;
}
//this function creates an obstacle
function createObstacle(){
var ob:Obstacle = new Obstacle();
if(lastob.x == 0)
ob.x = 800;
else
ob.x = lastob.x + dist_btw_obstacles;
ob.y = 100+Math.random()*(stage.stageHeight-200);
addChild(ob);
obstacles.push(ob);
lastob = ob;
}
}
}
Thanks in advance!
Draw a Box (with colour fill but no outline). Convert to MovieClip type. Give a name eg: "Menu"
It will be
a container for your menu. Add content by double-clicking it, to add
graphics & text on new layers. Or if you have already have content on some other frames, then just "cut frames" and later do a "paste frames" inside the timeline of this new movieClip.
When you converted, it was added to the Library section
(ctrl + L). Find it ("Menu") in the library and right-click then choose "properties". In
linkage section click "export for actionscript". The Class name should become "Menu" automatically. Now just click "OK".
Example usage in game code.. (ie: To add to screen or remove etc)
//# load the movieClip...
var Menu_Screen : Menu = new Menu(); //# Menu is linkage name given in Library
//# Adding to screen...
gameContainer_MC.addChild( Menu_Screen );
gameCcontainer_MC.removeChild( Menu_Screen );
//# Controlling the movieClip...
Menu_Screen.x = 50;
gameContainer_MC.Menu_Screen.x = 50;
I was trying to add a gameover screen with a restart button for my game.I had placed the restart button at frame 22.When my player dies it goes to frame 22 and i'm able to restart the game on clicking the button,but this message gets looped in the output area.Please help me how i can correct this issue.
Issue is not there when i remove the line
gotoAndPlay(22);
at Frame 17,but without that i will not get the desired functionality.
Please find my code below
At Frame 17 - Game code
stop();
import flash.events.Event;
import flash.events.MouseEvent;
var mouseIsDown = false;
var speed = 0;
var score = 0;
addEventListener(Event.ENTER_FRAME,mainLoop);
stage.addEventListener(MouseEvent.MOUSE_DOWN,clicked);
stage.addEventListener(MouseEvent.MOUSE_UP,unclicked);
function clicked(m:MouseEvent)
{
mouseIsDown = true;
}
function unclicked(m:MouseEvent)
{
mouseIsDown = false;
}
function mainLoop(e:Event)
{
score = score + 10;
output.text = "Score: "+score;
if(mouseIsDown)
{
speed -= 2;
}
else
{
speed+=2;
}
if(speed > 10) speed = 10;
if(speed < -10) speed = -10;
player.y += speed;
for(var i = 0; i < numChildren; i++)
{
if (getChildAt(i) is Cloud || getChildAt(i) is Boundary)
{
var b = getChildAt(i) as MovieClip;
if(b.hitTestObject(player))
{
for(var counter = 0; counter < 12; counter++)
{
var boom = new Boom();
boom.x = player.x;
boom.y = player.y;
boom.rotation = Math.random() * 360;
boom.scaleX = boom.scaleY = 0.5 + Math.random();
addChild(boom);
}
player.visible = false;
removeEventListener(Event.ENTER_FRAME,mainLoop);
gotoAndPlay(22);
}
}
}
}
At frame 22 - Restart screen
stop();
import flash.events.MouseEvent;
foutput.text = "Score: "+ fscore;
btn_playagain.addEventListener(MouseEvent.CLICK, playagain);
function playagain(m:MouseEvent)
{
gotoAndPlay(17);
}
btnback3.addEventListener(MouseEvent.CLICK, backMain3);
function backMain3(m:MouseEvent)
{
gotoAndPlay(1);
}
At frame 1 - Main Menu screen
stop();
import flash.events.MouseEvent;
import flash.system.fscommand;
btnnewgame.addEventListener(MouseEvent.CLICK, newGame);
function newGame(m:MouseEvent)
{
gotoAndPlay(17);
}
btnins.addEventListener(MouseEvent.CLICK, instruct);
function instruct(m:MouseEvent)
{
gotoAndPlay(6);
}
btncredits.addEventListener(MouseEvent.CLICK, credits);
function credits(m:MouseEvent)
{
gotoAndPlay(11);
}
btnexit.addEventListener(MouseEvent.CLICK, exitfunc);
function exitfunc(m:MouseEvent)
{
fscommand("quit");
}
At Frame 6 - Instructions Screen
stop();
btnback1.addEventListener(MouseEvent.CLICK, backMain1);
function backMain1(m:MouseEvent)
{
gotoAndPlay(1);
}
At Frame 11 - Credits Screen
stop();
btnback2.addEventListener(MouseEvent.CLICK, backMain2);
function backMain2(m:MouseEvent)
{
gotoAndPlay(1);
}
That error means that you are trying to call a method on a null object, meaning one of the objects you are using on frame 22 doesn't actually exist at that moment.
The likely candidates for the offending variable are foutput, btn_playagain, and btnback3. Check to make sure that they are on the stage at frame 22, and are spelt correctly.
You use output.text on frame 17, are you sure that it should be foutput.text on frame 22?
So ok Im somewhat new to flash im more of a java man myself but anyway I keep getting this error and all the solutions ive been find either don't work or they break the games collision
Here's the Code
stop();
import flash.utils.Timer;
import flash.utils.getDefinitionByName;
import flash.events.Event;
import flash.events.TimerEvent;
var playerobj:player;
var nextObject:Timer;
var objects:Array = new Array();
var score:int = 0;
const speed:Number = 9.0;
playerobj = new player();
playerobj.y = 650;
addChild(playerobj);
setNextObject();
addEventListener(Event.ENTER_FRAME, moveObjects);
function setNextObject()
{
nextObject = new Timer(1000+Math.random()*1000,1);
nextObject.addEventListener(TimerEvent.TIMER_COMPLETE,newObject);
nextObject.start();
}
function newObject(e:Event)
{
var newObject:AI;
newObject = new AI();
newObject.x = Math.random() * 480;
addChild(newObject);
objects.push(newObject);
setNextObject();
}
function moveObjects(e:Event)
{
for (var i:int=objects.length-1; i>=0; i--)
{
objects[i].y += speed;
if (objects[i].y > 800)
{
removeChild(objects[i]);
score = score + 10000;
objects.splice(i,1);
}
if (objects[i].hitTestObject(playerobj))
{
cleanUp();
}
}
playerobj.x = mouseX;
}
function cleanUp():void
{
while (this.numChildren > 0)
{
removeChildAt(0);
}
nextObject.stop();
gotoAndStop(4);
stop();
}
It must be somehow related to this problem but whenever gotoAndStop is called the game seems to loop around back into the frame not really sure why, Thanks for your help
In the cleanup function, right after declaring it, you should remove the ENTER_FRAME event listener. Also, I would stop the timer before removing childs and I would just remove the objects you added to stage dynamically. And the stop() in the cleanup function is redundant.
function cleanUp():void {
removeEventListener(Event.ENTER_FRAME, moveObjects);
nextObject.stop();
for(var i:uint = 0; i < objects.length; i++){
removeChild(objects[i]);
}
removeChild(playerObj)
gotoAndStop(4);
}
Also, it's better to keep minimal code in the timeline and move as much as you can in classes.
the error is in the cleanUp()
function moveObjects(e:Event)
{
for (var i:int=objects.length-1; i>=0; i--)
{
objects[i].y += speed;
if (objects[i].y > 800)
{
removeChild(objects[i]);
score = score + 10000;
objects.splice(i,1);
}
if (objects[i].hitTestObject(playerobj))
{
cleanUp();
}
}
//playerobj no more exists if cleanUp() is called, move this line above cleanUp();
//playerobj.x = mouseX;
//or inside cleanUp() put that line
//removeEventListener(Event.ENTER_FRAME, moveObjects);
}
My game starts with a start frame. click a button to the game. if I hit an object I go to game over screen. Everytime I hit the start over button on the game over screen my characters controls get faster. I have set no variables for speed, simply just "mc_guy.x +=3" or .y , etc. If I had to say by how much faster I would want to say that the speed doubles.
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.display.MovieClip;
//prevent game loop
stop();
// event listeners for movement
mc_Guy.addEventListener(Event.ENTER_FRAME, update);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownGuy);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUpGuy);
// this array holds references to all the keys
var keys:Array = [];
//initiate default values
fuelGauge.height = 100;
//Gravity
addEventListener(Event.ENTER_FRAME,Gravity)
var GyAmt:Number = 5;
function Gravity(e:Event){
mc_Guy.y += GyAmt;
if (gameFloor.hitTestObject(mc_Guy)){
mc_Guy.y = gameFloor.y;}
else if (gameFloor2.hitTestObject(mc_Guy)){
mc_Guy.y = gameFloor2.y;}
else if (gameFloor3.hitTestObject(mc_Guy)){
mc_Guy.y = gameFloor3.y;}}
// the event listeners
function update(e:Event):void
{
if (keys[Keyboard.RIGHT])
{
mc_Guy.x += 3;
}
if (keys[Keyboard.LEFT])
{
mc_Guy.x -= 3;
}
if (keys[Keyboard.SPACE]){
mc_Guy.y -= 10;
//drain fuel
fuelGauge.height -= 1;
gaugePercent.text = String(fuelGauge.height)
if (fuelGauge.height == 0){
nextFrame();}}
}
function onKeyDownGuy(e:KeyboardEvent):void
{
keys[e.keyCode] = true;
}
function onKeyUpGuy(e:KeyboardEvent):void
{
keys[e.keyCode] = false;
}
//Array storing each wall
var MC_wall:Array = new Array(mc_Wall,mc_Wall2,mc_Wall5,
mc_Wall6,mc_Wall7,mc_Wall8,mc_Wall9,mc_Wall10,mc_Wall11,mc_Wall12, mc_Wall13)
//Collision Detection
addEventListener(Event.ENTER_FRAME,loop);
function loop(e:Event){
var i:Number = 0;
do {
if (MC_wall[i].hitTestObject(mc_Guy)){
nextFrame();}
i++;
} while (i < MC_wall.length);
/* for (var i:Number = 0; i < MC_wall.length; i++){
if (MC_wall[i].hitTestObject(mc_Guy)){
nextFrame();}
}*/
if(mc_Guy.hitTestPoint(mc_WallRun.x, mc_WallRun.y, false)){
nextFrame();}
else if(mc_Guy.hitTestObject(fuelPowerup)){
removeChild(fuelPowerup);
fuelGauge.height = 100;
gaugePercent.text = String(fuelGauge.height)}
else if(mc_Guy.hitTestObject(doorKey)){
removeChild(doorKey)
//open door
mc_Wall13.height -=20
mc_Wall13.y -= 10
}
}
//Object Movement
addEventListener(Event.ENTER_FRAME, onEnterFrame);
var spinSpeed:Number=6;
var axisMove:Number = 90;
var axisMovement:Number = 3;
function onEnterFrame(event:Event):void
{
mc_WallRun.rotation+=spinSpeed;
//count the movement on axis and move
axisMove -= 3;
mc_Wall9.x += axisMovement;
gameFloor3.x += axisMovement * .9;
if(axisMove <= 0){
axisMove += 90
axisMovement = axisMovement*-1
}
}
Gameover frame:
import flash.events.MouseEvent;
stop();
restartGame.addEventListener(MouseEvent.MOUSE_DOWN, playAgain);
function playAgain(event:MouseEvent):void{
prevFrame();
}
It sounds like when you restart your game
mc_Guy.addEventListener(Event.ENTER_FRAME, update);
is called again, without removing the previously added listener.
So update is now called two times on Event.ENTER_FRAME, and then once more per frame per game reset, causing the guy to move faster.