1

我想要一个场景,其中 5000 像素高的图像在每次帧刷新时向上移动 5 像素。当图像全部向上时,我希望看到图像的顶部连接到图像的底部。这应该一直持续到关卡“完成”。我怎样才能“循环”这样的图像?

4

2 回答 2

1

请注意,Flash 无法加载大于 16,769,025像素(或 4095x4095)的图像。只要宽度不大于 3353,5000 像素的高度就可以使用。

也就是说,我会通过在舞台上保留两个图像副本来循环图像,使用父对象同时移动两者,并在遇到循环点后重置为原点。

考虑以下阶段设置:

Stage ¬
    0: MainTimeline:MovieClip ¬
        0: Container:MovieClip ¬
            0: img1:Bitmap
            1: img2:Bitmap

现在向上移动容器,您只需要检查循环的第二个图像是否到达了第一个图像的原点。

function onEnterFrame(e:Event):void {
    Container.y = Container.y - 5;

    if (Container.y < -5000) {
        Container.y = -5;
    }
}
于 2013-03-28T16:06:21.607 回答
1

您可以创建该图像的副本,将其隐藏/保持在上方,诀窍是更新位置并相应地循环,以便当一个图像低于屏幕时,它会回到顶部并重复。

下面是一个基本片段,用于说明使用 DisplayObject 类和 scrollRect 属性的想法:

//ignore this, you have your content already
var dummyContent:BitmapData = new BitmapData(100,100,false);
dummyContent.perlinNoise(10,10,8,12,true,true);

//important stuff starts here
var container:Sprite = addChild(new Sprite()) as Sprite;//make a container
container.scrollRect = new Rectangle(0,0,dummyContent.width,dummyContent.height);//set a scrollRect/'mask'
var part1:DisplayObject = container.addChild(new Bitmap(dummyContent));//add two copies
var part2:DisplayObject = container.addChild(new Bitmap(dummyContent));//of the same content
part2.y -= part2.height;//set the 2nd at the top of the 1st

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    //move both
    part1.y += 5;
    part2.y += 5;
    //check if any reach the bottom so they can be moved back up
    if(part1.y >= part1.height) part1.y = -part1.height;
    if(part2.y >= part2.height) part2.y = -part2.height;
    //the above can also be nicely placed in a loop if you plan on using more seamless looping clips/images
}

显然你会有不同的内容,但原理是一样的。

如果您正在处理图像,您可以简单地使用 BitmapData 的 copyPixels 方法:

var s:int = 5;//scroll speed
//make some content
var w:int = 100;
var h:int = 100;
var dummyContent:BitmapData = new BitmapData(w,h,false);
dummyContent.perlinNoise(10,10,8,12,true,true);

//prepare for stiching
var renderPos:Point = new Point();//position to render the current image to
var prenderPos:Point = new Point();//position to render the previous image (the 'hidden' copy above)
var render:BitmapData = new BitmapData(w,h,false);//create a bitmap data instance to render updated pixels int
addChild(new Bitmap(render));//and add it to the stage

addEventListener(Event.ENTER_FRAME,update);
function update(e:Event):void{
    renderPos.y = (renderPos.y+s)%h;//update the scroll position for the 1st part, % is used to loop back to 0 when the position gets to the content height
    prenderPos.y = renderPos.y - h;//update the scroll position for the 2nd part (above)
    render.lock();//freeze pixel updates
    render.copyPixels(dummyContent,dummyContent.rect,renderPos);//copy pixels from the scroll position to the bottom
    render.copyPixels(dummyContent,dummyContent.rect,prenderPos);//copy pixels from the top to the scroll position
    render.unlock();//unfreeze/update ALL THE PIXELS
}

您可以尝试使用更改高度(height-scrollPosition)的 Rectangle 对象,这样您每次可能访问更少的像素,或者您可以使用 BitmapData 的 getVector 方法手动计算单个 for 循环,但如果性能实际上是一个问题,则需要研究对于这样一个简单的任务,值得检查什么更快(复制完整位图矩形与复制部分位图矩形与使用矢量手动复制值)

于 2013-03-28T16:12:15.577 回答