First Working Version
This commit is contained in:
parent
de94402c96
commit
fa73b3c44f
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Zenith Vector</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #000;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
}
|
||||||
|
#game-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="game-container"></div>
|
||||||
|
|
||||||
|
<!-- Load Phaser from local file -->
|
||||||
|
<script src="phaser.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Import game modules using ES6 modules -->
|
||||||
|
<script type="module">
|
||||||
|
import { config } from './src/config.js';
|
||||||
|
import { GameScene } from './src/scenes/GameScene.js';
|
||||||
|
|
||||||
|
const game = new Phaser.Game(config);
|
||||||
|
game.scene.add('GameScene', GameScene, true);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,18 @@
|
||||||
|
export const config = {
|
||||||
|
type: Phaser.AUTO,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
parent: 'game-container',
|
||||||
|
physics: {
|
||||||
|
default: 'arcade',
|
||||||
|
arcade: {
|
||||||
|
gravity: { y: 0 },
|
||||||
|
debug: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scene: {
|
||||||
|
preload: function() {},
|
||||||
|
create: function() {},
|
||||||
|
update: function() {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
class Player extends Phaser.GameObjects.Container {
|
||||||
|
constructor(scene, x, y) {
|
||||||
|
super(scene, x, y);
|
||||||
|
|
||||||
|
// Create the player sprite
|
||||||
|
this.sprite = scene.add.sprite(0, 0, 'player');
|
||||||
|
this.add(this.sprite);
|
||||||
|
|
||||||
|
// Set up input controls using A/D keys instead of arrow keys
|
||||||
|
this.keys = scene.input.keyboard.addKeys({
|
||||||
|
a: Phaser.Input.Keyboard.KeyCodes.A,
|
||||||
|
d: Phaser.Input.Keyboard.KeyCodes.D
|
||||||
|
});
|
||||||
|
|
||||||
|
// Player properties
|
||||||
|
this.speed = 200;
|
||||||
|
this.health = 100;
|
||||||
|
this.isAlive = true;
|
||||||
|
|
||||||
|
// Set initial position
|
||||||
|
this.setPosition(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
if (!this.isAlive) return;
|
||||||
|
|
||||||
|
// Move with A/D keys instead of arrow keys
|
||||||
|
if (this.keys.a.isDown) {
|
||||||
|
this.x -= this.speed * this.scene.game.loop.delta / 1000;
|
||||||
|
}
|
||||||
|
if (this.keys.d.isDown) {
|
||||||
|
this.x += this.speed * this.scene.game.loop.delta / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep player within bounds
|
||||||
|
this.x = Phaser.Math.Clamp(this.x, 25, 775);
|
||||||
|
|
||||||
|
// Update position of the container's child sprite
|
||||||
|
this.sprite.setPosition(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
aimAt(targetX, targetY) {
|
||||||
|
// Not used in current implementation but kept for potential future use
|
||||||
|
}
|
||||||
|
|
||||||
|
fire() {
|
||||||
|
if (!this.isAlive) return;
|
||||||
|
|
||||||
|
// Fire bullet from player position
|
||||||
|
const bullet = new Bullet(this.scene, this.x, this.y - 20);
|
||||||
|
this.scene.bullets.add(bullet);
|
||||||
|
|
||||||
|
// Set bullet velocity
|
||||||
|
bullet.setVelocityY(-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
hit(damage) {
|
||||||
|
if (!this.isAlive) return;
|
||||||
|
|
||||||
|
this.health -= damage;
|
||||||
|
|
||||||
|
if (this.health <= 0) {
|
||||||
|
this.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
export class GameScene extends Phaser.Scene {
|
||||||
|
constructor() {
|
||||||
|
super({ key: 'GameScene' });
|
||||||
|
|
||||||
|
// Game objects references
|
||||||
|
this.player = null;
|
||||||
|
this.enemies = null;
|
||||||
|
this.bullets = null;
|
||||||
|
this.cursors = null;
|
||||||
|
|
||||||
|
// Game state
|
||||||
|
this.score = 0;
|
||||||
|
this.gameOver = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
preload() {
|
||||||
|
// Load assets here (will be implemented in a later step)
|
||||||
|
console.log('Loading assets...');
|
||||||
|
|
||||||
|
// Create simple placeholder graphics for now
|
||||||
|
this.createPlaceholderGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
// Set background color
|
||||||
|
this.cameras.main.setBackgroundColor('#0a0a2a');
|
||||||
|
|
||||||
|
// Create player ship
|
||||||
|
this.player = this.physics.add.sprite(400, 500, 'player');
|
||||||
|
this.player.setCollideWorldBounds(true);
|
||||||
|
|
||||||
|
// Create groups for bullets and enemies
|
||||||
|
this.bullets = this.physics.add.group();
|
||||||
|
this.enemies = this.physics.add.group();
|
||||||
|
|
||||||
|
// Setup controls
|
||||||
|
this.cursors = this.input.keyboard.createCursorKeys();
|
||||||
|
|
||||||
|
// Setup collision detection
|
||||||
|
this.physics.add.overlap(this.bullets, this.enemies, this.hitEnemy, null, this);
|
||||||
|
this.physics.add.overlap(this.player, this.enemies, this.hitPlayer, null, this);
|
||||||
|
|
||||||
|
// Start enemy spawning
|
||||||
|
this.time.addEvent({
|
||||||
|
delay: 1000,
|
||||||
|
callback: this.spawnEnemy,
|
||||||
|
callbackScope: this,
|
||||||
|
loop: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create UI elements
|
||||||
|
this.createUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
if (this.gameOver) return;
|
||||||
|
|
||||||
|
// Player movement
|
||||||
|
if (this.cursors.left.isDown) {
|
||||||
|
this.player.setVelocityX(-200);
|
||||||
|
} else if (this.cursors.right.isDown) {
|
||||||
|
this.player.setVelocityX(200);
|
||||||
|
} else {
|
||||||
|
this.player.setVelocityX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shooting
|
||||||
|
if (Phaser.Input.Keyboard.JustDown(this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE))) {
|
||||||
|
this.shoot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createPlaceholderGraphics() {
|
||||||
|
// Create simple placeholder graphics for player, bullets and enemies
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = 32;
|
||||||
|
canvas.height = 32;
|
||||||
|
|
||||||
|
// Player ship (triangle)
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.fillStyle = '#00ffcc';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(16, 5);
|
||||||
|
ctx.lineTo(5, 30);
|
||||||
|
ctx.lineTo(27, 30);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
this.textures.addCanvas('player', canvas);
|
||||||
|
|
||||||
|
// Enemy (square)
|
||||||
|
const enemyCanvas = document.createElement('canvas');
|
||||||
|
enemyCanvas.width = 24;
|
||||||
|
enemyCanvas.height = 24;
|
||||||
|
|
||||||
|
const eCtx = enemyCanvas.getContext('2d');
|
||||||
|
eCtx.fillStyle = '#ff3366';
|
||||||
|
eCtx.fillRect(0, 0, 24, 24);
|
||||||
|
|
||||||
|
this.textures.addCanvas('enemy', enemyCanvas);
|
||||||
|
|
||||||
|
// Bullet (small circle)
|
||||||
|
const bulletCanvas = document.createElement('canvas');
|
||||||
|
bulletCanvas.width = 8;
|
||||||
|
bulletCanvas.height = 8;
|
||||||
|
|
||||||
|
const bCtx = bulletCanvas.getContext('2d');
|
||||||
|
bCtx.fillStyle = '#ffff00';
|
||||||
|
bCtx.beginPath();
|
||||||
|
bCtx.arc(4, 4, 3, 0, Math.PI * 2);
|
||||||
|
bCtx.fill();
|
||||||
|
|
||||||
|
this.textures.addCanvas('bullet', bulletCanvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
createUI() {
|
||||||
|
// Create score text
|
||||||
|
this.scoreText = this.add.text(16, 16, 'Score: 0', {
|
||||||
|
fontSize: '32px',
|
||||||
|
fill: '#ffffff',
|
||||||
|
fontFamily: 'Arial'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create game title
|
||||||
|
this.titleText = this.add.text(400, 50, 'Zenith Vector', {
|
||||||
|
fontSize: '48px',
|
||||||
|
fill: '#00ffcc',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
align: 'center'
|
||||||
|
});
|
||||||
|
this.titleText.setOrigin(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
shoot() {
|
||||||
|
const bullet = this.bullets.create(this.player.x, this.player.y - 20, 'bullet');
|
||||||
|
bullet.setVelocityY(-300);
|
||||||
|
bullet.setScale(1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
spawnEnemy() {
|
||||||
|
const x = Phaser.Math.Between(20, 780);
|
||||||
|
const enemy = this.enemies.create(x, 0, 'enemy');
|
||||||
|
|
||||||
|
// Randomize enemy speed
|
||||||
|
const speed = Phaser.Math.Between(50, 150);
|
||||||
|
enemy.setVelocityY(speed);
|
||||||
|
|
||||||
|
// Add some rotation for visual effect
|
||||||
|
enemy.setRotation(Phaser.Math.FloatBetween(-0.2, 0.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
hitEnemy(bullet, enemy) {
|
||||||
|
bullet.destroy();
|
||||||
|
enemy.destroy();
|
||||||
|
|
||||||
|
this.score += 10;
|
||||||
|
this.scoreText.setText('Score: ' + this.score);
|
||||||
|
}
|
||||||
|
|
||||||
|
hitPlayer(player, enemy) {
|
||||||
|
player.destroy();
|
||||||
|
enemy.destroy();
|
||||||
|
|
||||||
|
this.gameOver = true;
|
||||||
|
|
||||||
|
// Show game over text
|
||||||
|
const gameOverText = this.add.text(400, 300, 'GAME OVER', {
|
||||||
|
fontSize: '64px',
|
||||||
|
fill: '#ff3366',
|
||||||
|
fontFamily: 'Arial'
|
||||||
|
});
|
||||||
|
gameOverText.setOrigin(0.5);
|
||||||
|
|
||||||
|
// Restart game after delay
|
||||||
|
this.time.delayedCall(2000, () => {
|
||||||
|
this.scene.restart();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
python -m http.server 8000
|
||||||
Loading…
Reference in New Issue