I tried to reproduce it with a simple project.
reproduce.zip (196.1 KB)
Use arrow keys to move left and right, space for “jump”.
local screenW, screenH, halfW = display.actualContentWidth, display.actualContentHeight, display.contentCenterX
local crate
local left, right, hspd = 0, 0, 1
function scene:create( event )
-- Called when the scene's view does not exist.
--
-- INSERT code here to initialize the scene
-- e.g. add display objects to 'sceneGroup', add touch listeners, etc.
local sceneGroup = self.view
-- We need physics started to add bodies, but we don't want the simulaton
-- running until the scene is on the screen.
physics.start()
physics.setDrawMode("hybrid");
physics.setGravity(0, 32);
physics.pause()
-- create a grey rectangle as the backdrop
-- the physical screen will likely be a different shape than our defined content area
-- since we are going to position the background from it's top, left corner, draw the
-- background at the real top, left corner.
local background = display.newRect( display.screenOriginX, display.screenOriginY, screenW, screenH )
background.anchorX = 0
background.anchorY = 0
background:setFillColor( .5 )
-- make a crate (off-screen), position it, and rotate slightly
crate = display.newRect(127, 794, 40, 40 )
-- add physics to the crate
physics.addBody( crate, { density=12.0, friction=0, bounce=0 } )
crate.isFixedRotation = true
-- create a grass object and add physics (with custom shape)
local grass = display.newImageRect( "grass.png", 256, 82 )
-- draw the grass at the very bottom of the screen
grass.x, grass.y = 128, 1087
physics.addBody( grass, "static", { friction=0 } )
local grass2 = display.newImageRect( "grass.png", 256, 82 )
-- draw the grass at the very bottom of the screen
grass2.x, grass2.y = 384, 1087
physics.addBody( grass2, "static", { friction=0 } )
local grass3 = display.newImageRect( "grass.png", 256, 82 )
-- draw the grass at the very bottom of the screen
grass3.x, grass3.y = 640, 1087
physics.addBody( grass3, "static", { friction=0 } )
local wall = display.newImageRect( "grass.png", 32, 992 )
-- draw the grass at the very bottom of the screen
wall.x, wall.y = 16, 556
physics.addBody( wall, "static", { friction=0 } )
-- all display objects must be inserted into group
sceneGroup:insert( background )
sceneGroup:insert( grass)
sceneGroup:insert( grass2)
sceneGroup:insert( grass3)
sceneGroup:insert( wall )
sceneGroup:insert( crate )
function crate:collision( event )
local phase = event.phase
local other = event.other
local vx, vy = crate:getLinearVelocity()
if phase == "began" then
if self.jumping and vy > 0 then
-- Landed after jumping
crate.jumping = false
end
end
end
crate:addEventListener( "collision" )
-- events
local function key(event)
local phase = event.phase
local name = event.keyName
local lastEvent = {}
if (phase == lastEvent.phase) and (name == lastEvent.keyName) then
return false
end -- Filter repeating keys
if phase == "down" then
if "left" == name or "a" == name then
left = -hspd
end
if "right" == name or "d" == name then
right = hspd
elseif "space" == name then
if not crate.jumping then
crate:applyLinearImpulse(0, -550)
crate.jumping = true
end
end
elseif phase == "up" then
if "left" == name or "a" == name then
left = 0
end
if "right" == name or "d" == name then
right = 0
end
end
lastEvent = event
end
Runtime:addEventListener( "key", key )
end
-- Function to scroll the map
function scene:enterFrame(event)
-- Easy way to scroll a map based on a character
local sceneGroup = self.view
if crate then
local x, y = crate.x - display.contentCenterX, crate.y - display.contentCenterY -- 镜头位置
if x < 0 then
x = 0
end
if y < 0 then
y = 0
end
sceneGroup.x, sceneGroup.y = -x, -y
local vx, vy = crate:getLinearVelocity()
local dx = left + right
crate:setLinearVelocity(dx*60, vy)
end
end
function scene:show( event )
local sceneGroup = self.view
local sceneself = self
local phase = event.phase
if phase == "will" then
-- Called when the scene is still off screen and is about to move on screen
function ef(event)
sceneself:enterFrame(event)
end
Runtime:addEventListener("enterFrame", ef)
elseif phase == "did" then
-- Called when the scene is now on screen
--
-- INSERT code here to make the scene come alive
-- e.g. start timers, begin animation, play audio, etc.
physics.start()
end
end