В рамках дипломного проекта вам необходимо реализовать ключевые компоненты игры. Игра будет запускаться и работать в браузере.
Реализовывать проект и предоставить его на проверку можно двумя способами:
- Локально и публиковать код в ваш репозитории GitHub или BitBucket
- В онлайн песочнице CodePen или Repl.it
Сама игра будет функционировать когда вы окончательно реализуете все компоненты. Но чтобы понять правильно ли реализован каждый из них, для каждого компоненты дан пример кода и результат работы его, по которому вы можете проверить правильно ли вы его реализовали. Сам код пимеров в итоговом решении оставлять не рекомендуется.
Так же есть возможность запустить тесты, которые покажут верно ли реализован каждый компонент. Об этом будет подробно описано в разделе Тестирование.
- Установить git.
- Создайте аккаунт в сервисе GitHub или BitBucket
- Создайте публичный репозиторий.
- Скопируйте ссылку на репозиторий (рекомендуем использовать HTTPS, если ранее вы не сталкивались с SSH).
- Клонируйте ваш репозиторий локально используя команду
git clone
.
Итогом будет наличие папки на локальном компьютере, в которым инициализорован git репозиторий, и настроена связь с репозиторием на GitHub или BitBucket.
- Скачайте свежую версию проекта по ссылке
https://github.com/netology-code/js-game/releases
- Разверните архив проекта в папку созданную при подготовке репозитория.
- Ваш код пишите в файле
./game.js
- Для запуска игры откройте в браузере файл
./index.html
- Для запуска тестов откройте в браузере файл
./test/index.html
Менять остальные файлы не рекомендуется.
- Добавьте к коммиту файл
game.js
командойgit add game.js
- Сделайте коммит
git commit
- Опубликуйте изменения с помощью команды
git push
Все компоненты игры будут работать локально, кроме функции loadLevels
, действия которой будут заблокированы политикой безопасности бразуера.
Один из вариантов обойти это: запустить локальный веб-сервер.
- Установить php на компьютер
- Для запуска сервера в папке проекта запустить команду
php -S localhost:3000
- Для запуска игры откройте в браузере адрес
http://localhost:3000/index.html
- Для запуска тестов откройте в браузере адрес
http://localhost:3000/test/index.html
- Установить NodeJS
- В папке проекта выполнить команду
npm install
- Для запуска сервера в папке проекта запустить команду
npm start
- Для запуска игры откройте в браузере адрес
http://localhost:3000/index.html
- Для запуска тестов откройте в браузере адрес
http://localhost:3000/test/index.html
При использовании NodeJS тесты и игра будут обновляться автоматически при изменении файлов.
Для реализации в онлайн песочнице вам нужно:
- Зарегистрироваться на сервисе CodePen
- Открыть заготовку проекта по ссылке:
https://codepen.io/dfitiskin/pen/XRZqWd?editors=0010
- Нажать кнопку «Fork», тем самым создав свою копию заготовки.
- Реализовывать код игры последовательно следую инструкции в окне «JS».
- Переодически сохраняйте результат, чтобы не потерять изменения.
- Отправляйте наставнику на проверку ссылку на ваш пен.
Инструкция по использованию сервиса CodePen: https://netology-university.bitbucket.io/wm/resourses/codepen-guide.html
- Зарегистрироваться на сервисе Repl.it
- Создать новую песочницу «HTML, CSS, JS»
https://repl.it/languages/web_project
- Во вкладке
index.html
поместите следующий код
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://netology-code.github.io/js-game/css/main.css">
</head>
<body>
<script src="https://netology-code.github.io/js-game/js/app.js"></script>
<script src="./index.js"></script>
</body>
</html>
- Нажмите кнопку «Save»
- Реализовывать код игры последовательно следую инструкции во вкладке «index.js».
- Переодически сохраняйте результат, чтобы не потерять изменения.
- Отправляйте наставнику на проверку ссылку на вашу песочницу, которую пожно получить по кнопке «Share».
В файле ./test/index.html
настроена среда автоматизированного тестирования вашего кода. Она проверяет созданные компоненты на соответствие требованиям. И если находит расхождения, сообщает об ошибки. Тем самым, тесты — ваш навигатор, показывающий какой часть требований в вашем коде вы выполнили, а какую нет.
По тестам можно осуществлять навигацию. Можно выбрать конкретный компонет, или конкретный метод, и следить за выполнением только выбранных тестов, не отвлекаясь на другие.
Так же можно отобразить только проваленные тесты, или наоборот, только успешные.
Просто кликайте на соответствующий пункт, чтобы сосредоточиться на нем.
Процесс реализации можно построить таким образом:
- Выбрать компонет или даже метод компонента.
- Отфильтровать тесты, оставив только выбранный компонент или его метод.
- Реализовать код который удовлетворит первому проваленному тесту.
- Убедиться что тест помечен как успешный.
- Если остались еще проваленные тесты, вернуться к пункту 3.
Такой подход называется разработка через тестирование или TDD. За тем лишь исключением, что тесты уже написаны.
Для того чтобы максимально просто и быстро получить базовый рабочий вариант проекта, рекомендуем придерживаться следующего плана разработки:
- Реализовать базовые классы игры
Vector
,Actor
иLevel
. - После этого вы уже сможете запустить игру.
const grid = [
new Array(3),
['wall', 'wall', 'lava']
];
const level = new Level(grid);
runLevel(level, DOMDisplay);
На экране отобразится схема уровня. Узнайте подробнее про функцию runLevel
и класс DOMDisplay
ниже.
- Реализуйте
LevelParser
, что позволит вам описывать уровни с помощью текстовой схемы:
const schema = [
' ',
' ',
' ',
' ',
' !xxx',
' ',
'xxx! ',
' '
];
const parser = new LevelParser();
const level = parser.parse(schema);
runLevel(level, DOMDisplay);
- Реализуйте
Player
и поместите его символ на схему и добавьте словарь при создании парсера:
const schema = [
' ',
' ',
' ',
' ',
' !xxx',
' @ ',
'xxx! ',
' '
];
const actorDict = {
'@': Player
}
const parser = new LevelParser(actorDict);
const level = parser.parse(schema);
runLevel(level, DOMDisplay);
- Реализуйте другие движущиеся объекты игрового поля и помещайте их символы на схему и в словарь парсера.
- Реализуйте загрузку уровней с помощью функции
loadLevels
и запуск игры с помощьюrunGame
. - Когда игрок пройдет все уровни, используйте функцию
alert
чтобы сообщить о победе.
Отвечает за отрисовку в браузере сетки игрового поля и движущихся объектов. Конструктор принимает два аргумента: первый узел DOM, в котором необходимо отрисовать игровое поле и уровень Level
описывающий игровое поле.
Непосредственно создавать этот объект не потребуется. Его необходимо передавать вторым аргументом в функцию runLevel
и третьим аргументом в функцию runGame
.
Пример использования:
const schema = [
' ',
' ',
' = ',
' ',
' !xxx',
' @ ',
'xxx! ',
' '
];
const actorDict = {
'@': Player,
'=': HorizontalFireball
}
const parser = new LevelParser(actorDict);
const level = parser.parse(schema);
DOMDisplay(document.body, level);
После такого вызова будет отрисовано исходное состояние сетки игрового поля, все движущиеся объекты. Но эта схема будет статичной.
Инициализирует процесс регулярной отрисовки текущего состояния игрового поля и обработку событий клавиатуры.
Принимает два аргумента: уровень, объект класса Level
и конструктор объекта отвечающего за отрисовку. В случае реализации игры в браузере вторым аргументом необходимо использовать класс DOMDisplay
.
Функция возвращает промис, который разрешится статусом завершения игры, строка. С учетом реализации класс Level
он может принимать значений won
и lost
.
Пример использования:
const schema = [
' ',
' ',
' = ',
' o ',
' !xxx',
' @ ',
'xxx! ',
' '
];
const actorDict = {
'@': Player,
'=': HorizontalFireball
}
const parser = new LevelParser(actorDict);
const level = parser.parse(schema);
runLevel(level, DOMDisplay)
.then(status => console.log(`Игрок ${status}`));
После вызова такого кода в браузере будет отрисована схема уровня, движущиеся объекты будут перемещаться, и вы сможете управлять игроком с клавиатуры.
Инициализирует процесс прохождения игры состоящей из последовательного прохождения нескольких уровней.
Принимает три аргумента: список схем уровней, массив каждый элемент которого схема (массив строк); парсер схем, объект LevelParser
, и конструктор объекта отвечающего за отрисовку. В случае реализации игры в браузере третьим аргументом необходимо использовать класс DOMDisplay
.
Возвращает промис, который разрешится когда пользователь пройдет все уровни.
Пример использования:
const schemas = [
[
' ',
' ',
' = ',
' o ',
' !xxx',
' @ ',
'xxx! ',
' '
],
[
' v ',
' v ',
' v ',
' o',
' x',
'@ x ',
'x ',
' '
]
];
const actorDict = {
'@': Player,
'v': FireRain
}
const parser = new LevelParser(actorDict);
runGame(schemas, parser, DOMDisplay)
.then(() => console.log('Вы выиграли приз!'));
Запустит игру из двух уровней, которые необходимо будет пройти последовательно.
Загружает коллекцию уровней. Не принимает аргументов.
Возвращает промис, который разрешится
Необходимо реализовать класс Vector
, который позволит контролировать расположение объектов в двухмерном пространстве и управлять их размером и перемещением.
Принимает два аргумента: координата по оси X и по оси Y, числа, по умолчанию 0
.
Создает объект со свойствами x
и y
равные переданным в конструктор координатам.
Принимает один аргумент: вектор, объект Vector
.
Если передать аргумент другого типа, то бросает исключение Можно прибавлять к вектору только вектор типа Vector
.
Создает и возвращает новый объект типа Vector
, координаты которого будут суммой соответствующих координат суммируемых векторов.
Принимает один аргумент: множитель, число.
Создает и возвращает новый объект типа Vector
, координаты которого будут равны соответствующим координатам исходного вектора умноженным на множитель.
const start = new Vector(30, 50);
const moveTo = new Vector(5, 10);
const finish = start.plus(moveTo.times(2));
console.log(`Исходное расположение: ${start.x}:${start.y}`);
console.log(`Текущее расположение: ${finish.x}:${finish.y}`);
Результат выполнения кода:
Исходное расположение: 30:50
Текущее расположение: 40:70
Необходимо реализовать класс Actor
, который позволит контролировать все движущиеся объекты на игровом поле и контролировать их пересечение.
Принимает три аргумента: расположение, объект типа Vector
, размер, тоже объект типа Vector
и скорость, тоже объект типа Vector
. Все аргументы не обязательные. По умолчанию создается объект с координатами 0:0, размером на 1x1 и скоростью 0:0.
Если в качестве первого, второго или третьего аргумента передать не объект типа Vector
, то конструктор должен бросить исключение.
Должно быть определено свойство pos
, в котором размещен Vector
.
Должно быть определено свойство size
, в котором размещен Vector
.
Должно быть определено свойство speed
, в котором размещен Vector
.
Должен быть определен метод act
, который ничего не делает.
Должны быть определены свойства только для чтения left
, top
, right
, bottom
, в котором установлены границы объекта по осям X и Y с учетом его расположения и размера.
Должен иметь свойство type
, строка со значением actor
, только для чтения.
Метод проверяет пересекается ли текущий объект с переданным объектом, и если да, возвращает true
, иначе false
.
Принимает один аргумент: движущийся объект типа Actor
. Если передать аргумент другого типа или вызвать без аргументов, то метод бросает исключение.
Если передать в качестве аргумента этот же объект, то всегда возвращает false
. Объект не пересекается сам с собой.
Объекты имеющие смежные границы не пересекаются.
const items = new Map();
const player = new Actor();
items.set('Игрок', player);
items.set('Первая монета', new Actor(new Vector(10, 10)));
items.set('Вторая монета', new Actor(new Vector(15, 5)));
function position(item) {
return ['left', 'top', 'right', 'bottom']
.map(side => `${side}: ${item[side]}`)
.join(', ');
}
function movePlayer(x, y) {
player.pos = player.pos.plus(new Vector(x, y));
}
function status(item, title) {
console.log(`${title}: ${position(item)}`);
if (player.isIntersect(item)) {
console.log(`Игрок подобрал ${title}`);
}
}
items.forEach(status);
movePlayer(10, 10);
items.forEach(status);
movePlayer(5, -5);
items.forEach(status);
Результат работы примера:
Игрок: left: 0, top: 0, right: 1, bottom: 1
Первая монета: left: 10, top: 10, right: 11, bottom: 11
Вторая монета: left: 15, top: 5, right: 16, bottom: 6
Игрок: left: 10, top: 10, right: 11, bottom: 11
Первая монета: left: 10, top: 10, right: 11, bottom: 11
Игрок подобрал Первая монета
Вторая монета: left: 15, top: 5, right: 16, bottom: 6
Игрок: left: 15, top: 5, right: 16, bottom: 6
Первая монета: left: 10, top: 10, right: 11, bottom: 11
Вторая монета: left: 15, top: 5, right: 16, bottom: 6
Игрок подобрал Вторая монета
Объекты класса Level
реализуют схему игрового поля конкретного уровня, контроллируют все движущиеся объекты на нём и реализуют логику игры. Уровень представляет собой координатное поле, имеющее фиксированную ширину и высоту.
Сетка уровня представляет собой координатное двумерное поле, представленное двумерным массивом. Первый массив — строки игрового поля, индекс этого массива соответствует координате Y на игровом поле. Элемент с индексом 5
соответствует строке с координатой Y равной 5
. Вложенные массивы расположенные в элементах массива строк представляют ячейки поля. Индекс этих массивов соответствует координате X. Например, элемент с индексом 10
, соответстует ячейке с координатой X равной 10
.
Так как grid
это двумерный массив представляющий сетку игрового поля, то чтобы узнать что находится в ячейке с координатами X=10 и Y=5 (10:5), необходимо получить значение grid[5][10]
. Если значение этого элемента равно undefined
, то эта ячейка пуста. Иначе там будет строка описывающая препятствие. Например wall
— для стены и lava
— для лавы. Отсюда вытекает следующий факт: все препятствия имеют целочисленные размеры и координаты.
Принимает два аргумента: сетку игрового поля с препятствиями, массив массивов строк, и список движущихся объектов, массив объектов Actor
. Оба аргумента не обязательные.
Имеет свойство grid
— сетка игрового поля. Двумерный массив строк.
Имеет свойство actors
— список движущихся объектов игрового поля, массив объектов Actor
.
Имеет свойство height
— высота игрового поля, равное числу строк в сетке из первого аргмента.
Имеет свойство width
- ширина игрового поля, равное числу ячеек в строке сетки из первого аргмента. При этом, если в разных строках разное число ячеек, то width
будет равно максимальному количеству ячеек в строке.
Имеет свойство status
- состояние прохождения уровня, равное null
после создания.
Имеет свойство finishDelay
— таймаут после окончания игры, равен 1
после создания. Необходим чтобы после выигрыша или проигрыша игра не завершалась мнгновенно.
Определеяет завершен ли уровень. Не принимает аргументов.
Возвращает true
если свойство status
не равно null
и finishDelay
меньше нуля.
Определяет расположен ли какой-то другой движущийся объект в переданной позиции, и если да, вернёт этот объект.
Принимает один аргумент — движущийся объект, Actor
. Если не передать аргумент, или передать не объект Actor
метод должен бросить исключение.
Возвращает undefined
если переданный движущийся объект не пересекается ни с одним объектом на игровом поле.
Возвращает объект Actor
, если переданный объект пересекается с ним на игровом поле. Если пересекается с несколькими объектами, вернет первый.
Аналогично методу actorAt
определяет нет ли препятствия в указанном месте. Так же этот метод контроллирует выход объекта за границы игрового поля.
Так как движущиеся объекты не могут двигаться сквозь стены, то метод принимает два аргумента: положение, куда собираемся передвинуть объект, вектор Vector
, и размер этого объекта, тоже вектор Vector
. Если первым и вторым аргументом передать не Vector
, то метод бросает исключение.
Вернет строку соответствующую препятствию из сетки игрового поля, пересаекающему область описанную двумя переданными векторами, либо undefined
, если в этой области препятствий нет.
Если описанная двумя векторами область выходит за пределы игрового поля, то метод вернет строку lava
, если область выступает снизу. И вернет wall
в остальных случаях. Будем считать, что игровое поле слева, сверху и справа огорожено стеной и снизу у него смертельная лава.
Метод удаляет переданный объект с игрового поля. Если такого объекта на игровом поле нет, не делает ничего.
Принимает один аргумент, объект Actor
. Находит и удаляет его.
Определяет остались ли еще объекты переданного типа на игровом поле.
Принимает один аргумент, тип движущегося объекта, строка.
Возвращает true
, если на игровом поле нет объектов этого типа (свойство type
). Иначе возвращает false
.
Один из ключевых методов, определяющий логику игры. Меняет состояние игрового поля при касании игрока каких-либо объектов или препятствий.
Если состояние игры уже отлично от null
, то не делаем ничего, игра уже и так завершилась.
Принимает два аргмента. Тип препятствия или объекта, строка. Движущийся объект, которого коснулся игрок, объект типа Actor
, не обязательный аргумент.
Если первым аргументом передать строку lava
или fireball
, то меняем статус игры на lost
(свойство status
). Игрок проигрывает при касании лавы или шаровой молнии.
Если первым аргментом передать строку coin
, а вторым объект монеты, то необходимо удалить эту монету с игрового поля. Если при этом на игровом поле не осталось больше монет, то меняем статус игры на won
. Игрок побеждает, когда собирает все монеты на уровне. Отсюда вытекает факт, что уровень без монет пройти невозможно.
const grid = [
[undefined, undefined],
['wall', 'wall']
];
const goldCoin = { type: 'coin', title: 'Золото' };
const bronzeCoin = { type: 'coin', title: 'Бронза' };
const player = new Actor();
const fireball = new Actor();
const level = new Level(undefined, [ goldCoin, bronzeCoin, player, fireball ]);
level.playerTouched('coin', goldCoin);
level.playerTouched('coin', bronzeCoin);
if (level.noMoreActors('coin')) {
console.log('Все монеты собраны');
console.log(`Статус игры: ${level.status}`);
}
const obstacle = level.obstacleAt(new Vector(1, 1), player.size);
if (obstacle) {
console.log(`На пути препятствие: ${obstacle}`);
}
const otherActor = level.actorAt(player);
if (otherActor === fireball) {
console.log('Пользователь столкнулся с шаровой молнией');
}
Результат выполнения:
Все монеты собраны
Статус игры: won
На пути препятствие: wall
Пользователь столкнулся с шаровой молнией
Объект класса LevelParser
позволяет создать игровое поле Level
из массива строк по следующему принципу:
- Каждый элемент массив соответствует строке в сетке уровня.
- Каждый символ строки соответствует ячейке в сетке уровня.
- Символ определяет тип объекта или препятствия.
- Индекс строки, и индекс символа определяют исходные координаты объекта или координаты препятствия.
Символы и соответствующие им препятствия и объекты игрового поля:
- x — стена, препятствие
- ! — лава, препятствие
- @ — игрок, объект
- o — монетка, объект
- = — движущаяся горизонтально шаровая молния, объект
- | — движущаяся вертикально шаровая молния, объект
- v — огненный дождь, объект
Обратите внимание что тут слово символ означает букву, цифру или знак, которые используются в строках, а не тип данных
Symbol
.
Принимает один аргумент: словарь движущихся объектов игрового поля, объект, ключами которого являются символы из текстового представления уровня, а значениями конструкторы, с помощью которых можно создать новый объект.
Принимает символ, строка. Возвращает конструктор объекта по его символу, используя словарь. Если в словаре не нашлось ключа с таким символом, вернет undefined
.
Аналогично принимает символ, строка. Возвращает строку соответствующую символу припятствия. Если символу нет соответствующего препятствия, то вернет undefined
.
Вернет wall
, если передать x
.
Вернет lava
, если передать !
.
Вернет undefined
, если передать любой другой символ.
Принимает массив строк и преобразует его в массив массивов, в ячейках которого хранится либо строка соответствующая препятствию, либо undefined
.
Движущиейся объекты не должны присутствовать на сетке.
Принимает массив строк и преобразует его в массив движущихся объектов используя для их создания конструкторы из словаря.
Количество движущихся объектов в результирующем массиве должно быть равно количеству символов объектов в массиве строк.
Каждый объект должен быть создан с использованием вектора определяющего его положение с учетом координат, полученных на основе индекса строки в массиве (Y) и индекса символа в строке (X).
Для создания объекта должен быть использован конструктор из словаря, соответствующий символу. При этом, если этот конструктор не является экземпляром Actor
, то такой символ игнорируется, и объект не создается.
Принимает массив строк, создает и возвращает игровое поле заполненное препятсвиями и движущимися объектами полученными на освнове символов и словаря.
const plan = [
' @ ',
'x!x'
];
const actorsDict = Object.create(null);
actorsDict['@'] = Actor;
const parser = new LevelParser(actorsDict);
const level = parser.parse(plan);
level.grid.forEach((line, y) => {
line.forEach((cell, x) => console.log(`(${x}:${y}) ${cell}`));
});
level.actors.forEach(actor => console.log(`(${actor.pos.x}:${actor.pos.y}) ${actor.type}`));
Результат выполнения кода:
(0:0) undefined
(1:0) undefined
(2:0) undefined
(0:1) wall
(1:1) lava
(2:1) wall
(1:0) actor
Класс Fireball
станет прототипом для движущихся опасностей на игровом поле. Он должен наследовать весь функционал движущегося объекта Actor
.
Принимает два аргумента: координаты, объект Vector
и скорость, тоже объект Vector
. Оба аргумента не обязательные. По умолчанию создается объект с координатами 0:0
и скоростью 0:0
.
Созданный объект должен иметь свойство type
со значением fireball
. Это свойство только для чтения.
Так же должен иметь размер 1:1
в свойстве size
, объект Vector
.
Создает и возвращает вектор Vector
следующей позиции шаровой молнии. Это функция времени. И как в школьной задаче, новая позиция это текущая позиция плюс скорость умноженная на время. И так по каждой из осей.
Принимает один аргумент, время, число. Аргумент не обязательный, по умолчанию равен 1
.
Обрабатывает сталкновение молнии с препятствием. Не принимает аргументов. Ничего не возвращает.
Меняет вектор скорости на противоположный. Если он был 5:5
, то после должен стать -5:-5
.
Обновляет состояние движущегося объекта.
Принимает два аргумента. Первый — время, число, второй, игровое поле, объект Level
.
Метод ничего не возвращает. Но должен выполнить следующие действия:
- Получить следующую позицию, используя время.
- Выяснить не пересечется ли в следующей позиции объект с каким-либо препятствием. Пересечения с другими движущимися объектами учитывать не нужно.
- Если нет, обновить текущую позицию объекта.
- Если объект пересекается с препятствием, то необходим обработать это событие. При этом текущее положение остается прежним.
const time = 5;
const speed = new Vector(1, 0);
const position = new Vector(5, 5);
const ball = new Fireball(position, speed);
const nextPosition = ball.getNextPosition(time);
console.log(`Новая позиция: ${nextPosition.x}: ${nextPosition.y}`);
ball.handleObstacle();
console.log(`Текущая скорость: ${ball.speed.x}: ${ball.speed.y}`);
Результат работы кода:
Новая позиция: 10: 5
Текущая скорость: -1: 0
Вам необходимо самостоятельно реализовать класс HorizontalFireball
. Он будет представлять собой объект который движется по горизонтали со скоростью 2
и при столкновении с препятствием движется в обратную сторону.
Конструктор должен принимать один аргумент: координаты текущего положения, объект Vector
. И создавать объект размером 1:1
и скоростью равной 2
по оси X.
Вам необходимо самостоятельно реализовать класс VerticalFireball
. Он будет представлять собой объект который движется по вертикали со скоростью 2
и при столкновении с препятствием движется в обратную сторону.
Конструктор должен принимать один аргумент: координаты текущего положения, объект Vector
. И создавать объект размером 1:1
и скоростью равной 2
по оси Y.
Вам необходимо самостоятельно реализовать класс FireRain
. Он будет представлять собой объект который движется по вертикали со скоростью 3
и при столкновении с препятствием начинает движение в том же направлении из исходного положения, которое задано при создании.
Конструктор должен принимать один аргумент: координаты текущего положения, объект Vector
. И создавать объект размером 1:1
и скоростью равной 3
по оси Y.
Класс Coin
реализует поведение монетки на игровом поле. Чтобы привлекать к себе внимание, монетки должны постоянно подпрыгивать в рамках своей ячейки. Он должен наследовать весь функционал движущегося объекта Actor
.
Принимает один аргмент: координаты положения на игровом поле, объект Vector
.
Созданный объект должен иметь размер 0,6:0,6
. А его реальный координаты должны отличаться от тех что переданы в конструктор на вектор 0,2:0,1
.
Свойство type
созданного объекта должно иметь значение coin
.
Так же объект должен иметь следующие свойства:
- Скорость подпрыгивания,
springSpeed
, равное8
; - Радиус подпрыгивания,
springDist
, равен0.07
; - Фаза подпрыгивания,
spring
, случайное число от0
до2π
.
Обновляет фазу подпрыгивания. Это функция времени.
Принимает один аргумент, время, число, по умолчанию 1
.
Ничего не возвращает. Обновляет текущую фазу spring
, увеличив её на скорость springSpeed
умноженную на время.
Создает и возвращает вектор подпрыгивания. Не принимает аргментов.
Так как подпрыгивание происходит только по оси Y, то координата X вектора всегда равна нулю.
Координата Y вектора равна синусу текущей фазы, умноженному на радиус.
Обновляет текущую фазу, создает и возвращает вектор новой позиции монетки.
Принимает один аргумент, время, число, по умолчанию 1
.
Новый вектор равен базовому вектору положения, увеличенному на вектор подпрыгивания. Увеличивать нужно именно базовый вектор положения, который получен в конструкторе, а не текущий.
Принимает один аргмент, время. Получает новую позицию объекта, и задает её как текущую. Ничего не возвращает.
Класс Player
содержит базовый функционал движущегося объекта, который представляет игрока на игровом поле. Должен наследовать возможности Actor
.
Принимает один аргумент: координаты положения на игровом поле, объект Vector
.
Созданный объект реальное положение которого отличается от того что передано в конструктор на веткор 0:-0,5
. Имеет размер 0,8:1,5
. И скорость 0:0
.
Имеет свойство type
равное player
.