2012-04-01 18 views
0

Immer noch ein iPad-Spiel in Actionscript 3 programmierend, stoße ich auf ein Problem, das mich davon abhält, weiter voranzukommen. Ich benutze Blitting für die Animation und verwende daher alle meine Objekte zum Rendern. Alle Objekte sind Kinder einer Spielklasse mit einer BitmapData-Leinwand, auf der die Spielelemente gerendert werden.Actionscript 3: Benutzereingabenereignisse, die nicht von Kindern ausgelöst werden Blit-Sprite-Objekte

Das ist, wie es funktionieren sollte. Bis jetzt gibt es keine Kompilierungs- oder Laufzeitfehler, aber aus irgendeinem Grund kann ich kein Benutzereingabeereignis von einem Objekt abgesehen vom Spiel selbst erhalten. Ich habe sowohl den Ereignisfluss als auch die Überlagerung der Objekte überprüft, aber bisher konnte ich nur herausfinden, dass der Haupt-Canvas das einzige Element ist, das für Ereignisse verwendet werden kann. Da Spieler in der Lage sein müssen, sie zu berühren, sind zwei Spielelemente betroffen: Twinkys und Tennisschläger.

Ich habe versucht, die Schichtung der Elemente in der Reihenfolge Instanciation und Rendering zu ändern, einige zu verstecken, Ereignistypen zu ändern (Mausereignis statt Berührungsereignisse) und die mouseEnabled Eigenschaft der Spielklasse ohne positives Ergebnis zu wechseln. Ich kann mir nur sicher sein, dass die Spielklasse alle auf ihre Kinder ausgerichteten Ereignisse abfängt, so dass es unmöglich ist, sie zu spielen. Ich hoffe, dass jemand sehen kann, was ich falsch gemacht habe.

Spielklasse:

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 Klasse:

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; 
    } 
} 
} 

Schläger Klasse:

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); 
    } 
} 
} 

Antwort

2

Touch-Ereignisse werden nur Feuer, wenn Sie ein Sprite Grafiken berühren. Aber alle deine Grafiken werden auf eine einzelne Bitmap gezeichnet, sodass deine verschiedenen Sprites nichts miteinander zu tun haben.

Flash bietet eine Anzeigeliste und macht einen guten Job es von Rendering, so sollten Sie nicht Ihre eigenen komplizierten Strukturen brauchen, so zu bauen.

sollten Sie prüfen jedes Sprite macht seine eigenen Grafiken und Dinge enthalten nur leichter trainieren. Wenn die Leistung eine große Sorge ist, schlage ich vor, bekommen es zuerst zu arbeiten, und dann mit verschiedenen Optimierungsstrategien danach spielen, um (zB cacheAsBitmap, Clipping/Scrollen mit scrollRect etc.)

+0

Natürlich ... Vielen Dank für die Hilfe, ich Beim nächsten Mal werde ich aufmerksamer sein. – Yokai