简体   繁体   English

通过触摸可平滑地移动具有3000个元素的组(Corona SDK)

[英]Smooth movement of a group with 3000 elements by touch (Corona sdk)

How to get a smooth moving group with by touch with a large number of elements for example 3000. 如何通过触摸大量元素(例如3000)来获得平滑的移动组。

On my average android, the movement takes place in small jerks. 在我平均的android上,运动发生在小抽搐中。

If the elements are reduced to 10 then move be smooth. 如果元素减少到10,则移动平滑。

Such a large number of items are needed for the puzzle. 拼图需要如此大量的物品。 The user will be able to click and change any an element. 用户将能够单击并更改任何元素。 Therefore, any element can have a different appearance. 因此,任何元素都可以具有不同的外观。 Using zoom, the user can see everything at the same time. 使用缩放,用户可以同时看到所有内容。 Below is an example of a code with the generation of 3600 elements and processing the event on the movements of group. 下面是一个代码示例,该代码生成3600个元素并根据组的移动处理事件。

Sample code: 样例代码:

main.lua 主lua

local composer = require( "composer" )

composer.gotoScene( "demo" )

demo.lua 演示

local composer = require( "composer" )
local scene = composer.newScene()


local COUNT_ROWS = 60
local COUNT_CELLS = 60
local MARGIN_RECT = 3
local RECT_SIZE = 30

local viewGroup 
local rectsPreferenses = {}

local cretateRectsGroup
, initRectsPrefs
, onTouch
, scalePropByWidthHeight


function scene:create(event)
    self.sceneGroup = self.view
    local bg = display.newRect(display.screenOriginX, display.screenOriginY, display.actualContentWidth, display.actualContentHeight)
    bg.anchorX = 0
    bg.anchorY = 0
    bg:setFillColor(1,1,0)
    self.sceneGroup:insert(bg)
end

function scene:destroy( event )

end

function scene:show( event )
    if event.phase == "will" then
        viewGroup = cretateRectsGroup(self.sceneGroup)

        local maxWidth = display.actualContentWidth
        local maxHeight = display.actualContentWidth
        local initScale = scalePropByWidthHeight(viewGroup, {height = maxHeight, width = maxWidth})

        viewGroup.xScale = initScale
        viewGroup.yScale = initScale

    elseif event.phase == "did" then

    end

end

function scene:hide( event )

end

function cretateRectsGroup(sceneGroup)
    local group = display.newGroup()
    group.x = display.actualContentWidth/2 + display.screenOriginX
    group.y = display.actualContentHeight/2 + display.screenOriginY
    group.anchorChildren = true

    local bgW = COUNT_ROWS*RECT_SIZE + COUNT_ROWS*MARGIN_RECT
    local bgH = COUNT_CELLS*RECT_SIZE + COUNT_CELLS*MARGIN_RECT
    local bg = display.newRect(0, 0, bgW, bgH)
    bg.anchorX = 0
    bg.anchorY = 0
    bg:setFillColor(0,1,0)
    bg:addEventListener("touch", onTouch)
    group:insert(bg)

    initRectsPrefs(0,0)
    for i=1, #rectsPreferenses do

        local rectPref = rectsPreferenses[i]
        local rect = display.newRect(0, 0, rectPref.width, rectPref.height)
        rect.anchorX = 0
        rect.anchorY = 0
        rect.x = rectPref.x
        rect.y = rectPref.y
        rect:setFillColor(rectPref.fillColor[1], rectPref.fillColor[2], rectPref.fillColor[3])
        group:insert(rect)
    end

    sceneGroup:insert(group)
    return group
end

function initRectsPrefs(x, y)
    local index = 0
    local curX = x
    local curY = y

    math.randomseed(os.time())
    local rand = math.random
    for i=1, COUNT_ROWS do
        curX = x
        for j=1, COUNT_CELLS do
            index = index + 1
            local r = rand()
            local g = rand()
            local b = rand()
            local optRect = {
                  id = index
                , x = curX
                , y = curY
                , width = RECT_SIZE
                , height = RECT_SIZE
                , fillColor = {r, g, b}
            }
            rectsPreferenses[index] = optRect
            curX = curX + RECT_SIZE + MARGIN_RECT
        end
            curY = curY + RECT_SIZE + MARGIN_RECT
    end
end

function onTouch(event)
    local group = event.target.parent
    local newTouchX, newTouchY = event.x, event.y

    if (event.phase == "began") or (group.lastTouchPosX == nil) or (group.lastTouchPosY == nil) then
        group.lastTouchPosX = newTouchX
        group.lastTouchPosY = newTouchY
        return
    end
    if (event.phase == "ended") or (event.phase == "cancelled") then
        group.lastTouchPosX = nil
        group.lastTouchPosY = nil
        return
    end

    local deltaX = (newTouchX - group.lastTouchPosX)
    local deltaY = (newTouchY - group.lastTouchPosY)
    group.x = group.x + deltaX
    group.y = group.y + deltaY

    group.lastTouchPosX = newTouchX
    group.lastTouchPosY = newTouchY
end

function scalePropByWidthHeight(target, targerTo)
    local scale = 1
    local scaleSize = target.width
    if target.height > target.width then
        scaleSize = target.height
    end

    if ( scaleSize/targerTo.width > scaleSize/targerTo.height ) then 
        scale = targerTo.width/scaleSize
    else
        scale = targerTo.height/scaleSize
    end

    return scale
end

scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )

return scene

I found a solution to this problem using the output to the texture. 我使用输出到纹理找到了解决此问题的方法。

texture = graphics.newTexture( {type="canvas", width=textureW, height=textureH} )
local imgTexture = display.newImageRect(group, texture.filename, texture.baseDir, textureW, textureH)
texture:draw(textureGroup)    
texture:invalidate( {source="cache", accumulate=false} )

demo.lua: demo.lua:

local composer = require( "composer" )
local scene = composer.newScene()


local COUNT_ROWS = 60
local COUNT_CELLS = 60
local MARGIN_RECT = 3
local RECT_SIZE = 30

local viewGroup 
local rectsPreferenses = {}

local cretateRectsGroup
, initRectsPrefs
, onTouch
, scalePropByWidthHeight


function scene:create(event)
    self.sceneGroup = self.view
    local bg = display.newRect(display.screenOriginX, display.screenOriginY, display.actualContentWidth, display.actualContentHeight)
    bg.anchorX = 0
    bg.anchorY = 0
    bg:setFillColor(1,1,0)
    self.sceneGroup:insert(bg)
end

function scene:destroy( event )
    if self.sceneGroup.texture then
        self.sceneGroup.texture:removeSelf()
    end
end

function scene:show( event )
    if event.phase == "will" then
        viewGroup = cretateRectsGroup(self.sceneGroup)

        local maxWidth = display.actualContentWidth
        local maxHeight = display.actualContentWidth
        local initScale = scalePropByWidthHeight(viewGroup, {height = maxHeight, width = maxWidth})

        viewGroup.xScale = initScale
        viewGroup.yScale = initScale

    elseif event.phase == "did" then

    end

end

function scene:hide( event )

end

function cretateRectsGroup(sceneGroup)
    local group = display.newGroup()
    group.x = display.actualContentWidth/2 + display.screenOriginX
    group.y = display.actualContentHeight/2 + display.screenOriginY
    group.anchorChildren = true

    local bgW = COUNT_ROWS*RECT_SIZE + COUNT_ROWS*MARGIN_RECT
    local bgH = COUNT_CELLS*RECT_SIZE + COUNT_CELLS*MARGIN_RECT
    local bg = display.newRect(0, 0, bgW, bgH)
    bg.anchorX = 0
    bg.anchorY = 0
    bg:setFillColor(0,1,0)
    bg:addEventListener("touch", onTouch)
    group:insert(bg)

    local textureGroup = display.newGroup()
    textureGroup.anchorX = 0
    textureGroup.anchorY = 0

    local bgTetxture = display.newRect(0, 0, bgW, bgH)
    bgTetxture.anchorX = 0
    bgTetxture.anchorY = 0
    bgTetxture:setFillColor(0,1,0)
    textureGroup:insert(bgTetxture)

    initRectsPrefs(0,0)
    for i=1, #rectsPreferenses do

        local rectPref = rectsPreferenses[i]
        local rect = display.newRect(0, 0, rectPref.width, rectPref.height)
        rect.anchorX = 0
        rect.anchorY = 0
        rect.x = rectPref.x
        rect.y = rectPref.y
        rect:setFillColor(rectPref.fillColor[1], rectPref.fillColor[2], rectPref.fillColor[3])
        textureGroup:insert(rect)
    end


    local textureW = bgW
    local textureH = bgH
    local texture = graphics.newTexture( {type="canvas", width=textureW, height=textureH} )
    sceneGroup.texture = texture
    local offsetZerroTextureX = -(textureW*0.5)
    local offsetZerroTextureY = -(textureH*0.5)

    local imgTexture = display.newImageRect(group, texture.filename, texture.baseDir, textureW, textureH)
    sceneGroup.imgTexture = imgTexture
    imgTexture.anchorX = 0
    imgTexture.anchorY = 0

    textureGroup.x = offsetZerroTextureX
    textureGroup.y = offsetZerroTextureY

    texture:draw(textureGroup)    
    texture:invalidate( {source="cache", accumulate=false} )
    return group
end

function initRectsPrefs(x, y)
    local index = 0
    local curX = x
    local curY = y

    math.randomseed(os.time())
    local rand = math.random
    for i=1, COUNT_ROWS do
        curX = x
        for j=1, COUNT_CELLS do
            index = index + 1
            local r = rand()
            local g = rand()
            local b = rand()
            local optRect = {
                  id = index
                , x = curX
                , y = curY
                , width = RECT_SIZE
                , height = RECT_SIZE
                , fillColor = {r, g, b}
            }
            rectsPreferenses[index] = optRect
            curX = curX + RECT_SIZE + MARGIN_RECT
        end
            curY = curY + RECT_SIZE + MARGIN_RECT
    end
end

function onTouch(event)
    local group = event.target.parent
    local newTouchX, newTouchY = event.x, event.y

    if (event.phase == "began") or (group.lastTouchPosX == nil) or (group.lastTouchPosY == nil) then
        group.lastTouchPosX = newTouchX
        group.lastTouchPosY = newTouchY
        return
    end
    if (event.phase == "ended") or (event.phase == "cancelled") then
        group.lastTouchPosX = nil
        group.lastTouchPosY = nil
        return
    end

    local deltaX = (newTouchX - group.lastTouchPosX)
    local deltaY = (newTouchY - group.lastTouchPosY)
    group.x = group.x + deltaX
    group.y = group.y + deltaY

    group.lastTouchPosX = newTouchX
    group.lastTouchPosY = newTouchY
end

function scalePropByWidthHeight(target, targerTo)
    local scale = 1
    local scaleSize = target.width
    if target.height > target.width then
        scaleSize = target.height
    end

    if ( scaleSize/targerTo.width > scaleSize/targerTo.height ) then 
        scale = targerTo.width/scaleSize
    else
        scale = targerTo.height/scaleSize
    end

    return scale
end

scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )

return scene

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM