Создание 2D-игр с Tiniest2D
Пример завершенной игры
Lesson 10 of 11 • 10 XP
Keep your place in this quest
Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.
Пример: Полная игра
Этот урок создаёт небольшую коллекционную игру. Игрок перемещается по сцене, сталкивается со стенами, собирает монеты и выводит итоговый счёт, когда игра заканчивается.
Вместо того чтобы вставлять весь скрипт сразу, пример разбит на те же части, которые вы будете использовать в большинстве проектов Tiniest2D:
- переменные ассетов и состояния
start()onUpdate(dt)onCollision(objA, objB)end()
1. Ассеты и состояние игры
Первый раздел создаёт ассеты и переменные, которые будут использоваться в остальной части скрипта. Спрайты — это изображения, сцена — это уровень, игрок — это объект, размещённый в этой сцене, а переменные счёта/скорости хранят простое состояние игры.
// Создать ассеты
var playerImg = Sprite(16, 16)
var wallImg = Sprite(16, 16)
var coinImg = Sprite(8, 8)
var level = Scene()
// Создать игрока
var player = Object("Player")
// Состояние игры
var score = 0
var speed = 100
На этом этапе переменные существуют, но игра ещё не поместила ничего в сцену. Эта настройка происходит в start().
2. Функция start()
start() запускается один раз, когда начинается игра. Используйте её для настройки объектов, установки первой сцены, позиционирования камеры и подготовки начальных значений.
func start() {
// Настройка игрока
setSprite(player, playerImg)
setCollisionType(player, COLLISION_DYNAMIC())
setX(player, 50)
setY(player, 50)
addObject(level, player)
// Установить начальную сцену
setScene(level)
// Центрировать камеру на игроке
setCameraX(level, getX(player))
setCameraY(level, getY(player))
setCameraZoom(level, 3)
print("Соберите монеты!")
}
Игрок использует COLLISION_DYNAMIC(), потому что он должен сталкиваться и быть вытолкнутым из стен. Камера начинает с центровки на игроке, чтобы вид уровня начинался в правильном месте.
3. Функция onUpdate(dt)
onUpdate(dt) выполняется каждый кадр. Здесь игрок читает ввод, перемещается, обновляет камеру и проверяет клавиши сброса.
dt означает "дельта время": количество времени с предыдущего кадра. Умножение движения на dt делает скорость движения более последовательной на разных частотах кадров.
func onUpdate(dt) {
// Движение игрока
var moveX = 0
var moveY = 0
if (isKeyHeld(KEY_LEFT()) || isKeyHeld(KEY_A())) {
moveX = -1
}
if (isKeyHeld(KEY_RIGHT()) || isKeyHeld(KEY_D())) {
moveX = 1
}
if (isKeyHeld(KEY_UP()) || isKeyHeld(KEY_W())) {
moveY = -1
}
if (isKeyHeld(KEY_DOWN()) || isKeyHeld(KEY_S())) {
moveY = 1
}
// Применить движение
setX(player, getX(player) + moveX * speed * dt)
setY(player, getY(player) + moveY * speed * dt)
// Камера следует за игроком
setCameraX(level, getX(player))
setCameraY(level, getY(player))
// Сброс уровня с помощью клавиши R
if (isKeyPressed(KEY_R())) {
resetScene(level)
setX(player, 50)
setY(player, 50)
score = 0
print("Уровень сброшен!")
}
}
Код движения формирует направление на основе ввода с клавиатуры. Затем он добавляет это направление к текущей позиции игрока. Камера обновляется после движения, чтобы следовать за новой позицией.
4. Функция onCollision(objA, objB)
onCollision(objA, objB) выполняется, когда два объекта сталкиваются. В этом примере монеты должны использовать COLLISION_TRIGGER(). Триггерные объекты сообщают о перекрытиях, но не блокируют движение.
func onCollision(objA, objB) {
var nameB = getName(objB)
var typeB = getCollisionType(objB)
// Сбор монет (монеты должны быть типа TRIGGER в редакторе сцены)
if (typeB == COLLISION_TRIGGER()) {
removeObject(level, objB)
score = score + 1
print("Счёт: " + score)
}
}
Когда игрок касается триггера, скрипт удаляет этот объект из сцены и увеличивает счёт. Это основной шаблон для получения предметов, ключей, усилителей и контрольных точек.
5. Функция end()
end() запускается, когда игра останавливается. В этом примере просто выводится итоговый счёт, но в более крупных играх можно использовать эту функцию для очистки или финальных отладочных сообщений.
func end() {
print("Итоговый счёт: " + score)
}
Настройка примера
- Создайте спрайты:
- Ctrl+Клик на
playerImg, нарисуйте персонажа (например, простую фигуру) - Ctrl+Клик на
wallImg, нарисуйте солидный блок -
Ctrl+Клик на
coinImg, нарисуйте маленький круг или ромб -
Дизайн сцены:
- Ctrl+Клик на
level - Выберите
wallImgв левой панели, установите столкновение на "Статическое" - Нарисуйте стены вокруг краёв и создайте лабиринт
- Выберите
coinImg, установите столкновение на "Нет" для декоративных плиток монет -
Разместите монеты по уровню в качестве визуальных подсказок
-
Создайте триггерные объекты монет:
Спрайты, вставленные в сцену, полезны для плиток и украшений, но собираемые монеты должны быть объектами, чтобы коллизии могли их удалять. Добавьте объекты монет так:
var coin1 = Object("Coin1")
var coin2 = Object("Coin2")
func start() {
// ... настройка игрока ...
// Настройка монет как триггеров
setSprite(coin1, coinImg)
setCollisionType(coin1, COLLISION_TRIGGER())
setX(coin1, 100)
setY(coin1, 80)
addObject(level, coin1)
setSprite(coin2, coinImg)
setCollisionType(coin2, COLLISION_TRIGGER())
setX(coin2, 150)
setY(coin2, 120)
addObject(level, coin2)
// ... остальная часть start ...
}
Этот же шаблон можно расширить для других монет, врагов, дверей или любых объектов, которым необходимо поведение скрипта.