summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2022-08-21 20:37:53 -0500
committerthe lemons <citrons@mondecitronne.com>2022-08-21 20:37:53 -0500
commit4fbbf73aeb39566f73d54e3d42670c7c258e2466 (patch)
tree41bef03c3547c69b8e703b068da4d84c8df1ce31
everything so far
basic mechanics and player control have been implemented, but they work very poorly at present.
-rw-r--r--Bolvis.lua125
-rw-r--r--Camera.lua24
-rw-r--r--Obj.lua68
-rw-r--r--apioform.pngbin0 -> 645 bytes
-rw-r--r--bolvis.pngbin0 -> 133196 bytes
-rw-r--r--conf.lua6
-rw-r--r--game.lua43
-rw-r--r--hand-closed.pngbin0 -> 8067 bytes
-rw-r--r--hand-open.pngbin0 -> 10843 bytes
-rw-r--r--main.lua76
-rw-r--r--physics.lua70
-rw-r--r--stuff.lua10
-rw-r--r--test.pngbin0 -> 41407 bytes
-rw-r--r--utah-teapot.pngbin0 -> 75038 bytes
14 files changed, 422 insertions, 0 deletions
diff --git a/Bolvis.lua b/Bolvis.lua
new file mode 100644
index 0000000..7f7f0e9
--- /dev/null
+++ b/Bolvis.lua
@@ -0,0 +1,125 @@
+local game = require 'game'
+local physics = require 'physics'
+local Camera = require 'Camera'
+
+local Bolvis = physics.Object:extend()
+Bolvis.sprite = love.graphics.newImage("bolvis.png", {dpiscale = 5})
+Bolvis.z = 50
+
+local Hand = game.Object:extend()
+Hand.sprite_open = love.graphics.newImage("hand-open.png", {dpiscale = 3.5})
+Hand.sprite_closed = love.graphics.newImage("hand-closed.png", {dpiscale = 3.5})
+Hand.max_speed = 10
+Hand.z = 49
+
+function Bolvis:new(pos, rotation)
+ physics.Object.new(self, pos, rotation, nil, 'dynamic')
+ self.shape = love.physics.newRectangleShape(90, 90)
+ self.fixture = love.physics.newFixture(self.body, self.shape)
+ self.fixture:setRestitution(0.2)
+ self.fixture:setDensity(20)
+ self.hand = Hand(self)
+ self.camera = Camera()
+ self.camera:follow(self)
+end
+
+function Bolvis:update()
+ self.body:setAngle(0)
+ physics.Object.update(self)
+end
+
+function Hand:new(bolvis)
+ game.Object.new(self)
+ self.offset = {100, -100}
+ self.bolvis = bolvis
+ self.sprite = self.sprite_open
+end
+
+function Hand:angle()
+ local x, y = unpack(self.pos)
+ local bx, by = unpack(self.bolvis.pos)
+ local ox, oy = x - bx, y - by
+ local a = math.atan(oy / math.abs(ox)) + math.pi / 2
+ if ox < 0 then a = -a end
+ return a
+end
+
+local function clamp(n, max, min)
+ return math.max(math.min(n, max), min)
+end
+
+function Hand:update()
+ self.rot = self:angle()
+ if not self.grab_joint then
+ self.pos[1] = self.bolvis.pos[1] + self.offset[1]
+ self.pos[2] = self.bolvis.pos[2] + self.offset[2]
+ else
+ self.pos = {self.grabbed.body:getWorldPoint(unpack(self.grab_pos))}
+ end
+end
+
+function Hand:present_offset()
+ local x, y = unpack(self.pos)
+ local bx, by = unpack(self.bolvis.pos)
+ return x - bx, y - by
+end
+
+function Hand:mousemoved(_, _, dx, dy)
+ dx = clamp(dx, self.max_speed, -self.max_speed)
+ dy = clamp(dy, self.max_speed, -self.max_speed)
+ self.offset[1] = clamp(self.offset[1] + dx, 1920 / 2, -1920 / 2)
+ self.offset[2] = clamp(self.offset[2] + dy, 1080 / 2, -1080 / 2)
+ if self.grab_joint then
+ local x, y = unpack(self.offset)
+ self.grab_joint:setLinearOffset(x + self.grab_pos[1], y + self.grab_pos[2])
+ end
+end
+
+function Hand:mousepressed(_, _, button)
+ if button == 1 then
+ self.sprite = self.sprite_closed
+ local grabbed
+ for o in pairs(game.all_objects) do
+ if o.fixture then
+ if o.fixture:testPoint(unpack(self.pos)) then
+ if o ~= self.bolvis then
+ self.grabbed = o
+ break
+ end
+ end
+ end
+ end
+ if self.grabbed then
+ local x1, y1 = unpack(self.bolvis.pos)
+ local x2, y2 = unpack(self.bolvis.pos)
+ self.grab_joint = love.physics.newMotorJoint(
+ self.bolvis.body, self.grabbed.body, 0.5, true)
+ self.grab_joint:setMaxForce(500)
+ self.grab_pos = {self.grabbed.body:getLocalPoint(unpack(self.pos))}
+ end
+ end
+end
+
+function Hand:mousereleased(_, _, button)
+ if button == 1 then
+ self.sprite = self.sprite_open
+ if self.grab_joint then
+ self.grabbed = nil
+ self.grab_joint:destroy()
+ self.grab_joint = nil
+ end
+ self.offset = {self:present_offset()}
+ end
+end
+
+function Hand:draw()
+ local x1, y1 = unpack(self.bolvis.pos)
+ local x2, y2 = unpack(self.pos)
+ love.graphics.setColor(1, 0.8, 0.9)
+ love.graphics.setLineWidth(15)
+ love.graphics.line(x1, y1, x2, y2)
+ love.graphics.setColor(1, 1, 1)
+ game.Object.draw(self)
+end
+
+return Bolvis
diff --git a/Camera.lua b/Camera.lua
new file mode 100644
index 0000000..8a12fa8
--- /dev/null
+++ b/Camera.lua
@@ -0,0 +1,24 @@
+local game = require 'game'
+
+local Camera = game.Object:extend()
+
+function Camera:use()
+ local x, y = unpack(self.pos)
+ local scale = 1 / self.scale
+ local transform = love.math.newTransform(
+ -x + 1920 / 2, -y + 1080 / 2, -self.rot, scale, scale)
+ love.graphics.applyTransform(transform)
+end
+
+function Camera:follow(obj)
+ self.following = obj
+end
+
+function Camera:update(dt)
+ if self.following then
+ self.pos[1] = self.following.pos[1]
+ self.pos[2] = self.following.pos[2]
+ end
+end
+
+return Camera
diff --git a/Obj.lua b/Obj.lua
new file mode 100644
index 0000000..cbd6f81
--- /dev/null
+++ b/Obj.lua
@@ -0,0 +1,68 @@
+--
+-- classic
+--
+-- Copyright (c) 2014, rxi
+--
+-- This module is free software; you can redistribute it and/or modify it under
+-- the terms of the MIT license. See LICENSE for details.
+--
+
+
+local Object = {}
+Object.__index = Object
+
+
+function Object:new()
+end
+
+
+function Object:extend()
+ local cls = {}
+ for k, v in pairs(self) do
+ if k:find("__") == 1 then
+ cls[k] = v
+ end
+ end
+ cls.__index = cls
+ cls.super = self
+ setmetatable(cls, self)
+ return cls
+end
+
+
+function Object:implement(...)
+ for _, cls in pairs({...}) do
+ for k, v in pairs(cls) do
+ if self[k] == nil and type(v) == "function" then
+ self[k] = v
+ end
+ end
+ end
+end
+
+
+function Object:is(T)
+ local mt = getmetatable(self)
+ while mt do
+ if mt == T then
+ return true
+ end
+ mt = getmetatable(mt)
+ end
+ return false
+end
+
+
+function Object:__tostring()
+ return "Object"
+end
+
+
+function Object:__call(...)
+ local obj = setmetatable({}, self)
+ obj:new(...)
+ return obj
+end
+
+
+return Object
diff --git a/apioform.png b/apioform.png
new file mode 100644
index 0000000..cc04a1a
--- /dev/null
+++ b/apioform.png
Binary files differ
diff --git a/bolvis.png b/bolvis.png
new file mode 100644
index 0000000..8e388d0
--- /dev/null
+++ b/bolvis.png
Binary files differ
diff --git a/conf.lua b/conf.lua
new file mode 100644
index 0000000..ec855bf
--- /dev/null
+++ b/conf.lua
@@ -0,0 +1,6 @@
+function love.conf(t)
+ t.identity = "bolvis"
+ t.window.title = "bolvis the spintholeom"
+ t.window.icon = "bolvis.png"
+ t.window.resizable = true
+end
diff --git a/game.lua b/game.lua
new file mode 100644
index 0000000..16b1e06
--- /dev/null
+++ b/game.lua
@@ -0,0 +1,43 @@
+local Obj = require 'Obj'
+
+local M = {}
+
+M.all_objects = {}
+
+M.Object = Obj:extend()
+M.Object.z = 0
+
+function M.Object:new(pos, rotation, scale)
+ self.pos = pos or {0, 0, 0}
+ self.rot = rotation or 0
+ self.scale = scale or 1
+ self:enable()
+end
+
+function M.Object:enable()
+ M.all_objects[self] = true
+end
+
+function M.Object:disable()
+ M.all_objects[self] = nil
+end
+
+function M.Object:update()
+end
+
+function M.Object:draw()
+ if self.sprite then
+ local x, y = unpack(self.pos)
+ local w, h = self.sprite:getDimensions()
+ ox = (w * self.scale) / 2
+ oy = (h * self.scale) / 2
+ love.graphics.draw(
+ self.sprite, x, y, self.rot, self.scale, self.scale, ox, oy)
+ end
+end
+
+function M.Object:visible()
+ return not self.hidden
+end
+
+return M
diff --git a/hand-closed.png b/hand-closed.png
new file mode 100644
index 0000000..c6df3d3
--- /dev/null
+++ b/hand-closed.png
Binary files differ
diff --git a/hand-open.png b/hand-open.png
new file mode 100644
index 0000000..1ad33a9
--- /dev/null
+++ b/hand-open.png
Binary files differ
diff --git a/main.lua b/main.lua
new file mode 100644
index 0000000..6d3fadc
--- /dev/null
+++ b/main.lua
@@ -0,0 +1,76 @@
+local game = require 'game'
+local physics = require 'physics'
+local Bolvis = require 'Bolvis'
+local stuff = require 'stuff'
+
+local camera
+
+function love.load()
+ love.mouse.setRelativeMode(true)
+
+ local bolvis = Bolvis({960, 540})
+ camera = bolvis.camera
+
+ stuff.Teapot({400, 540}, 0)
+ stuff.Apioform({600, 540}, 0)
+ stuff.TestPlatform({960, 300})
+ stuff.TestPlatform({960, 700})
+ stuff.TestPlatform({430, 700})
+ stuff.TestPlatform({1490, 700})
+end
+
+local function screen_transform()
+ local ww, wh = love.graphics.getDimensions()
+ local sw, sh = 1920, 1080
+ local scalex, scaley = ww / sw, wh / sh
+ local scale
+ if scalex * sh < wh then
+ scale = scalex
+ else
+ scale = scaley
+ end
+ local dimx, dimy = sw * scale, sh * scale
+ local x, y = ww / 2 - dimx / 2, wh / 2 - dimy / 2
+ return love.math.newTransform(x, y, 0, scale, scale)
+end
+
+local to_draw
+local events = {}
+
+local function event(name)
+ love[name] = function(...)
+ table.insert(events, {type = name, ...})
+ end
+end
+
+function love.update(dt)
+ to_draw = {}
+ physics.world:update(dt, 20, 20)
+ for o in pairs(game.all_objects) do
+ for _, e in ipairs(events) do
+ if o[e.type] then
+ o[e.type](o, unpack(e))
+ end
+ end
+ o:update(dt)
+ if o:visible() then
+ table.insert(to_draw, o)
+ end
+ end
+ events = {}
+end
+
+function love.draw()
+ love.graphics.applyTransform(screen_transform())
+ camera:use()
+ table.sort(to_draw, function(a, b) return a.z < b.z end)
+ for _, o in ipairs(to_draw) do
+ o:draw()
+ end
+end
+
+event "mousemoved"
+event "mousepressed"
+event "mousereleased"
+event "keypressed"
+event "keyreleased"
diff --git a/physics.lua b/physics.lua
new file mode 100644
index 0000000..336a7c2
--- /dev/null
+++ b/physics.lua
@@ -0,0 +1,70 @@
+local game = require 'game'
+
+local M = {}
+
+love.physics.setMeter(300)
+M.world = love.physics.newWorld(0, 2000)
+M.Object = game.Object:extend()
+
+local bodies = {}
+setmetatable(bodies, {__mode = 'kv'})
+function M.body_object(body)
+ return bodies[body]
+end
+
+function M.Object:new(pos, rotation, scale, type)
+ game.Object.new(self, pos, rotation, scale)
+ local x, y = unpack(self.pos)
+ self.body = love.physics.newBody(M.world, x, y, type)
+ self.body:setAngle(self.rot)
+ bodies[self.body] = self
+end
+
+function M.Object:enable()
+ game.Object.enable(self)
+ if body then
+ self.body:setActive(true)
+ end
+end
+
+function M.Object:disable()
+ game.Object.disable(self)
+ self.body:setActive(false)
+end
+
+function M.Object:update()
+ local x, y = self.body:getWorldPoint(0, 0)
+ self.pos[1], self.pos[2] = x, y
+ self.rot = self.body:getAngle()
+end
+
+local sprites = {}
+setmetatable(sprites, {__mode = 'v'})
+
+function M.simple(sprite, shape, body_type, restitution)
+ local class = M.Object:extend()
+ if type(sprite) == 'string' then
+ sprite = sprites[sprite] or love.graphics.newImage(sprite, {dpiscale = 2})
+ end
+ class.sprite = sprite
+
+ local w, h = sprite:getDimensions()
+ function class:new(pos, rotation, scale)
+ M.Object.new(self, pos, rotation, scale, body_type or 'dynamic')
+
+ if not shape or shape == 'rect' then
+ self.shape = love.physics.newRectangleShape(w, h)
+ elseif shape == 'circle' then
+ self.shape = love.physics.newCircleShape(w / 2)
+ else
+ self.shape = love.physics.newPolygonShape(unpack(shape))
+ end
+ self.fixture = love.physics.newFixture(self.body, self.shape)
+ if restitution then
+ self.fixture:setRestitution(restitution)
+ end
+ end
+ return class
+end
+
+return M
diff --git a/stuff.lua b/stuff.lua
new file mode 100644
index 0000000..8fde7d1
--- /dev/null
+++ b/stuff.lua
@@ -0,0 +1,10 @@
+local game = require 'game'
+local physics = require 'physics'
+
+local M = {}
+
+M.TestPlatform = physics.simple("test.png", 'rect', 'static')
+M.Teapot = physics.simple("utah-teapot.png")
+M.Apioform = physics.simple("apioform.png")
+
+return M
diff --git a/test.png b/test.png
new file mode 100644
index 0000000..864afbf
--- /dev/null
+++ b/test.png
Binary files differ
diff --git a/utah-teapot.png b/utah-teapot.png
new file mode 100644
index 0000000..a4a7e92
--- /dev/null
+++ b/utah-teapot.png
Binary files differ