Corona SDK提供的原始滾動視圖只支持垂直和水平滾動,但它不能在同一時間完成。如何使滾動視圖可以滾動到所有方向的加速度?
正如你所看到的那樣,視頻打擊就是這樣做的。但它不是免費的。那我該怎麼做呢? https://www.youtube.com/watch?feature=player_embedded&v=ecAcUxex46c#t=74
非常感謝。
Corona SDK提供的原始滾動視圖只支持垂直和水平滾動,但它不能在同一時間完成。如何使滾動視圖可以滾動到所有方向的加速度?
正如你所看到的那樣,視頻打擊就是這樣做的。但它不是免費的。那我該怎麼做呢? https://www.youtube.com/watch?feature=player_embedded&v=ecAcUxex46c#t=74
非常感謝。
這是一個例子,你可以使用圖片代替矩形我把:
local widget = require("widget")
local sceneGroup = display.newGroup();
-- Create scene
local ox, oy = math.abs(display.screenOriginX), math.abs(display.screenOriginY)
local tabBarHeight = 25
-- Adjust background color for some themes
local backgroundColor = { 240/255 }
-- scrollView listener
local function scrollListener(event)
local phase = event.phase
local direction = event.direction
if "began" == phase then
--print("Began")
elseif "moved" == phase then
--print("Moved")
elseif "ended" == phase then
--print("Ended")
end
-- If the scrollView has reached its scroll limit
if event.limitReached then
if "up" == direction then
--print("Reached Top Limit")
elseif "down" == direction then
--print("Reached Bottom Limit")
elseif "left" == direction then
--print("Reached Left Limit")
elseif "right" == direction then
--print("Reached Right Limit")
end
end
return true
end
-- Create a scrollView
local scrollView = widget.newScrollView {
left = 20-ox,
top = 62,
width = display.contentWidth+ox+ox-60,
height = display.contentHeight-32-tabBarHeight-120,
hideBackground = false,
backgroundColor = backgroundColor,
--isBounceEnabled = false,
horizontalScrollingDisabled = false,
verticalScrollingDisabled = false,
listener = scrollListener
}
sceneGroup:insert(scrollView)
-- Insert an image into the scrollView
local background = display.newRect(100, 100, 1200, 1200)
background.x = background.contentWidth * 0.5
background.y = background.contentHeight * 0.5
scrollView:insert(background)
-------------------------------------------------------------------------
-- Insert various other widgets into scrollView to exhibit functionality
-------------------------------------------------------------------------
-- Radio button set
local radioGroup = display.newGroup()
local radioButton = widget.newSwitch {
left = 20,
style = "radio",
initialSwitchState = true
}
radioGroup:insert(radioButton)
radioButton.y = 50
local radioButton2 = widget.newSwitch {
style = "radio"
}
radioGroup:insert(radioButton2)
radioButton2.x = radioButton.x+radioButton.width
radioButton2.y = 50
scrollView:insert(radioGroup)
-- Checkbox
local checkboxButton = widget.newSwitch {
style = "checkbox"
}
checkboxButton.x = radioButton2.x+radioButton2.width+20
checkboxButton.y = 50
scrollView:insert(checkboxButton)
-- On/off switch
local onOffSwitch = widget.newSwitch {
style = "onOff",
initialSwitchState = false
}
onOffSwitch.y = 50
scrollView:insert(onOffSwitch)
-- Stepper
local stepper = widget.newStepper {
left = 20,
top = 80,
initialValue = 4,
minimumValue = 0,
maximumValue = 25
}
scrollView:insert(stepper)
-- Progress view
local progressView = widget.newProgressView {
left = 130,
width = 125,
isAnimated = true,
}
scrollView:insert(progressView)
progressView.y = stepper.y
local currentProgress = 0.0
testTimer = timer.performWithDelay(100, function(event)
currentProgress = currentProgress + 0.01
progressView:setProgress(currentProgress)
end, 50)
onOffSwitch.x = progressView.x+12
在所有方向上的拖動和縮放選項:
-- turn on multitouch
system.activate("multitouch")
-- which environment are we running on?
local isDevice = (system.getInfo("environment") == "device")
-- returns the distance between points a and b
function lengthOf(a, b)
local width, height = b.x-a.x, b.y-a.y
return (width*width + height*height)^0.5
end
-- returns the degrees between (0,0) and pt
-- note: 0 degrees is 'east'
function angleOfPoint(pt)
local x, y = pt.x, pt.y
local radian = math.atan2(y,x)
local angle = radian*180/math.pi
if angle < 0 then angle = 360 + angle end
return angle
end
-- returns the degrees between two points
-- note: 0 degrees is 'east'
function angleBetweenPoints(a, b)
local x, y = b.x - a.x, b.y - a.y
return angleOfPoint({ x=x, y=y })
end
-- returns the smallest angle between the two angles
-- ie: the difference between the two angles via the shortest distance
function smallestAngleDiff(target, source)
local a = target - source
if (a > 180) then
a = a - 360
elseif (a < -180) then
a = a + 360
end
return a
end
-- rotates a point around the (0,0) point by degrees
-- returns new point object
function rotatePoint(point, degrees)
local x, y = point.x, point.y
local theta = math.rad(degrees)
local pt = {
x = x * math.cos(theta) - y * math.sin(theta),
y = x * math.sin(theta) + y * math.cos(theta)
}
return pt
end
-- rotates point around the centre by degrees
-- rounds the returned coordinates using math.round() if round == true
-- returns new coordinates object
function rotateAboutPoint(point, centre, degrees, round)
local pt = { x=point.x - centre.x, y=point.y - centre.y }
pt = rotatePoint(pt, degrees)
pt.x, pt.y = pt.x + centre.x, pt.y + centre.y
if (round) then
pt.x = math.round(pt.x)
pt.y = math.round(pt.y)
end
return pt
end
-- calculates the average centre of a list of points
local function calcAvgCentre(points)
local x, y = 0, 0
for i=1, #points do
local pt = points[i]
x = x + pt.x
y = y + pt.y
end
return { x = x/#points, y = y/#points }
end
-- calculate each tracking dot's distance and angle from the midpoint
local function updateTracking(centre, points)
for i=1, #points do
local point = points[i]
point.prevAngle = point.angle
point.prevDistance = point.distance
point.angle = angleBetweenPoints(centre, point)
point.distance = lengthOf(centre, point)
end
end
-- calculates rotation amount based on the average change in tracking point rotation
local function calcAverageRotation(points)
local total = 0
for i=1, #points do
local point = points[i]
total = total + smallestAngleDiff(point.angle, point.prevAngle)
end
return total/#points
end
-- calculates scaling amount based on the average change in tracking point distances
local function calcAverageScaling(points)
local total = 0
for i=1, #points do
local point = points[i]
total = total + point.distance/point.prevDistance
end
return total/#points
end
-- creates an object to be moved
function newTrackDot(e)
-- create a user interface object
local circle = display.newCircle(e.x, e.y, 50)
-- make it less imposing
circle.alpha = .5
-- keep reference to the rectangle
local rect = e.target
-- standard multi-touch event listener
function circle:touch(e)
-- get the object which received the touch event
local target = circle
-- store the parent object in the event
e.parent = rect
-- handle each phase of the touch event life cycle...
if (e.phase == "began") then
-- tell corona that following touches come to this display object
display.getCurrentStage():setFocus(target, e.id)
-- remember that this object has the focus
target.hasFocus = true
-- indicate the event was handled
return true
elseif (target.hasFocus) then
-- this object is handling touches
if (e.phase == "moved") then
-- move the display object with the touch (or whatever)
target.x, target.y = e.x, e.y
else -- "ended" and "cancelled" phases
-- stop being responsible for touches
display.getCurrentStage():setFocus(target, nil)
-- remember this object no longer has the focus
target.hasFocus = false
end
-- send the event parameter to the rect object
rect:touch(e)
-- indicate that we handled the touch and not to propagate it
return true
end
-- if the target is not responsible for this touch event return false
return false
end
-- listen for touches starting on the touch layer
circle:addEventListener("touch")
-- listen for a tap when running in the simulator
function circle:tap(e)
if (e.numTaps == 2) then
-- set the parent
e.parent = rect
-- call touch to remove the tracking dot
rect:touch(e)
end
return true
end
-- only attach tap listener in the simulator
if (not isDevice) then
circle:addEventListener("tap")
end
-- pass the began phase to the tracking dot
circle:touch(e)
-- return the object for use
return circle
end
-- spawning tracking dots
-- create display group to listen for new touches
local group = display.newGroup()
-- populate display group with objects
local rect = display.newRect(group, 200, 200, 200, 100)
rect:setFillColor(0,0,255)
rect = display.newRect(group, 300, 300, 200, 100)
rect:setFillColor(0,255,0)
rect = display.newRect(group, 100, 400, 200, 100)
rect:setFillColor(255,0,0)
-- keep a list of the tracking dots
group.dots = {}
-- advanced multi-touch event listener
function touch(self, e)
-- get the object which received the touch event
local target = e.target
-- get reference to self object
local rect = self
-- handle began phase of the touch event life cycle...
if (e.phase == "began") then
print(e.phase, e.x, e.y)
-- create a tracking dot
local dot = newTrackDot(e)
-- add the new dot to the list
rect.dots[ #rect.dots+1 ] = dot
-- pre-store the average centre position of all touch points
rect.prevCentre = calcAvgCentre(rect.dots)
-- pre-store the tracking dot scale and rotation values
updateTracking(rect.prevCentre, rect.dots)
-- we handled the began phase
return true
elseif (e.parent == rect) then
if (e.phase == "moved") then
print(e.phase, e.x, e.y)
-- declare working variables
local centre, scale, rotate = {}, 1, 0
-- calculate the average centre position of all touch points
centre = calcAvgCentre(rect.dots)
-- refresh tracking dot scale and rotation values
updateTracking(rect.prevCentre, rect.dots)
-- if there is more than one tracking dot, calculate the rotation and scaling
if (#rect.dots > 1) then
-- calculate the average rotation of the tracking dots
rotate = calcAverageRotation(rect.dots)
-- calculate the average scaling of the tracking dots
scale = calcAverageScaling(rect.dots)
-- apply rotation to rect
rect.rotation = rect.rotation + rotate
-- apply scaling to rect
rect.xScale, rect.yScale = rect.xScale * scale, rect.yScale * scale
end
-- declare working point for the rect location
local pt = {}
-- translation relative to centre point move
pt.x = rect.x + (centre.x - rect.prevCentre.x)
pt.y = rect.y + (centre.y - rect.prevCentre.y)
-- scale around the average centre of the pinch
-- (centre of the tracking dots, not the rect centre)
pt.x = centre.x + ((pt.x - centre.x) * scale)
pt.y = centre.y + ((pt.y - centre.y) * scale)
-- rotate the rect centre around the pinch centre
-- (same rotation as the rect is rotated!)
pt = rotateAboutPoint(pt, centre, rotate, false)
-- apply pinch translation, scaling and rotation to the rect centre
rect.x, rect.y = pt.x, pt.y
-- store the centre of all touch points
rect.prevCentre = centre
else -- "ended" and "cancelled" phases
print(e.phase, e.x, e.y)
-- remove the tracking dot from the list
if (isDevice or e.numTaps == 2) then
-- get index of dot to be removed
local index = table.indexOf(rect.dots, e.target)
-- remove dot from list
table.remove(rect.dots, index)
-- remove tracking dot from the screen
e.target:removeSelf()
-- store the new centre of all touch points
rect.prevCentre = calcAvgCentre(rect.dots)
-- refresh tracking dot scale and rotation values
updateTracking(rect.prevCentre, rect.dots)
end
end
return true
end
-- if the target is not responsible for this touch event return false
return false
end
-- attach pinch zoom touch listener
group.touch = touch
-- listen for touches starting on the touch object
group:addEventListener("touch")
一套面具和拖動選擇對象.Drag應該是有限的。 – AndroidUser