我遇到了一个我无法解决的错误。我正在制作一个游戏,它应该在失去你的3个生命后说“你输了”,但在我的情况下,一切都冻结了,我得到了一个错误。
TypeError:错误#2007:参数hitTestObject必须为非null。 在flash.display :: DisplayObject / _hitTest() 在flash.display :: DisplayObject / hitTestObject() at Fatality / enterFrameEvents()[C:\ Documents and Settings \ labo \ Bureaublad \ GIP 12 mei \ Fatality.as:26]
看看我的代码。这是我在课堂上编写的代码
基本上这个课程在我的突围游戏中是一个“游戏结束”的力量。当它触及划桨时,它的游戏就结束了。问题是它在接触球拍后冻结而不是显示“你输了”。
package
{
import flash.display.*;
import flash.events.*;
public class Fatality extends MovieClip
{
private var yspeed:Number = 1;
private var _root:MovieClip;
public function Fatality()
{
// constructor code
addEventListener(Event.ADDED, beginClass);
addEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
private function beginClass(event:Event):void
{
//defining _root as the document root
////je definieërt _root als het document root
_root = MovieClip(root);
}
private function enterFrameEvents(event:Event):void
{
this.y = this.y + yspeed;
if (this.hitTestObject(_root.mcPaddle))
{
this.removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
this.parent.removeChild(this);
if (_root.lives == 3)
{
_root.removeChild(_root.hartje3);
_root.removeChild(_root.hartje2);
_root.removeChild(_root.hartje1);
}
else if (_root.lives == 2)
{
_root.removeChild(_root.hartje2);
_root.removeChild(_root.hartje1);
}
else if (_root.lives == 1)
{
_root.removeChild(_root.hartje1);
}
_root.gameOver = true;
//De listeners weg doen
_root.mcBall.removeEventListener(Event.ENTER_FRAME, _root.moveBall);
_root.mcPaddle.removeEventListener(Event.ENTER_FRAME, _root.movePaddle);
removeEventListener(Event.ENTER_FRAME, _root.checkLevel);
removeEventListener(Event.ENTER_FRAME, _root.updateTextFields);
//Ga naar een lose frame
_root.gotoAndStop('lose');
}
}
}
}
最后一部分是指丢失帧,这里是丢失帧的代码
//De lose frame
//reset het spel als je op je muis klikt
stage.addEventListener(MouseEvent.CLICK, resetGame);
function resetGame(event:MouseEvent):void{
//deze listener weg doen
stage.removeEventListener(MouseEvent.CLICK, resetGame);
//het spel resetten
gotoAndPlay(1);
}
//de eindscore laten zien
txtScore.text = "Final Score: "+score;
如果有人帮我解决这个错误,我真的很感激,因为它让我非常讨厌,谢谢。
修改
主要代码:
import flash.events.MouseEvent;
import flash.events.Event;
stop();
//Variabelen
//Nodige variabelen voor de beweging van de bal
var ballXSpeed:Number = 8;//X Snelheid van de bal
var ballYSpeed:Number = 8;//Y Snelheid van de bal
//Hoeveel bricks er over zijn op het stage (podium)
var brickAmt:int = 0;
//Hoeveel levens je hebt
var lives:int = 3;
//Als het game over is
var gameOver:Boolean = false;
//De score van het spel
var score:int = 0;
//Eerst heb ik een een functie gemaakt waar
//al de code in zit die nodig is om het spel te starten
//dit bevat listeners, variabelen en andere dingen
function beginCode(event:MouseEvent):void
{
//doet de listener weg wanneer je klikt
stage.removeEventListener(MouseEvent.CLICK, beginCode);
//Voegt een listener toe aan de paddle
//die een functie runt elke keer als een frame voorbij is
mcPaddle.addEventListener(Event.ENTER_FRAME, movePaddle);
//Voegt een listener toe aan de ball;
//die een functie runt elke keer als een frame voorbij is
mcBall.addEventListener(Event.ENTER_FRAME, moveBall);
//Voegt een listener toe om te checken of het level voorbij is;
addEventListener(Event.ENTER_FRAME, checkLevel);
//verwijdert het "click to start" tekst
txtStart.text = '';
}
function movePaddle(event:Event):void
{
//De paddle volgt de muis
mcPaddle.x = mouseX - mcPaddle.width / 2;
//Houdt de paddle op het stage
//Als de muis te ver naar links gaat
if (mouseX < mcPaddle.width / 2)
{
//Houdt de paddle op het stage
mcPaddle.x = 0;
}
//Als de muis te ver naar rechts gaat
if (mouseX > stage.stageWidth - mcPaddle.width / 2)
{
//Houdt de paddle on stage
mcPaddle.x = stage.stageWidth - mcPaddle.width;
}
}
function ContinueGame(event:Event):void
{
mcBall.addEventListener(Event.ENTER_FRAME, moveBall);
}
function moveBall(event:Event):void
{
//Dit is de code voor de beweging van de bal
mcBall.x += ballXSpeed;//Beweegt de bal horizontaal
mcBall.y += ballYSpeed;//Beweegt de bal verticaal
//Stuitert de bal weg van de muren
if (mcBall.x >= stage.stageWidth - mcBall.width)
{
//Als de bal de rechterkant raakt
//van het scherm, en weg stuitert
ballXSpeed *= -1;
}
if (mcBall.x <= 0)
{
//Als de bal de linkerkant raakt
//van het scherm, en weg stuitert
ballXSpeed *= -1;
}
if (mcBall.y >= stage.stageHeight - mcBall.height)
{
//Als de bal de grond raakt
//stuitert het omhoog en verlies je 1 leven
//ballYSpeed *= -1;
lives--;
if (lives == 2)
{
removeChild(this.hartje3);
}
else if (lives == 1)
{
removeChild(this.hartje2);
}
else if (lives == 0)
{
removeChild(this.hartje1);
}
ballXSpeed = 8;
ballYSpeed = 8;
mcBall.x = 151.9;
mcBall.y = 264.9;
mcBall.removeEventListener(Event.ENTER_FRAME, moveBall);
stage.addEventListener(MouseEvent.CLICK, ContinueGame);
//Wanneer er geen levens meer over zijn
if (lives <= 0)
{
//het is nu game over
gameOver = true;
//De listeners weg doen
mcBall.removeEventListener(Event.ENTER_FRAME, moveBall);
mcPaddle.removeEventListener(Event.ENTER_FRAME, movePaddle);
removeEventListener(Event.ENTER_FRAME, checkLevel);
removeEventListener(Event.ENTER_FRAME, updateTextFields);
//Ga naar een lose frame
gotoAndStop('lose');
}
}
else
{
if (mcBall.y <= 0)
{
//Als de bal de bovenkant raakt van het scherm
//en stuitert terug naar beneden
ballYSpeed *= -1;
}
//Je raakt de paddle
if (mcBall.hitTestObject(mcPaddle))
{
calcBallAngle();
}
}
}
function calcBallAngle():void
{
//ballPosition is de positie van het balletje op de paddle
var ballPosition:Number = mcBall.x - mcPaddle.x;
//hitPercent converts ballPosition in een percentage
//Helemaal naar links is -0.5
//Helemaal naar rechts is 0.5
//Het midden is 0
var hitPercent:Number = (ballPosition / (mcPaddle.width - mcBall.width)) - .5;
//Neemt het hitPercent en maakt het een groter nummer zodat de bal
//werkelijk stuitert
ballXSpeed = hitPercent * 10;
//Zorgt dat het balletje terug omhoog stuitert
ballYSpeed *= -1;
}
function makeLvl():void
{//Zet de bricks op level 1
//checkt of er nog levels over zijn
if (currentLvl > lvlArray.length)
{
//het is nu game over
gameOver = true;
//de listeners weg doen
mcPaddle.removeEventListener(Event.ENTER_FRAME, movePaddle);
mcBall.removeEventListener(Event.ENTER_FRAME, moveBall);
removeEventListener(Event.ENTER_FRAME, checkLevel);
removeEventListener(Event.ENTER_FRAME, updateTextFields);
//ga naar een lose frame
gotoAndStop("win");
}
//vindt de array lengte van de level code
//De index moet currentLvl-1 zijn want:
//array indexes beginnen vanaf 0 en onze level start op 1
//onze level zal altijd 1 hoger zijn dan de index van de array
var arrayLength:int = lvlArray[currentLvl - 1].length;
//de huidige rij van bricks die we aan het maken zijn
var brickRow:int = 0;
//Een lus die dr bricks op het stage zet
for (var i:int = 0; i<arrayLength; i++)
{
//Checkt of het een brick moet zetten daar
if (lvlArray[currentLvl - 1][i] == 1)
{
//maakt een variabele aan van de brick
var brick:Brick = new Brick();
//regelt de coordinaten van de brick via de i variabele en brickRow
brick.x = 15 + (i - brickRow * 7) * 75;
brick.y = 10 + brickRow * 20;
//checkt of de huidige brick een nieuwe rij nodig heeft
for (var c:int = 1; c<=10; c++)
{
if (i == c*7-1)
{
brickRow++;
}
}
//nu zet dit de brick op het stage
addChild(brick);
}
}
}
function checkLevel(event:Event):void
{
//checkt of de bricks allemaal weg zijn
if (brickAmt == 0)
{
//reset het level door het level te verhogen
currentLvl++;
//makeLvl wordt opnieuw gerunt
//reset de tekst "click to begin"
txtStart.text = "Click To Begin";
makeLvl();
//reset de positie van het balletje en de paddle
mcBall.x = 150;
mcBall.y = 265;
mcBall.width = 10;
mcBall.height = 10;
mcPaddle.x = 230;
//al de listeners weg doen
mcPaddle.removeEventListener(Event.ENTER_FRAME, movePaddle);
mcBall.removeEventListener(Event.ENTER_FRAME, moveBall);
removeEventListener(Event.ENTER_FRAME, checkLevel);
//je "listent" voor een click van de muis om het spel terug te starten
stage.addEventListener(MouseEvent.CLICK, beginCode);
}
}
function updateTextFields(event:Event):void
{
}
//als je clickt met je muis, begint het spel
stage.addEventListener(MouseEvent.CLICK, beginCode);
//de tekst die tevoorschijn komt;
txtStart.text = "Click To Begin";
//een functie maken om de text fields te updaten
addEventListener(Event.ENTER_FRAME, updateTextFields);
//het level maken
makeLvl();
pauseButton.addEventListener(MouseEvent.CLICK, pauseGame);
function pauseGame(e:MouseEvent):void
{
stage.frameRate = 0;
}
playButton.addEventListener(MouseEvent.CLICK, resumeGame);
function resumeGame(e:MouseEvent):void
{
stage.frameRate = 24;
}
砖块的代码:
//klassen moeten altijd in een packed zitten
package
{
//display elements importeren die we kunnen gebruiken in deze klasse
import flash.display.*;
import flash.events.*;
//de naam van de klasse definiëren en zeggen dat
//het de MovieClip klasse "extends",
//dat wil zeggen dat het dezelfde properties heeft als die van een movieclip
public class Brick extends MovieClip
{
//de main timeline
private var _root:MovieClip;
//alle klassen moeten een functie hebben die elke keer
//runt wanneer een instance van die klasse op het stage wordt gezet
public function Brick()
{
//deze code runt wanneer de brick op het stage wordt gezet
addEventListener(Event.ADDED, beginClass);
//enter frame code
addEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
//private functions zijn functies die je niet kan gebruiken
//vanuit de main timeline, maar enkel vanuit de klasse zelf
private function beginClass(event:Event):void
{
//je definieërt _root als het document root
_root = MovieClip(root);
//verhoogt het aantal bricks op het stage
_root.brickAmt++;
}
private function enterFrameEvents(event:Event):void
{
//controleren of de player heeft verloren
if (_root.gameOver)
{
//deze brick kapot maken
this.parent.removeChild(this);
//stoppen met deze code te runnen;
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
}
//hit testing met het balletje
if (this.hitTestObject(_root.mcBall))
{
//hierdoor stuitert het balletje verticaal
_root.ballYSpeed *= -1;
//Creeër een Power UP (Werk met een Random
//om een powerup te maken en werk met een
//tweede random om te bepalen welke power)
MakePowerUp();
//deze brick kapot maken
this.parent.removeChild(this);
//stoppen met deze code te runnen;
removeEventListener(Event.ENTER_FRAME, enterFrameEvents);
//verlaagt het aantal bricks op het stage
_root.brickAmt--;
//de score verhogen
_root.score += 10;
}
}
function MakePowerUp():void
{
//random plaatsen om te beslissen of er een power aangemaakt wordt
//en zo ja, welke
var getal = randomRange(1,40);
if (getal < 3)
{
var power:Power = new Power();
power.x = this.x + 35;
power.y = this.y + 5;
_root.addChild(power);
}
else if (getal < 6)
{
var power2:Power2 = new Power2();
power2.x = this.x + 35;
power2.y = this.y + 5;
_root.addChild(power2);
}
else if (getal < 9)
{
var mario:Enlarger = new Enlarger();
mario.x = this.x + 35;
mario.y = this.y + 5;
_root.addChild(mario);
}
else if (getal < 14)
{
var power3:Power3 = new Power3();
power3.x = this.x + 35;
power3.y = this.y + 5;
_root.addChild(power3);
}
else if (getal < 16)
{
var fat:Fatality = new Fatality();
fat.x = this.x + 35;
fat.y = this.y + 5;
_root.addChild(fat);
}
else if (getal < 20)
{
var lifesteal:Lifestealer = new Lifestealer();
lifesteal.x = this.x + 35;
lifesteal.y = this.y + 5;
_root.addChild(lifesteal);
}
}
function randomRange(minNum: Number, maxNum:Number):Number
{
return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);
}
}
}
答案 0 :(得分:0)
错误是指第26行:
if (this.hitTestObject(_root.mcPaddle))
错误告诉您程序中此时_root.mcPaddle
为null
。
答案 1 :(得分:0)
您有一个连接到所有砖块的enterframe侦听器。他们在游戏结束后继续开火。您必须在启动游戏结束条件时删除所有这些内容。麻烦的是,你显然没有跟踪那里有多少砖,它们是什么。我建议制作一个砖块阵列,像往常一样放置它们,但是使用一个单独的输入框架监听器,它将检查球是否依次与任何砖块碰撞,而不是对this
即砖块进行测试。通过这种方式,您将拥有一个包含所有enterframe代码的固定点,简化调试,让您自己更轻松地扩展游戏功能,并整合所有与游戏流程相关的代码。为此,您将不得不使用一个经理类,很可能是Level
,您可以将其添加到框架而不是一组砖块中,这将从与数据表对应的数据表中创建必要数量的砖块。水平。
如果你想同时手工创建一个级别,也就是在舞台上放置砖块,并且具有这样的功能,你可以创建一个容器精灵,它与整个级别重叠,包含所有砖块,这就是Level
类型或扩展Level
之一,并创建一个Level
类,它将跟踪其所有子类型Brick
,枚举它们并添加到内部数组。示例枚举器代码:
public class Level extends Sprite {
private var bricks:Array=new Array();
private var numBricks:int=0;
public function Level() {
for (var i:int=0;i<numChildren;i++) {
if (getChildAt(i) is Brick) {
numBricks++;
bricks.push(getChildAt(i));
}
}
// do the rest of initialization
addEventListener(Event.ENTER_FRAME,processLevel);
}
private function processLevel(e:Event):void {
moveBall();
movePaddle();
movePowerups();
for (var i:int=numBricks-1;i>=0;i--) {
if (bricks[i].hitTestObject(ball)) {
// process hit brick
bricks.splice(i,1); // drop a now nonexistent brick off array
numBricks--;
if (numBricks==0) { } // level won, add code to advance
// and don't forget cleanup, and return statement!
}
}
// about the same for powerups, including an array, number of powerups,
// powerups effect, etc.
}