Hrátky se systémem LÖVE – kolize a odrazy těles

Pavel Tišnovský 23. 6. 2009

Další knihovnou nabízenou "herním" systémem LÖVE, kterou si v seriálu o programovacím jazyku Lua popíšeme, je knihovna nazvaná love.physics, pomocí které je možné provádět simulace vzájemných kolizí i odrazů dvojrozměrných těles s respektováním jejich tvaru, hybnosti i hmotnosti.

Obsah

1. Hrátky se systémem LÖVE – kolize a odrazy těles
2. Základní objekty využívané v modulu love.physics
3. Vytvoření herního světa a hmotných těles
4. První demonstrační příklad – pohybující se těleso a statická podlaha
5. Druhý demonstrační příklad – změna počáteční rotace tělesa
6. Třetí demonstrační příklad – dvojice šikmých statických podlah
7. Literatura a odkazy na Internetu
8. Obsah dalšího pokračování seriálu

1. Hrátky se systémem LÖVE – kolize a odrazy objektů

V předchozích částech tohoto seriálu jsme si stručně popsali nejdůležitější knihovnu, na které je postavena největší část funkcionality celého herního systému LÖVE. Jednalo se o knihovnu love.graphics, která podporuje jak vytvoření okna určeného pro grafický výstup a přepnutí grafického výstupu do celoobrazovkového režimu, tak i vykreslování různých grafických objektů, počínaje body, úsečkami, kružnicemi a polygony, přes fonty a rastrové obrázky, konče tvarově složitými a dynamicky se měnícími částicovými systémy. Dnes začneme s popisem další knihovny, která je poměrně přiléhavě nazvaná love.physics. S využitím této knihovny je možné simulovat vzájemné interakce (kolize a odrazy) dvojrozměrných těles, vytvářet složitější objekty složené ze vzájemně provázaných základních tvarů (shape) a těles (body) i ovlivňovat trajektorii pohybujících se těles pomocí externích sil, které mohou na tato tělesa různým způsobem působit. Taktéž je možné libovolnou část tělesa navázat ke kurzoru myši, takže se současně s pohybem myši pohybuje i tato část tělesa, která může ovlivnit i části další, s nimiž je spojena pomocí programově vytvořené vazby.

lua1601

Obrázek 1: Jednoduchá hra popsaná v předchozích částech tohoto seriálu, která byla z velké části založena na knihovně love.graphics.

2. Základní objekty využívané v modulu love.physics

Před použitím knihovny love.physics ve vlastních aplikacích je nutné pochopit, s jakými objekty tato knihovna pracuje. Většina operací, tj. především vlastní simulace, pracuje se čtyřmi typy objektů:

  1. World – tento objekt představuje celý dvojrozměrný „svět“, ve kterém simulace pohybu a vzájemné interakce těles (kolize, odrazy) probíhá. Jedná se o obdélníkovou oblast, jenž představuje hranice, ve kterých by měly ležet vrcholy všech těles, přesněji řečeno všech tvarů, ze kterých se tělesa skládají. Nastavená hranice by měla být dostatečně velká, aby viditelná tělesa tuto hranici nemohla překročit, protože simulace probíhají pouze uvnitř herního světa (sami si můžete vyzkoušet, co se stane, když bude hranice ležet v ploše obrazovky a těleso tuto hranici překročí – pohyb tělesa se zastaví a přestanou pracovat i detektory kolizí). Na druhou stranu příliš rozsáhlý herní svět může zpomalovat výpočty vzájemných kolizí těles.
  2. Body – tento objekt představuje nestlačitelnou hmotu umístěnou v herním světě. Při vytváření tělesa lze nastavit jeho souřadnice v rámci herního světa, úhel natočení, hmotnost, těžiště (v kontextu této knihovny se jedná o bod, ve kterém je soustředěna hmotnost tělesa) i další fyzikální parametry. V případě, že je hmotnost tělesa nulová, nepůsobí na těleso gravitace. Existují i speciální typy těles nazývané střely (bullets), které se od „běžných“ těles odlišují především použitím přesnějšího (a také pomalejšího) algoritmu pro detekci kolizí. V případě, že by byl použit základní algoritmus detekce kolizí a v herním světě by se velkou rychlostí pohybovala například střela proti tenké stěně, mohlo by se stát, že by střela touto stěnou prolétla, aniž by byla kolize správně vyhodnocena. Použitím střel se budeme zabývat v navazující části tohoto seriálu.
  3. Shape – geometrický tvar, který může být přiřazený k tělesu. Tvar představuje hranici tělesa, která je použita při detekci kolizí. V současné verzi knihovny love.physics je repertoár použitelných tvarů omezen pouze na konvexní uzavřené polygony a kruhy, protože výpočty kolizí s nekonvexními tvary jsou složitější než s tvary konvexními (ve skutečnosti se nejedná přímo o omezení knihovny love.physics, ale C++ knihovny Box2D, jejíž funkce a metody jsou interně volány). S využitím tvaru přiřazeného k tělesu je možné vypočítat i celkovou hmotnost tělesa a souřadnice jeho těžiště – viz demonstrační příklady, kde tuto vlastnost využijeme.
  4. Joint – tento objekt představuje vazbu mezi tělesy, které se nachází v herním světě. Existuje několik typů vazeb, například vazba, u níž je zadána vzdálenost dvou těles, přičemž simulační knihovna se snaží tato tělesa natočit a posunout tak, aby byla zvolená vazba splněna (samotný objekt představující vazbu je neviditelný, ovšem samozřejmě je možné například získat souřadnice koncových bodů vazby a ty vykreslit formou úseček). Je však možné použít i další typy vazeb, například vazbu představující kladku či páku apod. V dnešních demonstračních příkladech nejsou vazby použity, zabývat se jimi budeme až v dalších článcích.
lua1602

Obrázek 2: Částicový systém, v němž mají částice nastavené záporné radiální zrychlení (směr vektoru tohoto zrychlení odpovídá vektoru počáteční rychlosti částice).

3. Vytvoření herního světa a hmotných těles

V předchozí kapitole byly popsány základní typy objektů, se kterými se při práci s knihovnou love.physics můžeme setkat. Nyní si řekněme, jak se s těmito objekty skutečně pracuje. Nejjednodušší je vytvoření herního světa, který se zkonstruuje pomocí funkce love.physics.new­World(size_x, size_y). Této funkci, která vrací objekt typu world, se předává velikost obdélníku, ve které se celý simulovaný svět nachází. Jedinou metodou tohoto objektu, kterou v dnešních příkladech použijeme, je metoda nazvaná setGravity(gx, gy), pomocí níž se nastavuje – jak již ostatně samotný název této metody napovídá – vektor gravitační síly. Do vytvořeného světa je možné vložit libovolné množství těles představovaných objekty typu Body.

lua1603

Obrázek 3: Další částicový systém, v němž mají částice nastavené záporné radiální zrychlení.

Nové těleso se vytváří pomocí funkce love.physics.new­Body(), jejímž prvním parametrem je objekt typu „svět“ (další parametry se mohou lišit, neboť se jedná o přetíženou funkci). Důvod, proč se nejedná přímo o metodu objektu world, spočívá v návaznosti na knihovnu Box2D, kde se taktéž jedná o statickou funkci třídy World, nikoli o metodu (ostatně sám autor této jinak skvělé knihovny s mnoha dobrými nápady přiznává, že její API mohlo být navrženo lépe). Každému vytvořenému tělesu lze přiřadit několik důležitých fyzikálních vlastností, především hmotnost, počáteční rychlost a taktéž počáteční rotaci. Hmotnost lze nastavit buď přímo při zavolání funkce love.physics.new­Body() nebo později, například na základě automatického výpočtu hmotnosti ze znalosti tvaru přiřazeného tělesu (knihovna si interně spočítá plochu tvaru a posléze pomocí této hodnoty vyčíslí hmotnost celého tělesa).

lua1604

Obrázek 4: Rastrový obrázek (sprite), který je použitý v níže popsaných demonstračních příkladech pro reprezentaci pohybujícího se tělesa – míčku. Některé pixely umístěné mimo míček jsou zcela průhledné. Tento obrázek musí mít název „green_ball.png“ a je nutné, aby byl umístěný ve stejném adresáři, v jakém se nachází i demonstrační příklady, jinak je nebude možné spustit.

Poslední operací, kterou je nutné i u jednoduchých simulovaných systémů provést, je volba a přiřazení tvaru (shape) ke každému tělesu. Jak jsme si již řekli v předchozí kapitole, je možné pro tvar tělesa použít konvexní polygon či kruh. V demonstračních příkladech se používá polygon ve tvaru obdélníku vytvářený funkcí (opět ne metodou!) nazvanou love.physics.new­RectangleShape() a míček vytvořený z kruhu funkcí love.physics.new­CircleShape(). Prvním parametrem těchto funkcí je vždy objekty představující těleso (body), další parametry se samozřejmě liší podle tvaru objektu.

4. První demonstrační příklad – pohybující se těleso a statická podlaha

V dnešním prvním demonstračním příkladu je ukázán způsob použití tvarů a těles ve velmi jednoduché simulaci. V simulovaném světě se nachází dvě tělesa – podlaha představovaná podlouhlým obdélníkem a míček představovaný kruhovým tvarem, při jehož vykreslení je použit rastrový obrázek s plně či částečně průhlednými pixely (zde můžeme využít skutečnosti, že je možné rastrový obrázek při jeho vykreslení natáčet). Podlaha má nastavenou nulovou hmotnost, takže na ní nepůsobí gravitace, zatímco hmotnost míčku a jeho těžiště je spočteno automaticky pomocí metody setMassFromSha­pes(). Před vlastním spuštěním simulace začne na míček působit síla, jejíž vektor je vodorovný a směřuje doprava (viz metoda ball_body:apply­Force). Právě tato síla a gravitace (resp. tíhové zrychlení) určuje první část trajektorie míčku. Po dopadu na podlahu a několika tlumených odrazech se míček začne vlivem tření otáčet a posléze z podlahy spadne. Klávesou [R] je možné simulaci znovu spustit, ovšem na míček již přestane působit horizontální síla; klávesou [Esc] je program ukončen. Vidíme, že i v takto jednoduché simulaci je nutné počítat s relativně velkým množstvím vlivů a bez použití knihovny love.physics by byly výpočty obtížné.

lua1605

Obrázek 5: První demonstrační příklad – začátek simulace.

Následuje výpis zdrojového kódu prvního demonstračního příkladu:

-------------------------------------------------
-- Seriál "Programovací jazyk Lua"
--
-- První demonstrační příklad:
--     simulace pohybu tělesa ve tvaru 2D míčku,
--     které dopadá na obdélníkovou podlahu
-------------------------------------------------

-- rozměry okna
window = {
    width = 800,
    height = 600
}

-- objekt představující svět, ve kterém se provádí simulace
world = nil

function load()
    -- inicializace grafického režimu
    love.graphics.setMode(window.width, window.height, false, false, 0)

    -- vytvoření "světa" o rozměrech 2000x2000 délkových jednotek
    world = love.physics.newWorld(2000, 2000)
    world:setGravity(0, 50)

    -- podlaha na souřadnicích [0, 0] s nulovou hmotností
    ground_body = love.physics.newBody(world, 0, 0, 0)

    -- obdélník (tvar) představující podlahu
    ground_shape = love.physics.newRectangleShape(ground_body, 400, 500, 500, 10)

    -- rastrový obrázek představující těleso - míček
    ball = love.graphics.newImage("green_ball.png")

    -- vytvoření tělesa na zadaných souřadnicích
    ball_body = love.physics.newBody(world, 200, 100)

    -- přiřazení tvaru k tělesu
    ball_shape = love.physics.newCircleShape(ball_body, 31)

    -- výpočet hmotnosti míčku na základě jeho poloměru
    ball_body:setMassFromShapes()

    -- aplikace síly na míček
    ball_body:applyForce(1000000, 0, 100, 100)
end

-- pravidelně volaná callback funkce
function update(dt)
   -- Update the world.
   world:update(dt)
end

-- callback funkce volaná průběžně ve chvíli, kdy je zapotřebí
-- překreslit obsah okna
function draw()
   -- vykreslení podlahy
   love.graphics.polygon(love.draw_line, ground_shape:getPoints())

   -- vykreslení míčku se správným natočením
   love.graphics.draw(ball, ball_body:getX(), ball_body:getY(), ball_body:getAngle())
end

-- callback funkce volaná ve chvíli, kdy uživatel stlačí nějakou klávesu
function keypressed(key)
    -- klávesou [ESC] se program ukončí
    if key == love.key_escape then
        love.system.exit()
    end
    -- klávesou [R] se nastaví nové souřadnice
    -- míčku a míček se zastaví
    if key == love.key_r then
        ball_body:setPosition(200, 100)
        ball_body:setVelocity(0, 0)
        ball_body:setSpin(0)
    end
end

-- finito
lua1606

Obrázek 6: První demonstrační příklad – dopad míčku na podlahu.

lua1607

Obrázek 7: První demonstrační příklad – míček padá z podlahy.

5. Druhý demonstrační příklad – změna počáteční rotace tělesa

Ve druhém demonstračním příkladu je ukázán vliv rotace tělesa (nazývaného v knihovně love.physics termínem spin). Rotující těleso – v tomto demonstračním příkladu se opět jedná o kulatý míček – po svém dopadu na podlahu část své rotační energie přemění na dopředný pohyb, popř. je naopak rotační energie využita k zastavení dopředného pohybu a začátku pohybu zpětného, v závislosti na směru rotace a úhlu, pod kterým míček dopadne na podlahu. Pomocí kláves [0][9] je možné nastavit počáteční rotaci míčku, která se však využije ve chvíli stlačení klávesy [R] (restart).

lua1608

Obrázek 8: Druhý demonstrační příklad – začátek simulace.

V případě, že je počáteční rotace kladná (což značí jeho otáčení ve směru hodinových ručiček), je míček po dopadu na podlahu urychlen a pohybuje se doprava, při dostatečně velké záporné rotaci (míček se otáčí proti směru hodinových ručiček) může dojít buď k pozastavení posunu míčku nebo dokonce k tomu, že se míček začne pohybovat opačným směrem. V horní části obrazovky je možné sledovat všechny důležité fyzikální parametry míčku – jeho polohu, rychlost i aktuální hodnotu otáčení. Povšimněte si, že právě tato hodnota se po dopadu (a několikerém odrazu) míčku mění.

lua1609

Obrázek 9: Druhý demonstrační příklad – pád míčku na podlahu, prozatím se rotace míčku nesnižuje.

Zdrojový kód druhého demonstračního příkladu má tvar:

-------------------------------------------------
-- Seriál "Programovací jazyk Lua"
--
-- Druhý demonstrační příklad:
--     simulace pohybu tělesa ve tvaru 2D míčku,
--     které dopadá na obdélníkovou podlahu
--     změna počáteční rotace míčku a ukázka
--     jejího vlivu na trajektorii míčku po dopadu
-------------------------------------------------

-- rozměry okna
window = {
    width = 800,
    height = 600
}

-- objekt představující svět, ve kterém se provádí simulace
world = nil

-- počáteční rotace míčku
initial_spin = 500

function load()
    -- inicializace grafického režimu
    love.graphics.setMode(window.width, window.height, false, false, 0)

    -- načtení fontu
    local font = love.graphics.newFont(love.default_font, 16)
    love.graphics.setFont(font)

    -- vytvoření "světa" o rozměrech 2000x2000 délkových jednotek
    world = love.physics.newWorld(2000, 2000)
    world:setGravity(0, 50)

    -- podlaha na souřadnicích [0, 0] s nulovou hmotností
    ground_body = love.physics.newBody(world, 0, 0, 0)

    -- obdélník (tvar) představující podlahu
    ground_shape = love.physics.newRectangleShape(ground_body, 400, 500, 500, 10)

    -- rastrový obrázek představující těleso - míček
    ball = love.graphics.newImage("green_ball.png")

    -- vytvoření tělesa na zadaných souřadnicích
    ball_body = love.physics.newBody(world, 200, 100)

    -- přiřazení tvaru k tělesu
    ball_shape = love.physics.newCircleShape(ball_body, 31)

    -- výpočet hmotnosti míčku na základě jeho poloměru
    ball_body:setMassFromShapes()

    -- nastavení počáteční rotace míčku
    ball_body:setSpin(initial_spin)

    -- aplikace síly na míček
    ball_body:applyForce(1000000, 0, 100, 100)
end

-- pravidelně volaná callback funkce
function update(dt)
   -- Update the world.
   world:update(dt)
end

-- callback funkce volaná průběžně ve chvíli, kdy je zapotřebí
-- překreslit obsah okna
function draw()
   love.graphics.setColor(160, 160, 160)

   -- vykreslení podlahy
   love.graphics.polygon(love.draw_line, ground_shape:getPoints())

   -- vykreslení míčku se správným natočením
   love.graphics.draw(ball, ball_body:getX(), ball_body:getY(), ball_body:getAngle())

   love.graphics.setColor(255, 255, 0)
   -- získání aktuálních informací o míčku
   local x, y = ball_body:getPosition()
   local vx, vy = ball_body:getVelocity()
   local spin = ball_body:getSpin()
   -- výpis informací
   love.graphics.draw(string.format("position: %d, %d", x, y), 10, 20)
   love.graphics.draw(string.format("velocity: %d, %d", vx, vy), 10, 40)
   love.graphics.draw(string.format("spin: %d", spin), 10, 60)
   love.graphics.draw(string.format("initial spin: %d ('0'-'9' to change)", initial_spin), 10, 80)
end

-- callback funkce volaná ve chvíli, kdy uživatel stlačí nějakou klávesu
function keypressed(key)
    -- klávesou [ESC] se program ukončí
    if key == love.key_escape then
        love.system.exit()
    end
    -- klávesou [R] se nastaví nové souřadnice
    -- míčku a rotace míčku se zastaví
    if key == love.key_r then
        ball_body:setPosition(200, 100)
        ball_body:setVelocity(80, 0)
        ball_body:setSpin(initial_spin)
    end
    -- změna počáteční rotace míčku
    if key >= love.key_0 and key <= love.key_9 then
        local code = key - love.key_0
        initial_spin = code*200-1000
    end
end

-- finito
lua1610

Obrázek 10: Druhý demonstrační příklad – dopad míčku na podlahu, rotace se začíná snižovat a míček se vlivem tření pohybuje směrem doleva a nikoli doprava.

lua1611

Obrázek 11: Rotace míčku se snížila, její energie posloužila ke změně směru pohybu míčku.

lua1612

Obrázek 12: Míček padá z horní plochy podlahy.

6. Třetí demonstrační příklad – dvojice šikmých statických podlah

Ve třetím demonstračním příkladu se místo podlahy, tj. tělesa s vodorovnou horní stěnou, na nějž nepůsobí gravitace, používá dvojice šikmo postavených kvádrů. Míček po dopadu na první kvádr začíná klouzat po jeho horní části, přičemž se jeho rychlost i rotace postupně urychluje vlivem gravitace, jejíž vektor je orientován směrem dolů (jak orientaci tohoto vektoru, tak i jeho délku je sice možné měnit, výsledek však nepůsobí příliš realisticky).

lua1613

Obrázek 13: Třetí demonstrační příklad – začátek simulace.

Po dopadu na druhý kvádr se rotace míčku zpomalí (viz horní část obrazovky, do níž se vypisují jeho základní fyzikální parametry) a začíná pohyb opačným směrem. Podobně jako u druhého demonstračního příkladu, i zde je možné pomocí kláves [0][9] měnit počáteční rotaci míčku a ovlivnit tak jeho trajektorii. Změnou globálních konstant frame1_angle a frame2_angle lze změnit natočení obou kvádrů, po jejichž povrchu se míček kutálí.

lua1614

Obrázek 14: Třetí demonstrační příklad – dopad míčku na první kvádr.

Následuje výpis zdrojového kódu třetího demonstračního příkladu:

-------------------------------------------------
-- Seriál "Programovací jazyk Lua"
--
-- Třetí demonstrační příklad: použití šikmých "podlah"
-------------------------------------------------

-- rozměry okna
window = {
    width = 800,
    height = 600
}

-- objekt představující svět, ve kterém se provádí simulace
world = nil

-- počáteční rotace míčku
initial_spin = 500

-- natočení obou "podlah"
frame1_angle = -20
frame2_angle = 45

function load()
    -- inicializace grafického režimu
    love.graphics.setMode(window.width, window.height, false, false, 0)

    -- načtení fontu
    local font = love.graphics.newFont(love.default_font, 16)
    love.graphics.setFont(font)

    -- vytvoření "světa" o rozměrech 2000x2000 délkových jednotek
    world = love.physics.newWorld(2000, 2000)
    world:setGravity(0, 50)

    -- podlaha na souřadnicích [0, 0] s nulovou hmotností
    ground = love.physics.newBody(world, 0, 0, 0)

    -- obdélník představující podlahu
    ground_shape = love.physics.newRectangleShape(ground, 400, 500, 600, 10, frame1_angle)

    bridge = love.physics.newBody(world, 0, -100, 0)
    bridge_shape = love.physics.newRectangleShape(bridge, 200, 300, 300, 10, frame2_angle)

    -- rastrový obrázek představující těleso - míček
    ball = love.graphics.newImage("green_ball.png")

    -- vytvoření tělesa na zadaných souřadnicích
    ball_body = love.physics.newBody(world, 200, 100)

    -- přiřazení tvaru k tělesu
    ball_shape = love.physics.newCircleShape(ball_body, 31)

    -- výpočet hmotnosti na základě jeho poloměru
    ball_body:setMassFromShapes()
end

-- pravidelně volaná callback funkce
function update(dt)
   -- Update the world.
   world:update(dt)
end

-- callback funkce volaná průběžně ve chvíli, kdy je zapotřebí
-- překreslit obsah okna
function draw()
   love.graphics.setColor(160, 160, 160)

   -- vykreslení podlahy
   love.graphics.polygon(love.draw_line, ground_shape:getPoints())
   love.graphics.polygon(love.draw_line, bridge_shape:getPoints())

   -- vykreslení míčku se správným natočením
   love.graphics.draw(ball, ball_body:getX(), ball_body:getY(), ball_body:getAngle())

   love.graphics.setColor(255, 255, 0)

   -- získání aktuálních informací o míčku
   local x, y = ball_body:getPosition()
   local vx, vy = ball_body:getVelocity()
   local spin = ball_body:getSpin()

   -- výpis informací
   love.graphics.draw(string.format("position: %d, %d", x, y), 10, 20)
   love.graphics.draw(string.format("velocity: %d, %d", vx, vy), 10, 40)
   love.graphics.draw(string.format("spin: %d", spin), 10, 60)
   love.graphics.draw(string.format("initial spin: %d ('0'-'9' to change)", initial_spin), 10, 80)
end

-- callback funkce volaná ve chvíli, kdy uživatel stlačí nějakou klávesu
function keypressed(key)
    -- klávesou [ESC] se program ukončí
    if key == love.key_escape then
        love.system.exit()
    end
    -- klávesou [R] se nastaví nové souřadnice
    -- míčku a rotace míčku se zastaví
    if key == love.key_space then
        -- Apply a random impulse
        body:applyImpulse(100000-math.random(0, 200000), 0)
    end
    if key == love.key_r then
        ball_body:setPosition(200, 100)
        ball_body:setVelocity(0, 0)
        ball_body:setSpin(initial_spin)
    end
    -- změna í rotace míčku
    if key >= love.key_0 and key <= love.key_9 then
        local code = key - love.key_0
        initial_spin = code*200-1000
    end
end

-- finito
lua1615

Obrázek 15: Třetí demonstrační příklad – míček dopadl na druhý kvádr.

lua1616

Obrázek 16: Třetí demonstrační příklad – míček klouže po druhém kvádru.

widgety

7. Literatura a odkazy na Internetu

  1. Baraff David and Witkin Andrew:
    Physically Based Modeling,
    SIGGRAPH Course Notes, July 1998, pages B1–C12
  2. Magnetat-Thalmann B., Thalmann D. and Arnaldi B.:
    Computer Animation and Simulation 2000,
    Springer Verlag, Wien, ISBN 3–2118–3549–0
  3. Box2D Physics Engine (jedná se o engine, na němž je knihovna love.physics založena)
    http://www.box2d­.org/
  4. Domovská stránka systému LÖVE
    http://love2d­.org/
  5. Tutoriály k systému LÖVE
    http://love2d­.org/?page=do­cumentation
  6. Screenshoty aplikací vytvořených v LÖVE
    http://love2d­.org/screenshots
  7. Domovská stránka programovacího jazyka Lua
    http://www.lu­a.org/ 
  8. Lua
    http://www.li­nuxexpres.cz/pra­xe/lua
  9. Lua
    http://cs.wiki­pedia.org/wiki/Lua
  10. Lua (programming language)
    http://en.wiki­pedia.org/wiki/Lu­a_(programmin­g_language)

8. Obsah dalšího pokračování seriálu

V navazující části seriálu o programovacím jazyku Lua a systému LÖVE si ukážeme další (poněkud složitější a taktéž zajímavější) způsoby využití modulu love.physics, především způsob vytváření složitějších těles z jednodušších tvarů. Uvidíme, že zdánlivě jednoduché prostředí pro simulaci fyzikálně reálného pohybu a kolize těles nabízené tímto modulem ve skutečnosti umožňuje tvorbu i velmi komplexních systémů, které je navíc možné interaktivně ovlivňovat uživatelem – například posunem některých tvarů pomocí myši.

Našli jste v článku chybu?
Vitalia.cz: Jak Ondra o astma přišel

Jak Ondra o astma přišel

Vitalia.cz: 5 důvodů, proč jet na výlov rybníka

5 důvodů, proč jet na výlov rybníka

Lupa.cz: Další Češi si nechali vložit do těla čip

Další Češi si nechali vložit do těla čip

DigiZone.cz: Test LG 55UH750V aneb Cena/výkon

Test LG 55UH750V aneb Cena/výkon

Vitalia.cz: Jaký je rozdíl mezi brambůrky a chipsy?

Jaký je rozdíl mezi brambůrky a chipsy?

Vitalia.cz: Když všichni seli řepku, on vsadil na dýně

Když všichni seli řepku, on vsadil na dýně

Vitalia.cz: Tohle jsou nejlepší česká piva podle odborníků

Tohle jsou nejlepší česká piva podle odborníků

Podnikatel.cz: Znáte už 5 novinek k #EET

Znáte už 5 novinek k #EET

Podnikatel.cz: Dva měsíce na EET. Budou stačit?

Dva měsíce na EET. Budou stačit?

Podnikatel.cz: EET pro e-shopy? Postavené na hlavu

EET pro e-shopy? Postavené na hlavu

Vitalia.cz: Kterou dýni můžete jíst za syrova?

Kterou dýni můžete jíst za syrova?

Vitalia.cz: Test dětských svačinek: Tyhle ne!

Test dětských svačinek: Tyhle ne!

Podnikatel.cz: Babišovi se nedá věřit, stěžovali si hospodští

Babišovi se nedá věřit, stěžovali si hospodští

DigiZone.cz: Světový pohár v přímém přenosu na ČT

Světový pohár v přímém přenosu na ČT

Lupa.cz: Hackeři mají data z půlmiliardy účtů Yahoo

Hackeři mají data z půlmiliardy účtů Yahoo

Lupa.cz: Aukro.cz mění majitele. Vrací se do českých rukou

Aukro.cz mění majitele. Vrací se do českých rukou

Vitalia.cz: Muž, který miluje příliš. Ženám neimponuje

Muž, který miluje příliš. Ženám neimponuje

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

DigiZone.cz: Rapl: seriál, který vás smíří s ČT

Rapl: seriál, který vás smíří s ČT

Vitalia.cz: Tahák, jak vyzrát nad zápachem z úst

Tahák, jak vyzrát nad zápachem z úst