Corona 中的 iPad 式慣性滾動 (iPad-style inertial scrolling in Corona)


問題描述

Corona 中的 iPad 式慣性滾動 (iPad-style inertial scrolling in Corona)

I'm trying to imitate an iPad-style inertia scroll in Corona, using the touch event and the enterFrame event. In short, I should be able to drag and "throw" an object to a certain extent, similar to scrolling on the iPad. I'm fairly new to Corona, but I've used other languages before. (This is my second day.)

This is the code I've got so far:

local bg = display.newImage("cloud.jpg");
bg:setReferencePoint(bg.TopLeftReferencePoint);
bg.x = 0;
bg.y = 0;

function bg:touch (event)
    print("event", event)
    for i,v in pairs(event) do
        print("**: ",i,v)
    end

    bg.x = event.x;
    bg.y = event.y;

    bg.xStart = event.xStart;
    bg.yStart = event.yStart;

    if (event.phase == "ended")
    then
        bg.xdelta = bg.xStart + bg.x;
        bg.ydelta = bg.yStart + bg.y;
        Runtime.addEventListener("enterFrame", bg);
    end 
end

function bg:enterFrame(event)
    bg.x = bg.x + bg.xdelta;
    bg.y = bg.y + bg.ydelta;
    // TODO: Add code to decrease delta so that object gradually stops.
end

bg:addEventListener("touch");

This is throwing an error in the compiler. What am I doing wrong? I tried making the enterFrame function a local function instead of a table function, but I ran into the same issue. I'm sure that the answer is VERY simple, but I'm not familiar enough with Corona to see it immediately.

Edit: I've done some reading and I've realized that this is closer to what I want:

local bg = display.newImage("cloud.jpg");
bg:setReferencePoint(bg.TopLeftReferencePoint);
bg.x = 0;
bg.y = 0;
bg.xdelta = 0;
bg.ydelta = 0;

local function onEveryFrame(event)
    bg.x = bg.x + (bg.oldx - bg.x);
    bg.y = bg.y + (bg.oldy - bg.y);
end

function bg:touch (event)
    if (event.phase == "ended")
    then
        print("ended")
        bg.oldx = bg.x;
        bg.oldy = bg.y;

        bg.x = event.x;
        bg.y = event.y;
        Runtime.addEventListener("enterFrame", onEveryFrame)
    end 

    print("event", event)
    for i,v in pairs(event) do
        print("**: ",i,v)
    end

    bg.oldx = bg.x;
    bg.oldy = bg.y;

    bg.x = event.x;
    bg.y = event.y;

    print("bg.x:", bg.x)
    print("bg.oldx:", bg.oldx)
    print("bg.y:", bg.y)
    print("bg.oldy:", bg.oldy)
end

bg:addEventListener("touch");

This is no longer erroring out, but I'm not getting the desired result either...


參考解法

方法 1:

I have not attempted to solve this problem in Corona, but encountered it a lot in Director when implementing smooth scrolling. 

While dragging, capture a velocity that measures speed over several touch events, comparing position differences to timestamp differences. Use a table or a linked list for the individual measuring points, and average the velocity over the stored values.

Then the "ended" event in the same position as the last "moved" event will only slightly decrease speed, preserving inertia. In absence of dragging events, subtract a value from the velocity for friction.

方法 2:

Actually, you have a syntax error.

It is Runtime:AddEventListener (pay attention to the : instead of .)

EDIT:

Now about your math:

Your logic do: during a moved event, it sets the bg.p (p for position, both x and y) to event.p

During the ended event you set bg.olp to bg.p and then bg.p to event.p and then you try to every frame do bg.p+=(bg.oldp-bg.p)

This maybe would work IF you did the olp logic on "moved" because the result is this:

Users move finger: moved event triggers, and bg.p changed (thus you see it moving). Users attempt to remove finger: This trigger a "ended" event, that has a very high change that it will trigger in the same place as the last "moved" event (you would need to move the finger VERY, VERY, VERY fast to trigger a "ended" far from the last "moved"). This will make your bg.oldp be the same as bg.p and thus you do bg.p+=(bg.olp-bg.p) the result is bg.p+=0

(by jedd.ahyoungKnutopiaspeeder)

參考文件

  1. iPad-style inertial scrolling in Corona (CC BY-SA 3.0/4.0)

#lua #coronasdk






相關問題

使用 MSXML2.ServerXMLHTTP 從網頁訪問數據會在 Lua 中返回截斷的數據 (Using MSXML2.ServerXMLHTTP to access data from a web page returns truncated data in Lua)

如何在 VS 2008 中包含 Lua 庫 (How can I include Lua library in VS 2008)

Corona 中的 iPad 式慣性滾動 (iPad-style inertial scrolling in Corona)

Lua cư xử kỳ lạ trên nền tảng PowerPC / LynxOS, tại sao? (Lua behaves weird on PowerPC/LynxOS platform, why?)

我們如何在函數輸入參數中輸入類型值作為對象? (How do we input type value as object in function input parameter?)

反編譯 Lua 字節碼的最佳工具? (Best tool(s) for decompiling Lua bytecode?)

本機 Lua 中的高效可變字節數組 (Efficient mutable byte array in native Lua)

在 Lua 中字符串化對象名稱 (Stringify object name in Lua)

純 Lua 中的全功能正則表達式庫 (Fully-featured regex library in pure Lua)

自我作為參數,並設置範圍? (self as param, and setting scope?)

已經放 } 但錯誤仍然說 } 是預期的? (Already put } but the error still says that } is expected?)

我想使用 HPC 的 gpu 並嘗試 module add CUDA ...但出現錯誤。錯誤是“Lmod 檢測到以下錯誤: (I want to use the gpu of the HPC and try module add CUDA... But errors occurs. The error is "Lmod has detected the following error:)







留言討論