<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser-arcade-physics.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script>
const config = {
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
scene: {
preload: preload,
create: create,
update: update
},
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: false
}
}
};
let player;
let enemy;
let joystick;
let score = 0;
let scoreText;
let gameOver = false;
const game = new Phaser.Game(config);
function preload() {
this.load.image('player', 'assets/sprites/player.png');
this.load.image('enemy', 'assets/sprites/enemy.png');
}
function create() {
// Создание игрока
player = this.physics.add.sprite(400, 300, 'player');
player.setScale(0.5);
player.setCollideWorldBounds(true);
// Создание врага
enemy = this.physics.add.sprite(100, 100, 'enemy');
enemy.setScale(1.5);
enemy.setTint(0xff0000);
// Виртуальный джойстик
joystick = this.plugins.get('virtual-joystick').add(this, {
radius: 50,
x: 100,
y: config.height - 100,
base: this.add.circle(0, 0, 50, 0x888888).setAlpha(0.5),
thumb: this.add.circle(0, 0, 25, 0xcccccc).setAlpha(0.5)
});
// Текст счета
scoreText = this.add.text(20, 20, 'Score: 0', {
fontSize: '24px',
fill: '#fff',
backgroundColor: '#000'
});
// Коллизия игрока с врагом
this.physics.add.overlap(player, enemy, hitEnemy, null, this);
}
function update() {
if (gameOver) return;
// Движение игрока
const speed = 200;
if (joystick.force > 0) {
player.setVelocityX(joystick.velocityX * speed);
player.setVelocityY(joystick.velocityY * speed);
} else {
player.setVelocity(0);
}
// Преследование врага
this.physics.moveToObject(enemy, player, 250);
// Обновление счета
score += 0.1;
scoreText.setText(`Score: ${Math.floor(score)}`);
}
function hitEnemy() {
gameOver = true;
player.setTint(0xff0000);
this.physics.pause();
this.add.text(config.width/2 - 100, config.height/2, 'Game Over!\nTap to restart', {
fontSize: '32px',
fill: '#fff',
backgroundColor: '#000'
}).setInteractive()
.on('pointerdown', () => location.reload());
}
// Плагин для виртуального джойстика
class VirtualJoystickPlugin extends Phaser.Plugins.BasePlugin {
constructor(pluginManager) {
super(pluginManager);
pluginManager.registerGameObject('virtualJoystick', this.createJoystick);
}
createJoystick(config) {
return new VirtualJoystick(this.scene, config);
}
}
class VirtualJoystick {
constructor(scene, { radius, x, y, base, thumb }) {
this.scene = scene;
this.radius = radius;
this.base = base.setPosition(x, y);
this.thumb = thumb.setPosition(x, y);
this.position = new Phaser.Math.Vector2(x, y);
this.force = 0;
this.velocityX = 0;
this.velocityY = 0;
this.pointer = scene.input.activePointer;
this.isDown = false;
scene.input.on('pointerdown', this.onDown, this);
scene.input.on('pointerup', this.onUp, this);
scene.input.on('pointermove', this.onMove, this);
}
onDown(pointer) {
if (Phaser.Geom.Circle.ContainsPoint(this.base.getBounds(), pointer)) {
this.isDown = true;
}
}
onUp() {
this.isDown = false;
this.thumb.setPosition(this.position.x, this.position.y);
this.force = 0;
this.velocityX = 0;
this.velocityY = 0;
}
onMove(pointer) {
if (this.isDown) {
const deltaX = pointer.x - this.position.x;
const deltaY = pointer.y - this.position.y;
const angle = Math.atan2(deltaY, deltaX);
const distance = Math.min(Phaser.Math.Distance.Between(
this.position.x,
this.position.y,
pointer.x,
pointer.y
), this.radius);
this.thumb.setPosition(
this.position.x + Math.cos(angle) * distance,
this.position.y + Math.sin(angle) * distance
);
this.force = distance / this.radius;
this.velocityX = Math.cos(angle);
this.velocityY = Math.sin(angle);
}
}
}
// Регистрация плагина джойстика
Phaser.Plugins.PluginManager.register('virtual-joystick', VirtualJoystickPlugin, 'virtualJoystick');
</script>
</body>
</html>
Для работы игры вам нужно:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser-arcade-physics.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script>
const config = {
type: Phaser.AUTO,
width: window.innerWidth,
height: window.innerHeight,
scene: {
preload: preload,
create: create,
update: update
},
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: false
}
}
};
let player;
let enemy;
let joystick;
let score = 0;
let scoreText;
let gameOver = false;
const game = new Phaser.Game(config);
function preload() {
this.load.image('player', 'assets/sprites/player.png');
this.load.image('enemy', 'assets/sprites/enemy.png');
}
function create() {
// Создание игрока
player = this.physics.add.sprite(400, 300, 'player');
player.setScale(0.5);
player.setCollideWorldBounds(true);
// Создание врага
enemy = this.physics.add.sprite(100, 100, 'enemy');
enemy.setScale(1.5);
enemy.setTint(0xff0000);
// Виртуальный джойстик
joystick = this.plugins.get('virtual-joystick').add(this, {
radius: 50,
x: 100,
y: config.height - 100,
base: this.add.circle(0, 0, 50, 0x888888).setAlpha(0.5),
thumb: this.add.circle(0, 0, 25, 0xcccccc).setAlpha(0.5)
});
// Текст счета
scoreText = this.add.text(20, 20, 'Score: 0', {
fontSize: '24px',
fill: '#fff',
backgroundColor: '#000'
});
// Коллизия игрока с врагом
this.physics.add.overlap(player, enemy, hitEnemy, null, this);
}
function update() {
if (gameOver) return;
// Движение игрока
const speed = 200;
if (joystick.force > 0) {
player.setVelocityX(joystick.velocityX * speed);
player.setVelocityY(joystick.velocityY * speed);
} else {
player.setVelocity(0);
}
// Преследование врага
this.physics.moveToObject(enemy, player, 250);
// Обновление счета
score += 0.1;
scoreText.setText(`Score: ${Math.floor(score)}`);
}
function hitEnemy() {
gameOver = true;
player.setTint(0xff0000);
this.physics.pause();
this.add.text(config.width/2 - 100, config.height/2, 'Game Over!\nTap to restart', {
fontSize: '32px',
fill: '#fff',
backgroundColor: '#000'
}).setInteractive()
.on('pointerdown', () => location.reload());
}
// Плагин для виртуального джойстика
class VirtualJoystickPlugin extends Phaser.Plugins.BasePlugin {
constructor(pluginManager) {
super(pluginManager);
pluginManager.registerGameObject('virtualJoystick', this.createJoystick);
}
createJoystick(config) {
return new VirtualJoystick(this.scene, config);
}
}
class VirtualJoystick {
constructor(scene, { radius, x, y, base, thumb }) {
this.scene = scene;
this.radius = radius;
this.base = base.setPosition(x, y);
this.thumb = thumb.setPosition(x, y);
this.position = new Phaser.Math.Vector2(x, y);
this.force = 0;
this.velocityX = 0;
this.velocityY = 0;
this.pointer = scene.input.activePointer;
this.isDown = false;
scene.input.on('pointerdown', this.onDown, this);
scene.input.on('pointerup', this.onUp, this);
scene.input.on('pointermove', this.onMove, this);
}
onDown(pointer) {
if (Phaser.Geom.Circle.ContainsPoint(this.base.getBounds(), pointer)) {
this.isDown = true;
}
}
onUp() {
this.isDown = false;
this.thumb.setPosition(this.position.x, this.position.y);
this.force = 0;
this.velocityX = 0;
this.velocityY = 0;
}
onMove(pointer) {
if (this.isDown) {
const deltaX = pointer.x - this.position.x;
const deltaY = pointer.y - this.position.y;
const angle = Math.atan2(deltaY, deltaX);
const distance = Math.min(Phaser.Math.Distance.Between(
this.position.x,
this.position.y,
pointer.x,
pointer.y
), this.radius);
this.thumb.setPosition(
this.position.x + Math.cos(angle) * distance,
this.position.y + Math.sin(angle) * distance
);
this.force = distance / this.radius;
this.velocityX = Math.cos(angle);
this.velocityY = Math.sin(angle);
}
}
}
// Регистрация плагина джойстика
Phaser.Plugins.PluginManager.register('virtual-joystick', VirtualJoystickPlugin, 'virtualJoystick');
</script>
</body>
</html>