Paper.js предоставляет векторную сцену и удобную модель работы с
объектами, что делает его подходящим инструментом для создания 2D-игр с
упором на геометрию, анимацию и интерактивность. Основой является объект
Project, содержащий Layer и графические
элементы (Path, Shape, Group), а
также система обработки событий и таймлайна.
Игровое приложение на Paper.js обычно строится вокруг:
Paper.js предоставляет встроенный обработчик onFrame,
который вызывается каждый кадр. Это основной механизм обновления логики
игры.
function onFrame(event) {
// event.delta — время между кадрами
}
Ключевые задачи в onFrame:
Пример простого движения:
let player = new Path.Circle({
center: view.center,
radius: 20,
fillColor: 'blue'
});
function onFrame(event) {
player.position.x += 100 * event.delta;
}
Paper.js использует объект Point для представления
координат и векторов. Это существенно упрощает физику и движение.
let velocity = new Point(2, 3);
player.position += velocity;
Полезные операции:
add, subtractnormalizelengthgetDistanceПример движения к цели:
let target = new Point(300, 200);
function onFrame() {
let direction = target.subtract(player.position);
direction.length = 2;
player.position += direction;
}
Paper.js поддерживает события мыши и клавиатуры.
function onMouseMove(event) {
player.position = event.point;
}
let keys = {};
function onKeyDown(event) {
keys[event.key] = true;
}
function onKeyUp(event) {
keys[event.key] = false;
}
function onFrame() {
if (keys['left']) player.position.x -= 3;
if (keys['right']) player.position.x += 3;
}
Для удобства используется объектно-ориентированный подход.
class GameObject {
constructor() {
this.shape = null;
}
update(delta) {}
remove() {
this.shape.remove();
}
}
class Player extends GameObject {
constructor(position) {
super();
this.shape = new Path.Circle({
center: position,
radius: 20,
fillColor: 'blue'
});
this.speed = 200;
}
update(delta) {
let move = new Point(0, 0);
if (keys['w']) move.y -= 1;
if (keys['s']) move.y += 1;
if (keys['a']) move.x -= 1;
if (keys['d']) move.x += 1;
move.length = this.speed * delta;
this.shape.position += move;
}
}
Paper.js предоставляет метод intersects, который
упрощает проверку пересечений.
if (player.shape.intersects(enemy.shape)) {
console.log("Collision!");
}
let distance = player.shape.position.getDistance(enemy.shape.position);
if (distance < playerRadius + enemyRadius) {
// столкновение
}
Пример создания простых врагов:
class Enemy extends GameObject {
constructor(position) {
super();
this.shape = new Path.Circle({
center: position,
radius: 15,
fillColor: 'red'
});
}
update(delta) {
this.shape.position.y += 50 * delta;
}
}
Создание с интервалом:
let enemies = [];
setInterval(() => {
let x = Math.random() * view.size.width;
let enemy = new Enemy(new Point(x, 0));
enemies.push(enemy);
}, 1000);
class Bullet extends GameObject {
constructor(position) {
super();
this.shape = new Path.Circle({
center: position,
radius: 5,
fillColor: 'yellow'
});
this.velocity = new Point(0, -300);
}
update(delta) {
this.shape.position += this.velocity * delta;
}
}
Создание при клике:
let bullets = [];
function onMouseDown(event) {
let bullet = new Bullet(player.shape.position.clone());
bullets.push(bullet);
}
Важно удалять объекты, чтобы избежать утечек памяти.
bullets = bullets.filter(bullet => {
if (bullet.shape.position.y < 0) {
bullet.remove();
return false;
}
return true;
});
Paper.js позволяет создавать плавные визуальные эффекты.
function onFrame(event) {
player.scale(1 + Math.sin(event.time * 5) * 0.01);
}
function createExplosion(position) {
let circle = new Path.Circle({
center: position,
radius: 10,
fillColor: 'orange'
});
let life = 0;
function animate(event) {
life += event.delta;
circle.scale(1.1);
circle.opacity -= 0.02;
if (circle.opacity <= 0) {
circle.remove();
view.off('frame', animate);
}
}
view.on('frame', animate);
}
Для сложных сцен используется Layer и
Group.
let playerLayer = new Layer();
let enemyLayer = new Layer();
let group = new Group([player.shape]);
Преимущества:
Paper.js не имеет встроенной камеры, но можно имитировать её через
смещение view.center.
function onFrame() {
view.center = player.shape.position;
}
PathonFrameevent.deltalet player = new Player(view.center);
let enemies = [];
function onFrame(event) {
player.update(event.delta);
enemies.forEach(enemy => enemy.update(event.delta));
enemies.forEach(enemy => {
if (player.shape.intersects(enemy.shape)) {
console.log("Game Over");
}
});
}
let score = 0;
function increaseScore() {
score += 10;
}
let text = new PointText({
point: [10, 20],
content: 'Score: 0',
fillColor: 'black'
});
Обновление:
text.content = 'Score: ' + score;
Paper.js не работает со звуком напрямую, используется стандартный API:
let sound = new Audio('shoot.mp3');
sound.play();
Однако для:
библиотека остаётся мощным и удобным инструментом.