我目前正在尝试制作游戏,但现在的问题是,当我调度事件时,只有我的主类选择它(引擎)。我希望我的Weapons.as也能把它拿起来。我的主要类是Engine.as(分配给舞台类),而我的weapon.as就是这艘船。我从一个名为Score.as的班级调度该事件。
主要问题是我的Weapons.as没有拿起“gameO”,也没有“gameOver”事件,score.as发送。另一件事是,如果我设置if(s_hp == 100)(它是从它开始的那个),我的Weapons.as设法获取调度的事件,但只有那时......
更具体一点,我想/需要将一个事件从Score.as,通过Weapons.as鼓泡到我的主类Engine.as。 Weapons.as中的eventListener需要拾取并移除船只并使其无法射击,然后将事件进一步传递到Engine.as类,这几乎可以从舞台中删除所有内容
给予我任何帮助! :)
编辑:完整课程
Score.as:
package Etys
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.text.TextField;
import flash.events.Event;
import flash.utils.Timer;
import flash.geom.ColorTransform;
public class Score extends MovieClip
{
private var stageRef:Stage;
public var s_score:Number = 0;
public var s_hits:Number;
public var s_kills:Number = 0;
public function Score(stageRef:Stage)
{
this.stageRef = stageRef;
s_hits = 100;
healthBar.width = 100;
kills.text = "Kills: \n0";
hits.text = "HP: \n100";
score.text = "Score: \n0";
kills.selectable = false;
hits.selectable = false;
score.selectable = false;
x = 10;
y = stageRef.stageHeight - height;
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
public function updateKills(value:Number) : void
{
s_kills += value;
kills.text = String("Kills: \n"+s_kills);
trace(s_hits+"I Kills");
}
public function updateHits(value:Number) : void
{
if(s_hits != 1 || s_hits != 0)
{
s_hits -= value;
healthBar.width -= value;
hits.text = String("HP: \n"+s_hits);
}else{
healthBar.width = 0;
s_hits = 0;
hits.text = String("HP: \n"+s_hits);
}
if(s_hits == 66 ||s_hits == 67)
{
var colorYellow:ColorTransform = healthBar.transform.colorTransform;
colorYellow.color = 0xFFFF00;
healthBar.transform.colorTransform = colorYellow;
}else if(s_hits == 33 || s_hits == 34)
{
var colorRed:ColorTransform = healthBar.transform.colorTransform;
colorRed.color = 0xFF0000;
healthBar.transform.colorTransform = colorRed;
}
s_score -= value;
score.text = String("Score: \n"+s_score);
trace(s_hits+"I Hits");
}
public function updateScore(value:Number) : void
{
s_score += value;
score.text = String("Score: \n"+s_score);
trace(s_hits+"I Score");
}
public function loop(e:Event)
{
if(s_hits == 99 || s_hits == 98)
{
this.dispatchEvent(new Event('gameOver', true));
this.dispatchEvent(new Event('gameO', true));
removeEventListener(Event.ENTER_FRAME, loop);
}
}
}
}
Weapons.as:
package Etys
{
import flash.display.MovieClip;
import flash.display.Stage;
import com.senocular.utils.KeyObject;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Weapons extends MovieClip
{
private var stageRef:Stage;
private var key:KeyObject;
private var speed:Number = 2;
private var vx:Number = 0;
private var vy:Number = 0;
private var friction:Number = 0.93;
private var maxspeed:Number = 8;
private var target:Stinger;
public var score:Score;
private var fireTimer:Timer;
private var canFire:Boolean = true;
private var stopIt:Boolean = false;
public function Weapons(stageRef:Stage)
{
this.stageRef = stageRef;
score = new Score(stageRef);
addChild(score);
score.addEventListener('gameO', lostGame, false, 0, false);
addChild(score);
key = new KeyObject(stageRef);
fireTimer = new Timer(200, 1);
fireTimer.addEventListener(TimerEvent.TIMER, fireTimerHandler, false, 0, true);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
public function loop(e:Event) : void
{
if (key.isDown(Keyboard.A))
{
vx -= speed;
}else if (key.isDown(Keyboard.D))
{
vx += speed;
}else{
vx *= friction;
}
if (key.isDown(Keyboard.W))
{
vy -= speed;
}else if (key.isDown(Keyboard.S))
{
vy += speed;
}else{
vy *= friction;
}
if (key.isDown(Keyboard.SPACE))
{
fireBullet();
}
//update position
x += vx;
y += vy;
//speed adjustment
if (vx > maxspeed)
{
vx = maxspeed;
}else if (vx < -maxspeed)
{
vx = -maxspeed;
}
if (vy > maxspeed)
{
vy = maxspeed;
}else if (vy < -maxspeed)
{
vy = -maxspeed;
}
//ship appearance
rotation = vx;
scaleX = (maxspeed - Math.abs(vx))/(maxspeed*4) + 0.75;
//stay inside screen
if (x > 537)
{
x = 537;
vx = -vx;
}
else if (x < 13)
{
x = 13;
vx = -vx;
}
if (y > 378)
{
y = 378;
vy = -vy;
}
else if (y < 216)
{
y = 216;
vy = -vy;
}
}
public function lostGame(e:Event)
{
trace("bash");
fireTimer.stop();
fireTimer.reset();
canFire = false;
fireTimer.removeEventListener(TimerEvent.TIMER, fireTimerHandler);
removeEventListener(Event.ENTER_FRAME, loop);
}
private function fireBullet() : void
{
//if canFire is true, fire a bullet
//set canFire to false and start our timer
//else do nothing.
if (canFire)
{
stageRef.addChild(new LaserBlue(stageRef, x + vx +15, y - 10));
stageRef.addChild(new LaserBlue2(stageRef, x + vx -15, y - 10));
canFire = false;
fireTimer.start();
}
}
//HANDLERS
private function fireTimerHandler(e:TimerEvent) : void
{
//timer ran, we can fire again.
canFire = true;
}
public function hitShip() : void
{
dispatchEvent(new Event("hitShipe"));
}
public function takeHit() : void
{
dispatchEvent(new Event("hit"));
}
}
}
发动机:
package Etys
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.media.SoundChannel;
import flash.utils.Timer;
import flash.display.*;
public class Engine extends MovieClip
{
private var numStars:int = 80;
private var numAsteroids:int = 4;
public static var enemyList:Array = new Array();
public static var enemyListFatso:Array = new Array();
private var ourShip:Weapons;
private var quality:qualityButton;
private var score:Score;
public function Engine() : void
{
ourShip = new Weapons(stage);
stage.addChild(ourShip);
ourShip.x = stage.stageWidth / 2;
ourShip.y = stage.stageHeight / 2;
ourShip.addEventListener("hit", shipHit, false, 0, true);
ourShip.addEventListener("hitShip", Hit, false, 0, true);
for (var i:int = 0; i < numStars; i++)
{
stage.addChildAt(new Star(stage), stage.getChildIndex(ourShip));
}
for (var a:int = 0; a < numAsteroids; a++)
{
stage.addChildAt(new Asteroids(stage), stage.getChildIndex(ourShip));
}
quality = new qualityButton(stage);
stage.addChild(quality);
score = new Score(stage);//create our HUD
stage.addChild(score);
score.addEventListener("gameOver", lostGame, false, 0, true);
//running a loop now.... so we can keep creating enemies randomly.
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
private function lowQ(e:MouseEvent)
{
stage.quality = StageQuality.LOW;
trace("Low");
}
private function highQ(e:MouseEvent)
{
stage.quality = StageQuality.BEST;
trace("High");
}
//our loop function
private function loop(e:Event):void
{
if (Math.floor(Math.random() * 90) == 4)
{
var enemyFatso:Fatso = new Fatso(stage,ourShip);
enemyFatso.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemyFatso, false, 0, true);
enemyFatso.addEventListener("killed", enemyFatsoKilled, false, 0, true);
enemyFatso.addEventListener("enemyC", enemyCrash, false, 0, true);
enemyListFatso.push(enemyFatso);
stage.addChild(enemyFatso);
}
//run if condition is met.
if (Math.floor(Math.random() * 90) == 5 || Math.floor(Math.random() * 90) == 6)
{
//create our enemy
var enemy:Stinger = new Stinger(stage,ourShip);
enemy.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy, false, 0, true);
enemy.addEventListener("killed", enemyKilled, false, 0, true);
enemy.addEventListener("enemyC", enemyCrash, false, 0, true);
enemyList.push(enemy);
stage.addChild(enemy);
}
}
private function enemyFatsoKilled(e:Event)
{
score.updateKills(1);
score.updateScore(e.currentTarget.points);
}
private function enemyKilled(e:Event)
{
score.updateKills(1);
score.updateScore(e.currentTarget.points);
}
private function enemyCrash(e:Event)
{
score.updateHits(2);
}
private function removeEnemyFatso(e:Event)
{
enemyListFatso.splice(enemyListFatso.indexOf(e.currentTarget), 1);
}
private function lostGame(e:Event)
{
dispatchEvent(new Event("removeShips", true));
stage.removeChild(ourShip);
ourShip.removeEventListener("hit", shipHit);
ourShip.removeEventListener("hitShip", Hit);
removeEventListener(Event.ENTER_FRAME, loop);
}
private function removeEnemy(e:Event)
{
enemyList.splice(enemyList.indexOf(e.currentTarget), 1);
}
private function Hit(e:Event)
{
trace("lol");
}
private function shipHit(e:Event)
{
score.updateHits(1);
}
}
}
答案 0 :(得分:0)
ActionScript 3中的事件在很大程度上非常简单。一个对象调度一个Event,一个Listener将处理它,这里有一个非常简单的例子,说明了双方如何交互:
事件调度程序类
// By extending the EventDispatcher class, we can now dispatch events! Note that
// Sprite and MovieClip both extend EventDispatcher through inheritance.
public class Dispatcher extends EventDispatcher {
public function Dispatcher() {
// Create a simple interval which will call the "dispatchTickleEvent"
// method every 1.5 seconds.
setInterval(dispatchTickleEvent, 1500);
}
private function dispatchTickleEvent() {
// Broadcast an Event of type TICKLE which other classes and listen
// out for.
dispatchEvent(new Event("TICKLE"));
}
}
听众类
// Note that event listeners don't have to extend anything in order to listen
// out for Events.
public class Listener {
public function Listener() {
// Create a new instance of the Dispatcher Class.
var dispatcher : Dispatcher = new Dispatcher();
// Here's where we add an EventListener to the Dispatcher instance.
// This simply means that each time the dispatcher instances emits
// an Event of type "TICKLE", the "onDispatcherTickled" function will
// be called.
dispatcher.addEventListener("TICKLE", onDispatcherTickled);
}
// This is the event handler method which will be called whenever our dispatcher
// instance broadcasts an Event of type "TICKLE".
private function onDispatcherTicked(event : Event) : void {
trace("The dispatcher was Tickled!");
}
}
这是一个非常强大的系统,因为它为类提供了一种松散耦合的方式来相互通信。通过松散耦合,我们的意思是监听器类不知道导致事件被广播的原因(在上面的例子中,它是由间隔自动引起的);这样就可以在不必更改Listener类的情况下修改行为 - 例如,我们可以这样做,以便在用户单击鼠标时仅调度Tickle事件。
到目前为止,这么简单,但事件有一个相当有趣的怪癖,当显示列表上的DisplayObjects开始调度称为冒泡或事件传播的事件时,它会发挥作用。
基本概念是,如果已添加到活动显示列表的DisplayObject(例如Sprite)调度一个Event,那么该Event将通过(bubble)通过其每个'父'DisplayObject直到它最终到达舞台。事件冒泡的一个很好的例子是shown on Ruben Swieringa's blog。如果您滚动到文章的底部,您将看到一个Flash动画,它演示了事件冒泡的效果。
这是一个非常简单的事件冒泡代码示例:
事件调度程序类,这次调度将冒泡的事件
// Note that we have to extend Sprite in order to be added to the Display List,
// but as mentioned before, Sprite itself extends EventDispatcher further down
// its inheritance tree.
public class Dispatcher extends Sprite {
public function Dispatcher() {
// The interval will call dispatchTickleEvent every 1.5 seconds.
setInterval(dispatchTickleEvent, 1500);
}
private function dispatchTickleEvent() {
// Dispatch the Tickle Event, but this time notice how we pass true as
// the second argument when constructing the new Event() instance, this
// tells the Event that it should Bubble up the Display List. All of
// the "internal" Flash Event which are dispatched automatically, such as
// MouseEvent.CLICK, Event.ENTER_FRAME, etc are all set to bubble by default.
dispatchEvent(new Event("TICKLE", true));
}
}
监听器类,它还设置了显示列表
public class Listener {
public function Listener(stage : Stage) {
// Create the Dispatcher instance.
const dispatcher : Dispatcher = new Dispatcher();
// Add the Dispatcher Instance to the Display List by adding it as a
// child of the Stage.
stage.addChild(dispatcher);
// Now we add the EventListeners, but instead of listening directly to
// the Dispatcher instance, like we did last time, we will instead listen
// for the Tickle event on the Stage.
stage.addEventListener("TICKLE", onTickleEvent);
}
private function onTickleEvent(event : Event) : void {
trace("Someone was tickled! :)");
}
}
因此,如果所有类实例都是要添加到显示列表的显示对象,那么它应该像将调度的事件冒泡到显示列表中然后将事件监听器添加到舞台一样简单。
希望有所帮助!