Delta time and understimate( Im not understanding the delta time) - lua
Hey you guys im with problems of understanding these problems with delta time. Its in Pong-3 of course CS50 - Introduction to Game devlopment. Im not understanding why dt is there. dt is a variable not mentioned in all code. BUt is callled in render process in language LUA. Its like a local variable but is not pre-defined or another way of introduce that variable. I will give the code and wait for... some answer.
--[[
GD50 2018
Pong Remake
pong-3
"The Paddle Update"
-- Main Program --
Author: Colton Ogden
cogden#cs50.harvard.edu
Originally programmed by Atari in 1972. Features two
paddles, controlled by players, with the goal of getting
the ball past your opponent's edge. First to 10 points wins.
This version is built to more closely resemble the NES than
the original Pong machines or the Atari 2600 in terms of
resolution, though in widescreen (16:9) so it looks nicer on
modern systems.
]]
-- push is a library that will allow us to draw our game at a virtual
-- resolution, instead of however large our window is; used to provide
-- a more retro aesthetic
--
-- https://github.com/Ulydev/push
push = require 'push'
WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720
VIRTUAL_WIDTH = 432
VIRTUAL_HEIGHT = 243
-- speed at which we will move our paddle; multiplied by dt in update
PADDLE_SPEED = 200
--[[
Runs when the game first starts up, only once; used to initialize the game.
]]
function love.load()
love.graphics.setDefaultFilter('nearest', 'nearest')
-- more "retro-looking" font object we can use for any text
smallFont = love.graphics.newFont('font.ttf', 8)
-- larger font for drawing the score on the screen
scoreFont = love.graphics.newFont('font.ttf', 32)
-- set LÖVE2D's active font to the smallFont obect
love.graphics.setFont(smallFont)
-- initialize window with virtual resolution
push:setupScreen(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, WINDOW_WIDTH, WINDOW_HEIGHT, {
fullscreen = false,
resizable = false,
vsync = true
})
-- initialize score variables, used for rendering on the screen and keeping
-- track of the winner
player1Score = 0
player2Score = 0
-- paddle positions on the Y axis (they can only move up or down)
player1Y = 30
player2Y = VIRTUAL_HEIGHT - 50
end
--[[
Runs every frame, with "dt" passed in, our delta in seconds
since the last frame, which LÖVE2D supplies us.
]]
function love.update(dt)
-- player 1 movement
if love.keyboard.isDown('w') then
-- add negative paddle speed to current Y scaled by deltaTime
player1Y = player1Y + -PADDLE_SPEED * dt
elseif love.keyboard.isDown('s') then
-- add positive paddle speed to current Y scaled by deltaTime
player1Y = player1Y + PADDLE_SPEED * dt
end
-- player 2 movement
if love.keyboard.isDown('up') then
-- add negative paddle speed to current Y scaled by deltaTime
player2Y = player2Y + -PADDLE_SPEED * dt
elseif love.keyboard.isDown('down') then
-- add positive paddle speed to current Y scaled by deltaTime
player2Y = player2Y + PADDLE_SPEED * dt
end
end
--[[
Keyboard handling, called by LÖVE2D each frame;
passes in the key we pressed so we can access.
]]
function love.keypressed(key)
-- keys can be accessed by string name
if key == 'escape' then
-- function LÖVE gives us to terminate application
love.event.quit()
end
end
--[[
Called after update by LÖVE2D, used to draw anything to the screen,
updated or otherwise.
]]
function love.draw()
-- begin rendering at virtual resolution
push:apply('start')
-- clear the screen with a specific color; in this case, a color similar
-- to some versions of the original Pong
love.graphics.clear(40/255, 45/255, 52/255, 255/255)
-- draw welcome text toward the top of the screen
love.graphics.setFont(smallFont)
love.graphics.printf('Hello Pong!', 0, 20, VIRTUAL_WIDTH, 'center')
-- draw score on the left and right center of the screen
-- need to switch font to draw before actually printing
love.graphics.setFont(scoreFont)
love.graphics.print(tostring(player1Score), VIRTUAL_WIDTH / 2 - 50,
VIRTUAL_HEIGHT / 3)
love.graphics.print(tostring(player2Score), VIRTUAL_WIDTH / 2 + 30,
VIRTUAL_HEIGHT / 3)
-- render first paddle (left side), now using the players' Y variable
love.graphics.rectangle('fill', 10, player1Y, 5, 20)
-- render second paddle (right side)
love.graphics.rectangle('fill', VIRTUAL_WIDTH - 10, player2Y, 5, 20)
-- render ball (center)
love.graphics.rectangle('fill', VIRTUAL_WIDTH / 2 - 2, VIRTUAL_HEIGHT / 2 - 2, 4, 4)
-- end rendering at virtual resolution
push:apply('end')
end
The Love update docs mention delta time briefly.
dt (Delta Time) holds the time in seconds since the last time the update function was called. Under normal circumstances this should be a small fraction of a second. The Love framework calls the update function for you repeatedly as part of your game loop. It also defines and keeps track of the dt variable somewhere within the framework, which is why you don't see it defined or introduced anywhere. You only have access to it from within the update function (unless you pass it elsewhere).
Why would you need the delta time?
Because you can't guarantee that update will always get called at a consistent rate. Imagine you have a player character that you move 1 pixel every time update is called. If your game is running at 60fps then your character moves 60px in 1 second. But of your game drops down to 59, or 50, or 12fps, then your character will slow down too, which is not usually what you want.
You can use the delta time to keep a consistent speed for your character. Multiplying the desired speed per second (60px) by dt will get you the exact amount to move each frame regardless of how often update is getting called.
That's what's happening in your code in places like this:
player2Y = player2Y + PADDLE_SPEED * dt
PADDLE_SPEED is the amount to move per second, multiplied by the number of seconds since the last update. The result is added to the player's position.
Related
How to adjust the amount of rotation programmatically in Roblox first person view?
The goal is to make a espionage game, so that it starts with a third person view, and if player press F, it changes to first person view. With first person view, it's like equipped with a binocular, and it has 3 zoom levels (camera.FieldOfView). Imagine there is a house in front of me about 100 feet away. When I am in first person view, I want to click key V to change field of view. I will have 3 levels: 50 degrees, 30 degrees, and 10 degrees. game:GetService("UserInputService").InputBegan:connect(function (input, _) if input.KeyCode == Enum.KeyCode.V then if player.CameraMode == Enum.CameraMode.LockFirstPerson then view_index = view_index + 1 if view_index >= table.getn(all_views) then view_index = view_index - table.getn(all_views) end camera.FieldOfView = all_views[view_index + 1] end end end) What I found is that when I move the mouse (approximately same distance on the mouse pad), my orientation moves approximately the same amount, that is to say, it always moves across the whole house. I hoped to move only across the window if it's 30 degree field of view, and less if it's 10 degree. I want to have more subtle controls on rotation when I "Zoom in" to look at the details of an object. Is there a way to do that?
It's game:GetService("UserInputService")..MouseDeltaSensitivity local UserInputService = game:GetService("UserInputService") UserInputService.MouseDeltaSensitivity = 0.1 -- or 1, or 0.01 for different sensitivity Check this link
Lua raycasting issues
I have worked day-in and day-out on a ray-casting engine I'm building for the Ti Nspire CX (with Lua), and am having issues with ray collision. I have fiddled around with the area which I believe has the problem, because drawing of rays on the screen has no issues: I have also done ALOT of debugging in this, such as displaying the coordinates which the rays are located when being shot outwards from the player. I say that I believe that the collision part has the problem because when I printed the radius of each ray, they all reached the maximum distance, which I set to be 40. This is the collision and single-ray management code: function ray() radius = 1 for n = 1, 40, 1 do -- increase of testdot x_ray = x + (radius * math.cos(rayf * 3.141592653/180)) y_ray = y - (radius * math.sin(rayf * 3.141592653/180)) --print(math.floor(x_ray,3), math.floor(y_ray,3), rayf, radius) for i = 1, 4, 1 do --for k,v in pairs(map) do -- testing for collision of testdot and a wall --print("X ",v[1],"<-->",math.floor(x_ray),"<-->",v[3]) --print("Y ",v[2],"<-->",math.floor(y_ray),"<-->",v[4])' ------------------------------------ if ( math.min(map[i][1],map[i][3]) <= x_ray and x_ray <= math.max(map[i][1],map[i][3]) ) and ( math.min(map[i][2],map[i][4]) <= y_ray and y_ray <= math.max(map[i][2],map[i][4]) ) then print("Collision") --return true end ------------------------------------ end radius = n end end I know the second for-loop could be condensed, but I did this in my debugging process to find out why this won't function as it should. The area around the ------------------------------------ is where the rays don't collide/over-reach/miss... I dont know why this isn't working, anyone have any suggestions? Just for reference, this collision is based off a python program I was having issues with here, in, of course, the collision part. Values of variables: x, y is the position of the player (while raycasting this will remain static) radius is the current radius of a single ray, and will continue to increment as long as no collision is detected rayf is the current degree of the ray (is not relative to the player). Is calculated at the start of the program by taking the players degree (which isnt shown in here but is called 'facing'), adding 30, then rotating clockwise until the FOV of 60 degrees has been satisfied. X-ray, y_ray are the current points of a single ray, and will continue to increment towards the specified rayf value, and will increment in values of 1 to make a radius equal to the n in the last for-loop. (Must note that the degrees are the same in a typical unit circle, and are NOT mirrored to match this mirrored y-axis; i.e. 90 degrees is up, 180 degrees is down.)
This isn't code review site but I'm going to try to first write the code in more understandable manner and then to guess the error in comments to the code. function ray(x,y,rayf,map) %Are you sure that your global variables x,y,rayf are not overwritten? %I believe these are correct if 0 degrees is "right", "90" - top and "180" - left %is it so? local x_proj = math.cos(rayf* 3.141592653/180); local y_proj = -math.sin(rayf* 3.141592653/180); for radius=1,40 do local x_ray = x + radius * x_proj local y_ray = y + radius * y_proj for i=1,4 do %I take it the map[i] is a particular rectangle located at a particular side of the room (so map[1] is located at the left edge of the screen, for example) %is it so? local wall_left_edge = math.min ( map[i][1],map[i][3] ) local wall_right_edge = math.max ( map[i][1],map[i][3] ) %if I understood correctly, the smaller y is above bigger y local wall_top_edge = math.min ( map[i][2], map[i][4] ) local wall_bottom_edge = math.max ( map[i][2], map[i][4] ) %it is beyond me why couldnt you just sort the wall coordinates beforehand %(say, top - 1 , bottom - 2 left - 3, right - 4) if (wall_left_edge < x) and (x < wall_right_edge) and (wall_top_edge < y) and (y < wall_bottom_edge) then %this does not detect collision, %it detects whether beam steps into the rectangle "map[i]" print("Collision") end end end end So, with taking into account the last comment, the walls you define must be broad and thick enough so that the beam is guaranteed to step into one: (wall_right_edge - wall_left_edge ) > 1 ( 1 is step of the radius loop) and (wall_bottom_edge - wall_top_edge ) > 1. At the corners walls must either overlap or they should share a boundary of length at least 1.
The reason the rays were always going past 40 was because the for-loop wasnt being canceled, which is a great reason to include a return to break out of the function and continue the code (I thought a return was included, however it wasn't functioning correctly, as you see in the: --return true Past this, the raycasting worked fine, but not math.floor-ing the new ray coord's also made the ray shoot beyond 40, for some unknown reason.
Is it possible to change the x and y coordinates in a transition.to in Corona SDK
I'm having a hard time figuring this out. I want to make an object, in my case a ball, local ball = display.newCircle(25,25,25) ball.x = 160 ball.y = -80 to move from its starting coordinates to another spot, but then, after the action is completed I want it to immediately appear in another spot lets say x=90 and y= 120 and transition to another place. How can I do this with lua? Thank you in advance.
I am not sure if I understood you correctly. Code below move ball from starting coordinates to destination coordinates. After ball reach its destination spot the x and y coordinate of ball are changed to x=90 and y= 120 and the second transition is called. local function listener(self) -- self== ball in this case self.x = 90 self.y = 120 transition.to(self, {time=yourTime, x=newDestX, y=newDestY}) end transition.to(ball, {time=yourTime, x=destX, y=destY, onComplete=listener}) For more information about transitions in Corona SDK read this.
Corona SDK 'camera follow' stop at certain point?
I have all my display objects in a group called game. I also have this loop function so a 'camera' effect is created, so the camera follows the ball. local function loop(x) local targetx = 600 -ball.x game.x = game.x + ((targetx - game.x) *0.05) end This setup gives a smooth follow of the ball, so the ball is not exactly in the middle of the screen all the time. My question is how to make the game stop following the ball after a certain point. I tried: local function loop(x) if ball.x < 600 and ball.x > 50 then local targetx = 600 -ball.x game.x = game.x + ((targetx - game.x) *0.05) end end ...but it gives a jerky return to following the ball after the ball exits, then returns into the 'following' area (x 50 to 600).
If your loop function is called in a timer, you could easily just cancel the timer / set x to the original x when your ball coordinates are under 50 or above 600.
You might check out Perspective - it's a library solely for virtual camera support for Corona that I wrote.
Changing a moving objects direction of travel in corona
I'm new to Corona and looking for a little help manipulating moving objects: Basically I want a set up where when I can click on a moving object, a dialog box will pop up giving me the option to change the speed of the object and the vector of travel. I'm pretty sure I can figure out the event handling and the dialog but I'm stuck on simply changing the direction of travel to the new vector in a simple example, I have a rect moving up the screen as follows: obj1 = display.newRect(500, 800, 10, 40) transition.to(obj1,{x=500, y = 100, time = 40000}) I know I can change the speed by adjusting the time, but if I use obj1:rotate(30) to turn the object 30 degrees, how do I make it travel in the new direction? Should I be using physics - linear impulse for example, instead of transitions? Apologies if this is a stupid question but I have searched without success for a solution.
This sounds like what you are trying to do. You would have to modify bits to fit your code but this is a working example. So if you copy it to a new main.lua file and run it you can see how it works. (Click to rotate obj). local obj = display.newRect(50,50, 10, 40) local SPEED = 1 local function move(event) obj.x = obj.x + math.cos(math.rad(obj.rotation)) * SPEED obj.y = obj.y + math.sin(math.rad(obj.rotation)) * SPEED end local function rotate(event) obj.rotation = obj.rotation + 45 end Runtime:addEventListener("enterFrame", move) Runtime:addEventListener("tap", rotate) Basically I used the "enterFrame" event to 'move' the rectangle, by recalculating the x and y of the objects location using its rotation (which is easy enough to modify) every frame.