HDictus / breezefield

a physics library wrapper for love2d
MIT License
76 stars 5 forks source link

update documentation: how to implement breezefield in classes/objects #23

Closed ghost closed 6 months ago

ghost commented 6 months ago

I use classic for classes from rxi

on call functions on collision:

little_ball = {}
little_ball.__index = little_ball
setmetatable(little_ball, bf.Collider) -- this is important
-- otherwise setting the new object's metatable to little_ball overwrites

function spawn_random_ball()
   little_ball.new(love.math.random(love.graphics.getWidth()), 0)
end

function little_ball.new(x, y)
   local n = bf.Collider.new(world, 'Circle', x, y, 5)
   setmetatable(n, little_ball)
   return n
end

bf.Collider is deprecated, and world:newCollider complains that it is not being called as a function

the above example doesn't work with classic:


Collider = Object:extend()

Collider.__index = Collider
setmetatable(Collider, bf.Collider)

function Collider:new(position, size, t)
    if t then
        if t.shape then
            local shape = t.shape
            else
            local shape = 'Rectangle'
        end
    else
        shape = 'Rectangle'
    end
    local n = world:newCollider(shape, position.x or game.xc, position.y or game.yc, size.x or 36, size.y or 36)
    setmetatable(n, Collider)
    return n
end

it complains that the extend method of classic is not found, even tho I defined __index to Collider, then I try:

Collider = Object:extend()

function Collider:new(position, size, t)
    self.__index = self
    setmetatable(self, bf.Collider)
    if t then
        if t.shape then
            self.shape = t.shape
            else
            self.shape = 'Rectangle'
        end
    else
        self.shape = 'Rectangle'
    end

    local n = world:newCollider(self.shape, {position.x or game.xc, position.y or game.yc, size.x or 36, size.y or 36})
    setmetatable(n, Collider)
    return n
end

which seems like a way, but it complains that at line 5, setmetatable(self, bf.Collider), it fails to find index collider, which now seems like a breezefield's flaw.

before this all, I tried making the world:newCollider as self.collider in Collider. geez, this is getting repetitive. well, turns out I can't access self when handling collisions:

Player = Collider:extend()
function Player:new(t)
    self:set_self(t) -- function to set all properties of t to self
    Player.super:new(self.position, self.size, self.shape)
-- important notice that I am keeping information in Player, not Player.collider
    self.SPEED = 7070
    self.dir = 1
    self.velocity = vector.new(0, 0)
    self.velocity.x = self.SPEED * self.dir
    self.collider:setFixedRotation(true)
    self.coltest = 0
-- I can't access self, because self.collider is passed as an argument, not self, and I couldn't just use self as that would be the function itself, not Player
-- I have to put the preSolve inside new because self.collider is only defined on Player.new, so it throws an error of collider not existing
    function self.collider:preSolve(other, collision)
        self.collider.coltest = "a"
        if other.groups then
            self.collider.coltest = "has group"
            if other.isStatic() then
                self.coltest = collision:getNormal()
                if collision:getNormal() == -1 or collision:getNormal() == 1 then
                    self.dir = self.dir * -1
                end
            end
        end
    end
end

so I ask:

ghost commented 6 months ago

how for whoever comes here: implement the function set_funcs in utils in your code and set the mainobject to your class and subobject to the collider, then use positional functions as normal