【问题标题】:Loop an image in Flash在 Flash 中循环图像
【发布时间】:2013-03-28 14:22:06
【问题描述】:

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

【问题讨论】:

    标签: actionscript-3 flash-cs5


    【解决方案1】:

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

    这是一个基本的 sn-p 来说明使用 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
    }
    

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

    【讨论】:

    • “拼接”正是我想要的。我要试试这个!
    【解决方案2】:

    请注意,Flash cannot load an image greater than 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;
        }
    }
    

    【讨论】:

    • 这也是我想到的第一件事!我想知道 ActionScript 是否有更好的想法。这是最简单的解决方案!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多