World:rayCast (日本語)
LÖVE 0.8.0 から使用可能 |
このメソッドは以前のバージョンでは非対応です。 |
斜線計算を行い、それと交差する取付具がある関数を呼び出します。コールバックの順序に関しては推定することができません。
関数の呼び出し毎に、六種類の引数が関数へ渡されます。
Contents
概要
function callback(fixture, x, y, xn, yn, fraction)
return 1
end
引数
Fixture fixture
- 斜線と交差する取付具。
number x
- 交差地点の x 位置。
number y
- 交差地点の y 位置。
number xn
- 形状の端にある表面法線ベクトル x 値。
number yn
- 形状の端にある表面法線ベクトル y 値。
number fraction
- 0 から 1 までの数値とした斜線上にある交差の位置です (または斜線の長さが返値で変更されたものと同等の高さ)。
返値
number
- 斜線は返値により制御できます。標準値は 1 であり正数にて斜線の長さを新規設定します。値 0 は斜線の終端です。コールバック関数で -1 が返される場合は、何も発生せず公差は無視されます。
注釈
LÖVE 0.8.0 ではコールバック関数へ渡される法線ベクトルは love.physics.getMeter により尺度変更されてしまう不具合があります。
関数
概要
World:rayCast( x1, y1, x2, y2, callback )
引数
number x1
- 斜線の始点として x 位置。
number y1
- 斜線の始点として y 位置。
number x2
- 斜線の終点として x 位置。
number y2
- 斜線の終点として y 位置。
function callback
- この関数は六種類の引数を取得して必ず数値を返します。
返値
ありません。
用例
いくつかの無作為な形状に対して斜線計算します。
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 -- 全ての形状に対して斜線計算を継続します。
end
function createStuff()
-- 以前の要素を消去します。
for i = #Terrain.Stuff, 1, -1 do
Terrain.Stuff[i].Fixture:destroy()
Terrain.Stuff[i] = nil
end
-- いくつか形状を無作為に生成します。
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()
-- ここで現在の尺度に対する不具合を回避するために 1 を設定します。
love.physics.setMeter(1)
-- 開始ごとに同じ要素を無作為に開始します。
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)
-- 取付具の当たる一覧の消去。
Ray.hitList = {}
-- 斜線位置の計算。
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
-- 射線計算を行い hitList テーブルへ登録します。
World:rayCast(Ray.x1, Ray.y1, Ray.x2, Ray.y2, worldRayCastCallback)
end
function love.draw()
-- 地形の描画。
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
-- 斜線の描画。
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)
-- 存在する場合は交差地点および通常ベクトルを描画します。
for i, hit in ipairs(Ray.hitList) do
love.graphics.setColor(255, 0, 0)
love.graphics.print(i, hit.x, hit.y) -- 地点のほかに当たり順を表示します。
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
関連
そのほかの言語
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