我正在构建一个Adobe Air AS3 IOS和Android App,其中我在舞台中央有一个影片剪辑。当您开始触摸此影片剪辑时,您可以在舞台上移动它。
这就是我这样做的方式:
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
MC_M1.alpha = 1;
MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);
MC_M1.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
MC_M1.x = 0.516 * gameIntro.stageWidthToUse;
MC_M1.y = 0.75 * gameIntro.stageHeightToUse;
MC_M1.height = 0.2 * gameIntro.stageHeightToUse;
MC_M1.width = MC_M1.height / 1.4;
gameIntro.STAGE.stage.addChildAt(MC_M1,1);
function onTouchBegin(event:TouchEvent)
{
trace("TouchBegin");
if (touchMoveID != 0)
{
trace("It Did Not");
return;
}
touchMoveID = event.touchPointID;
gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}
function onTouchMove(event:TouchEvent)
{
if (event.touchPointID != touchMoveID)
{
return;
}
//trace("Moving")
MC_M1.x = event.stageX;
MC_M1.y = event.stageY;
}
function onTouchEnd(event:TouchEvent)
{
if (event.touchPointID != touchMoveID)
{
return;
}
//trace("Ending");
touchMoveID = 0;
gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}
当玩家实际上失去游戏时,我实际做的是以下几点:
MC_M1.removeEventListener(Event.ENTER_FRAME , ifHitAct);
MC_M1.removeEventListener(TouchEvent.TOUCH_BEGIN , onTouchBegin);
gameIntro.STAGE.stage.removeChild(MC_M1);
MC_M1.alpha = 0;
isDead = 1;
replayButToUse.x = 0.127 * gameIntro.stageWidthToUse;
replayButToUse.y = 0.91 * gameIntro.stageHeightToUse;
replayButToUse.addEventListener(MouseEvent.CLICK, gotoIntro);
这一切都发生在一个名为:introClassToUse的类中
因此,当用户失去时,他将获得一个重播按钮,当他点击它时,他将返回同一个班级并使用以下代码重新加载所有内容:
function gotoIntro(event:MouseEvent):void
{
replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
replayButToUse.alpha = 0;
replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
stop();
var reload:introClassToUse = new introClassToUse();
}
所以一切都重新开始,游戏重新启动。我的问题是,当我倾向于重播游戏超过2-3次时,我面临一种非常奇怪的行为。 MC_M1只是停止收听任何触摸事件,但继续收听ENTER_FRAME事件,我继续触摸MC_M1,但它似乎没有响应它。我甚至从我的iPhone远程调试它,对于前几次重放,我可以看到trace("TouchBegin");
的结果,它向我展示了TouchBegin,但经过几次重播后,触摸事件就冻结了。我错过了什么?
我非常感谢任何帮助,我是AS3的新手,我需要学习,以便我可以管理更多
修改1:
我在任何帧上都没有代码,我只有很多AS类。
fla文件链接到名为gameIntro的AS类。在本课程中,我将以下内容联系起来:
- STAGE是Stage类型的对象
- gameIntro.STAGE = stage
稍后,当用户单击播放按钮时,我会调用类introClassToUse。这个类具有所有游戏功能。上面的所有代码都在introClassToUse中。当用户松开并点击重播按钮时,他将转到“goToIntro”功能,即我记得introClassToUse。
一切正常,其他几个定时器都已实现,唯一的问题是经过多次重放后,MC_M1只是冻结了
每次用户丢失时我都会删除MC_M1并在我回调introClassToUse时重新添加它们,因为我试图使用.visible属性,它根本不起作用(这就是我使用gameIntro.STAGE的原因) .stage.removeChild(MC_M1)
答案 0 :(得分:1)
我知道这个问题很老但也许有人仍在想这里发生了什么(像我一样)。 您的代码中存在很多问题,但问题的根源在于:
function gotoIntro(event:MouseEvent):void{
//...
var reload:introClassToUse = new introClassToUse();
}
introClassToUse
课程中。这基本上意味着你在旧的游戏中创建了一个新的游戏实例,这似乎完全没错。您应该考虑在类定义中仅使用实例属性,并在外部类中创建new introClassToUse()
;
您没有提供有关代码的许多重要细节,例如
整个班级结构的样子 - 例如,你不能将MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);
这样的行放在你班级的范围内,所以很明显你在某些功能中有这个,我们不会这样做。知道何时以及何时被呼叫。
声明和分配变量的位置和方式。很难判断您的MC_M1
是实例或类的属性,是内部/公共/私有/ ......
您是否将图书馆符号链接到您的班级或从stage
获取。
可能有很多东西可以给你这样的结果。根据你所写的内容,我已经复制了与你所描述的相似的行为,但是使用了鼠标事件和假的松散状态。每当你将mc部分放在鼠尾草的右边缘之外时,这将结束游戏,显示重启按钮并在你点击它时再次启动(基本上它主要是你的代码)。它工作正常大约10秒,而且突然你不能移动mc了。帧事件仍在追踪,但触摸/鼠标不是。
怎么可能?我怀疑你只能删除某个地方的听众,并且隐藏的mc卡在新的地方。这很容易被忽视,特别是如果你使用静态属性。我们再一次不知道你的影片剪辑来自哪里,所以我们只能猜测你的代码发生了什么,但我试图简单地说这就是我做的方式。问题可能存在于一些完全不同的地方,但您可以猜测所有情况。
项目的文档类 - GameIntro.as
package
{
import flash.display.Sprite;
public class GameIntro extends Sprite
{
//Document class. this need to be compiled with strict mode off.
public function GameIntro() {
GameIntro.STAGE = stage;
GameIntro.stageWidthToUse = stage.stageWidth;
GameIntro.stageHeightToUse = stage.stageHeight;
var intro:IntroClassToUse = new IntroClassToUse();
stage.addChild(intro);
}
}
}
<强> IntroClassToUse.as 强>
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* You need to have library symbol linked to this class in .fla with two mcs -
* mcFromLibrarySymbol (dragable) and repButton (reapatButton)
*/
public class IntroClassToUse extends MovieClip
{
var t = 0; //timer ticks
var fc:uint = 0; //frames counter
var isDead = 0;
var mc;
static var repButton;
var logicContex:Timer = new Timer(30);
public function IntroClassToUse() {
trace("toUse", GameIntro.stageWidthToUse);
mc = mcFromLibrarySymbol;
if(!repButton) repButton = repButtonX;
logicContex.addEventListener(TimerEvent.TIMER, logicInterval);
logicContex.start();
init();
}
internal function init() {
trace("init");
mc.alpha = 1;
mc.addEventListener(Event.ENTER_FRAME, onFrame);
mc.addEventListener(MouseEvent.MOUSE_DOWN, onMDown);
mc.x = 0.516 * GameIntro.stageWidthToUse;
mc.y = 0.75 * GameIntro.stageHeightToUse;
mc.height = 0.2 * GameIntro.stageHeightToUse;
mc.width = mc.height / 1.4;
GameIntro.STAGE.stage.addChildAt(mc, 1);
}
internal function onLoose() {
trace("onLoose");
mc.removeEventListener(Event.ENTER_FRAME , onFrame);
mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
GameIntro.STAGE.stage.removeChild(mc);
mc.alpha = 0;
isDead = 1;
repButton.x = 0.127 * GameIntro.stageWidthToUse;
repButton.y = 0.91 * GameIntro.stageHeightToUse;
repButton.addEventListener(MouseEvent.CLICK, onReplay);
repButton.alpha = 1;
}
internal function onReplay(e:MouseEvent):void {
trace("onReplay");
repButton.removeEventListener(MouseEvent.CLICK, onReplay);
repButton.alpha = 0;
stop();
new IntroClassToUse();
}
internal function onMDown(e:MouseEvent):void {
trace("mouseDow");
GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMMove);
GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_UP, onMUp);
}
internal function onMMove(e:MouseEvent):void {
mc.x = e.stageX;
mc.y = e.stageY;
}
//you loose the game if you release you mc with part of it over rigth stage edge.
internal function onMUp(e:MouseEvent):void {
trace("mouseUp");
GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMMove);
GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_UP, onMUp);
trace("Stage:", GameIntro.STAGE.numChildren);
if (mc.x + mc.width > GameIntro.STAGE.stageWidth) onLoose();
}
internal function onFrame(e:Event):void {
trace("frames", fc++);
}
internal function logicInterval(e:TimerEvent):void {
if (t++ < 300 || !isDead) return;
init();
mc.alpha = 0;
mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
isDead = 0;
}
}
}