我正在关注一个avoider游戏教程,似乎无法在我班级的所有部分获得更新值。
package
{
import flash.display.Sprite;
import flash.text.TextField
import flash.text.TextFormat
public class Score extends Sprite
{
public var scoreDisplay:String;
public var currentValue:int;
public function Score()
{
updateDisplay()
}
public function updateDisplay():void
{
scoreDisplay = currentValue.toString();
var format:TextFormat = new TextFormat();
format.size = 25;
format.font = "Verdana"
var myText:TextField = new TextField();
myText.defaultTextFormat = format;
myText.text = scoreDisplay;
myText.background = true;
myText.autoSize
myText.width = 50;
myText.height = 35;
addChild(myText)
myText.x = 340
myText.y = 10
myText.mouseEnabled = false
}
public function addToValue( amountToAdd:Number ):void
{
currentValue = currentValue + amountToAdd;
}
}
}
每当我在'addToValue'中运行'currentValue'的跟踪时,它会以10的增量进行更新,但'updateDisplay'中'currentValue'的跟踪始终具有值0.我绝对无法弄清楚为什么一个'currentValue'没有更新另一个。
编辑1:
package
{
import flash.display.Sprite;
public class Start extends Sprite
{
public var game:Game;
public var gameover:GameOver;
public var background:Sprite;
public function Start()
{
background = new Sprite
background.graphics.beginFill(0xC0C0C0)
background.graphics.drawRect(0, 0, 400, 300)
background.graphics.endFill();
addChild(background)
var score:Score = new Score()
addChild(score)
game = new Game();
game.addEventListener(AvatarEvent.DEAD, startOver);
addChild(game);
}
public function startOver(avatarEvent:AvatarEvent):void
{
game.removeEventListener(AvatarEvent.DEAD, startOver);
gameover = new GameOver();
gameover.addEventListener(NavigationEvent.RESTART, requestRestart);
removeChild(game)
addChild(gameover);
}
private function requestRestart(e:NavigationEvent):void
{
restartGame();
}
public function restartGame():void
{
gameover.removeEventListener(NavigationEvent.RESTART, requestRestart);
game = new Game();
game.addEventListener(AvatarEvent.DEAD, startOver);
addChild(game);
removeChild(gameover);
}
}
}
编辑2
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.Timer;
import Score;
public class Game extends Sprite
{
public var army:Array;
public var gameTimer:Timer;
public var player:Player;
public var background:Sprite;
private var instanceScore:Score
public function Game()
{
army = new Array();
var newenemy:Enemy = new Enemy(100, -15);
army.push(newenemy);
addChild(newenemy);
player = new Player();
addChild(player);
player.x = mouseX;
player.y = mouseY;
gameTimer = new Timer(20);
gameTimer.addEventListener(TimerEvent.TIMER, move);
gameTimer.addEventListener(TimerEvent.TIMER, onTick);
gameTimer.start();
instanceScore = new Score();
}
private function move(timerEvent:TimerEvent):void
{
player.x = mouseX;
player.y = mouseY;
for each (var enemy:Enemy in army)
{
enemy.moveDownABit();
if (player.hitTestObject(enemy))
{
gameTimer.stop();
dispatchEvent( new AvatarEvent( AvatarEvent.DEAD));
}
}
}
public function onTick(e:Event):void
{
if (Math.random() < .1)
{
var randomX:Number = Math.random() * 400;
var newEnemy:Enemy = new Enemy(randomX, -15);
army.push(newEnemy);
addChild(newEnemy);
instanceScore.addToValue(10)
var score:Score = new Score()
addChild(score)
}
}
}
}
答案 0 :(得分:1)
在addToValue
调用updateDisplay
中,还要将TextFields
提取到实例变量,并将其添加到init
方法中。必须明确设置值。您期望隐式数据流...在ActionScript 3中没有给出。另一种方式是事件......但这也只是使用方法。
首先,我会创建一个专门的通知事件。只要您更熟悉ActionScript中的架构概念,这就派上用场了。这可能是偏离一般的,但出于访问者(get score
)和mutators(set score
)的演示目的,这可能是一个好主意。
package {
import flash.events.Event;
public class ScoreChangeEvent extends Event {
public static const SCORE_CHANGED:String = 'scoreChanged';
private var _score:int;
public function get score():int {
return _score;
}
public function ScoreChangeEvent(score:int) {
super(SCORE_CHANGED, true, false);
this._score = score;
}
override public function clone():Event {
return new ScoreChangeEvent(_score);
}
}
}
然后我重构了代码的某些部分,使可访问的内容成为可访问的,可扩展的,可扩展的和不可访问的内容,以及外部世界无法访问的内容。
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
[Event(name="scoreChanged", type="ScoreChangeEvent")]
public class ScoreDisplay extends Sprite {
/** The text field displaying the score. */
protected var _scoreTextField:TextField;
/** The internal storage variable for score to display. */
private var _score:int;
/**
* The score to be displayed. When the score changes,
* a ScoreChangeEvent will be dispatched.
*
* @see ScoreChangeEvent#SCORE_CHANGED
*/
public function get score():int {
return _score;
}
public function set score(value:int):void {
if (_score == value) {
return;
}
_score = value;
updateDisplayList();
this.dispatchEvent(new ScoreChangeEvent(_score));
}
public function ScoreDisplay() {
init();
}
/** Creation of children and initial rendering. */
private function init():void {
this.createChildren();
this.updateDisplayList();
}
/**
* DisplayObjects, which are one created once should be
* created in a dedicated method.
*/
protected function createChildren():void {
if (!_scoreTextField) {
const format:TextFormat = new TextFormat();
format.size = 25;
format.font = "Verdana";
_scoreTextField = new TextField();
_scoreTextField.defaultTextFormat = format;
_scoreTextField.background = true;
_scoreTextField.autoSize;
_scoreTextField.width = 50;
_scoreTextField.height = 35;
_scoreTextField.x = 340;
_scoreTextField.y = 10;
_scoreTextField.mouseEnabled = false;
addChild(_scoreTextField);
}
}
/** Reset the display. */
public function reset():void {
this.score = 0;
}
/**
* Adds a certain value to the current score.
* @param value The calue to be added.
*/
public function addToScore(value:int):void {
score += value;
}
/**
* Update the display when ever needed.
*
* This method should never be triggered by an
* different class, only be the instance itself
* when a value changed.
*/
protected function updateDisplayList() {
this._scoreTextField.text = this.score.toString();
}
}
}
score
,这样可以很容易地了解日志记录或调试器更改值的时间。_scoreTextField
受到保护,这意味着可以通过扩展子类来修改它。addToScore
将修改score
属性,作为回报更新显示。updateDisplayList
更改时才会调用score
。这样可以很容易地理解发生了什么。我的代码是Flex组件生命周期的廉价副本,只是为了说明某些模式在Flash中98%的用户界面相关编程中可能变得非常方便。
相反,您的class
也可以简单地重构为
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
public class ScoreDisplay extends Sprite {
protected var scoreTextField:TextField;
private var _score:int;
public function get score():int {
return _score;
}
public function set score(value:int):void {
if (_score == value) {
return;
}
_score = value;
scoreTextField.text = _score.toString();
}
public function ScoreDisplay() {
const format:TextFormat = new TextFormat();
format.size = 25;
format.font = "Verdana";
scoreTextField = new TextField();
scoreTextField.defaultTextFormat = format;
scoreTextField.background = true;
scoreTextField.autoSize;
scoreTextField.width = 50;
scoreTextField.height = 35;
scoreTextField.x = 340;
scoreTextField.y = 10;
scoreTextField.mouseEnabled = false;
addChild(scoreTextField);
}
public function addToScore(value:int):void {
score += value;
}
}
}
但是,当游戏变得更加复杂并且更重要时,该代码不是真正可扩展的并且需要更多更改,这将需要您在扩展组件时进行更多思考。
我希望这有点帮助。