通过触摸平滑移动具有 3000 个元素的组(Corona sdk)
Posted
技术标签:
【中文标题】通过触摸平滑移动具有 3000 个元素的组(Corona sdk)【英文标题】:Smooth movement of a group with 3000 elements by touch (Corona sdk) 【发布时间】:2018-03-28 08:29:32 【问题描述】:如何通过触摸大量元素(例如 3000)获得平滑移动组。
在我的普通机器人上,动作发生在轻微的抽搐中。
如果元素减少到 10 则移动平滑。
拼图需要这么多的物品。 用户将能够单击并更改任何元素。因此,任何元素都可以有不同的外观。 使用缩放,用户可以同时看到所有内容。 下面是一个生成 3600 个元素并处理组移动事件的代码示例。
示例代码:
main.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
【问题讨论】:
【参考方案1】:我找到了使用纹理输出解决此问题的方法。
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:
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
【讨论】:
以上是关于通过触摸平滑移动具有 3000 个元素的组(Corona sdk)的主要内容,如果未能解决你的问题,请参考以下文章
Tomcat apache 8 服务器(端口 - 8080)上的 Pentaho API 在通过不同的 Web 应用程序调用时会出现 COR 问题(反应 JS,端口 - 3000)
iOS Game Center 将排行榜和成就移动到 2 个游戏的组中