320 likes | 484 Views
Löve and Lua. based on http://nova-fusion.com/2011/06/14/a-guide-to-getting-started-with-love2d/. Löve. 2D game framework simple to use free. Game Structure. a folder with main.lua, other files
E N D
Löve and Lua • based on http://nova-fusion.com/2011/06/14/a-guide-to-getting-started-with-love2d/
Löve • 2D game framework • simple to use • free
Game Structure • a folder with main.lua, other files • to distribute, just create a zip file of the directory contents, and give the zip file a .love extension: • cd humpy • zip -r ../humpy.love * • ... then you can double click the .love file to run it
Löve’s API • the “love” module is a Lua table, containing • the various other modules (also tables) • audio,image,graphics,mouse, keyboard,physics,etc. • many modules contain classes, eg Image • callbacks are defined in the love module • let your program handle events, draw, update,etc • you don’t have to define all of them, just the ones you need (exist default versions of each (most do nothing))
callbacks in love module • love.load() -- one-time setup • love.draw() -- to render the frame • love.update() -- to update simulation • love.mousepressed(), love.mousereleased() • love.run() -- main loop
~tebo/4849/Love/simple • function love.load() • player={} • player.vx = 10 • player.vy = -30 • player.x = 320 • player.y = 240 • image = love.graphics.newImage("masonic-eye.jpg") • end • function love.update(dt) • player.x = player.x + player.vx * dt • player.y = player.y + player.vy * dt • end • function love.draw() • love.graphics.print( tostring(player.vx), 300,200 ) • love.graphics.print( tostring(player.vy), 350,200 ) • love.graphics.draw ( image, player.x, player.y) • end • function love.mousepressed ( x, y, button ) • if button == 'l' then • player.x = x • player.y = y • end • end
love.graphics • for drawing lines, shapes, text • Image and Drawable objects • reading images and fonts • managing framebuffer • special objects like particle systems
Points • love.graphics.point ( x, y ) --draws a point • love.graphics.setPointSize ( size ) • love.graphics.setPointStyle ( style )
~tebo/4849/Love/stars • function love.load() • stars = {} • max_stars = 100 • for i=1, max_stars do • local x = math.random( 5, love.graphics.getWidth()-5) • local y = math.random( 5, love.graphics.getHeight()-5) • stars[i] = {x, y} • end • love.graphics.setPointSize ( 3 ) • love.graphics.setPointStyle ( "smooth" ) • end • function love.draw() • for i=1, #stars do -- loop through all of our stars • love.graphics.point( stars[i][1], stars[i][2]) -- draw each point • end • end
Lines • love.graphics.line ( x1,y1, x2, y2, ... ) • love.graphics.line (table_of_points) • love.graphics.setLineWidth ( w ) • love.graphics.setLineStyle ( style )
~tebo/4849/Code/Love/lines • function love.load() • points = { 0, 0 } • end • function love.draw() • x, y = love.mouse.getPosition() • love.graphics.setColor ( 255, 0, 0 ) • love.graphics.line ( 320, 240, x, y ) • points[#points + 1] = x • points[#points + 1] = y • love.graphics.setColor ( 0, 255, 0 ) • love.graphics.line ( points ) • end
Drawables • drawable = love.graphics.newImage ( “filename” ) • drawable = love.graphics.newParticleSystem () • love.graphics.draw( drawable, x, y, r, sx, sy, ox, oy )
~tebo/4849/Code/Love/flyeye • function love.load() • skyeye = love.graphics.newImage("masonic-eye.jpg") • width = skyeye:getWidth() • height = skyeye:getHeight() • angle = 0 • rotvel = 10 • end • function love.update(dt) • angle = angle + rotvel * dt • end • function love.draw() • love.graphics.draw( skyeye, 100, 100, math.rad(angle), 1, 1, width / 2, height / 2) • end
love.audio • ‘Source’ object -- can be played • use OpenAL (directional sources, listener) • (not working on mac???) • sounds are “static” (in RAM) or “stream”
noisy • function love.load() • love.graphics.setBackgroundColor ( 255,255,255 ) • music = love.audio.newSource("overbeated.ogg") -- if "static" is omitted, LÖVE will stream the file from disk, good for longer music tracks • music:play() • listener={} • listener.listenerImage = love.graphics.newImage ( "listener.png" ) • listener.w = listener.listenerImage:getWidth() • listener.h = listener.listenerImage:getHeight() • listener.x = 320 • listener.y = 240 • listener.angle = 0 • sound = love.audio.newSource("bing.wav", "static") -- the "static" tells LÖVE to load the file into memory, good for short sound effects • sound:setDirection( 0, 1, 0 ) -- "down" • -- setup listener (not working on macosx at least) • love.audio.setOrientation ( 0,-1,0, 0,0,1 ) -- forward and up vectors • love.audio.setPosition ( listener.x, listener.y, 0 ) • love.audio.setVelocity ( 0, 100, 0 ) • end • function love.mousepressed( x, y, button ) • sound:stop() • -- set source position (doesn't seem to work on macosx?) • sound:setPosition ( x, y, 0 ) • sound:setPitch ( y / 240.0 ) • sound:setVolume ( x / 320.0 ) • sound:play() • end • function love.draw() • love.graphics.setColorMode("replace") • love.graphics.draw(listener.listenerImage, listener.x, listener.y, math.rad(listener.angle), 1, 1, • listener.w/2, listener.h/2) • end
Lua • can run under embedding application (Love) • can run standalone (lua) • good for experimenting, learning
chunks • sequence of lua statements • needs no separator between consecutive statements • line breaks ignored • can be read from interactive console • can be read from a file • both: lua -i filename • starts up console after running chunk from filename
identifiers • string of letters, digits, underscores • starts with letter or underscore • dont’ use names like _VERSION • case sensitive • dont use reserved words: • and end break in repeat while false local return do for nil then else function not true elseif if or until
comments • single line comment: starts with -- (2 hyphens) • block comments • --[[ • --]] • (disable by adding a hyphen at front of opening comment ---[[ is just a single line comment)
Types and Values • Lua is dynamically typed • no type definitions • each value carries a type • 8 basic types: • nil, boolean, number, string, userdata, function, thread, table • the type() function returns a string with the type’s name • print( type(“Hello World”) ) • print ( type(10.4*3))
Nil • a type with a single value, nil • a “non-value” meaning “no useful value” • different from every other value • globals are nil by default (before assignment) • delete a variable by assigning nil to it • return nil
Booleans • two values: true and false • conditionals consider nil and false as false • anything else (including 0, “”) is true
Numbers • double-precision floating-point • no rounding errors with integers < 10^14 • ex) 4 3.1543 6.25e23 100e-3
Strings • sequence of characters • can contain any embedded code, incl zero • immutable - can’t change strings, just create new ones with changes • a = “one string” • b = string.gsub(a, “one”, “another”0 • print (a) • print (b) • can use single or double quotes • can include C-like escape sequences (\n, \t, etc) • can also use [[ and ]] to delimit multi-line strings
strings • any numeric operation applied to a string tries to convert the string to a number • print (“10” + 1) -- prints 11 • if a number is given when a string is expected, lua tries to convert it • print(10 .. 20 ) -- prints 1020 • .. operator is string concatenation • best to do explicit coercion • tonumber(string) • tostring(number) • get string length with the length operator, # • a = “hello” • print(#a)
Tables • associative arrays -- indexed with any value except nil • the ONLY data structure in lua • used for arrays, sets, records, queues, etc. • tables are objects
table examples • a = {} -- creates an empty table • k = “x” • a[k] = 10 • a[20] = “cool” • print(a[“x”]) --> 10 • k = 20 • print(a[k]) --> “cool” • a[“x”] = a[“x”] + 1 • print(a[“x”]) --> 11
tables • tables grow as needed to hold new values • a.name is syntactic sugar for a[“name”] • not a[name] !!! • lua convention: arrays start at 1! • # gives last index (size) of table (doesn’t count holes...) • for i = 1,#a do • print (a[i]) • end
functions • first-class values • can store in variables, • can pass as arguments to other functions • can be returned from functions • “proper lexical scoping” of nested functions
userdata and threads • userdata - for arbitrary C data in lua variables • threads - coroutines(?)