在ActionScript3中,addChild / removeChild和显示列表顺序有问题(Trouble with addChild/removeChild and display list order in ActionScript3)
我正在研究一个项目,其中包括一个玩家可以投掷石头的湖牌,这反过来会导致章鱼从每个石头击中湖泊的位置上升到湖中。
在石头击中之后和章鱼出现之前,还会有一个石头飞溅的符号。
屏幕上可能会同时出现很多章节,需要在显示列表中对它们进行排序,以便那些应该显得更加突出的章节落后于其他章节。
这些符号的每个实例应该只播放一次然后删除。
我的代码使用了不同的添加/删除子方法以及循环,条件和数组,我在各种教程和论坛的帮助下将它们放在一起。
我遇到的问题是,当您快速连续两次或多次点击湖面时,石头和飞溅符号不能正确移除并经常保持循环。
这是我正在使用的代码。 有任何想法吗?
var stone:Stone; var stoneSplash:StoneSplash; var octopus1:Octopus1; var octopus2:Octopus2; var whichOctopus:Array = [addOctopus1, addOctopus2]; var octopusScale:Number; var octopusContainer:MovieClip = new MovieClip; lake.lakeHitArea.addEventListener(MouseEvent.CLICK, onClickLake); //Add octopusContainer to the stage's display list just above the Lake addChildAt(octopusContainer,getChildIndex(lake) + 1); octopusContainer.x = 0; octopusContainer.y = 0; function onClickLake(e:MouseEvent):void { trace("CLICK"); throwStone(mouseX, mouseY); } function throwStone(stonePositionX:int, stonePositionY:int) { stone = new Stone(); stone.x = stonePositionX; stone.y = stonePositionY; addChild(stone); addEventListener(Event.ENTER_FRAME, removeStone); } function removeStone(e:Event):void { var count:int = numChildren; var children:Array = [count]; //load all the children of the component into an Array for (var i:int=0; i<count/* -1*/; i++) { children[i] = getChildAt(i/* + 1*/); } for (i=0; i<count/* - 1*/; i++) { if (children[i] is Stone) { if (children[i].currentFrameLabel == "Splash") { stoneSplash = new StoneSplash(); octopusContainer.addChild(stoneSplash); stoneSplash.x = children[i].x; stoneSplash.y = children[i].y; } if (children[i].currentFrameLabel == "end") { octopusContainer.removeChild(stoneSplash); var positionX:int = children[i].x; var positionY:int = children[i].y; addOctopus(positionX, positionY); removeChild(children[i]); } } } } function addOctopus(positionX, positionY) { var o:int = Math.round(randomNumber(0,1)); whichOctopus[o](positionX, positionY); reorderDisplayList(); addEventListener(Event.ENTER_FRAME, removeOctopus); } function addOctopus1(positionX: int, positionY:int):void { // if (whichOctopus1 == true) // { // var octopus:* = octopus1_1; // } // else // { // octopus = octopus1_2; // } octopus1 = new Octopus1(); var octopus:DisplayObject = octopus1; octopusContainer.addChild(octopus); octopus.x = positionX; octopus.y = positionY; octopusScale = randomNumber(0.5,0.85); octopus.scaleX = octopusScale; octopus.scaleY = octopusScale; trace("children = " + octopusContainer.numChildren); testPosition(octopus); } function addOctopus2(positionX: int, positionY:int):void { // if (whichOctopus2 == true) // { // var octopus:* = octopus2_1; // } // else // { // octopus = octopus2_2; // } octopus2 = new Octopus2(); var octopus:DisplayObject = octopus2; octopusContainer.addChild(octopus); octopus.x = positionX; octopus.y = positionY; octopusScale = randomNumber(0.25,0.5); octopus.scaleX = octopusScale; octopus.scaleY = octopusScale; trace("children = " + octopusContainer.numChildren); testPosition(octopus); } function testPosition(octopus:Object):void { trace(octopus) for (var i:int = 0; i < 200; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox1.x * octopus.scaleX,octopus.y + octopus.hitTestBox1.y * octopus.scaleY,true)) { break; } else { octopus.x++; } } for (i = 0; i < 100; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox2.x * octopus.scaleX,octopus.y + octopus.hitTestBox2.y * octopus.scaleY,true)) { break; } else { octopus.y--; } } for (i = 0; i < 200; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox3.x * octopus.scaleX,octopus.y + octopus.hitTestBox3.y * octopus.scaleY,true)) { break; } else { trace(i); octopus.x--; } } for (i = 0; i < 100; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox1.x * octopus.scaleX,octopus.y + octopus.hitTestBox1.y * octopus.scaleY,true)) { break; } else { octopus.y--; trace(i); } } } function randomNumber(min:Number, max:Number):Number { return Math.random() * (max - min) + min; } function reorderDisplayList():void { //the number of children in our component var count:int = octopusContainer.numChildren; var children:Array = [count]; //load all the children of the component into an Array for (var i:int=0; i<count; i++) { children[i] = octopusContainer.getChildAt(i); } //sort the Array children based on their 'y' property children.sortOn("y", Array.NUMERIC); //re-add the children to the component ; //in the order of the sorted Array we just created. //When we add the children using 'addChild' it will //be added at the top of the component's displaylist //and will automatically be removed from its original position. for (i=0; i<count/* - 1*/; i++) { if (children[i] is Octopus1 || children[i] is Octopus2) { // trace("child = " + children[i] + " at i: " + i); octopusContainer.removeChild(children[i]); octopusContainer.addChild(children[i]); } } } function removeOctopus(e:Event):void { var count:int = octopusContainer.numChildren; var children:Array = [count]; //load all the children of the component into an Array for (var i:int=0; i<count/* -1*/; i++) { children[i] = octopusContainer.getChildAt(i/* + 1*/); } for (i=0; i<count/* - 1*/; i++) { if (children[i] is Octopus1 || children[i] is Octopus2) { trace(i); trace("Is an octopus"); if (children[i].currentFrame >= 202) { octopusContainer.removeChild(children[i]); } } } }
我非常感谢任何帮助我克服这个障碍并继续我的项目的建议。
先谢谢你。
克里斯柯林斯。
I am working on a project, which includes a Lake symbol that the player can throw stones into, which in turn causes octopi to rise out of the lake in the positions that each stone hits the lake.
There is also a symbol for the splash made by the stone which will appear after the stone hits and before the octopus appears.
It is likely that there will be many octopi on the screen at the same time and they need to be ordered in the display list so that the ones that should appear further back are behind the others.
Each instance of these symbols should only play once and then be removed.
My code for this makes use of the different add/remove child method alongside for loops, conditionals and arrays which I have put together with the help of various tutorials and forums.
The problem I have is that when you click on the lake two or more times in quick succession, the stone and the splash symbols aren't removed properly and often keep looping.
Here is the code I am using. Any ideas?
var stone:Stone; var stoneSplash:StoneSplash; var octopus1:Octopus1; var octopus2:Octopus2; var whichOctopus:Array = [addOctopus1, addOctopus2]; var octopusScale:Number; var octopusContainer:MovieClip = new MovieClip; lake.lakeHitArea.addEventListener(MouseEvent.CLICK, onClickLake); //Add octopusContainer to the stage's display list just above the Lake addChildAt(octopusContainer,getChildIndex(lake) + 1); octopusContainer.x = 0; octopusContainer.y = 0; function onClickLake(e:MouseEvent):void { trace("CLICK"); throwStone(mouseX, mouseY); } function throwStone(stonePositionX:int, stonePositionY:int) { stone = new Stone(); stone.x = stonePositionX; stone.y = stonePositionY; addChild(stone); addEventListener(Event.ENTER_FRAME, removeStone); } function removeStone(e:Event):void { var count:int = numChildren; var children:Array = [count]; //load all the children of the component into an Array for (var i:int=0; i<count/* -1*/; i++) { children[i] = getChildAt(i/* + 1*/); } for (i=0; i<count/* - 1*/; i++) { if (children[i] is Stone) { if (children[i].currentFrameLabel == "Splash") { stoneSplash = new StoneSplash(); octopusContainer.addChild(stoneSplash); stoneSplash.x = children[i].x; stoneSplash.y = children[i].y; } if (children[i].currentFrameLabel == "end") { octopusContainer.removeChild(stoneSplash); var positionX:int = children[i].x; var positionY:int = children[i].y; addOctopus(positionX, positionY); removeChild(children[i]); } } } } function addOctopus(positionX, positionY) { var o:int = Math.round(randomNumber(0,1)); whichOctopus[o](positionX, positionY); reorderDisplayList(); addEventListener(Event.ENTER_FRAME, removeOctopus); } function addOctopus1(positionX: int, positionY:int):void { // if (whichOctopus1 == true) // { // var octopus:* = octopus1_1; // } // else // { // octopus = octopus1_2; // } octopus1 = new Octopus1(); var octopus:DisplayObject = octopus1; octopusContainer.addChild(octopus); octopus.x = positionX; octopus.y = positionY; octopusScale = randomNumber(0.5,0.85); octopus.scaleX = octopusScale; octopus.scaleY = octopusScale; trace("children = " + octopusContainer.numChildren); testPosition(octopus); } function addOctopus2(positionX: int, positionY:int):void { // if (whichOctopus2 == true) // { // var octopus:* = octopus2_1; // } // else // { // octopus = octopus2_2; // } octopus2 = new Octopus2(); var octopus:DisplayObject = octopus2; octopusContainer.addChild(octopus); octopus.x = positionX; octopus.y = positionY; octopusScale = randomNumber(0.25,0.5); octopus.scaleX = octopusScale; octopus.scaleY = octopusScale; trace("children = " + octopusContainer.numChildren); testPosition(octopus); } function testPosition(octopus:Object):void { trace(octopus) for (var i:int = 0; i < 200; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox1.x * octopus.scaleX,octopus.y + octopus.hitTestBox1.y * octopus.scaleY,true)) { break; } else { octopus.x++; } } for (i = 0; i < 100; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox2.x * octopus.scaleX,octopus.y + octopus.hitTestBox2.y * octopus.scaleY,true)) { break; } else { octopus.y--; } } for (i = 0; i < 200; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox3.x * octopus.scaleX,octopus.y + octopus.hitTestBox3.y * octopus.scaleY,true)) { break; } else { trace(i); octopus.x--; } } for (i = 0; i < 100; i++) { if (lake.hitTestPoint(octopus.x + octopus.hitTestBox1.x * octopus.scaleX,octopus.y + octopus.hitTestBox1.y * octopus.scaleY,true)) { break; } else { octopus.y--; trace(i); } } } function randomNumber(min:Number, max:Number):Number { return Math.random() * (max - min) + min; } function reorderDisplayList():void { //the number of children in our component var count:int = octopusContainer.numChildren; var children:Array = [count]; //load all the children of the component into an Array for (var i:int=0; i<count; i++) { children[i] = octopusContainer.getChildAt(i); } //sort the Array children based on their 'y' property children.sortOn("y", Array.NUMERIC); //re-add the children to the component ; //in the order of the sorted Array we just created. //When we add the children using 'addChild' it will //be added at the top of the component's displaylist //and will automatically be removed from its original position. for (i=0; i<count/* - 1*/; i++) { if (children[i] is Octopus1 || children[i] is Octopus2) { // trace("child = " + children[i] + " at i: " + i); octopusContainer.removeChild(children[i]); octopusContainer.addChild(children[i]); } } } function removeOctopus(e:Event):void { var count:int = octopusContainer.numChildren; var children:Array = [count]; //load all the children of the component into an Array for (var i:int=0; i<count/* -1*/; i++) { children[i] = octopusContainer.getChildAt(i/* + 1*/); } for (i=0; i<count/* - 1*/; i++) { if (children[i] is Octopus1 || children[i] is Octopus2) { trace(i); trace("Is an octopus"); if (children[i].currentFrame >= 202) { octopusContainer.removeChild(children[i]); } } } }
I would greatly appreciate any advice to help me overcome this hurdle and continue with my project.
Thank you in advance.
Chris Collins.
原文:https://stackoverflow.com/questions/24940157
最满意答案
Hrm,似乎我可以使用masked数组来做到这一点:
masked_array = np.ma.array (a, mask=np.isnan(a)) cmap = matplotlib.cm.jet cmap.set_bad('white',1.) ax.imshow(masked_array, interpolation='nearest', cmap=cmap)
这应该足够了,虽然我仍然乐意提出建议。 :]
Hrm, it appears I can use a masked array to do this:
masked_array = np.ma.array (a, mask=np.isnan(a)) cmap = matplotlib.cm.jet cmap.set_bad('white',1.) ax.imshow(masked_array, interpolation='nearest', cmap=cmap)
This should suffice, though I'm still open to suggestions. :]
相关问答
更多-
我已经编写了一些示例代码,可以帮助您解决问题。 代码首先使用numpy.random生成一些随机数据。 然后计算你的x极限和y极限,其中x极限将基于你的问题给出的两个unix时间戳,而y极限只是通用数字。 代码然后绘制随机数据并使用pyplot方法将x轴格式转换为很好表示的字符串(而不是unix时间戳或数组数)。 该代码很好评论,并应解释你需要的一切,如果不是,请评论并要求澄清。 import numpy as np import matplotlib.pyplot as plt import matpl ...
-
如何在matplotlib中关闭imshow()的模糊效果?(How to 'turn off' blurry effect of imshow() in matplotlib?)[2023-05-05]
默认情况下(更改为mpl 2.0), imshow内插数据(如您想要为图像所做的那样)。 所有你需要做的是告诉它不插值: im = plt.imshow(..., interpolation='none') 'nearest'也会为你想要的工作。 请参阅matlab中的imagesc \ imshow像素之间的平滑,像matplotlib imshow一样,用于所有种类的插值。 DOC By default (which is changed mpl 2.0), imshow interpolates t ... -
如何使用matplotlib中的imshow绘制NaN值作为特殊颜色?(How can I plot NaN values as a special color with imshow in matplotlib?)[2023-09-19]
Hrm,似乎我可以使用masked数组来做到这一点: masked_array = np.ma.array (a, mask=np.isnan(a)) cmap = matplotlib.cm.jet cmap.set_bad('white',1.) ax.imshow(masked_array, interpolation='nearest', cmap=cmap) 这应该足够了,虽然我仍然乐意提出建议。 :] Hrm, it appears I can use a masked array to do ... -
你不能用z掩盖z在z中创建一个普通的colourmap吗? dd = d[:, :3] dd[:,2] = dd[:,2] * d[:,3] 然后转换为这样的图像: M = dd.max(0) m = dd.min(0) x = np.arange(m[0], M[0] + 1) y = np.arange(m[1], M[1] + 1) [X, Y] = np.meshgrid(x, y) Z = np.zeros_like(X) for num in range(0,size(dd, 0)): ...
-
我没有看到一种方法来干净地矢量化这个。 如果你真的只有一些点,那就写一个循环去做 def brute_force_clean_nans(x, y): x_clean, y_clean = [], [] cnt = 0 for _x, _y in zip(x, y): if np.isnan(_y): cnt += 1 if cnt == 5: # on the 5th nan, put ...
-
有几种方法可以做到这一点,这取决于您是否需要标记大区域或分散的单个像素。 如果您需要标记较大的区域,可以通过在图像上添加矩形来实现: import matplotlib as mpl import matplotlib.pyplot as plt ax = plt.gca() ax.imshow(rand(50,50)) ax.add_patch(mpl.patches.Rectangle((2,2),20,20,hatch='//////////',fill=False,snap=False)) plt ...
-
Matlab imshow省略了NaN(Matlab imshow omit NaN)[2023-06-03]
您可以将图像对象的AlphaData设置为等于~isnan(data) ,以便NaN将显示为透明值。 R = rand(10); R(R < 0.25) = NaN; him = imshow(R, 'InitialMagnification', 10000); colormap parula set(him, 'AlphaData', ~isnan(R)) 如果需要特定颜色,可以打开轴并将轴的颜色设置为您希望NaN值的颜色。 axis on; % Make a red axis set(gca, ' ... -
IIUC,这个代码可以为你工作。 我将X轴间隔设置为30秒(而不是3,这是您要求的),因为3秒的间隔会导致x轴的拥挤。 无论如何,它应该让你知道如何前进。 在代码中创建NaN值的NaN的基本思想是在数据中创建一个新列,以便将每个连续(非NaN )块组合在一起,然后绘制每个组。 import matplotlib.pyplot as plt import matplotlib.dates as md # Make sure `datatime` is in datetime format df['datat ...
-
您只需将刻度标签更改为更适合您数据的标签即可。 例如,这里我们将每个第5个像素设置为指数函数: import numpy as np import matplotlib.pyplot as plt im = np.random.rand(21,21) fig,(ax1,ax2) = plt.subplots(1,2) ax1.imshow(im) ax2.imshow(im) # Where we want the ticks, in pixel locations ticks = np.linsp ...
-
尝试: cax = ax.imshow(matrix, interpolation='nearest', cmap=cm.coolwarm, vmin=0, vmax=100) Try: cax = ax.imshow(matrix, interpolation='nearest', cmap=cm.coolwarm, vmin=0, vmax=100)