okay so I have a jump button and a runtime listener function for when the jump button is pressed.
So whenver the jump button is pressed I apply linear impulse to the game hero.
local function controls(event)
if(event.phase=="began") then
if (buttonpressed.id=="jump") then
hero:applyLinearImpulse(0,-10,hero.x,hero.y)
end
elseif(event.phase=="ended") then
end
end
Now problem is if if the user keeps on tapping the jump button then the hero keeps on going up. I cant think of anyhting to counter this. One thing I could do is change the above code to:
local function controls(event)
if(event.phase=="began") then
if (buttonpressed.id=="jump" and hero.y>display.contentHeight/2) then
hero:applyLinearImpulse(0,-10,hero.x,hero.y)
end
elseif(event.phase=="ended") then
end
end
But this would still allow the jumping button to work until half of the screen is reached.
Kindly help me on this.
Thanks
Add a jump counter that resets when the player collides with the floor, that way you can allow double jumps etc later if you want to.
You could check the velocity of the hero and only allow the jump if the velocity is below a certain threshold:
if (buttonpressed.id=="jump" and hero.y>display.contentHeight/2) then
local vx, vy = hero:getLinearVelocity()
if vy < velocity_threshold then -- you have to define this value
hero:applyLinearImpulse(0,-10,hero.x,hero.y)
end
end
This should work. Another approach could be (i don't know much about corona) using linearDamping. This results in a damping of the linear motion, which sounds like something you could need.
You can also create a Boolean.
When the jump begins the boolean is true.
When the player collides with the floor is false.
While the boolean is true you cannot jump again.
Related
I'm trying to code a Pong game on Lua using the framework Love2D with some extra features. Among others, I want curves to occur. In order to do so, I'm trying to implement the trajectory of horizontally launched projectiles. I have a ball table with a position attribute for x (ball.x) and another for y (ball.y). I, also, have a an attribute for the x velocity (ball.dx) and another for the y velocity (ball.dy). Finally, I have an acceleration variable (gravity)
In my game, if the paddle moves and the ball hits it, the ball should follow and horizontal curve. In order to create my curves, I want to change the y-axis velocity on each frame in order to make my ball move in an arc across the screen. The main issue that I have is that I don't know how to change this velocity in each frame in order to create the expected arc. The most recent attempt that I made was to create a while loop like the following code. However, it creates an infinite loop. Can someone enlighten me please?
Clarification:
-Player.x and player.y are the player coordinate
-Player2.x and Player2.y are the opponent coordinate
-This piece of code is inside another if statement detecting a collision. It is inside the love.update(dt) function.
Thank you so much!
if love.keyboard.isDown("up") and distanceBetween(ball.x,ball.y,player.x,player.y)>30 then
ball.dy=0
while CollisionDetector(ball.x,player2.x,ball.y,player2.y, player2.width,player2.height,ball.size)==false or ball.x>0 or ball.y-20>0 or ball.y+20<love.graphics.getHeight() do
ball.dy=ball.dy+gravity*dt
ball.y=ball.y+ball.dy
end
end
I believe the snippet you've provided is a part of love.update function. (At least it should be.) That function is supposed to perform a single step of the game at a time and return. It is not supposed to handle the whole flight in a single call.
In your particular case, while loop expects the ball to move, but that is not something that will happen until the loop and encompassing function end.
In general, to simulate ongoing processes you'll have to store the information about such process. For example, if you want gravity be dependent on the paddle movement direction, then you'll have to modify the corresponding variable and store it between the call.
In your code, there are multiple other design flaws that make it do not what you think it should do. With some functions and code parts left to be implemented by yourself, the code outline would look as follows:
function collides(ball,player)
return (ball.x,player.x,ball.y,player.y, player.width,player.height,ball.size)
end
function love.update(dt)
handle_paddle_movements()
--handle the ball-paddle interaction
if collides(ball,player1) or collides(ball,player2) then
ball.dx=-ball.dx
if love.keyboard.isDown("up") then
--store the info you need to know about the interaction
ball.d2y = -gravity
else if love.keyboard.isDown("down")
ball.d2y = gravity
else
ball.d2y = 0
end
end
handle_the_wall_collision()
--ball movement code should be separate from collision handling
--concrete equations can be whatever you want
ball.x = ball.x+ball.dx*dt
ball.dy = ball.dy + ball.d2y * dt
ball.y = ball.y + ball.dy * dt
end
How do I prevent the player from dying when they fall in the void?
The only way to do it is to lift it up the Y-Axis.
I recommend selecting everything then moving it up an EXACT amount of studs (e.g. 100) Then just change the script and add 100 studs to all the values.
To be safe I would increase it by a lot more studs than you think you will need.
This is the only way I know of and I think is possible,
Hope this helps.
From devforum.roblox.com, executing the following
workspace.FallenPartsDestroyHeight=0/0
from the command bar will set FallenPartsDestroyHeight to nan which appears to disable the automatic destruction of objects based on Y position.
I'm working on a small game using lua with Löve2D, and I used this code to make my character jump:
epsilon = 0.1
x,y = player.body:getLinearVelocity()
if math.abs(math.ceil(y)) < epsilon then cantJump = false else cantJump = true end
if love.keyboard.isDown(" ") and not cantJump then player.body:setLinearVelocity(0,-500) end
player.body:setAngle(0)
player.body:setX(math.ceil(player.body:getX()))
player.body:setY(math.ceil(player.body:getY()))
end
But sometimes, I have to wait a short time to see the player jumping when I press space button. How can I fix that ?
I think the problem is the math.ceil. try removing it, since it is changing the player's position, or just move it to before you tell it to jump.
in my game the player is supposed to die when it goes out of bounds downwards, i have implemented physics and I would like to know how to get the current Y of my player and use it in an if statement sorta like this
if player.y == display.contentHeight+100 then
endGame()
end
Declare the below statement
h=display.contentHeight
Hence create a Runtime eventlistener
local function RTListener(event)
if player.y>h then
endGame()
end
end
Runtime:addEventListener("Runtime",RTListener)
It will ends the game, when player goes out of bounds..
I have a player who is navigating in space. Since it is space, there is not gravity therefore no parabolic trajectory. The player is just going in a horizontal line from left to right. The player is not actually moving, but the background is, so it looks like he is. The x value is fixed.
I have 2 buttons that help the player avoid obstacles like asteroids. One button gives the player upward force, the other one downward force. The following are the functions called when those buttons are pressed.
function moveUp( event )
if event.phase == "ended" then
player:applyForce(0, 8, player.x, player.y)
player:setSequence("jump")
jumpChannel = audio.play(jumpSound)
end
return true
end
function moveDown( event )
if event.phase == "ended" then
player:applyForce(0, -8, player.x, player.y)
player:setSequence("jump")
jumpChannel = audio.play(jumpSound)
end
return true
end
The problem with this implementation is that whenever a force is applied the player keeps going in that direction. Then you have to apply force in the opposite direction and he will keep going in that direction forever. That is not what I want. What I want is :
when UP is pressed, player goes up for certain value (say 50 px) in Y. Then the player keeps going in the horizontal direction from left to right in the new altitude.
When DOWN is pressed, player goes down certain value. Then the player keeps going in the horizontal direction from left to right in the new altitude.
What is the best way to accomplish this? Can I do this using the applyForce function or is there another method? Thanks in advance for your time!
You have to remember that F=ma: if force applied is 0, a is 0, which means velocity does not change. You have two choices:
apply an opposite force that will decrease the speed, and stop when speed is 0. Every Body has myBody.linearDamping factor which you could set to non-zero. If that doesn't work, you can apply your own damping: you make it proportional to Body velocity, so you need an enterFrame event handler that updates the force based on current velocity:
function enterFrame(e)
local v = player:getLinearVelocity()
player:applyForce(- a * v)
end
Here the "a" is damping, some arbitrary number (0 is what you have now; the larger it is, the faster the player will return to 0 velocity). I haven't checked whether the applyForce() is additive (adds to existing forces) or absolute (replaces existing). But you get the idea.
directly move the player:
function moveUp( event )
if event.phase == "ended" then
player:setLinearVelocity(0, 8) -- pixels/sec
You will still need an enterFrame handler to monitor position and setLinearVelocity(0,0) when desired position reached.
You will get smoother, more "realistic" motion with option 1.