123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846 |
- --[[
- Copyright (c) 2006-2010 LOVE Development Team
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- --]]
- -- Make sure love table exists.
- if not love then love = {} end
- -- Used for setup:
- love.path = {}
- love.arg = {}
- -- Unparsed arguments:
- argv = {}
- -- Replace any \ with /.
- function love.path.normalslashes(p)
- return string.gsub(p, "\\", "/")
- end
- -- Makes sure there is a slash at the end
- -- of a path.
- function love.path.endslash(p)
- if string.sub(p, string.len(p)-1) ~= "/" then
- return p .. "/"
- else
- return p
- end
- end
- -- Checks whether a path is absolute or not.
- function love.path.abs(p)
- local tmp = love.path.normalslashes(p)
- -- Path is absolute if it starts with a "/".
- if string.find(tmp, "/") == 1 then
- return true
- end
- -- Path is absolute if it starts with a
- -- letter followed by a colon.
- if string.find(tmp, "%a:") == 1 then
- return true
- end
- -- Relative.
- return false
- end
- -- Converts any path into a full path.
- function love.path.getfull(p)
- if love.path.abs(p) then
- return love.path.normalslashes(p)
- end
- local cwd = love.filesystem.getWorkingDirectory()
- cwd = love.path.normalslashes(cwd)
- cwd = love.path.endslash(cwd)
- -- Construct a full path.
- return cwd .. love.path.normalslashes(p)
- end
- -- Returns the leaf of a full path.
- function love.path.leaf(p)
- local a = 1
- local last = p
- while a do
- a = string.find(p, "/", a+1)
- if a then
- last = string.sub(p, a+1)
- end
- end
- return last
- end
- -- Finds the key in the table with the lowest integral index. The lowest
- -- will typically the executable, for instance "lua5.1.exe".
- function love.arg.getLow(a)
- local m = math.huge
- for k,v in pairs(a) do
- if k < m then
- m = k
- end
- end
- return a[m]
- end
- love.arg.options = {
- console = { a = 0 },
- game = { a = 1 }
- }
- function love.arg.parse_option(m, i)
- m.set = true
- if m.a > 0 then
- m.arg = {}
- for j=i,i+m.a-1 do
- table.insert(m.arg, arg[j])
- i = j
- end
- end
- return i
- end
- function love.arg.parse_options()
- local game
- local argc = #arg
- for i=1,argc do
- -- Look for options.
- local s, e, m = string.find(arg[i], "%-%-(.+)")
- if m and love.arg.options[m] then
- i = love.arg.parse_option(love.arg.options[m], i+1)
- elseif not game then
- game = i
- end
- end
- if not love.arg.options.game.set then
- love.arg.parse_option(love.arg.options.game, game or 0)
- end
- end
- function love.createhandlers()
- -- Standard callback handlers.
- love.handlers = {
- kp = function (b, u)
- if love.keypressed then love.keypressed(b, u) end
- end,
- kr = function (b)
- if love.keyreleased then love.keyreleased(b) end
- end,
- mp = function (x,y,b)
- if love.mousepressed then love.mousepressed(x,y,b) end
- end,
- mr = function (x,y,b)
- if love.mousereleased then love.mousereleased(x,y,b) end
- end,
- jp = function (j,b)
- if love.joystickpressed then love.joystickpressed(j,b) end
- end,
- jr = function (j,b)
- if love.joystickreleased then love.joystickreleased(j,b) end
- end,
- q = function ()
- return
- end,
- }
- end
- -- This can't be overriden.
- function love.boot()
- -- This is absolutely needed.
- require("love")
- require("love.filesystem")
- love.arg.parse_options()
- local o = love.arg.options
- local abs_arg0 = love.path.getfull(love.arg.getLow(arg))
- love.filesystem.init(abs_arg0)
- -- Is this one of those fancy "fused" games?
- local can_has_game = pcall(love.filesystem.setSource, abs_arg0)
- if not can_has_game and o.game.set and o.game.arg[1] then
- local full_source = love.path.getfull(o.game.arg[1])
- local leaf = love.path.leaf(full_source)
- love.filesystem.setIdentity(leaf)
- can_has_game = pcall(love.filesystem.setSource, full_source)
- end
- if can_has_game and not (love.filesystem.exists("main.lua") or love.filesystem.exists("conf.lua")) then
- no_game_code = true
- end
- if not can_has_game then
- love.filesystem = nil
- love.nogame()
- end
- end
- function love.init()
- -- Create default configuration settings.
- local c = {
- title = "Untitled",
- author = "Unnamed",
- version = 0,
- screen = {
- width = 800,
- height = 600,
- fullscreen = false,
- vsync = true,
- fsaa = 0,
- },
- modules = {
- event = true,
- keyboard = true,
- mouse = true,
- timer = true,
- joystick = true,
- image = true,
- graphics = true,
- audio = true,
- physics = true,
- sound = true,
- font = true,
- thread = true,
- },
- console = false, -- Only relevant for windows.
- }
- -- If config file exists, load it and allow it to update config table.
- if not love.conf and love.filesystem and love.filesystem.exists("conf.lua") then
- require("conf.lua")
- end
- -- Yes, conf.lua might not exist, but there are other ways of making
- -- love.conf appear, so we should check for it anyway.
- if love.conf then
- local ok, err = pcall(love.conf, c)
- if not ok then
- print(err)
- -- continue
- end
- end
- if love.arg.options.console.set then
- c.console = true
- end
- -- Gets desired modules.
- for k,v in pairs(c.modules) do
- if v then
- require("love." .. k)
- end
- end
- if love.event then
- love.createhandlers()
- end
- -- Setup screen here.
- if c.screen and c.modules.graphics then
- if love.graphics.checkMode(c.screen.width, c.screen.height, c.screen.fullscreen) then
- assert(love.graphics.setMode(c.screen.width, c.screen.height, c.screen.fullscreen, c.screen.vsync, c.screen.fsaa), "Could not set screen mode")
- end
- love.graphics.setCaption(c.title)
- end
- if love.filesystem and love.filesystem.exists("main.lua") then require("main.lua") end
- if no_game_code then
- error("No code to run\nYour game might be packaged incorrectly\nMake sure main.lua is at the top level of the zip")
- end
- -- Console hack
- if c.console and love._openConsole then
- love._openConsole()
- end
- end
- function love.run()
- if love.load then love.load(arg) end
- local dt = 0
- -- Main loop time.
- while true do
- if love.timer then
- love.timer.step()
- dt = love.timer.getDelta()
- end
- if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
- if love.graphics then
- love.graphics.clear()
- if love.draw then love.draw() end
- end
- -- Process events.
- if love.event then
- for e,a,b,c in love.event.poll() do
- if e == "q" then
- if love.audio then
- love.audio.stop()
- end
- return
- end
- love.handlers[e](a,b,c)
- end
- end
- if love.timer then love.timer.sleep(1) end
- if love.graphics then love.graphics.present() end
- end
- end
- -----------------------------------------------------------
- -- Default screen.
- -----------------------------------------------------------
- function love.nogame()
- love.load = function()
- major, minor, rev = string.match(love._version_string, "(%d)%.(%d)%.(%d)")
- if not major then major = 0 end
- if not minor then minor = 0 end
- if not rev then rev = 0 end
- love.graphics.setBackgroundColor(0x84, 0xca, 0xff)
- names = {
- "wheel_0",
- "wheel_1",
- "wheel_2",
- "wheel_3",
- "wheel_4",
- "wheel_5",
- "wheel_6",
- "wheel_7",
- "wheel_8",
- "wheel_9",
- "belt_tooth",
- "belt_track",
- "turret_body",
- "turret_cannon",
- "star",
- "knoll01",
- "knoll02",
- "knoll03",
- "knoll04",
- "tree01",
- "bubble",
- "love",
- }
- local decode = function(file)
- return love.graphics.newImage(love.image.newImageData(file))
- end
- images = {}
- for i,v in pairs(names) do
- images[v] = decode(love["_"..v.."_png"])
- end
- pools = {
- {
- images.knoll01,
- images.knoll02,
- },
- {
- images.knoll03,
- images.knoll04,
- },
- }
- List = {}
- List.__index = List
- List.new = function(self)
- local o = {
- head = nil,
- }
- setmetatable(o, List)
- return o
- end
- List.update = function(self, dt)
- local n = self.head
- while n do
- n:update(dt)
- n = n.next
- end
- end
- List.draw = function(self)
- local n = self.head
- while n do
- n:draw()
- n = n.next
- end
- end
- Node = {}
- Node.__index = Node
- Node.new = function(self, object)
- local o = {
- next = nil,
- }
- setmetatable(o, List)
- return o
- end
- Node.insert = function(self, list)
- local h = list.head
- list.head = self
- self.next = h
- end
- Node.remove = function(self)
- parent.next = self.next
- end
- Object = Node:new()
- Object.__index = Object
- setmetatable(Object, Node)
- Object.new = function(self)
- local o = {
- image = nil,
- x = 0,
- y = 0,
- dx = -400,
- dy = 0,
- scale = 1,
- r = 0,
- duration = 30,
- passed = 0,
- t = 0,
- alpha = 255
- }
- setmetatable(o, Object)
- return o
- end
- Object.update = function(self, dt)
- self.passed = self.passed + dt
- while self.passed > self.duration do
- self.passed = self.passed - self.duration
- end
- self.t = self.passed/self.duration
- end
- Object.draw = function(self)
- if self.image then
- local x = self.x + self.dx*self.t
- local y = self.y + self.dy*self.t
- local r = self.r*self.t
- love.graphics.setColor(255, 255, 255, self.alpha)
- love.graphics.draw(self.image, x, y, r, self.scale)
- love.graphics.setColor(255, 255, 255, 255)
- end
- end
- Tree = Object:new()
- Tree.__index = Tree
- setmetatable(Tree, Object)
- Tree.new = function(self)
- local o = {}
- o.image = images.tree01
- o.x = 800 + math.random(0, 800)
- o.y = 300 + math.random(0, 40)
- o.xt = -200;
- o.dx = o.xt - o.x
- o.speed = 100
- o.duration = -o.dx/o.speed
- setmetatable(o, Tree)
- return o
- end
- Star = Object:new()
- Star.__index = Star
- setmetatable(Star, Object)
- Star.new = function(self, speed, scale)
- local o = {}
- o.image = images.star
- o.x = 800 + math.random(0, 800)
- o.y = -200 + math.random(0, 300)
- o.xt = -50;
- o.dy = 400
- o.dx = o.xt - o.x
- o.speed = speed
- o.scale = scale
- o.duration = -o.dx/o.speed
- o.r = math.pi * 5
- o.alpha = 100 + math.random(155)
- setmetatable(o, Star)
- return o
- end
- Knoll = Object:new()
- Knoll.__index = Knoll
- setmetatable(Knoll, Object)
- Knoll.new = function(self, pool, var, speed)
- local o = {}
- o.image = pools[pool][math.random(1, #pools[pool])]
- o.x = 800 + math.random(0, 800)
- o.y = 300 + var - math.random(0, var*2)
- o.xt = -200;
- o.dx = o.xt - o.x
- o.speed = speed
- o.duration = -o.dx/o.speed
- setmetatable(o, Star)
- return o
- end
- Belt = Object:new()
- Belt.__index = Belt
- setmetatable(Belt, Object)
- Belt.new = function(self, n)
- local o = {}
- o.r = 30
- o.d = o.r*2
- o.half_c = math.pi*o.r
- o.c = 2*o.half_c
- o.x = 200
- o.y = 300
- o.th = 1
- o.ta = 1
- o.w = o.th*o.half_c
- o.total = o.th*2+o.ta*2
- o.teeth = {}
- for i=0,n-1 do
- local b = { x = 0, y = 0, t = (o.total/n)*i }
- table.insert(o.teeth, b)
- end
- setmetatable(o, Belt)
- return o
- end
- Belt.update = function(self, dt)
- for i,b in ipairs(self.teeth) do
- b.t = b.t + dt
- if b.t < self.th then
- local t = b.t
- b.x = self.x + self.w * (t/self.th)
- b.y = self.y
- elseif b.t < self.th + self.ta then
- local t = (self.th + self.ta - b.t)
- b.x = self.x + self.w + math.cos(-math.pi*t + math.pi/2)*self.r
- b.y = self.y + self.r + math.sin(-math.pi*t + math.pi/2)*self.r
- elseif b.t < self.th*2 + self.ta then
- local t = (b.t - self.th*2 + self.ta)/self.th
- b.x = self.x + self.w * (2-t)
- b.y = self.y + self.d
- elseif b.t < self.total then
- local t = (self.th*2 + self.ta - b.t)
- b.x = self.x + math.cos(-math.pi*t + math.pi/2)*self.r
- b.y = self.y + self.r + math.sin(-math.pi*t + math.pi/2)*self.r
- else
- b.t = b.t - self.total
- end
- end
- end
- Belt.draw = function(self)
- for i,b in ipairs(self.teeth) do
- love.graphics.draw(images.belt_tooth, b.x, b.y)
- end
- end
- Tank = Object:new()
- Tank.__index = Tank
- setmetatable(Tank, Object)
- Tank.new = function(self)
- local o = {}
- o.x = 200
- o.y = 490
- o.i = 49
- o.belt = Belt:new(30)
- o.belt.x = o.x-7
- o.belt.y = o.y-37
- o.angle = 0
- setmetatable(o, Tank)
- return o
- end
- Tank.update = function(self, dt)
- self.angle = self.angle + dt * math.pi/2
- self.belt:update(dt)
- end
- Tank.draw = function(self)
- love.graphics.draw(images.turret_cannon, self.x+30, self.y-80)
- love.graphics.draw(images.turret_body, self.x-12, self.y-110)
- love.graphics.draw(images.belt_track, self.belt.x-74, self.belt.y-28)
- love.graphics.draw(images["wheel_"..tostring(major)], self.x, self.y, self.angle, 1, 1, 32, 32)
- love.graphics.draw(images["wheel_"..tostring(minor)], self.x+self.i, self.y, self.angle, 1, 1, 32, 32)
- love.graphics.draw(images["wheel_"..tostring(rev)], self.x+self.i*2, self.y, self.angle, 1, 1, 32, 32)
- self.belt:draw()
- end
- Bubble = Object:new()
- Bubble.__index = Bubble
- setmetatable(Bubble, Object)
- Bubble.new = function(self)
- local o = {}
- o.x = 240
- o.y = 190
- o.angle = 0
- setmetatable(o, Bubble)
- return o
- end
- Bubble.update = function(self, dt)
- self.angle = self.angle + dt*5
- end
- Bubble.draw = function(self)
- local yv = math.sin(self.angle)*5
- love.graphics.draw(images.bubble, self.x, self.y+yv)
- love.graphics.draw(images.love, self.x+8, self.y+yv+95)
- end
- timers = {}
- Timer = {}
- Timer.__index = Timer
- Timer.spawn = function(self, tick, f)
- local o = {
- passed = 0,
- tick = tick,
- f = f
- }
- setmetatable(o, Timer)
- table.insert(timers, o)
- end
- Timer.update = function(self, dt)
- self.passed = self.passed + dt
- while self.passed > self.tick do
- self.passed = self.passed - self.tick
- self.f()
- end
- end
- lists = {
- b = List:new(),
- f = List:new()
- }
- do
- local t = Bubble:new()
- t:insert(lists.f)
- end
- do
- local t = Tank:new()
- t:insert(lists.f)
- end
- for i=1,3 do
- local t = Tree:new(50, 300)
- t:insert(lists.b)
- end
- for i=1,2 do
- local t = Knoll:new(1, 50, 100)
- t:insert(lists.b)
- end
- for i=1,40 do
- local t = Star:new(100, 1)
- t:insert(lists.b)
- end
- for i=1,5 do
- local t = Knoll:new(2, 100, 50)
- t:insert(lists.b)
- end
- for i,v in pairs(lists) do
- v:update(10)
- end
- end
- love.update = function(dt)
- for i,v in ipairs(timers) do v:update(dt) end
- for i,v in pairs(lists) do
- v:update(dt)
- end
- love.timer.sleep(10)
- end
- love.draw = function()
- lists.b:draw()
- -- Ground
- love.graphics.setColor(146, 201, 87)
- love.graphics.rectangle("fill", 0, 530, 800, 70)
- love.graphics.setColor(205, 227, 161)
- love.graphics.rectangle("fill", 0, 520, 800, 10)
- love.graphics.setColor(255, 255, 255)
- lists.f:draw()
- end
- love.conf = function(t)
- t.title = "*Tank* you for using LOVE " .. love._version_string .. " (" .. love._version_codename .. ")"
- t.modules.audio = false
- t.modules.sound = false
- t.modules.physics = false
- t.modules.joystick = false
- t.modules.native = false
- t.modules.font = false
- end
- end
- -----------------------------------------------------------
- -- Error screen.
- -----------------------------------------------------------
- local debug = debug
- local function error_printer(msg, layer)
- print((debug.traceback("Error: " .. msg, 1+(layer or 1)):gsub("\n[^\n]+$", "")))
- end
- function love.errhand(msg)
- error_printer(msg, 2)
- if not love.graphics or not love.event or not love.graphics.isCreated() then
- return
- end
- -- Load.
- love.graphics.setScissor()
- love.graphics.setBackgroundColor(89, 157, 220)
- local font = love.graphics.newFont(love._vera_ttf, 14)
- love.graphics.setFont(font)
- love.graphics.setColor(255, 255, 255, 255)
- local trace = debug.traceback()
- love.graphics.clear()
- local err = {}
- table.insert(err, "Error\n")
- table.insert(err, msg.."\n\n")
- for l in string.gmatch(trace, "(.-)\n") do
- if not string.match(l, "boot.lua") then
- l = string.gsub(l, "stack traceback:", "Traceback\n")
- table.insert(err, l)
- end
- end
- local p = table.concat(err, "\n")
- p = string.gsub(p, "\t", "")
- p = string.gsub(p, "%[string \"(.-)\"%]", "%1")
- local function draw()
- love.graphics.clear()
- love.graphics.printf(p, 70, 70, love.graphics.getWidth() - 70)
- love.graphics.present()
- end
- draw()
- local e, a, b, c
- while true do
- e, a, b, c = love.event.wait()
- if e == "q" then
- return
- end
- if e == "kp" and a == "escape" then
- return
- end
- draw()
- end
- end
- -----------------------------------------------------------
- -- The root of all calls.
- -----------------------------------------------------------
- local result = xpcall(love.boot, error_printer)
- if not result then return end
- local result = xpcall(love.init, love.errhand)
- if not result then return end
- local result = xpcall(love.run, love.errhand)
- if not result then return end
|