Hi, I just downloaded Love/Lua and I am not realy getting it. I have a lot of history with programming so I must be doing something stupid.
Here is my first test program -
function love.load()
grid = love.graphics.newImage("grid.bmp")
srgb = love.graphics.newImage("srgb.bmp")
x = 0
y = 0
xo = 1
yo = 1
-- love.graphics.draw(srgb, 0, 0)
end
function move()
current_time = love.timer.getMicroTime()
if current_time / 500 == math.floor(current_time / 500) then
x = x + xo
end
end
function love.draw()
local display_init = false
if display_init == false then
local xo = 128 -- 50 - 32 = 18; 18 / 2 = 9; 9 - 1 = 8; 8 * 16 = 128
local yo = 28 -- 37.5 - 32 = 5.5; 5.5 / 2 = 2.75; 2.75 - 1 = 1.75; 1.75 * 16 = 28
local x
local y
for y = 1, 32 do -- 0 to 36.5 ie 37.5 places at 16x16 or 600 px
for x = 1, 32 do -- 0 to 49 ie 50 places at 16x16 or 800px
love.graphics.draw(grid, xo + x * 16, yo + y * 16)
end
end
display_init = true
end
love.graphics.draw(srgb, x * 16, y * 16)
love.graphics.print("FPS: " .. tostring(love.timer.getFPS()), 730, 0)
end
function love.keypressed(key)
if key == "left" and x > 0 then x = x - 1 end
if key == "right" and x < 49 then x = x + 1 end
if key == "up" and y > 0 then y = y - 1 end
if key == "down" and y < 36 then y = y + 1 end
end
the load draw and keypressed are doing what I expect but the move() doesn't seem to be doing anything.
I don't understand the program flow. Do I just dump code into the global (root) scope and does it run concurrently with the love. functions ??
What happens with code that is not within a function definition (root or global scope) does it run once or does it loop??
The language looks very BASIC like, should I be using labels and goto's ??
Do functions declared in the root scope run cincurrently with the love. functions or do they explicitly need to be called ??
I know these are stupid questions to someone who knows the answers. I started this half an hour ago and I would appeciate someone giving me a bit of a boost as I have extensive coding experience and I should be further along than I am so far.
Another thing - the love.draw() seems tricky, what if you have a game with multiple levels and tween screens? Do you use something like switch/case (if/then) to select the code for the current screen or tween screen?
newby wanting some guidence
Re: newby wanting some guidence
Please wrap your code in [ code ] tags.
You seem to have a good grasp of BASIC. I would advise you to take a look at http://lua-users.org/wiki/TutorialDirectory which contains the answers to most of your questions.
Labels and gotos should be avoided (in most cases, they do have their uses). Using other structures like functions and tables is a much cleaner way to write your code.
As for Löve, what happens is this:
The entry point is main.lua. This is loaded first (with the exception of conf.lua, though it's use is solely for configuration). It should contain any of the love module callbacks you wish to use.
love.load is called once your main.lua has been read. Once this is completed love.run will perpetually call love.update and love.draw alternately. You can override love.run, however the supplied function is often all that is required.
To answer the question about 'free floating code' (not in a function), it is ran once (when the file is loaded). For example, the following would produce 2:
I hope this helps.
You seem to have a good grasp of BASIC. I would advise you to take a look at http://lua-users.org/wiki/TutorialDirectory which contains the answers to most of your questions.
Labels and gotos should be avoided (in most cases, they do have their uses). Using other structures like functions and tables is a much cleaner way to write your code.
As for Löve, what happens is this:
The entry point is main.lua. This is loaded first (with the exception of conf.lua, though it's use is solely for configuration). It should contain any of the love module callbacks you wish to use.
love.load is called once your main.lua has been read. Once this is completed love.run will perpetually call love.update and love.draw alternately. You can override love.run, however the supplied function is often all that is required.
To answer the question about 'free floating code' (not in a function), it is ran once (when the file is loaded). For example, the following would produce 2:
Code: Select all
love.load = function()
x = 1 + y
end
y = 1
Do you recognise when the world won't stop for you? Or when the days don't care what you've got to do? When the weight's too tough to lift up, what do you? Don't let them choose for you, that's on you.
Re: newby wanting some guidence
Thanks Lafolie
I now have a basic idea of how it works.
With the code below I can see that I can still get a decent frame rate when animating a large number of actors.
I did notice that the lowest times between calling update was about 5 miliseconds. When I tried 10000 concurrent animations it rose to about 12 miliseconds.
What I want to do is to build a basic engine for tiled games. I don't want the realy old school tile restrictions that every actor must be on a grid position. I want them to move by one or two pixels at a time.
Is there a way to have it so that some code executes at a presice rate and have that (or other) code then execute a separate block of code on say 1 in 16 times of the original code. ie - pixel animation that then executes logic code on every sixteenth execution when an animated actor is in a grid position.
someting like -
also - how do I make .love files to upload here ?
I now have a basic idea of how it works.
With the code below I can see that I can still get a decent frame rate when animating a large number of actors.
I did notice that the lowest times between calling update was about 5 miliseconds. When I tried 10000 concurrent animations it rose to about 12 miliseconds.
What I want to do is to build a basic engine for tiled games. I don't want the realy old school tile restrictions that every actor must be on a grid position. I want them to move by one or two pixels at a time.
Is there a way to have it so that some code executes at a presice rate and have that (or other) code then execute a separate block of code on say 1 in 16 times of the original code. ie - pixel animation that then executes logic code on every sixteenth execution when an animated actor is in a grid position.
someting like -
Code: Select all
-- code that executes every 1000 microseconds or one milisecond or 0.001 seconds
function do_all_animation()
do_pixel_level_animations()
local pixel_block_sync = 0
pixel_block_sync = pixel_block_sync + 1
if pixel_block_sync == 16 then do
pixel_block_sync = 0
do_block_level_animations()
end
end
also - how do I make .love files to upload here ?
Code: Select all
function love.load()
grid = love.graphics.newImage("grid.bmp")
srgb = love.graphics.newImage("srgb.bmp")
timer = 0
update = 0
balls = {}
local x = 0
local y = 0
local xo = 0
local yo = 0
local ball_count = 1000
local ball index = 1
local this_ball = {}
for ball_index = 1, ball_count do
x = math.random(5, 779)
y = math.random(5, 579)
xo = 0
yo = 0
while xo * yo == 0 do
xo = math.random(-2, 2) * 2
yo = math.random(-2, 2) * 2
end
this_ball = {x, y, xo, yo}
balls[ball_index] = this_ball
end
end
function love.update(dt)
update = dt
local time = math.floor(love.timer.getMicroTime() * 50)
if time ~= timer then
timer = time
local ball_count = #balls
local ball_index
for ball_index = 1, ball_count do
this_ball = balls[ball_index]
local x = this_ball[1]
local y = this_ball[2]
local xo = this_ball[3]
local yo = this_ball[4]
x = x + xo
y = y + yo
if x < 1 then
x = -x
xo = -xo
end
if x > 783 then
x = 783 - (x - 783)
xo = -xo
end
if y < 1 then
y = -y
yo = -yo
end
if y > 583 then
y = 583 - (y - 583)
yo = -yo
end
this_ball[1] = x
this_ball[2] = y
this_ball[3] = xo
this_ball[4] = yo
balls[ball_index] = this_ball
end
end
end
function love.draw()
local display_init = false
if display_init == false then
local xo = 128 -- 50 - 32 = 18; 18 / 2 = 9; 9 - 1 = 8; 8 * 16 = 128
local yo = 28 -- 37.5 - 32 = 5.5; 5.5 / 2 = 2.75; 2.75 - 1 = 1.75; 1.75 * 16 = 28
local x
local y
for y = 1, 32 do -- 0 to 36.5 ie 37.5 places at 16x16 or 600 px
for x = 1, 32 do -- 0 to 49 ie 50 places at 16x16 or 800px
love.graphics.draw(grid, xo + x * 16, yo + y * 16)
end
end
display_init = true
end
local ball_count = #balls
local ball_index
for ball_index = 1, ball_count do
local this_ball = balls[ball_index]
love.graphics.draw(srgb, this_ball[1], this_ball[2])
end
love.graphics.print(tostring(update), 400, 0)
love.graphics.print(tostring(love.timer.getMicroTime()), 600, 0)
love.graphics.print("FPS: " .. tostring(love.timer.getFPS()), 730, 0)
end
- substitute541
- Party member
- Posts: 484
- Joined: Fri Aug 24, 2012 9:04 am
- Location: Southern Leyte, Visayas, Philippines
- Contact:
Re: newby wanting some guidence
See "Upload Attachment" when editing/creating a post. Alternatively, upload your file on a downloading site (I prefer Dropbox), and post the download link in your post using the [url] [/url] tags.
Currently designing themes for WordPress.
Sometimes lurks around the forum.
Sometimes lurks around the forum.
Re: newby wanting some guidence
Hi Rob.m,
you misunderstand the concept behind time measurement in a loop.
What you want (i believe) is to move things at a certain speed. The update() function however is called at slightly irregular times, depending on what your OS does in the background and depending on the code you execute each frame. So in advance you never know how much time passes between one function call of love.update and another one.
In order to move around things in a constant speed you have two choices:
1) Try to move things with constant offset. For that you need constant time steps. You can achieve that by measuring the time since the last movement and when it is larger than the desired time step, move the object by a constant distance.
2) Work with variable time steps and adapt the movement offset accordingly.
The second method is the one, you should use. It gives you simpler code and works better.
Code-wise it looks like that:
This is what you have at the moment
Instead you use dt (which tells you how much time passed since update was called the last time) and write
For the second question. You want some part of the code to be performed only at certain time steps, lets say once each second. Use a time counter (define in the love.load()
and update each frame:
The performSomething() will be called once a second.
you misunderstand the concept behind time measurement in a loop.
What you want (i believe) is to move things at a certain speed. The update() function however is called at slightly irregular times, depending on what your OS does in the background and depending on the code you execute each frame. So in advance you never know how much time passes between one function call of love.update and another one.
In order to move around things in a constant speed you have two choices:
1) Try to move things with constant offset. For that you need constant time steps. You can achieve that by measuring the time since the last movement and when it is larger than the desired time step, move the object by a constant distance.
2) Work with variable time steps and adapt the movement offset accordingly.
The second method is the one, you should use. It gives you simpler code and works better.
Code-wise it looks like that:
This is what you have at the moment
Code: Select all
function move()
current_time = love.timer.getMicroTime()
if current_time / 500 == math.floor(current_time / 500) then
x = x + xo
end
end
Code: Select all
function move(dt)
x = x + xo*dt
end
Code: Select all
timeCount = 0
Code: Select all
function love.update(dt)
timeCount = timeCount + dt
if timeCount >= 1 then
timeCount = timeCount-1
performSomething()
end
end
Check out my blog on gamedev
Re: newby wanting some guidence
You should also consider the SpriteBatch object when using tiles. A properly implemented spritebatch can drastically increase performance.
As for benchmarking... it's kind of tough, but you can get a rough estimate by tracking delatime, frames-per-second and memory usage.
One thing to bear in mind is that often tracking performance has a significant impact. For example lots of print and love.graphics.print statements can cause an increase in dt and thus a deterioration in framerate.
I find the best way to judge your programs performance is by simply distributing it, whether it be to friends or other computers you own, and see what values are reported (FPS is a good candidate since your friends are likely to understand it).
Generally speaking you should not have to worry about performance. If it becomes an issue you're most likely doing something very inefficiently or perhaps even completely "wrong". Oh, there's also the odd caveat, such as rendering lots of text, but I did say generally speaking.
Oh, and here's my personal solution to tracking per-entity time values:
Since it doesn't use dt it is bound by real-time, which may or may not be desirable for you. I use this method of timekeeping for several things and find it to be quite elegant, but the previous method works just as well.
As for benchmarking... it's kind of tough, but you can get a rough estimate by tracking delatime, frames-per-second and memory usage.
Code: Select all
love.update = function(dt)
print(dt) --deltatime, time that love.run call took
print(love.timer.getFPS()) --frames-per-second. Not always the best way to judge performance!
print(gcinfo()) --amount of memory used in the llvm
print(love.timer.getMicroTime()) --precision timer. Useful for monitoring/debugging intensive functions and codeblocks
end
I find the best way to judge your programs performance is by simply distributing it, whether it be to friends or other computers you own, and see what values are reported (FPS is a good candidate since your friends are likely to understand it).
Generally speaking you should not have to worry about performance. If it becomes an issue you're most likely doing something very inefficiently or perhaps even completely "wrong". Oh, there's also the odd caveat, such as rendering lots of text, but I did say generally speaking.
Oh, and here's my personal solution to tracking per-entity time values:
Code: Select all
love.load = function()
object = {text = "Bucket", time = love.timer.getTIme(), delay = 1}
end
love.update(dt)
t = love.timer.getTime()
---print "Bucket" every second
if t - object.time > object.delay then
print(object.text)
object.time = t
end
end
Do you recognise when the world won't stop for you? Or when the days don't care what you've got to do? When the weight's too tough to lift up, what do you? Don't let them choose for you, that's on you.
Re: newby wanting some guidence
Thanks all.
Your solution if perfect lafolie.
I got excited when I saw -
object = {text = "Bucket", time = love.timer.getTIme(), delay = 1}
as at first I thought you were attaching a function within an psuedo object. time = function()
That is my next step but I will start another thread.
Your solution if perfect lafolie.
I got excited when I saw -
object = {text = "Bucket", time = love.timer.getTIme(), delay = 1}
as at first I thought you were attaching a function within an psuedo object. time = function()
That is my next step but I will start another thread.
Re: newby wanting some guidence
Also I just noticed in the your draw code you do this:
The code within the if block will always be executed since you explicitly state that the condition evaluates to true. Also you should know that Lua's philosophy allows for some sugar when doing these sort of expressions:
You also do quite a few declarations and calculations in your draw code. It is considered good practice to minimalise the draw operations by doing as few calculations as possible. Ideally your draw code would contain nothing but draw calls and perhaps a few loops. The drawing arguments should be defined and maintained elsewhere (such as in update and initialisation functions).
Code: Select all
local someFlag = false
if someFlag == false then
...
Code: Select all
if not someVar then end
--is equivalent to
if someVar == nil then end
if not someVar == true then end
--in certain contexts it could also replace
if someVar ~= true then end
--checking that variable is 'defined' (not nil)
if someVar then end
Do you recognise when the world won't stop for you? Or when the days don't care what you've got to do? When the weight's too tough to lift up, what do you? Don't let them choose for you, that's on you.
Who is online
Users browsing this forum: No registered users and 0 guests