아직 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);
}
}
}
물론 ... 도움을 주셔서 감사합니다. 다음 번에 내가이 일에 대해 더주의를 기울일 것입니다. – Yokai