Actionscript 3 AS3-太空射手敌方射击
我对AS3和编程都很陌生,我一直在AS3中开发一款太空射击游戏,在敌人射击方面遇到了麻烦。敌人从屏幕顶部垂直向下飞行,一旦他们的y坐标等于玩家的y坐标,就应该发射两次射击(一次向左,一次向右)。这可以正常工作,除非在30秒到2分钟之间发生以下错误 TypeError:错误#1009:无法访问空对象引用的属性或方法。 在EnemyShip2/FireEapon()[G:\Games Related\1942\src\EnemyShip2.as:78] 在EnemyShip2/loop2()[G:\Games Related\1942\src\EnemyShip2.as:65] TypeError:错误#1009:无法访问空对象引用的属性或方法。 在EnemyShot/removeSelf()[G:\Games Related\1942\src\EnemyShot.as:43] 在EnemyShot/loop()[G:\Games Related\1942\src\EnemyShot.as:36] 以下是敌舰级和敌方射击级的相关代码 敌舰Actionscript 3 AS3-太空射手敌方射击,actionscript-3,flashdevelop,Actionscript 3,Flashdevelop,我对AS3和编程都很陌生,我一直在AS3中开发一款太空射击游戏,在敌人射击方面遇到了麻烦。敌人从屏幕顶部垂直向下飞行,一旦他们的y坐标等于玩家的y坐标,就应该发射两次射击(一次向左,一次向右)。这可以正常工作,除非在30秒到2分钟之间发生以下错误 TypeError:错误#1009:无法访问空对象引用的属性或方法。 在EnemyShip2/FireEapon()[G:\Games Related\1942\src\EnemyShip2.as:78] 在EnemyShip2/loop2()[G:\
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.Stage;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* ...
* @author D Nelson
*/
[Embed(source = "../assets/enemyship2.png")]
//This enemy moves relatively slowly and fires horizontal shots
public class EnemyShip2 extends Bitmap
{
private var vy:Number = 3;
//private var ay:Number = .2;
private var target:HeroShip;
private var enemyShip2:EnemyShip2;
private var enemyfireTimer:Timer;
private var enemycanFire:Boolean = true;
public function EnemyShip2(target:HeroShip):void
{
this.target = target;
scaleX = 0.3;
scaleY = 0.3;
x = Math.floor(Math.random() * 550);
y = -105;
addEventListener(Event.ENTER_FRAME, loop2, false, 0, true);
enemyfireTimer = new Timer(1000, 1);
enemyfireTimer.addEventListener(TimerEvent.TIMER, handleenemyfireTimer, false, 0, true);
}
private function handleenemyfireTimer(e:TimerEvent) : void
{
//the timer runs, so a shot can be fired again
enemycanFire = true;
}
private function removeSelf2():void
{
removeEventListener(Event.ENTER_FRAME, loop2);
if (stage.contains(this))
{
stage.removeChild(this);
}
}
private function loop2 (e:Event):void
{
//vy += ay;
y += vy;
if (y > stage.stageHeight)
{
removeSelf2();
}
if (y >= target.y && (enemycanFire))
{
fireWeapon();
enemycanFire = false;
enemyfireTimer.start();
}
if (this.x > 540 || this.x < 10)
{
removeSelf2();
}
}
private function fireWeapon():void
{
stage.addChild(new EnemyShot(target, x, y, -4));
stage.addChild(new EnemyShot(target, x, y, +4));
}
}
}
包
{
导入flash.display.Sprite;
导入flash.display.Bitmap;
导入flash.display.Stage;
导入flash.events.Event;
导入flash.events.TimerEvent;
导入flash.utils.Timer;
/**
* ...
*@D尼尔森
*/
[Embed(source=“../assets/enemyship2.png”)]
//敌人移动相对缓慢,并发射水平射击
公共类Eneyship2扩展位图
{
私有变量vy:Number=3;
//私有变量ay:Number=.2;
私人var目标:HeroShip;
私有var Eneyship2:Eneyship2;
私有变量enemyfireTimer:计时器;
私有变量enemycanFire:Boolean=true;
公共功能敌人2(目标:英雄飞船):无效
{
this.target=目标;
scaleX=0.3;
scaleY=0.3;
x=数学地板(数学随机()*550);
y=-105;
addEventListener(Event.ENTER_FRAME,loop2,false,0,true);
enemyfireTimer=新定时器(1000,1);
enemyfireTimer.addEventListener(TimerEvent.TIMER,HandleNemyFireTimer,false,0,true);
}
私有函数handleenemyfireTimer(e:TimerEvent):无效
{
//计时器运行,因此可以再次发射子弹
enemycanFire=真;
}
私有函数removeSelf2():void
{
removeEventListener(Event.ENTER_FRAME,loop2);
如果(阶段包含(此))
{
阶段。移除儿童(本);
}
}
私有函数loop2(e:事件):无效
{
//vy+=ay;
y+=vy;
如果(y>阶段高度)
{
removeSelf2();
}
如果(y>=target.y&(enemycanFire))
{
防火墙();
enemycanFire=假;
enemyfireTimer.start();
}
如果(this.x>540 | | this.x<10)
{
removeSelf2();
}
}
私有函数FireEapon():void
{
stage.addChild(新敌人shot(target,x,y,-4));
stage.addChild(新敌人shot(target,x,y,+4));
}
}
}
敌人射击
package
{
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.events.Event;
import flash.display.Stage;
/**
* ...
* @author D Nelson
*/
[Embed(source="../assets/enemyshot.png")]
public class EnemyShot extends Bitmap
{
private var speed:Number;
private var target:HeroShip;
private var vx:Number;
public function EnemyShot(target:HeroShip, x:Number, y:Number, vx:Number)
{
this.target = target;
this.x = x;
this.y = y;
this.vx = vx;
scaleX = 0.3;
scaleY = 0.3;
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function loop(e:Event) : void
{
x += vx;
if (x >= 600 || x <= -50)
{
removeSelf();
}
}
private function removeSelf():void
{
removeEventListener(Event.ENTER_FRAME, loop);
if (stage.contains(this))
{
stage.removeChild(this);
}
}
}
}
包
{
导入flash.display.Sprite;
导入flash.display.Bitmap;
导入flash.events.Event;
导入flash.display.Stage;
/**
* ...
*@D尼尔森
*/
[嵌入(source=“../assets/enemyshot.png”)]
公共类EnemyShot扩展位图
{
私人var速度:数字;
私人var目标:HeroShip;
私有变量vx:编号;
公共功能敌人(目标:HeroShip,x:Number,y:Number,vx:Number)
{
this.target=目标;
这个.x=x;
这个。y=y;
这是vx=vx;
scaleX=0.3;
scaleY=0.3;
addEventListener(Event.ENTER_FRAME,循环,false,0,true);
}
私有函数循环(e:事件):无效
{
x+=vx;
如果(x>=600 | | x=stage.stageHeight)
{
//背景位于可见舞台区域下方,将其置于其他背景上方
background1.y=background2.y-background2.height;
}
else if(background2.y>=舞台高度)
{
background2.y=background1.y-background2.height;
}
}
//敌对1产卵
私有函数loop1(e:事件):void
{
//生成飞船产卵的概率(数字越小,几率越大;数字越小,几率越小)
如果(数学地板(数学随机()*55)==5)
{
var enemyShip1:enemyShip1=新的enemyShip1(heroShip);
enemyShip1.addEventListener(Event.REMOVED_FROM_STAGE,removeEnemy1,false,0,true);
敌人1阵列。推送(敌人1);
阶段。添加孩子(敌人1);
}
}
私有函数Removeenem1(e:事件):无效
{
//从阵列中移除最近离开屏幕的敌人
enemies1Array.splice(enemies1Array.indexOf(e.currentTarget),1);
}
//敌人2产卵
私有函数loop2(e:事件):无效
{
如果(数学地板(数学随机()*40)==5)
{
var enemyShip2:enemyShip2=新的enemyShip2(heroShip);
enemyShip2.addEventListener(Event.REMOVED_FROM_STAGE,removeEnemy2,false,0,true);
敌人2数组。推送(敌人2);
阶段。添加孩子(敌人2);
}
}
私有函数removeEnemy2(e:事件):无效
{
enemies2Array.splice(enemies2Array.indexOf(e.currentTarget),1);
}
}
}
一开始我以为这和enemi有关
package
{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.*;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.KeyboardEvent;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.utils.*;
import flash.utils.ByteArray;
import flash.utils.Timer;
import flash.text.*;
import flash.media.Sound;
import flash.media.SoundChannel;
/**
* ...
* @author D Nelson
*/
public class Main extends MovieClip
{
[Embed(source = "snd/gamemusic2.mp3")]
private var MySound : Class;
private var mainsound : Sound;
private var shootsound: Sound = new ShootSound;
private var sndChannel:SoundChannel = new SoundChannel;
public var heroShip:HeroShip;
public var enemyShip1:EnemyShip1
public var enemyShip2:EnemyShip2
public var enemyShip3:EnemyShip3
public var enemyShip4:EnemyShip4
public var bossShip: BossShip
public var enemyShot: EnemyShot;
public var playerShot: PlayerShot;
private var background1:Background1;
private var background2:Background2;
public static const scrollspeed:Number = 2;
public var playerShotArray:Array = new Array()
public var enemyShotArray:Array = new Array()
public var enemies1Array:Array = new Array()
public var enemies2Array:Array = new Array()
private var fireTimer:Timer; //this creates a delay between each shot
private var canFire:Boolean = true; //this checks if a shot can be fired
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
mainsound = (new MySound) as Sound;
shootsound = (new ShootSound) as Sound;
mainsound.play();
background1 = new Background1();
background2 = new Background2();
//setting the backgrounds one below another
background1.y = 0;
background2.y = background1.height;
//add background at the lowest depth level
stage.addChildAt(background1,0);
stage.addChildAt(background2, 0);
//sets up the timer and its listener
fireTimer = new Timer(250, 1);
fireTimer.addEventListener(TimerEvent.TIMER, handlefireTimer, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_DOWN, handleCharacterShoot);
//background scrolling effect
stage.addEventListener(Event.ENTER_FRAME, backgroundScroll);
//loop for enemy1 variety
stage.addEventListener(Event.ENTER_FRAME, loop1, false, 0, true);
//loop for enemy2 variety
stage.addEventListener(Event.ENTER_FRAME, loop2, false, 0, true);
//speed of player shots
setInterval(playerShootMovement, 10);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//entry point
heroShip = new HeroShip();
stage.addChild(heroShip);
//test values for enemies
/*enemyShip1 = new EnemyShip1();
stage.addChildAt(enemyShip1, 2);
enemyShip1.y = stage.stageWidth * 0.3;
enemyShip1.x = 300;
enemyShip2 = new EnemyShip2();
stage.addChildAt(enemyShip2, 2);
enemyShip2.y = stage.stageWidth * 0.3;
enemyShip2.x = 200;
enemyShip3 = new EnemyShip3();
stage.addChildAt(enemyShip3, 2);
enemyShip3.y = stage.stageWidth * 0.3;
enemyShip3.x = 100;
enemyShip4 = new EnemyShip4();
stage.addChildAt(enemyShip4, 2);
enemyShip4.y = stage.stageWidth * 0.3;
enemyShip4.x = 400;
bossShip = new BossShip();
stage.addChildAt(bossShip, 1);
bossShip.y = 10;
bossShip.x = 130;*/
Mouse.hide();
}
private function handlefireTimer(e:TimerEvent) : void
{
//the timer runs, so a shot can be fired again
canFire = true;
}
public function playerShoot():void
{
//if canFire is true, allow a shot to be fired, then set canFire to false and start the timer again
//else, do nothing
if (canFire)
{
//Add new line to the array
playerShotArray.push(playerShot = new PlayerShot);
//Spawn missile in ship
playerShot.y = heroShip.y;
playerShot.x = heroShip.x+11;
addChild(playerShot);
canFire = false;
fireTimer.start();
sndChannel = shootsound.play();
}
}
public function playerShootMovement():void
{
//code adapted from the Pie Throw tutorial
for (var i:int = 0; i < playerShotArray.length; i++)
{
playerShotArray[i].y -= 10;
if (playerShotArray[i].y == 850)
{
playerShotArray.shift();
}
}
}
public function handleCharacterShoot(e:KeyboardEvent):void
{
/**
* SpaceBar = 32
*/
if (e.keyCode == 32)
{
playerShoot();
}
}
public function backgroundScroll (evt:Event):void
{
background1.y += scrollspeed;
background2.y += scrollspeed;
if (background1.y >= stage.stageHeight)
{
//the background is below the visible stage area, put it above the other background
background1.y = background2.y - background2.height;
}
else if (background2.y >= stage.stageHeight)
{
background2.y = background1.y - background2.height;
}
}
//EnemyShip 1 spawning
private function loop1(e:Event):void
{
//generates probability for the ship to spawn (lower number to increase odds, decrease it to decrease odds)
if (Math.floor(Math.random() * 55) == 5)
{
var enemyShip1:EnemyShip1 = new EnemyShip1(heroShip);
enemyShip1.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy1, false, 0, true);
enemies1Array.push(enemyShip1);
stage.addChild(enemyShip1);
}
}
private function removeEnemy1(e:Event):void
{
//removes the enemy that most recently left the screen from the array
enemies1Array.splice(enemies1Array.indexOf(e.currentTarget), 1);
}
//EnemyShip2 spawning
private function loop2(e:Event):void
{
if (Math.floor(Math.random() * 40) == 5)
{
var enemyShip2:EnemyShip2 = new EnemyShip2(heroShip);
enemyShip2.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy2, false, 0, true);
enemies2Array.push(enemyShip2);
stage.addChild(enemyShip2);
}
}
private function removeEnemy2(e:Event):void
{
enemies2Array.splice(enemies2Array.indexOf(e.currentTarget), 1);
}
}
}
interface IGameObject {
update():void;
}
class Enemy extends Sprite implements IGameObject {
public update():void {
// move, fire, etc
}
}
class Player extends Sprite implements IGameObject {
public update():void {
// move, fire, etc
}
}
class Bullet extends Bitmap implements IGameObject {
public update():void {
// move, collide, etc
}
}
class Main extends Sprite {
private objects:Vector.<IGameObject> = new <IGameObject>[];
public start():void {
addEventListener(Event.ENTER_FRAME, update);
}
public stopGame():void {
removeEventListener(Event.ENTER_FRAME, update);
}
private function update(e:Event):void {
for each (var object:IGameObject in objects) {
object.update();
}
}
public addObject(object:IGameObject):void {
objects.push(object);
addChild(object as DisplayObject);
}
public removeObject(object:IGameObject):void {
objects.splice(objects.indexOf(object), 1);
removeChild(object as DisplayObject);
}
}