2012-04-01 8 views
0

아직 Actionscript 3에서 iPad 게임을 프로그래밍 중이지만 더 이상 진행하지 못하게하는 문제가 있습니다. 나는 애니메이션을 위해 blitting을 사용하며, 따라서 모든 객체는 렌더링을 위해 blitting을 사용합니다. 모든 객체는 게임 요소로 렌더링되는 bitmapData 캔버스가있는 게임 클래스의 하위 노드입니다.Actionscript 3 : 사용자 입력 이벤트가 자식 블릿 스프라이트 객체에서 실행되지 않습니다.

그것이 어떻게 작동하는지 알아보십시오. 지금까지는 컴파일이나 런타임 오류가 없지만 어떤 이유에서든 게임 자체와 다른 객체로부터 사용자 입력 이벤트를 얻을 수는 없습니다. 이벤트 흐름뿐만 아니라 객체의 겹침을 확인했지만 지금까지 내가 알 수있는 모든 것이 주 캔버스가 이벤트 타겟이 될 수있는 유일한 요소라는 것입니다. 플레이어는 터치 할 수 있어야하기 때문에 Twinkys 및 Racquets와 같은 두 가지 게임 요소가 관련됩니다.

나는 인스턴스 생성과 렌더링, 터치 이벤트 대신 마우스 이벤트를 사용하여 이벤트 유형 변경, 게임 클래스의 속성 전환 등 긍정적 인 결과없이 숨겨진 순서대로 요소의 레이어를 변경해 보았습니다. 내가 확신 할 수있는 것은 게임 클래스가 자식을 대상으로하는 모든 이벤트를 가로 채고있어 게임을 할 수 없다는 것입니다. 누군가 내가 뭘 잘못했는지 알 수 있기를 바랍니다.

게임 클래스 :

package Game 
{ 
import Game.*; 
import Game.Worlds.Level1.Level1; 

import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.display.Sprite; 
import flash.display3D.IndexBuffer3D; 
import flash.events.Event; 
import flash.events.TouchEvent; 
import flash.ui.Multitouch; 
import flash.ui.MultitouchInputMode; 

public class Game extends Sprite 
{ 
    /** Hold each racquet so as to retrieve them when collision detection is needed. **/ 
    internal var racquetList:Vector.<Racquet>= new Vector.<Racquet>(2,true); 
    /** Hold each Zwig so as to retrieve them when collision detection is needed. **/ 
    internal var zwigColliderList:Vector.<Collider>= new Vector.<Collider>(2,true); 

    /** Object that contains the coordinates for the Twinkys in the counter. **/ 
    internal var twinkyScore0:Object= {firstX:727,firstY:950,secondX:710,secondY:911, 
     thirdX:690,thirdY:872,fourthX:674,fourthY:840, 
     fifthX:657,fifthY:808}; 
    internal var twinkyScore1:Object= {firstX:41,firstY:74,secondX:58,secondY:113, 
     thirdX:78,thirdY:152,fourthX:94,fourthY:184, 
     fifthX:111,fifthY:216}; 

    /** Speed decay coefficient. The closer to 1 the less speed decays. **/ 
    private var friction:Number= .96; 
    /** Maximum speed cap for twinkys. The higher the number the grater the maximal speed. **/ 
    private var speedMax:Number= 10; 

    /** Important positions for the placement of game elements. 
    * LianaHeight is the height at which the liana on the players' HUDs is ending their zone and on which the racquet travels. 
    * TwinkyHeight is the height at which the players stop controlling their Twinkys. 
    * YMargin is the vertical margin for the Twinkys. Used to place them at the end of the tube when added. 
    * XMargin is the horizontal margin for the Twinkys. Used to place them at the end of the tube when added. **/ 
    private var positions:Object= {LianaHeight:165,TwinkyHeight:265,YMargin:8.0,XMargin:200.0}; 

    private var _mRef:ZwigsIpad; 
    Multitouch.inputMode= MultitouchInputMode.TOUCH_POINT; 

    private var _Canvas:BitmapData= new BitmapData(ZwigsIpad.BORDERS.right,ZwigsIpad.BORDERS.bottom,false); 
    private var _Background:Background; 
    private var _HUD1:HUD; 
    private var _HUD2:HUD; 
    private var _Score:Score; 
    private var _Zwig1:Zwig; 
    private var _Zwig2:Zwig; 
    private var _Racquet1:Racquet; 
    private var _Racquet2:Racquet; 
    private var _Twinky1:Twinky; 
    private var _Twinky2:Twinky; 

    /** Create the first level. It will create the stage and add the background, HUDs, Zwigs, Racquets and Twinkys, and manages the game until the end. **/ 
    public function Game(m:ZwigsIpad) 
    { 
     this._mRef= m; 
     this.addEventListener(Event.ADDED_TO_STAGE,init); 
    } 

    private function init(e:Event):void 
    { 
     this.removeEventListener(Event.ADDED_TO_STAGE,init); 

     // Add game canvas on which all assets are rendered 
     addChild(new Bitmap(this._Canvas)); 

     // Get informations from Level1 
     // LATER make it dependant from what level was chosen (switch case) 
     this.positions.LianaHeight= Level1.LIANA_HEIGHT; 
     this.positions.TwinkyHeight= Level1.TWINKY_HEIGHT; 
     this.positions.YMargin= Level1.TWINKY_MARGIN_Y; 
     this.positions.XMargin= Level1.TWINKY_MARGIN_X; 
     this.friction= Level1.TWINKY_FRICTION; 
     this.speedMax= Level1.TWINKY_SPEED_MAX; 

     // Add background 
     this._Background= new Background(this._Canvas,0); 
     addChild(this._Background); 

     // Add HUD 
     this._HUD1= new HUD(this._Canvas); 
     this._HUD2= new HUD(this._Canvas,true,1); 
     addChild(this._HUD1); 
     addChild(this._HUD2); 

     // Add scoring 
     this._Score= new Score(this,this._mRef); 
     addChild(this._Score); 

     // Add zwigs 
     this._Zwig1= new Zwig(this._Canvas); 
     this._Zwig2= new Zwig(this._Canvas,true,1); 
     addChild(this._Zwig1); 
     addChild(this._Zwig2); 

     // Add zwigs' colliders to vector 
     this.zwigColliderList[0]= this._Zwig1.collider; 
     this.zwigColliderList[1]= this._Zwig2.collider; 

     // Add racquets 
     this._Racquet1= new Racquet(this.positions,this._Canvas); 
     this._Racquet2= new Racquet(this.positions,this._Canvas,false,1); 
     addChild(this._Racquet1); 
     addChild(this._Racquet2); 

     // Add racquets to vector 
     this.racquetList[0]= this._Racquet1; 
     this.racquetList[1]= this._Racquet2; 

     // Add twinkys 
     this._Twinky1= new Twinky(this,this._Score,this,this.positions,this.friction,this.speedMax,this._Canvas,0); 
     this._Twinky2= new Twinky(this,this._Score,this,this.positions,this.friction,this.speedMax,this._Canvas,1,false,1); 
     addChild(this._Twinky1); 
     addChild(this._Twinky2); 

     this.addEventListener(Event.ENTER_FRAME,renderLevel); 
    } 

    private function renderLevel(e:Event):void 
    { 
     this._Canvas.lock(); 

     this._Background.render(); 
     this._HUD1.render(); 
     this._HUD2.render(); 
     this._Score.render(); 
     this._Zwig1.render(); 
     this._Zwig2.render(); 
     this._Racquet1.render(); 
     this._Racquet2.render(); 
     this._Twinky1.render(); 
     this._Twinky2.render(); 

     this._Canvas.unlock(); 
    } 
} 
} 

Twinky 클래스 :

package Game 
{ 
import Game.Game; 
import Game.Score; 

import com.greensock.TweenMax; 
import com.greensock.easing.*; 

import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.display.Sprite; 
import flash.events.Event; 
import flash.events.TouchEvent; 
import flash.geom.Point; 
import flash.geom.Rectangle; 
import flash.ui.Multitouch; 
import flash.ui.MultitouchInputMode; 

/** The Twinky is the main player controlled class. **/ 
internal class Twinky extends Sprite 
{ 
    private var _mRef:Game; 
    private var _sRef:Score; 
    private var player:uint; 

    Multitouch.inputMode= MultitouchInputMode.TOUCH_POINT; 
    private var _touchMoveID:int= 0; 
    private var _speedX:Number= 0; 
    private var _speedY:Number= 0; 
    private var xOffset:Number; 
    private var yOffset:Number; 
    private var currentX:Number; 
    private var currentY:Number; 
    private var oldX:Number; 
    private var oldY:Number; 
    private var dragging:Boolean= false; 
    private var launched:Boolean= false; 
    private var _point:Point= new Point(); 

    private var positions:Object; 
    private var friction:Number; 
    private var speedMax:Number; 
    private var canvas:BitmapData; 
    private var isAtBottom:Boolean; 
    private var skin:uint; 

    private var _image:BitmapData; 
    private var _idleArray:Array= new Array(); 
    private var i:uint= 0; 

    // Yellow twinky 
    [Embed (source= "Assets/Players/twinky1.png")] 
    private const Twinky1idle:Class; 
    private var _twinky1idleArray:Array; 
    // Red twinky 
    [Embed (source= "Assets/Players/twinky2.png")] 
    private const Twinky2idle:Class; 
    private var _twinky2idleArray:Array; 

    private const twinkyWidth:uint= 64; 
    private const twinkyHeight:uint= 64; 

    private var t1i001:Rectangle= new Rectangle(0,0,twinkyWidth,twinkyHeight); 
    private var t2i001:Rectangle= new Rectangle(0,0,twinkyWidth,twinkyHeight); 

    /** Create Twinky. Twinkys must be flicked to the same colored Zwig to 
    * feed it and die when they lost momentum. **/ 
    public function Twinky(daddy:Game,score:Score,m:Game,positions:Object,friction:Number,speedMax:Number,canvas:BitmapData,player:uint,isAtBottom:Boolean=true,skin:uint=0) 
    { 
     // Get score and game object reference 
     this._sRef= score; 
     this._mRef= daddy; 

     this.positions= positions; 
     this.friction= friction; 
     this.speedMax= speedMax; 
     this.canvas= canvas; 
     this.player= player; 
     this.isAtBottom= isAtBottom; 
     this.skin= skin; 

     this._twinky1idleArray= [t1i001]; 
     this._twinky2idleArray= [t2i001]; 

     this.addEventListener(Event.ADDED_TO_STAGE,init,false,0,true); 
    } 

    private function init(e:Event):void 
    { 
     this.removeEventListener(Event.ADDED_TO_STAGE,init); 

     // Get skin 
     switch (this.skin) 
     { 
      case 0: 
       this._image= new this.Twinky1idle().bitmapData; 
       this._idleArray= this._twinky1idleArray; 
      break; 

      case 1: 
       this._image= new this.Twinky2idle().bitmapData; 
       this._idleArray= this._twinky2idleArray; 
      break; 

      default: 
       this._image= new this.Twinky1idle().bitmapData; 
       this._idleArray= this._twinky1idleArray; 
      break; 
     } 

     // Give position 
     if (this.isAtBottom) 
     { 
      this.x= this.positions.XMargin; 
      this.y= ZwigsIpad.BORDERS.bottom - this.positions.YMargin; 

      // Animate entrance 
      TweenMax.from(this,1,{x:this.x-70,y:this.y-12,rotation:-180,alpha:.5}); 
     } 
     else 
     { 
      this.x= ZwigsIpad.BORDERS.right - this.positions.XMargin; 
      this.y= this.positions.YMargin; 

      // Animate entrance 
      TweenMax.from(this,1,{x:this.x+70,y:this.y+12,rotation:-180,alpha:.5}); 
     } 

     this._point.x= this.x; 
     this._point.y= this.y; 

     aText.appendText("\n position: "+this.x+" "+this.y); 

     // Detect touched 
     this.addEventListener(TouchEvent.TOUCH_BEGIN,touchDown); 
     // Always detect untouched 
     this._mRef.addEventListener(TouchEvent.TOUCH_END,touchUp); 
     // Always do kinetics 
     this._mRef.addEventListener(Event.ENTER_FRAME,freeMove); 
    } 

    /** Render the Twinky at its current coordinates by redrawing it. **/ 
    internal function render():void 
    { 
     this._point.x= this.x - this._idleArray[i].width * .5; 
     this._point.y= this.y - this._idleArray[i].height * .5; 

     this.canvas.copyPixels(this._image,this._idleArray[0/*i*/],this._point); 

     // When idle finished restart, else pursue with animation 
     /*if (i==this._idleArray.length - 1) 
      i= 0; 
     else 
      i++;*/ 
    } 

    // TWINKY AND RACQUET DO NOT DETECT TOUCH EVENTS because the main canvas covers them 
    // Start dragging when touched 
    private function touchDown(e:TouchEvent):void 
    { 
     aText.appendText("\n Twinky touched!"); 

     if (this._touchMoveID != 0) 
      return; 

     this._touchMoveID= e.touchPointID; 
     this.dragging= true; 
     // Get the mouse's offset on the object 
     this.xOffset= e.localX; 
     this.yOffset= e.localY; 

     this._mRef.addEventListener(TouchEvent.TOUCH_MOVE,touchMove); 
    } 

    private function touchMove(e:TouchEvent):void 
    { 
     if (e.touchPointID != this._touchMoveID) 
      return; 

     // Move twinky to where the mouse is 
     this.x= e.stageX - this.xOffset; 
     this.y= e.stageY - this.yOffset; 

     // Don't go farther than borders 
     if (this.x <= this.width * .5) 
     { 
      this.x= (this.width * .5) + .1; 
     } 

     if (this.x >= ZwigsIpad.BORDERS.right - (this.width * .5)) 
     { 
      this.x= ZwigsIpad.BORDERS.right - (this.width * .5) - .1; 
     } 

     if (this.y <= this.height * .5) 
     { 
      this.y= (this.height * .5) + .1; 
     } 

     if (this.y >= ZwigsIpad.BORDERS.bottom - (this.height * .5)) 
     { 
      this.y= ZwigsIpad.BORDERS.bottom - (this.height * .5) - .1; 
     } 

     // Be undraggable if zone is left 
     if (this.isAtBottom) 
     { 
      if (this.y < (ZwigsIpad.BORDERS.bottom - this.positions.TwinkyHeight)) 
      { 
       this._touchMoveID= 0; 
       this.dragging= false; 

       this._mRef.removeEventListener(TouchEvent.TOUCH_MOVE,touchMove); 
       return; 
      } 
     } 
     else 
     { 
      if (this.y > this.positions.TwinkyHeight) 
      { 
       this._touchMoveID= 0; 
       this.dragging= false; 

       this._mRef.removeEventListener(TouchEvent.TOUCH_MOVE,touchMove); 
       return; 
      } 
     } 

     // Refresh coordinates for display 
     this._point.x= this.x; 
     this._point.y= this.y; 

     e.updateAfterEvent(); 
    } 

    private function touchUp(e:TouchEvent):void 
    { 
     if (e.touchPointID != this._touchMoveID) 
      return; 

     this._touchMoveID= 0; 
     this.dragging= false; 

     this._mRef.removeEventListener(TouchEvent.TOUCH_MOVE,touchMove); 
    } 

    private function freeMove(e:Event):void 
    { 
     // Be undraggable if liana crossed 
     if (this.isAtBottom) 
     { 
      if (this.y < (ZwigsIpad.BORDERS.bottom - this.positions.TwinkyHeight)) 
      { 
       this.removeEventListener(TouchEvent.TOUCH_BEGIN,touchDown); 
       this._mRef.removeEventListener(Event.ENTER_FRAME,touchUp); 
       this.dragging= false; 
       this.launched= true; 
      } 
     } 
     else 
     { 
      if (this.y > this.positions.TwinkyHeight) 
      { 
       this.removeEventListener(TouchEvent.TOUCH_BEGIN,touchDown); 
       this._mRef.removeEventListener(Event.ENTER_FRAME,touchUp); 
       this.dragging= false; 
       this.launched= true; 
      } 
     } 

     // Move the twinky and calculate its speed if player is dragging it 
     if (this.dragging) 
     { 
      aText.appendText("\n Twinky dragged!"); 
      this.oldX= currentX; 
      this.oldY= currentY; 
      currentX= this.x; 
      currentY= this.y; 

      // Calculate speed in X and Y axis 
      this._speedX= this.currentX - this.oldX; 
      this._speedY= this.currentY - this.oldY; 

      // Cap maximal speed 
      if (this._speedX > this.speedMax) 
       this._speedX= this.speedMax; 

      if (this._speedY > this.speedMax) 
       this._speedY= this.speedMax; 
     } 
     // Otherwise move the twinky using its speed 
     else 
     { 
      this.x+= this._speedX; 
      this.y+= this._speedY; 
     } 

     // Detect collision with zwigs 
     for (i= 0 ; i < this._mRef.zwigColliderList.length ; i++) 
     { 
      var cemp:Collider= this._mRef.zwigColliderList[i] as Collider; 
      if (this.hitTestObject(cemp)) 
      { 
       this.removeEventListener(TouchEvent.TOUCH_BEGIN,touchDown); 
       this._mRef.removeEventListener(TouchEvent.TOUCH_END,touchUp); 
       this._mRef.removeEventListener(Event.ENTER_FRAME,freeMove); 
       this._sRef.die(this,this.player,true,i); 
       return; 
      } 
     } 

     // Detect collision with borders: left border 
     if (this.x <= this.width/2) 
     { 
      // Don't go any further 
      this.x= (this.width/2) + .1; 
      // Reverse speed to bounce 
      this._speedX*= -1; 
     } 
     // Right border 
     if (this.x >= ZwigsIpad.BORDERS.right - (this.width/2)) 
     { 
      this.x= ZwigsIpad.BORDERS.right - (this.width/2) - .1; 
      this._speedX*= -1; 
     } 
     // Top border 
     if (this.y <= this.height/2) 
     { 
      this.y= (this.height/2) + .1; 
      this._speedY*= -1; 
     } 
     // Bottom border 
     if (this.y >= ZwigsIpad.BORDERS.bottom - (this.height/2)) 
     { 
      this.y= ZwigsIpad.BORDERS.bottom - (this.height/2) - .1; 
      this._speedY*= -1; 
     } 

     // Detect collision with racquets 
     for (var i:uint= 0 ; i < this._mRef.racquetList.length ; i++) 
     { 
      var temp:Racquet= this._mRef.racquetList[i] as Racquet; 
      if (this.hitTestObject(temp)) 
      { 
       this._speedY*= -1; 
       this.y+= this._speedY; 
      } 
     } 

     // Speed decay 
     this._speedX*= this.friction; 
     this._speedY*= this.friction; 

     // Set speed to 0 if speed is smaller than .5 
     if (Math.abs(this._speedX) < .5) this._speedX= 0; 
     if (Math.abs(this._speedY) < .5) this._speedY= 0; 

     // If speed is null and it has been launched, kill twinky 
     if (this._speedX == 0 && this._speedY == 0 && this.launched) 
     { 
      this.removeEventListener(TouchEvent.TOUCH_BEGIN,touchDown); 
      this._mRef.removeEventListener(TouchEvent.TOUCH_END,touchUp); 
      this._mRef.removeEventListener(Event.ENTER_FRAME,freeMove); 
      TweenMax.to(this, 1.5, {alpha:0, ease:Linear.easeNone}); 
      this._sRef.die(this,this.player); 
      return; 
     } 

     // Refresh coordinates for display 
     this._point.x= this.x; 
     this._point.y= this.y; 
    } 
} 
} 

라켓 클래스 :

package Game 
{ 
import Game.Worlds.Level1.Level1; 

import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.display.Sprite; 
import flash.events.Event; 
import flash.events.TouchEvent; 
import flash.geom.Point; 
import flash.ui.Multitouch; 
import flash.ui.MultitouchInputMode; 

internal class Racquet extends Sprite 
{ 
    Multitouch.inputMode= MultitouchInputMode.TOUCH_POINT; 
    private var _touchMoveID:int= 0; 
    private var xOffset:Number; 
    private var dragging:Boolean= false; 

    private var positions:Object; 
    private var canvas:BitmapData; 
    private var isAtBottom:Boolean; 
    private var skin:uint; 

    private var _image:BitmapData; 
    private var _point:Point= new Point(); 

    // Yellow racquet 
    [Embed (source= "Assets/Players/racq1.png")] 
    private const Racquet1:Class; 
    // Red racquet 
    [Embed (source= "Assets/Players/racq2.png")] 
    private const Racquet2:Class; 

    public function Racquet(positions:Object,canvas:BitmapData,isAtBottom:Boolean=true,skin:uint=0) 
    { 
     this.positions= positions; 
     this.canvas= canvas; 
     this.isAtBottom= isAtBottom; 
     this.skin= skin; 

     this.addEventListener(Event.ADDED_TO_STAGE,init,false,0,true); 
    } 

    private function init(e:Event):void 
    { 
     this.removeEventListener(Event.ADDED_TO_STAGE,init); 

     // Get skin 
     switch (this.skin) 
     { 
      case 0: 
       //this._image= new R.Racquet1().bitmapData; 
       this._image= new this.Racquet1().bitmapData; 
      break; 

      case 1: 
       //this._image= new R.Racquet2().bitmapData; 
       this._image= new this.Racquet2().bitmapData; 
      break; 

      default: 
       this._image= new this.Racquet1().bitmapData; 
      break; 
     } 

     // Give position 
     if (this.isAtBottom) 
     { 
      this.x= ZwigsIpad.BORDERS.centerX; 
      this.y= ZwigsIpad.BORDERS.bottom - this.positions.LianaHeight; 
     } 
     else 
     { 
      this.x= ZwigsIpad.BORDERS.centerX; 
      this.y= this.positions.LianaHeight; 
     } 

     this._point.x= this.x; 
     this._point.y= this.y; 

     this.addEventListener(TouchEvent.TOUCH_BEGIN,touchDown,false,0,true); 
     this.parent.addEventListener(TouchEvent.TOUCH_END,touchUp,false,0,true); 
    } 

    internal function render():void 
    { 
     this._point.x= this.x - this._image.rect.width * .5; 
     this._point.y= this.y - this._image.rect.height * .5; 

     this.canvas.copyPixels(this._image,this._image.rect,this._point); 
    } 

    private function touchDown(e:TouchEvent):void 
    { 
     aText.appendText("\n Racquet touched!"); 
     if(this._touchMoveID != 0) 
      return; 

     this._touchMoveID= e.touchPointID; 

     this.xOffset= e.localX; 
     this.parent.addEventListener(TouchEvent.TOUCH_MOVE,touchMove,false,0,true); 
    } 

    private function touchMove(e:TouchEvent):void 
    { 
     if(e.touchPointID != this._touchMoveID) 
      return; 

     Multitouch.inputMode= MultitouchInputMode.TOUCH_POINT; 
     this._point.x= e.stageX - this.xOffset; 

     if (this._point.x <= ZwigsIpad.BORDERS.left + (this._image.width*.5)) 
      this._point.x= ZwigsIpad.BORDERS.left + (this._image.width*.5); 
     else if (this._point.x >= ZwigsIpad.BORDERS.right - (this._image.width*.5)) 
      this._point.x= ZwigsIpad.BORDERS.right - (this._image.width*.5); 
    } 

    private function touchUp(e:TouchEvent):void 
    { 
     if(e.touchPointID != this._touchMoveID) 
      return; 

     this._touchMoveID= 0; 
     this.parent.removeEventListener(TouchEvent.TOUCH_MOVE,touchMove); 
    } 
} 
} 

답변

2

터치 이벤트 것입니다 당신이 스프라이트의 그래픽을 만지지 만 불. 그러나 모든 그래픽이 하나의 비트 맵에 그려 지므로 다양한 스프라이트와 상호 작용할 필요가 없습니다.

플래시는 표시 목록을 제공하고이를 렌더링하는 훌륭한 작업을 수행하므로 이와 같은 복잡한 구조를 만들 필요가 없습니다.

각 스프라이트에 자체 그래픽이 포함되도록하는 것이 좋습니다. 퍼포먼스가 큰 걱정거리라면, 먼저 그것을 작동시키는 것이 좋습니다. 그리고 나서 다른 최적화 전략을 사용하십시오. (예 : cacheAsBitmap, scrollRect로 클리핑/스크롤링)

+0

물론 ... 도움을 주셔서 감사합니다. 다음 번에 내가이 일에 대해 더주의를 기울일 것입니다. – Yokai