World:rayCast (Français)
Disponible depuis LÖVE 0.8.0 |
Ce-tte method n'est pas supporté-e par des versions plus anciennes. |
Émet un rayon et appelle une fonction pour chaque fixtures dans son intersection.
Contents
Fonction
Synopsis
World:rayCast( x1, y1, x2, y2, callback )
Arguments
number (Français) x1
- Position en x du point de départ du rayon.
number (Français) y1
- Position en y du point de départ du rayon.
number (Français) x2
- Position en x du point d'arrivée du rayon.
number (Français) y2
- Position en x du point d'arrivée du rayon.
function (Français) callback
- Fonction appelée pour chaque fixture ayant une intersection avec le rayon. La fonction prend six arguments et doit retourner un nombre comme valeur de contrôle. Les points d'intersection donné à la fonction le seront dans un ordre arbitraire. Si vous désirez trouvez le point d'intersection le plus proche, vous devez faire le test vous même au sein de la fonction. La façon la plus simple de le faire est en utilisation la valeur de la fraction.
Retourne
Rien.
Fonction de rappel
Synopsis
control = callback( fixture, x, y, xn, yn, fraction )
Arguments
Fixture (Français) fixture
- La fixture en intersection avec le rayon.
number (Français) x
- La position en x du point d'intersection.
number (Français) y
- La position en y du point d'intersection.
number (Français) xn
- La valeur x du vecteur normal de la surface du bord de la forme.
number (Français) yn
- La valeur y du vecteur normal de la surface du bord de la forme.
number (Français) fraction
- La position de l'intersection sur le rayon sous forme de nombre compris entre 0 et 1 (ou bein plus élevé si la longueur du rayon a été changée par la valeur de retourn).
Retourne
number (Français) control
- Le rayon peut être contrôlé par la valeur de retour. Une valeur positive défini une nouvelle longueur de rayon, où 1 est la valeur par défaut. Une valeur de 0 termine le rayon. Si la fonction de rappel retourne -1, l'intersection est ignorée comme si elle n'avait pas eu lieu.
Notes
Il y a un bug dans LÖVE 0.8.0 où le vecteur normal passé à la fonction de rappel est agrandit par love.physics.getMeter.
Exemples
Émettre un rayon vers différents formes aléatoires.
function worldRayCastCallback(fixture, x, y, xn, yn, fraction)
local hit = {}
hit.fixture = fixture
hit.x, hit.y = x, y
hit.xn, hit.yn = xn, yn
hit.fraction = fraction
table.insert(Ray.hitList, hit)
return 1 -- Continue avec l'émission de rayon à travers toutes les formes.
end
function createStuff()
-- Nettoie les choses précédentes.
for i = #Terrain.Stuff, 1, -1 do
Terrain.Stuff[i].Fixture:destroy()
Terrain.Stuff[i] = nil
end
-- Génère quelques formes aléatoires.
for i = 1, 30 do
local p = {}
p.x, p.y = math.random(100, 700), math.random(100, 500)
local shapetype = math.random(3)
if shapetype == 1 then
local w, h, r = math.random() * 10 + 40, math.random() * 10 + 40, math.random() * math.pi * 2
p.Shape = love.physics.newRectangleShape(p.x, p.y, w, h, r)
elseif shapetype == 2 then
local a = math.random() * math.pi * 2
local x2, y2 = p.x + math.cos(a) * (math.random() * 30 + 20), p.y + math.sin(a) * (math.random() * 30 + 20)
p.Shape = love.physics.newEdgeShape(p.x, p.y, x2, y2)
else
local r = math.random() * 40 + 10
p.Shape = love.physics.newCircleShape(p.x, p.y, r)
end
p.Fixture = love.physics.newFixture(Terrain.Body, p.Shape)
Terrain.Stuff[i] = p
end
end
function love.keypressed()
createStuff()
end
function love.load()
-- Définit cela à 1 afin d'éviter tous les bugs de changement d'échelle actuels.
love.physics.setMeter(1)
-- Utilise les mêmes résultats aléatoires à chaque départ.
math.randomseed(0xfacef00d)
World = love.physics.newWorld()
Terrain = {}
Terrain.Body = love.physics.newBody(World, 0, 0, "static")
Terrain.Stuff = {}
createStuff()
Ray = {
x1 = 0,
y1 = 0,
x2 = 0,
y2 = 0,
hitList = {}
}
end
function love.update(dt)
local now = love.timer.getTime()
World:update(dt)
-- Nettoie la liste de collision de fixture.
Ray.hitList = {}
-- Calcule la position du rayon.
local pos = (math.sin(now/4) + 1.2) * 0.4
Ray.x2, Ray.y2 = math.cos(pos * (math.pi/2)) * 1000, math.sin(pos * (math.pi/2)) * 1000
-- Émet le rayon et peuple la table de collisions.
World:rayCast(Ray.x1, Ray.y1, Ray.x2, Ray.y2, worldRayCastCallback)
end
function love.draw()
-- Trace le terrain.
love.graphics.setColor(255, 255, 255)
for i, v in ipairs(Terrain.Stuff) do
if v.Shape:getType() == "polygon" then
love.graphics.polygon("line", Terrain.Body:getWorldPoints( v.Shape:getPoints() ))
elseif v.Shape:getType() == "edge" then
love.graphics.line(Terrain.Body:getWorldPoints( v.Shape:getPoints() ))
else
local x, y = Terrain.Body:getWorldPoints(v.x, v.y)
love.graphics.circle("line", x, y, v.Shape:getRadius())
end
end
-- Trace le rayon.
love.graphics.setLineWidth(3)
love.graphics.setColor(255, 255, 255, 100)
love.graphics.line(Ray.x1, Ray.y1, Ray.x2, Ray.y2)
love.graphics.setLineWidth(1)
-- Trace les points d'intersection et les vecteurs normaux, si il y en a eu.
for i, hit in ipairs(Ray.hitList) do
love.graphics.setColor(255, 0, 0)
love.graphics.print(i, hit.x, hit.y) -- Prints the hit order besides the point.
love.graphics.circle("line", hit.x, hit.y, 3)
love.graphics.setColor(0, 255, 0)
love.graphics.line(hit.x, hit.y, hit.x + hit.xn * 25, hit.y + hit.yn * 25)
end
end
Voir également
Autres langues
Dansk –
Deutsch –
English –
Español –
Français –
Indonesia –
Italiano –
Lietuviškai –
Magyar –
Nederlands –
Polski –
Português –
Română –
Slovenský –
Suomi –
Svenska –
Türkçe –
Česky –
Ελληνικά –
Български –
Русский –
Српски –
Українська –
עברית –
ไทย –
日本語 –
正體中文 –
简体中文 –
Tiếng Việt –
한국어
More info