Продолжаем изучать Love2d

в 17:58, , рубрики: game development, Gamedev, love2d, Lua, tutorial, Программирование, метки: , , ,

Продолжаем изучать Love2d
В предыдущем посте я рассказал как рисовать картинки и, вроде как, объяснил, что к чему в love2d. Сегодня я решил написать змейку, всем, кому интересно, прошу под кат. Запускаем Sublime Text 2, как его настроить для love я говорил в прошлый раз, но сегодня мы будем использовать дебаг, но для этого нужно написать три лишних строки, а именно: Рядом с main.lua, в корне каталога проекта, создаем файл и называем его conf.lua. Этот файл предназначен для настроек игры. В нем пишем такой вот код:

function love.conf(t)--Функция которую вызывает love перед стартом приложения
    io.stdout:setvbuf("no")--Из-за особенностей Sublime Text, точнее его консольки нужно вызывать эту функцию, 
                           --иначе все что мы выводим с помощью print(str) будет выведено после закрытия игры.
end

Подробнее об этой функции можно почитать здесь, и здесь.

Ну а теперь код

Подготовим переменные:

local apple, snake, direction, width, height, delay

function love.load()
	width = love.graphics.getWidth() / 10			--функция возвращает длину окна на данный момент
	print("Width " .. width)          				--дебаг вывод
	height = love.graphics.getHeight() /10			--тоже самое но с высотой
	print("Height " .. height)
	apple = { x = math.random() % width;			--теперь нам нужно яблоко генерируем X-координату
			  y = math.random() % height; } 		        --и Y..
	snake = { } 						--инициализируем таблицу с координатами змейки
	for i = 1, 10 do 						--первые 10 клеток надо с чего-то начинать
		point = { x = 10;					--и снова X..
				  y = 10 + i; }					--и Y..
		table.insert(snake, point)				--вписываем в таблицу
	end
	direction = "up"						--змейка должна куда-то ползти
	delay = 0							--змейка не должна быть нервной
end

Вроде бы все объяснил, для тех кто хоть раз писал змейку должно быть понятно все.

Теперь нам нужно рисовать змейку (Пока что без яблока);

function love.draw()
	love.graphics.setBackgroundColor(0, 0, 0)		        --чистим экран
	for k, v in pairs(snake) do 			        --отрисовываем каждую клетку
		love.graphics.rectangle("fill", v.x * 10, v.y * 10, 10, 10)
	end
end

А теперь должны возникнуть вопросы, а именно:
1) А какого цвета будет змейка
2) (Менее интересный) Что это за функция love.graphics.rectangle?

Ответы:

1) Она будет рисоваться белым, этот цвет ставиться внутри сишного кода перед вызовом love.draw(). Если вам этот цвет можно поставить вот таким вот методом:

love.graphics.setColor(0, 0, 255)				--змея будет синей

У этой функции четыре аргумента, но четвертый не является обязательным — это альфа цвета. Подробное описание вот здесь.
2) Как можно догадаться из названия, эта функция рисует четырехугольник цвета заданным этой функции. Первый аргумент — режим рисования, может быть «fine» или «line». Второй и третий аргумент координаты, Четвертый и пятый — размеры, подробно вот тут.

Можем продолжить

Ура! У нас есть неподвижная змейка, давайте потыкаем ее исправим это, напишем Update функцию:

function love.update(dt)
	if delay % 2 == 0 then						--лечим нервы
		table.remove(snake, table.getn(snake)) 				--убираем последний элемент и добавляем его в начало

		if direction == "up" then					--ну тут вроде все ясно, обрабатываем направление
			table.insert(snake, 1, { x = snake[1].x;
									 y = (snake[1].y - 1) % height; })
		elseif direction == "down" then
			table.insert(snake, 1, { x = snake[1].x;
									 y = (snake[1].y + 1) % height; })
		elseif direction == "left" then
			table.insert(snake, 1, { x = (snake[1].x - 1) % width;
									 y = snake[1].y; })
		else
			table.insert(snake, 1, { x = (snake[1].x + 1) % width;
									 y = snake[1].y; })
		end
	end
	delay = delay + 1
end

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

function love.keypressed(key)						--здесь мы будем смотреть какая кнопка была нажата
																		--выглядит стремно, но правильно
	if key == "up" then
		direction = "up"
	elseif key == "down" then
		direction = "down"
	elseif key == "left" then
		direction = "left"
	elseif key == "right" then
		direction = "right"
	elseif key == "escape" then
		love.event.quit()
	end
end

Теперь мы управляем происходящим, но где цель? Добавим-же яблок:
Во-первых, яблоко у нас есть, но мы его не рисуем, добавим прорисовку в love.draw():

love.graphics.setColor(255, 255, 0)					--мне нравиться голд
love.graphics.rectangle("fill", apple.x * 10, apple.y * 10, 10, 10)

А теперь нам надо рости:

if delay % 2 == 0 then							--лечим нервы
	if apple.x == snake[1].x and
		apple.y == snake[1].y then
		apple = { x = math.random(width);		                --вот и поели, генерируем X-координату
				  y = math.random(height); } 	                        --и Y..
	else 								--не сразу ясно, но понятно
		table.remove(snake, table.getn(snake)) 				--убираем последний элемент и добавляем его в начало
	end

	if direction == "up" then						--ну тут вроде все ясно, обрабатываем направление
		table.insert(snake, 1, { x = snake[1].x;
								 y = (snake[1].y - 1) % height; })
	elseif direction == "down" then
		table.insert(snake, 1, { x = snake[1].x;
								 y = (snake[1].y + 1) % height; })
	elseif direction == "left" then
		table.insert(snake, 1, { x = (snake[1].x - 1) % width;
								 y = snake[1].y; })
	else
		table.insert(snake, 1, { x = (snake[1].x + 1) % width;
								 y = snake[1].y; })
	end
end
delay = delay + 1

Ползаем, контролируем, поедаем, все готово!

Спасибо, за прочтение.
Исходники, с небольшим аддономом.

Буду благодарен за любые отзывы (:

Автор: yegorf1

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js