AS3: TypeError: Error #1009: Cannot access a property or method of a null object reference
AS3: TypeError: Error #1009: Cannot access a property or method of a null object reference
我一直在为一项任务开发一个 flash 游戏,到目前为止这真的很让人头疼。游戏相对简单,收集物品(纪念品),躲避敌人或失去生命值(理智),收集屏幕上的所有物品升级(物品,玩家和敌人重置,分数保持不变),被击中5次你得到游戏结束画面。
我遇到了一个烦人的奇怪错误。在没有物品的情况下结束游戏不会出现任何错误并且可以正常重置游戏(表面上),但问题是:
*在游戏结束时拥有任何物品会导致错误 1009。
*点击带有任何物品的退出游戏按钮会导致错误 1009。
*收集所有物品应该给"lvlUp"函数,但没有任何反应,if语句永远不会触发。
我在这个问题上度过了愉快的一天左右,并且有几次差点就把整个事情搞砸了,所以我决定在这里咨询经验丰富的编码人员。
对于乱码提前致歉,我才刚刚开始使用AS3
游戏文档class代码:
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.geom.Rectangle;
import player;
public class Memento extends MovieClip
{
//importing required variables
private var onScreenContent:Array;
private var playerSkill:int;
private var myXY:Array;
private var mySpeed:int;
private var border:Rectangle;
private var myMaxItems:int;
private var numItems:int;
private var numEnemies:int;
private var maxEnemies:int;
private var characterMC:player;
public var sanity:int;
public var mementos:int;
public var currentMementos:int;
//CONSTRUCTOR
public function Memento()
{
trace("initialising DOS game");
//simulates a selected skill level
playerSkill = 3;
sanity = 5;
mementos = 0;
onScreenContent = new Array ;
border = new Rectangle(30,180,870,750);
}
//code to add character into game at correct position
private function addCharacter():void
{
trace("Adding the character");
//set the initial values to character starting pos
var myXY:Array = [480,900];
var mySpeed:int = playerSkill + 6;
//create and add a new player to screen
characterMC = new player(myXY,border,mySpeed);
addChild(characterMC);
characterMC.focusRect = false;
stage.focus = characterMC;
}//end function addCharacter
//code to add items into game
private function addItems():void
{
trace("Initialising items");
//amount of items
var myMaxItems:int = playerSkill + 1;
//adding the items one at a time
for (var numItem:int = 0; numItem < myMaxItems; numItem++)
{
var thisItem:collect = new collect(border,playerSkill,characterMC);
thisItem.name = "Item";
//adding item to stage
onScreenContent.push(thisItem);
addChild(thisItem);
}//end for statement
}//end function addItems
//code to add enemies into game
private function addEnemy():void
{
trace("Adding Enemies");
//setting initial number of enemies to match game/skill level
var maxEnemies:int = playerSkill + 1;
//adding enemies one by one using a loop
for (var numEnemies:int = 0; numEnemies < maxEnemies; numEnemies++)
{
//creating a new enemy
var thisEnemy:enemy = new enemy(border,playerSkill,characterMC);
thisEnemy.name = "Enemy";
trace("adding enemies to stage");
onScreenContent.push(thisEnemy);
addChild(thisEnemy);
}
}//end function addEnemy
//code to update game scores
public function updateScores(myMC: MovieClip):void
{
//change player score if they collide with enemy or item
mementos += myMC.scoreMod;
sanity += myMC.healthMod;
if (currentMementos == 4)
{
trace("lvlup");
levelUp();
currentMementos = 0;
}//end if statement
if (myMC.name.indexOf("item") != -1)
{
var myIndex:int = onScreenContent.indexOf(myMC);
onScreenContent.splice(myIndex, 1);
currentMementos++;
}//end if statement
trace("updating player score");
//run updatescores function
displayScores();
//run gameover check
if (sanity <= 0)
{
trace("game over prompted");
gameOver();
}//end if statement
}
//function to update scores
private function displayScores():void
{
//update dynamic text fields
lifeDisplay.text = "*" + sanity;
scoreDisplay.text = "Mementos: " + mementos;
trace("displaying updated scores");
}
//function to level up
private function levelUp():void
{
// resetting all items
clearObjects();
removeChild(characterMC);
playerSkill += 1;
//resetting game stage
addCharacter();
addItems();
addEnemy();
}
public function clearObjects():void
{
//removing all remaining game objects
for each (var myObj in onScreenContent)
{
myObj.removeAsset();
myObj = null;
}
// reset the array for next level
onScreenContent = new Array();
}
//function to return from map stage back to main menu
function exitMap(event:MouseEvent):void
{
gotoAndStop(1);
//removing player
removeChild(characterMC);
clearObjects();
mementos = 0;
sanity = 5;
currentMementos = 0;
}//end function exitMap
//function to execute game over
private function gameOver():void
{
//game over script
trace("game over");
gotoAndStop(4);
clearObjects();
removeChild(characterMC);
mementos = 0;
sanity = 5;
currentMementos = 0;
}
}//end class
}//end package
敌人class代码:
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.geom.Rectangle;
public class enemy extends MovieClip
{
private var borderEnemy:Rectangle;
private var charNum:int;
private var charSpeed:int;
private var charDir:int;
private var offset:int;
private var characterMC:MovieClip;
public var healthMod:int;
public var scoreMod:int;
//CONSTRUCTOR FUNCTION
public function enemy(myBorder:Rectangle, mySkill:int, player:MovieClip)
{
//set values
trace("initialising an Enemy");
mySkill = 3;
characterMC = player;
borderEnemy = new Rectangle(50,180,840,750);
//setting constraing area
borderEnemy = myBorder;
offset = 20;
//values of lives/scores
healthMod = -1;
scoreMod = 0;
//nasty type linked to mySkill
charNum = Math.ceil(Math.random() * (mySkill + 2));
charSpeed = charNum + 1;
//what can I hit?
//eventlistener: starts code when character enters stage
addEventListener(Event.ADDED_TO_STAGE, initEnemy);
addEventListener(Event.ENTER_FRAME, checkCollision);
}//end function enemy
//function to initiate enemy
private function initEnemy(evt:Event):void
{
//displaying the enemy frame (appearence) according to charNum
gotoAndStop(charNum);
//setting item positon, linked to function
setPosition();
//start movement of enemy, linked to function
addEventListener(Event.ENTER_FRAME, moveEnemy);
//remove unneeded listener after initiation
removeEventListener(Event.ADDED_TO_STAGE,initEnemy);
}//end function initEnemy
//function to set enemy position
private function setPosition():void
{
//setting enemy positions
//trace("setting enemy position");
//code to determine enemy direction
charDir = Math.floor(Math.random() * 2);
//trace("charDir value is " + charDir);
//code to determine enemy location (vertically)
var myRand:int = Math.ceil(Math.random() * 8) * (Math.ceil(Math.random() * 5) + 2);
if (charDir < 1)
{
//trace("char entering from left");
//random option 1: character appears from the left
charDir = 1;
this.x = borderEnemy.left - offset - myRand;
this.scaleX = 1;
}
else
{
//trace("char entering from right");
//random option 2: character appears from the right
charDir = -1;
this.x = borderEnemy.right + offset + myRand;
this.scaleX = -1;
}
//set verticle position using myRand
var myHeight:int = borderEnemy.bottom - borderEnemy.top - offset * 1;
this.y = Math.ceil(Math.random() * myHeight) + borderEnemy.top * 1;
}//end function setPosition
//function to move enemies
private function moveEnemy(evt:Event):void
{
if (charDir < 1)
{
this.x += - charSpeed - 10;
}
else
{
this.x += charSpeed + 10;
}
//reset character as it hits the border
if (this.x < borderEnemy.left - 40 || this.x > borderEnemy.right + 40)
{
setPosition();
}
}//end function moveEnemy
//function to check for collisions between player and enemies
private function checkCollision(evt:Event):void
{
//detecting if enemy has hit the player character
if (this.hitTestObject(characterMC))
{
trace("Hit an enemy");
MovieClip(root).updateScores(this);
setPosition();
}//end if statement
}//end function checkCollision
//function to remove enemies from map
public function removeAsset():void
{
// remove event listeners and the item
removeEventListener(Event.ENTER_FRAME, checkCollision);
//removeEventListener(Event.ENTER_FRAME, moveEnemy);
this.parent.removeChild(this);
trace("removing the enemies");
}//end function removeAsset
}//end class
}//end package
项目class代码(收集)
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.geom.Rectangle;
public class collect extends MovieClip
{
private var itemNum:int;
private var borderCollect:Rectangle;
private var frameNum:int;
private var characterMC:MovieClip;
public var healthMod:int;
public var scoreMod:int;
public function collect(myBorder:Rectangle, mySkill:int, player:MovieClip)
{
borderCollect = new Rectangle(30,180,870,750);
characterMC = player;
healthMod = 0;
scoreMod = 1;
//constructor code
trace("Initialise an Item");
//constraint area for item spawn
var borderCollect = myBorder;
var offset = -200;
//which item is spawned - based on the player skill variable
var itemNum = Math.ceil(Math.random() * mySkill);
var frameNum = Math.ceil(Math.random() * 3);
//start process once item appears on stage
addEventListener(Event.ADDED_TO_STAGE,initItem);
addEventListener(Event.ENTER_FRAME, checkItems);
}//public function "collect" end, what is initiated by the class
private function initItem(evt:Event):void
{
//display frame based on itemNum
gotoAndStop(frameNum);
trace("selecting item frames");
//tun position item function
setPosition();
trace("setting item positions");
//remove no longer needed event listener
removeEventListener(Event.ADDED_TO_STAGE,initItem);
}//function initItem end
private function setPosition():void
{
var myBorder = new Rectangle(50,180,800,500);
var offset = 100;
//positioning the Item according to borders
trace("setting positions for items");
var myWidth:int = myBorder.right - myBorder.left - offset;
this.x = Math.ceil(Math.random() * myWidth) + myBorder.left * 1;
var myHeight:int = myBorder.bottom - myBorder.top - offset;
this.y = Math.ceil(Math.random() * myHeight) + myBorder.top * 1;
}//function setPosition end
private function checkItems(evt: Event):void
{
// hit the character
if (this.hitTestObject(characterMC))
{
trace("Got an Item");
MovieClip(root).updateScores(this);
removeAsset();
}//end if statement
}//end function checkCollision
public function removeAsset():void
{
// remove event listeners and the item
removeEventListener(Event.ENTER_FRAME, checkItems);
this.parent.removeChild(this);
trace("removing an Item");
}//end function removeMe
}//class end
}//package end
错误(收集到任何物品后游戏结束)
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at collect/removeAsset()[H:\DIG MEDIA Post CHris\Memento - items added\collect.as:77]
at Memento/clearObjects()[H:\DIG MEDIA Post CHris\Memento - items added\Memento.as:140]
at Memento/gameOver()[H:\DIG MEDIA Post CHris\Memento - items added\Memento.as:165]
at Memento/updateScores()[H:\DIG MEDIA Post CHris\Memento - items added\Memento.as:111]
at enemy/checkCollision()[H:\DIG MEDIA Post CHris\Memento - items added\enemy.as:113]
addItem、addEnemy、addItems 等也放置在连接到按钮的 .fla 框架中,而不是文档 class。我知道这是不好的做法,但它们从一开始就一直存在,当我尝试移动它们时,它导致了很多问题。
无论如何,非常感谢任何愿意筛选我的(格式糟糕的)代码以找出我犯的(可能非常愚蠢的)错误的人,我再次为大量代码块感到抱歉,我只是不确定哪里出错了。
我必须更仔细地研究它才能弄清楚为什么我的解决方案有效。它的本质是:在某些时候,您要删除的元素要么不存在,要么不再附加到父元素。此代码将确保您尝试删除的实例存在并且具有父项
if (this.parent) this.parent.removeChild(this);
我一直在为一项任务开发一个 flash 游戏,到目前为止这真的很让人头疼。游戏相对简单,收集物品(纪念品),躲避敌人或失去生命值(理智),收集屏幕上的所有物品升级(物品,玩家和敌人重置,分数保持不变),被击中5次你得到游戏结束画面。
我遇到了一个烦人的奇怪错误。在没有物品的情况下结束游戏不会出现任何错误并且可以正常重置游戏(表面上),但问题是:
*在游戏结束时拥有任何物品会导致错误 1009。
*点击带有任何物品的退出游戏按钮会导致错误 1009。
*收集所有物品应该给"lvlUp"函数,但没有任何反应,if语句永远不会触发。
我在这个问题上度过了愉快的一天左右,并且有几次差点就把整个事情搞砸了,所以我决定在这里咨询经验丰富的编码人员。
对于乱码提前致歉,我才刚刚开始使用AS3
游戏文档class代码:
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.geom.Rectangle;
import player;
public class Memento extends MovieClip
{
//importing required variables
private var onScreenContent:Array;
private var playerSkill:int;
private var myXY:Array;
private var mySpeed:int;
private var border:Rectangle;
private var myMaxItems:int;
private var numItems:int;
private var numEnemies:int;
private var maxEnemies:int;
private var characterMC:player;
public var sanity:int;
public var mementos:int;
public var currentMementos:int;
//CONSTRUCTOR
public function Memento()
{
trace("initialising DOS game");
//simulates a selected skill level
playerSkill = 3;
sanity = 5;
mementos = 0;
onScreenContent = new Array ;
border = new Rectangle(30,180,870,750);
}
//code to add character into game at correct position
private function addCharacter():void
{
trace("Adding the character");
//set the initial values to character starting pos
var myXY:Array = [480,900];
var mySpeed:int = playerSkill + 6;
//create and add a new player to screen
characterMC = new player(myXY,border,mySpeed);
addChild(characterMC);
characterMC.focusRect = false;
stage.focus = characterMC;
}//end function addCharacter
//code to add items into game
private function addItems():void
{
trace("Initialising items");
//amount of items
var myMaxItems:int = playerSkill + 1;
//adding the items one at a time
for (var numItem:int = 0; numItem < myMaxItems; numItem++)
{
var thisItem:collect = new collect(border,playerSkill,characterMC);
thisItem.name = "Item";
//adding item to stage
onScreenContent.push(thisItem);
addChild(thisItem);
}//end for statement
}//end function addItems
//code to add enemies into game
private function addEnemy():void
{
trace("Adding Enemies");
//setting initial number of enemies to match game/skill level
var maxEnemies:int = playerSkill + 1;
//adding enemies one by one using a loop
for (var numEnemies:int = 0; numEnemies < maxEnemies; numEnemies++)
{
//creating a new enemy
var thisEnemy:enemy = new enemy(border,playerSkill,characterMC);
thisEnemy.name = "Enemy";
trace("adding enemies to stage");
onScreenContent.push(thisEnemy);
addChild(thisEnemy);
}
}//end function addEnemy
//code to update game scores
public function updateScores(myMC: MovieClip):void
{
//change player score if they collide with enemy or item
mementos += myMC.scoreMod;
sanity += myMC.healthMod;
if (currentMementos == 4)
{
trace("lvlup");
levelUp();
currentMementos = 0;
}//end if statement
if (myMC.name.indexOf("item") != -1)
{
var myIndex:int = onScreenContent.indexOf(myMC);
onScreenContent.splice(myIndex, 1);
currentMementos++;
}//end if statement
trace("updating player score");
//run updatescores function
displayScores();
//run gameover check
if (sanity <= 0)
{
trace("game over prompted");
gameOver();
}//end if statement
}
//function to update scores
private function displayScores():void
{
//update dynamic text fields
lifeDisplay.text = "*" + sanity;
scoreDisplay.text = "Mementos: " + mementos;
trace("displaying updated scores");
}
//function to level up
private function levelUp():void
{
// resetting all items
clearObjects();
removeChild(characterMC);
playerSkill += 1;
//resetting game stage
addCharacter();
addItems();
addEnemy();
}
public function clearObjects():void
{
//removing all remaining game objects
for each (var myObj in onScreenContent)
{
myObj.removeAsset();
myObj = null;
}
// reset the array for next level
onScreenContent = new Array();
}
//function to return from map stage back to main menu
function exitMap(event:MouseEvent):void
{
gotoAndStop(1);
//removing player
removeChild(characterMC);
clearObjects();
mementos = 0;
sanity = 5;
currentMementos = 0;
}//end function exitMap
//function to execute game over
private function gameOver():void
{
//game over script
trace("game over");
gotoAndStop(4);
clearObjects();
removeChild(characterMC);
mementos = 0;
sanity = 5;
currentMementos = 0;
}
}//end class
}//end package
敌人class代码:
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.geom.Rectangle;
public class enemy extends MovieClip
{
private var borderEnemy:Rectangle;
private var charNum:int;
private var charSpeed:int;
private var charDir:int;
private var offset:int;
private var characterMC:MovieClip;
public var healthMod:int;
public var scoreMod:int;
//CONSTRUCTOR FUNCTION
public function enemy(myBorder:Rectangle, mySkill:int, player:MovieClip)
{
//set values
trace("initialising an Enemy");
mySkill = 3;
characterMC = player;
borderEnemy = new Rectangle(50,180,840,750);
//setting constraing area
borderEnemy = myBorder;
offset = 20;
//values of lives/scores
healthMod = -1;
scoreMod = 0;
//nasty type linked to mySkill
charNum = Math.ceil(Math.random() * (mySkill + 2));
charSpeed = charNum + 1;
//what can I hit?
//eventlistener: starts code when character enters stage
addEventListener(Event.ADDED_TO_STAGE, initEnemy);
addEventListener(Event.ENTER_FRAME, checkCollision);
}//end function enemy
//function to initiate enemy
private function initEnemy(evt:Event):void
{
//displaying the enemy frame (appearence) according to charNum
gotoAndStop(charNum);
//setting item positon, linked to function
setPosition();
//start movement of enemy, linked to function
addEventListener(Event.ENTER_FRAME, moveEnemy);
//remove unneeded listener after initiation
removeEventListener(Event.ADDED_TO_STAGE,initEnemy);
}//end function initEnemy
//function to set enemy position
private function setPosition():void
{
//setting enemy positions
//trace("setting enemy position");
//code to determine enemy direction
charDir = Math.floor(Math.random() * 2);
//trace("charDir value is " + charDir);
//code to determine enemy location (vertically)
var myRand:int = Math.ceil(Math.random() * 8) * (Math.ceil(Math.random() * 5) + 2);
if (charDir < 1)
{
//trace("char entering from left");
//random option 1: character appears from the left
charDir = 1;
this.x = borderEnemy.left - offset - myRand;
this.scaleX = 1;
}
else
{
//trace("char entering from right");
//random option 2: character appears from the right
charDir = -1;
this.x = borderEnemy.right + offset + myRand;
this.scaleX = -1;
}
//set verticle position using myRand
var myHeight:int = borderEnemy.bottom - borderEnemy.top - offset * 1;
this.y = Math.ceil(Math.random() * myHeight) + borderEnemy.top * 1;
}//end function setPosition
//function to move enemies
private function moveEnemy(evt:Event):void
{
if (charDir < 1)
{
this.x += - charSpeed - 10;
}
else
{
this.x += charSpeed + 10;
}
//reset character as it hits the border
if (this.x < borderEnemy.left - 40 || this.x > borderEnemy.right + 40)
{
setPosition();
}
}//end function moveEnemy
//function to check for collisions between player and enemies
private function checkCollision(evt:Event):void
{
//detecting if enemy has hit the player character
if (this.hitTestObject(characterMC))
{
trace("Hit an enemy");
MovieClip(root).updateScores(this);
setPosition();
}//end if statement
}//end function checkCollision
//function to remove enemies from map
public function removeAsset():void
{
// remove event listeners and the item
removeEventListener(Event.ENTER_FRAME, checkCollision);
//removeEventListener(Event.ENTER_FRAME, moveEnemy);
this.parent.removeChild(this);
trace("removing the enemies");
}//end function removeAsset
}//end class
}//end package
项目class代码(收集)
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.geom.Rectangle;
public class collect extends MovieClip
{
private var itemNum:int;
private var borderCollect:Rectangle;
private var frameNum:int;
private var characterMC:MovieClip;
public var healthMod:int;
public var scoreMod:int;
public function collect(myBorder:Rectangle, mySkill:int, player:MovieClip)
{
borderCollect = new Rectangle(30,180,870,750);
characterMC = player;
healthMod = 0;
scoreMod = 1;
//constructor code
trace("Initialise an Item");
//constraint area for item spawn
var borderCollect = myBorder;
var offset = -200;
//which item is spawned - based on the player skill variable
var itemNum = Math.ceil(Math.random() * mySkill);
var frameNum = Math.ceil(Math.random() * 3);
//start process once item appears on stage
addEventListener(Event.ADDED_TO_STAGE,initItem);
addEventListener(Event.ENTER_FRAME, checkItems);
}//public function "collect" end, what is initiated by the class
private function initItem(evt:Event):void
{
//display frame based on itemNum
gotoAndStop(frameNum);
trace("selecting item frames");
//tun position item function
setPosition();
trace("setting item positions");
//remove no longer needed event listener
removeEventListener(Event.ADDED_TO_STAGE,initItem);
}//function initItem end
private function setPosition():void
{
var myBorder = new Rectangle(50,180,800,500);
var offset = 100;
//positioning the Item according to borders
trace("setting positions for items");
var myWidth:int = myBorder.right - myBorder.left - offset;
this.x = Math.ceil(Math.random() * myWidth) + myBorder.left * 1;
var myHeight:int = myBorder.bottom - myBorder.top - offset;
this.y = Math.ceil(Math.random() * myHeight) + myBorder.top * 1;
}//function setPosition end
private function checkItems(evt: Event):void
{
// hit the character
if (this.hitTestObject(characterMC))
{
trace("Got an Item");
MovieClip(root).updateScores(this);
removeAsset();
}//end if statement
}//end function checkCollision
public function removeAsset():void
{
// remove event listeners and the item
removeEventListener(Event.ENTER_FRAME, checkItems);
this.parent.removeChild(this);
trace("removing an Item");
}//end function removeMe
}//class end
}//package end
错误(收集到任何物品后游戏结束)
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at collect/removeAsset()[H:\DIG MEDIA Post CHris\Memento - items added\collect.as:77]
at Memento/clearObjects()[H:\DIG MEDIA Post CHris\Memento - items added\Memento.as:140]
at Memento/gameOver()[H:\DIG MEDIA Post CHris\Memento - items added\Memento.as:165]
at Memento/updateScores()[H:\DIG MEDIA Post CHris\Memento - items added\Memento.as:111]
at enemy/checkCollision()[H:\DIG MEDIA Post CHris\Memento - items added\enemy.as:113]
addItem、addEnemy、addItems 等也放置在连接到按钮的 .fla 框架中,而不是文档 class。我知道这是不好的做法,但它们从一开始就一直存在,当我尝试移动它们时,它导致了很多问题。
无论如何,非常感谢任何愿意筛选我的(格式糟糕的)代码以找出我犯的(可能非常愚蠢的)错误的人,我再次为大量代码块感到抱歉,我只是不确定哪里出错了。
我必须更仔细地研究它才能弄清楚为什么我的解决方案有效。它的本质是:在某些时候,您要删除的元素要么不存在,要么不再附加到父元素。此代码将确保您尝试删除的实例存在并且具有父项
if (this.parent) this.parent.removeChild(this);