I recently finished making my first app by following a YouTube tutorial, but one thing bothered me. I want my paddle in my game to collide with the walls and stop moving, instead of passing through it like it currently does.
How could I do this?
main.lau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | require("physics") function main() setUpPhysics() createWalls() createBricks() createBall() createPaddle() startGame() end function setUpPhysics() physics.start() physics.setGravity(0,0) end function createWalls() local wallThickness = 15 -- Left Wall local wall = display.newRect(0 , 0, wallThickness, display.contentHeight) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) -- Right Wall wall = display.newRect(display.contentWidth - wallThickness , 0, wallThickness, display.contentHeight) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) -- Top Wall wall = display.newRect(0 , 0, display.contentWidth, wallThickness) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) -- Bottom Wall wall = display.newRect(0 , display.contentHeight - wallThickness, display.contentWidth, wallThickness) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) wall.type = "Bottom" end function createBricks() local brickWidth = 60 local brickHeight = 30 local numRows = 4 local numColumns = 6 local topLeft = {x = display.contentWidth / 2 - (brickWidth * numColumns) / 2, y = display.contentWidth / 8} local row local column for row = 0, numRows - 1 do for column = 0, numColumns - 1 do local brick = display.newRect(topLeft.x + (column * brickWidth), topLeft.y + (row * brickHeight), brickWidth, brickHeight) brick:setFillColor(math.random(50, 255), math.random(50, 255), math.random(50, 255)) brick.type = "Destructible" physics.addBody(brick, "static", {friction = 0, bounce = 1}) end end end function createBall() local ballRadius = 15 ball = display.newCircle(display.contentWidth / 2, display.contentHeight / 2, ballRadius) ball:setFillColor(255, 255, 255) physics.addBody(ball, "dynamic", {friction = 0, bounce = 1, radius = ballRadius}) ball.collision = function(self, event) if(event.phase == "ended") then if(event.other.type == "Destructible") then event.other:removeSelf() end if(event.other.type == "Bottom") then self:removeSelf() local onTimerComplete = function(event) createBall() startGame() end timer.performWithDelay(0, onTimerComplete) end end end ball:addEventListener("collision", ball) end function createPaddle() local paddleWidth = 200 local paddleHeight = 15 local paddle = display.newRect(display.contentWidth / 2 - paddleWidth / 2, display.contentHeight - display.contentHeight / 9.6, paddleWidth, paddleHeight) physics.addBody(paddle, "static", {friction = 0, bounce = 1}) local movePaddle = function(event) paddle.x = event.x end Runtime:addEventListener("touch", movePaddle) end function startGame() ball:setLinearVelocity(math.random(-150, 150), display.contentWidth / 1.25) end display.setStatusBar(display.HiddenStatusBar) main() |
You place the paddle in a non physics way by fixed position - maybe this overrides the collision. Try to use a physically way: move the paddle something like the puck in the multi puck example or better try to follow the instruction for touch joints:
http://developer.anscamobile.com/content/game-edition-physics-joints#Touch_joint
To avoid strange behavior you can "cut" the touch joint if the user touches out of your boundaries
What else do you guys suggest? Is it possible to add a type and have the paddle not go through that type?
I tried to do what is said above, but I didn't have any luck :/
Very basic and cobbled together, but try something like this;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | require("physics") function main() setUpPhysics() createWalls() createBricks() createBall() createPaddle() startGame() end function setUpPhysics() physics.start() physics.setGravity(0,0) end function createWalls() local wallThickness = 15 -- Left Wall local wall = display.newRect(0 , 0, wallThickness, display.contentHeight) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) -- Right Wall wall = display.newRect(display.contentWidth - wallThickness , 0, wallThickness, display.contentHeight) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) -- Top Wall wall = display.newRect(0 , 0, display.contentWidth, wallThickness) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) -- Bottom Wall wall = display.newRect(0 , display.contentHeight - wallThickness, display.contentWidth, wallThickness) physics.addBody(wall, "static", {friction = 0, bounce = 1}) wall:setFillColor(255, 255, 255) wall.type = "Bottom" end function createBricks() local brickWidth = 60 local brickHeight = 30 local numRows = 4 local numColumns = 6 local topLeft = {x = display.contentWidth / 2 - (brickWidth * numColumns) / 2, y = display.contentWidth / 8} local row local column for row = 0, numRows - 1 do for column = 0, numColumns - 1 do local brick = display.newRect(topLeft.x + (column * brickWidth), topLeft.y + (row * brickHeight), brickWidth, brickHeight) brick:setFillColor(math.random(50, 255), math.random(50, 255), math.random(50, 255)) brick.type = "Destructible" physics.addBody(brick, "static", {friction = 0, bounce = 1}) end end end function createBall() local ballRadius = 15 ball = display.newCircle(display.contentWidth / 2, display.contentHeight / 2, ballRadius) ball:setFillColor(255, 255, 255) physics.addBody(ball, "dynamic", {friction = 0, bounce = 1, radius = ballRadius}) ball.collision = function(self, event) if(event.phase == "ended") then if(event.other.type == "Destructible") then event.other:removeSelf() end if(event.other.type == "Bottom") then self:removeSelf() local onTimerComplete = function(event) createBall() startGame() end timer.performWithDelay(0, onTimerComplete) end end end ball:addEventListener("collision", ball) end function createPaddle() local paddleWidth = 200 local paddleHeight = 15 local paddle = display.newRect(display.contentWidth / 2 - paddleWidth / 2, display.contentHeight - display.contentHeight / 9.6, paddleWidth, paddleHeight) physics.addBody(paddle, "static", {friction = 0, bounce = 1}) local movePaddle = function(event) paddle.x = event.x if paddle.x > 240 then paddle.x = 240 elseif paddle.x < 100 then paddle.x = 100 end end Runtime:addEventListener("touch", movePaddle) end function startGame() ball:setLinearVelocity(math.random(-150, 150), display.contentWidth / 1.25) end display.setStatusBar(display.HiddenStatusBar) main() |
