Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flame needs a more complete minimal physics engine #3418

Open
1 task
gaaclarke opened this issue Dec 19, 2024 · 3 comments
Open
1 task

Flame needs a more complete minimal physics engine #3418

gaaclarke opened this issue Dec 19, 2024 · 3 comments

Comments

@gaaclarke
Copy link

Problem to solve

There is no physics engine that available for Flame that has enough features to make implementing platformer physics easy.

Proposal

Flame needs a physics engine akin to bump.lua. That implements moving objects and performing [slide, cross, bounce, touch] reactions when moving an AABB from one spot to another. This is not available with Flame's built in collision detection and bringing in box2d is overkill and not good for many types of games (like platformers). FWIW I tried to leverage the existing collision detection system to implement slide and I came to the conclusion it would just be easier to implement my own physics.

Wishlist:

  • slide collisions (like bump.lua's move with "slide")
  • rectangle casting (like bump.lua's check)

More information

No response

Other

  • Are you interested in working on a PR for this?
@gaaclarke
Copy link
Author

Here's the sort of thing I'd expect to be easy to do in Flame. This took only 30 minutes in Love2D + bump.lua but I struggled to make something similar with Flame's physics engine.

local bump = require('bump')
local class = require("30log")

local SPEED = 128;
local GRAVITY = 9;
local JUMP_POWER = 6;
local WORLD = bump.newWorld(16)
local Ninja = class("Ninja")

function Ninja:init()
    self.x = 0
    self.y = 0
    self.width = 16;
    self.height = 16;
    self.dy = 0
    self.onPlatform = false
    WORLD:add(self, self.x, self.y, self.width, self.height)
end

function Ninja:update(dt)
    local dx = 0
    local dy = self.dy
    self.dy = self.dy + GRAVITY * dt
    if love.keyboard.isDown('left') then
        dx = dx - dt * SPEED
    end
    if love.keyboard.isDown('right') then
        dx = dx + dt * SPEED
    end
    if self.onPlatform and love.keyboard.isDown('up') then
        self.dy = -JUMP_POWER
        self.onPlatform = false
    end

    local actualX, actualY, cols, len = WORLD:move(self, self.x + dx, self.y + dy)
    if len <= 0 then self.onPlatform = false end
    for _, col in ipairs(cols) do
        if col.itemRect.y + col.itemRect.h <= col.otherRect.y then
            -- Hit your feet.
            self.dy = 0
            self.onPlatform = true
            break
        end
        if col.itemRect.y >= col.otherRect.y + col.itemRect.h then
            -- Hit your head.
            self.dy = 0
        end
    end
    self.x = actualX
    self.y = actualY
end

function Ninja:draw(dt)
    love.graphics.setColor(1, 0, 0)
    love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
end

local Block = class("Block")

function Block:init(x, y)
    assert(x ~= nil)
    assert(y ~= nil)
    self.x = x
    self.y = y
    WORLD:add(self, self.x, self.y, 16, 16)
end

function Block:update(dt) end

function Block:draw()
    love.graphics.setColor(1, 1, 1)
    love.graphics.rectangle("fill", self.x, self.y, 16, 16)
end

local NINJA = Ninja:new()
local BLOCKS = {}

function love.load()
    for i = 14,16 do
        for j = 0,20 do
            table.insert(BLOCKS, Block:new(j * 16, i * 16))
        end
    end
    table.insert(BLOCKS, Block:new(5*16, 7*16))
end

function love.draw()
    for _, block in ipairs(BLOCKS) do
        block:draw()
    end
    NINJA:draw()
end

function love.update(dt)
    NINJA:update(dt)
end

jumperplatformer-ezgif com-video-to-gif-converter

@spydon
Copy link
Member

spydon commented Dec 19, 2024

Have you tried Leap which is an opinionated platformer package built on Flame?
https://pub.dev/packages/leap

@gaaclarke
Copy link
Author

Thanks that definitely looks like it would solve my needs. When it gets to a good state we should consider mentioning it on https://docs.flame-engine.org/latest/flame/collision_detection.html

I know reading through lua code can be tiresome if you aren't familiar with it, but I want to make sure you get a chance to see how bump.lua works. I think there are some lessons from its design Flame can learn from. It's much more fundamental than Leap so different things can be implemented with it besides platformers. The other nice thing it is a self contained object that can be used directly as one wants, it doesn't rely on hidden life-cycle events or reflection. It also handles every interaction with tunneling, which eliminates a common pitfall for new users.

I think it's likely if someone were to invest a good chunk of time on making a platformer that they ship, one could really benefit from all the built-in features in Leap. However, bump.lua is much faster to get started, easier to understand and easier to use novelly. It would be nice to have an equivalent in the Flame ecosystem for people that just like to make small games quickly. Maybe that means expanding the built-in physics system or just making a whole separate thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants