diff options
author | the lemons <citrons@mondecitronne.com> | 2022-08-21 20:37:53 -0500 |
---|---|---|
committer | the lemons <citrons@mondecitronne.com> | 2022-08-21 20:37:53 -0500 |
commit | 4fbbf73aeb39566f73d54e3d42670c7c258e2466 (patch) | |
tree | 41bef03c3547c69b8e703b068da4d84c8df1ce31 |
everything so far
basic mechanics and player control have been implemented, but they work
very poorly at present.
-rw-r--r-- | Bolvis.lua | 125 | ||||
-rw-r--r-- | Camera.lua | 24 | ||||
-rw-r--r-- | Obj.lua | 68 | ||||
-rw-r--r-- | apioform.png | bin | 0 -> 645 bytes | |||
-rw-r--r-- | bolvis.png | bin | 0 -> 133196 bytes | |||
-rw-r--r-- | conf.lua | 6 | ||||
-rw-r--r-- | game.lua | 43 | ||||
-rw-r--r-- | hand-closed.png | bin | 0 -> 8067 bytes | |||
-rw-r--r-- | hand-open.png | bin | 0 -> 10843 bytes | |||
-rw-r--r-- | main.lua | 76 | ||||
-rw-r--r-- | physics.lua | 70 | ||||
-rw-r--r-- | stuff.lua | 10 | ||||
-rw-r--r-- | test.png | bin | 0 -> 41407 bytes | |||
-rw-r--r-- | utah-teapot.png | bin | 0 -> 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 @@ -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 Binary files differnew file mode 100644 index 0000000..cc04a1a --- /dev/null +++ b/apioform.png diff --git a/bolvis.png b/bolvis.png Binary files differnew file mode 100644 index 0000000..8e388d0 --- /dev/null +++ b/bolvis.png 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 Binary files differnew file mode 100644 index 0000000..c6df3d3 --- /dev/null +++ b/hand-closed.png diff --git a/hand-open.png b/hand-open.png Binary files differnew file mode 100644 index 0000000..1ad33a9 --- /dev/null +++ b/hand-open.png 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 Binary files differnew file mode 100644 index 0000000..864afbf --- /dev/null +++ b/test.png diff --git a/utah-teapot.png b/utah-teapot.png Binary files differnew file mode 100644 index 0000000..a4a7e92 --- /dev/null +++ b/utah-teapot.png |