0

我正在通过 cs50 进行游戏开发课程,Colton Ogden 在其中教授 lua 中的 love2d。我在碰撞检测中遇到问题。当对象不旋转时,下面的代码/逻辑可以正常工作,例如 love.graphics.draw(texture, x, y, r)。

这里 x 和 y 是某个值,而 r(旋转为 0)。x 和 y 的值不断变化。

function Projectile:collides(target)
        if self.x > target.x + target.width or target.x > self.x + self.width then
            return false
        end
    
        if self.y > target.y + target.height or target.y > self.y + self.height then
            return false
        end
    
        return true
end

但是上面的代码不适用于旋转的目标,即 r 有一些不断变化的值。

下面是我如何旋转一个对象。

function Meteor:init(speed)
    self.r = math.random(-1, 1)
end

function Meteor:update(dt)
    if self.r > 0 then
        self.r = self.r + math.pi/9 * dt
    elseif self.r < 0 then
        self.r = self.r - math.pi/9 * dt
    else
        self.r = self.r    
    end
    
    if self.y < VIRTUAL_HEIGHT + 110 then
        self.y = self.y + self.speed * dt
    else
        self.remove = true
    end    
end

function Meteor:render()
    love.graphics.drawLayer(self.meteor, self.type, self.x, self.y, self.r)
end
4

2 回答 2

0

正如@Luke100000 所写,LÖVE 已经在 love.physics 中实现了碰撞检测。
阅读并尝试:https
://love2d.org/wiki/Tutorial:PhysicsCollisionCallbacks 对于我使用的零重力世界......

function love.load()
local meter=4.5
love.physics.setMeter(meter)
ZeroGravity=love.physics.newWorld(0,0,true)
ZeroGravity:setCallbacks(Hit,Release,preSolve,postSolve) -- <Collision Callbacks>
end

例如“Hit”回调函数......

-- <Collision Callback Functions>
Hit=function(a,b)
a:getBody():setUserData(os.date('%H:%M:%S'))
b:getBody():setUserData(os.date('%H:%M:%S'))
a:getUserData():emit(256)
b:getUserData():emit(256)
return true
end

在“命中”时发射 256 个零件的粒子系统在创建时分配给物理体的用户数据中的夹具......

function addAsteroid(x,y,r,kind)
local body=love.physics.newBody(ZeroGravity,x,y,kind)
local shape=love.physics.newCircleShape(r)
local fixture=love.physics.newFixture(body,shape,.01)
fixture:setUserData(psystem:clone()) -- Particlesystem for emitting
fixture:setDensity(1)
fixture:setFriction(1)
fixture:setRestitution(1)
--fixture:setFilterData(1,1,-1)
fixture:getUserData():start()
return body
end

粒子系统可能非常复杂,但值得学习。
在这里,我给你一个我的例子,它适用于四边形......

-- planets.lua
fields=1
quads={love.graphics.newImage("planets.png")
}
local assets={x=0,y=0,size=.1,time=-1,
[1]=love.graphics.newQuad(138,33,300,300,quads[1]:getDimensions()),
[2]=love.graphics.newQuad(505,37,300,300,quads[1]:getDimensions()),
[3]=love.graphics.newQuad(871,21,300,300,quads[1]:getDimensions()),
[4]=love.graphics.newQuad(1238,22,300,300,quads[1]:getDimensions()),
[5]=love.graphics.newQuad(1606,15,300,300,quads[1]:getDimensions()),
[6]=love.graphics.newQuad(1974,11,300,300,quads[1]:getDimensions()),
[7]=love.graphics.newQuad(1976,349,300,300,quads[1]:getDimensions()),
[8]=love.graphics.newQuad(136,382,300,300,quads[1]:getDimensions()),
[9]=love.graphics.newQuad(504,379,300,300,quads[1]:getDimensions()),
[10]=love.graphics.newQuad(871,366,300,300,quads[1]:getDimensions()),
[11]=love.graphics.newQuad(1236,362,300,300,quads[1]:getDimensions()),
[12]=love.graphics.newQuad(19,724,300,300,quads[1]:getDimensions()),
[13]=love.graphics.newQuad(1047,698,300,300,quads[1]:getDimensions()),
[14]=love.graphics.newQuad(1376,687,300,300,quads[1]:getDimensions()),
[15]=love.graphics.newQuad(1721,686,300,300,quads[1]:getDimensions()),
[16]=love.graphics.newQuad(2042,684,300,300,quads[1]:getDimensions()),
[17]=love.graphics.newQuad(347,704,660,300,quads[1]:getDimensions())
}
pquads={x=0,y=0,size=1,time=-1}
for i=12,12 do table.insert(pquads,assets[i]) end -- recall
assets=empty
psystem=love.graphics.newParticleSystem(quads[1],72)
psystem:setBufferSize(4096)
psystem:setLinearAcceleration(-150,-150,150,150) -- Random movement in all directions.
psystem:setEmissionArea('ellipse',145,145,math.rad(math.random(360)),false)
psystem:setQuads(pquads)
psystem:setSpread(75)
--[[psystem:setColors({love.math.random(),
love.math.random(),
love.math.random(),
0.3},{love.math.random(),
love.math.random(),
love.math.random(),
0.6},{love.math.random(),
love.math.random(),
love.math.random(),
0.3})]]--
--psystem:setColors({1,0,0,1},{0,0,1,1},{1,0,0,1})
--psystem:setColors({0,0,1,1},{1,1,1,1},{1,1,0,1},{1,0,0,1})
psystem:setSizes(math.random()*.05,0)
--psystem:setSizes(.1,.2,.3,.4,.3,.2,.1)
psystem:setSizeVariation(0)
psystem:setEmitterLifetime(pquads.time)
psystem:setParticleLifetime(pquads.size*11)
psystem:setEmissionRate(pquads.size*.11)
psystem:setInsertMode('top')
-- psystem:setPosition(-150,-150)

我使用的资产来自...
https://opengameart.org/art-search?keys=planets

于 2021-12-04T08:52:09.947 回答
0

有时,仅近似对象的碰撞会更容易且足够。在 LÖVE 中,您可以在 中指定纹理偏移love.graphics.draw()。让纹理在其中心旋转,看看近似是否有效。

如果您确实需要未对齐轴的矩形,您可能需要使用碰撞库。HardonCollider完美运行。

如果您也打算添加物理,那么LÖVE 物理模块更有意义。

于 2021-10-28T19:21:12.387 回答