From 4fbbf73aeb39566f73d54e3d42670c7c258e2466 Mon Sep 17 00:00:00 2001 From: the lemons Date: Sun, 21 Aug 2022 20:37:53 -0500 Subject: everything so far basic mechanics and player control have been implemented, but they work very poorly at present. --- Bolvis.lua | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Camera.lua | 24 +++++++++++ Obj.lua | 68 ++++++++++++++++++++++++++++++ apioform.png | Bin 0 -> 645 bytes bolvis.png | Bin 0 -> 133196 bytes conf.lua | 6 +++ game.lua | 43 +++++++++++++++++++ hand-closed.png | Bin 0 -> 8067 bytes hand-open.png | Bin 0 -> 10843 bytes main.lua | 76 ++++++++++++++++++++++++++++++++++ physics.lua | 70 +++++++++++++++++++++++++++++++ stuff.lua | 10 +++++ test.png | Bin 0 -> 41407 bytes utah-teapot.png | Bin 0 -> 75038 bytes 14 files changed, 422 insertions(+) create mode 100644 Bolvis.lua create mode 100644 Camera.lua create mode 100644 Obj.lua create mode 100644 apioform.png create mode 100644 bolvis.png create mode 100644 conf.lua create mode 100644 game.lua create mode 100644 hand-closed.png create mode 100644 hand-open.png create mode 100644 main.lua create mode 100644 physics.lua create mode 100644 stuff.lua create mode 100644 test.png create mode 100644 utah-teapot.png 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 Binary files /dev/null and b/apioform.png differ diff --git a/bolvis.png b/bolvis.png new file mode 100644 index 0000000..8e388d0 Binary files /dev/null and b/bolvis.png 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 Binary files /dev/null and b/hand-closed.png differ diff --git a/hand-open.png b/hand-open.png new file mode 100644 index 0000000..1ad33a9 Binary files /dev/null and b/hand-open.png 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 Binary files /dev/null and b/test.png differ diff --git a/utah-teapot.png b/utah-teapot.png new file mode 100644 index 0000000..a4a7e92 Binary files /dev/null and b/utah-teapot.png differ -- cgit v1.2.3