Tutorial:Physics (Русский)

В этом примере мы создадим красный шар, который будет кататься по зеленому полю.

Завершенный полный пример можно найти в конце страницы. Все функции должны быть помещены в один файл: main.lua.

Начнем с функции love.load()

love.load()

Прежде всего нам необходимо настроить (создать) мир world) для физических тел в нем.

function love.load()
  love.physics.setMeter(64) -- высота метра в нашем мире будет 64 пикселя
  world = love.physics.newWorld(0, 9.81*64, true) -- создаем мир для тел в нем, с горизонтальной гравитацией равной 0 и вертикальной гравитацией равной 9.81

Теперь, когда мир (world) создан, мы можем добавить тела (bodies), формы (shapes) и связать (скрепить) (fixture) их.

   objects = {} -- таблица для хранения объектов в ней
  
  -- создадим землю
  objects.ground = {}
  objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) -- запомните, форма (прямоугольник, который мы позже создадим) крепится к телу по центру, так что нам ее нужно пододвинуть (650/2, 650-50/2)
  objects.ground.shape = love.physics.newRectangleShape(650, 50) -- создаем форму - прямоугольник с шириной 650 и высотой 50
  objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) -- прикрепляем форму к телу
  
  -- создадим мяч
  objects.ball = {}
  objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") -- размещаем тело по центру мира и делаем его динамическим, чтобы оно могло двигаться
  objects.ball.shape = love.physics.newCircleShape( 20) -- форма мяча - круг с радиусом 20
  objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1) -- прикрепляем форму к телу и устанавливаем плотность = 1
  objects.ball.fixture:setRestitution(0.9) -- устанавливаем "отскок" (упругость) мячика
  
  -- создадим пару блоков, чтобы поиграть с ними
  objects.block1 = {}
  objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
  objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
  objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) -- более высокая плотность даст более высокую массу
  
  objects.block2 = {}
  objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
  objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)

Теперь, чтобы завершить функцию love.load(), зададим параметры: размер экрана и цвет фона.

  -- графические настройки
  love.graphics.setBackgroundColor(104, 136, 248) -- устанавливаем синий цвет для фона
  love.window.setMode(650, 650) -- устанавливаем размеры окна 650 на 650, оконный режим, вертикальная синхронизация включена, без сглаживания
end

Этого достаточно для первоначальной настройки физического движка. Теперь нам нужно отредактировать функцию love.update().

love.update()

function love.update(dt)
  world:update(dt) -- это приводит мир в движение
 
  -- создадим несколько событий для нажатия клавиш
  if love.keyboard.isDown("right") then -- стрелка вправо будет толкать мяч вправо
    objects.ball.body:applyForce(400, 0)
  elseif love.keyboard.isDown("left") then -- стрелка влево будет толкать мяч влево
    objects.ball.body:applyForce(-400, 0)
  elseif love.keyboard.isDown("up") then -- стрелка вверх будет распалогать мяч в воздухе
    objects.ball.body:setPosition(650/2, 650/2)
  end
end

Теперь, когда мир обновляется, нам нужно нарисовать мяч и землю.

love.draw()

Сначала земля.

function love.draw()
  love.graphics.setColor(72, 160, 14) -- устанавливаем зеленый цвет для рисования земли
  love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- рисуем закрашеный полигон по координатам земли

И в завершение, нарисуем мяч и блоки.

  love.graphics.setColor(193, 47, 14) -- устанавливаем красный цвет для рисования мяча
  love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius())

  love.graphics.setColor(50, 50, 50) -- устанавливаем серый цвет для рисования блоков
  love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints()))
  love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints()))
end

Готово! Положите полученный файл с кодом в zip архив, переименуйте в physics.love (или что-то другое) и запускайте. Результатом будет шар, катающийся по зеленой земле.

Скриншот уже в почти завершенном состоянии (без блоков).


main.lua

function love.load()
  love.physics.setMeter(64) -- длина метра в нашем мире будет 64px
  world = love.physics.newWorld(0, 9.81*64, true) -- создаем мир с горизонтальной гравитацией 0 и вертикальной гравитацией 9,81
  
  objects = {} -- таблица объектов
  
  -- создадим землю
  objects.ground = {}
  objects.ground.body = love.physics.newBody(world, 650/2, 650-50/2) -- запомни, форма (прямоугольник, который создадим позже) прикрепляется к телу по центру, по этому нужно пододвинуть (650/2, 650-50/2)
  objects.ground.shape = love.physics.newRectangleShape(650, 50) -- создаем форму - прямоугольник с шириной 650 и высотой 50
  objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) -- прикрепляем форму к телу
  
  -- создадим мяч
  objects.ball = {}
  objects.ball.body = love.physics.newBody(world, 650/2, 650/2, "dynamic") -- размещаем тело по центру мира и делаем его динамическим, чтобы оно могло двигаться
  objects.ball.shape = love.physics.newCircleShape( 20) -- форма мяча - круг с радиусом 20
  objects.ball.fixture = love.physics.newFixture(objects.ball.body, objects.ball.shape, 1) -- прикрепляем форму к телу и устанавливаем плотность = 1
  objects.ball.fixture:setRestitution(0.9) -- устанавливаем "отскок" (упругость) мячика
  
  -- создадим пару блоков, чтобы поиграть с ними
  objects.block1 = {}
  objects.block1.body = love.physics.newBody(world, 200, 550, "dynamic")
  objects.block1.shape = love.physics.newRectangleShape(0, 0, 50, 100)
  objects.block1.fixture = love.physics.newFixture(objects.block1.body, objects.block1.shape, 5) -- более высокая плотность даст более высокую массу
  
  objects.block2 = {}
  objects.block2.body = love.physics.newBody(world, 200, 400, "dynamic")
  objects.block2.shape = love.physics.newRectangleShape(0, 0, 100, 50)
  objects.block2.fixture = love.physics.newFixture(objects.block2.body, objects.block2.shape, 2)
  
  -- графические настройки
  love.graphics.setBackgroundColor(104, 136, 248) -- устанавливаем синий цвет для фона
  love.window.setMode(650, 650) -- устанавливаем размеры окна 650 на 650, оконный режим, вертикальная синхронизация включена, без сглаживания
end

function love.update(dt)
  world:update(dt) -- это приводит мир в движение
 
  -- создадим несколько событий для нажатия клавиш
  if love.keyboard.isDown("right") then -- стрелка вправо будет толкать мяч вправо
    objects.ball.body:applyForce(400, 0)
  elseif love.keyboard.isDown("left") then -- стрелка влево будет толкать мяч влево
    objects.ball.body:applyForce(-400, 0)
  elseif love.keyboard.isDown("up") then -- стрелка вверх будет распалогать мяч в воздухе
    objects.ball.body:setPosition(650/2, 650/2)
  end
end

function love.draw()
  love.graphics.setColor(72, 160, 14) -- устанавливаем зеленый цвет для рисования земли
  love.graphics.polygon("fill", objects.ground.body:getWorldPoints(objects.ground.shape:getPoints())) -- рисуем закрашеный полигон по координатам земли
  
  love.graphics.setColor(193, 47, 14) -- устанавливаем красный цвет для рисования мяча
  love.graphics.circle("fill", objects.ball.body:getX(), objects.ball.body:getY(), objects.ball.shape:getRadius())

  love.graphics.setColor(50, 50, 50) -- устанавливаем серый цвет для рисования блоков
  love.graphics.polygon("fill", objects.block1.body:getWorldPoints(objects.block1.shape:getPoints()))
  love.graphics.polygon("fill", objects.block2.body:getWorldPoints(objects.block2.shape:getPoints()))
end



Другие языки