first commit
This commit is contained in:
commit
425978dcb4
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
|
|
@ -0,0 +1,58 @@
|
|||
{ "compressionlevel":-1,
|
||||
"height":18,
|
||||
"infinite":false,
|
||||
"layers":[
|
||||
{
|
||||
"data":[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 3, 1, 2147483651, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, 2147483651, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 2147483651, 2, 2,
|
||||
2, 3, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 2147483651, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2147483651, 2,
|
||||
2, 1, 1, 1, 1, 2147483651, 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2147483651, 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 2, 2, 2, 3, 1, 1, 1, 1, 4, 2, 2, 2147483652, 1, 1, 1, 1, 2147483651, 2, 2, 2, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 2147483651, 3, 1, 1, 1, 1, 1, 4, 2, 2, 2, 2, 2147483652, 1, 1, 1, 1, 1, 2147483651, 3, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 2, 2, 2, 3, 2147483651, 2, 2, 2, 2147483652, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 2, 2, 2, 3, 1, 1, 1, 1, 2147483651, 2, 2, 2, 2147483652, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 1, 1, 1, 2147483651, 2, 2, 2, 2147483652, 1073741825, 1073741825, 1073741825, 1073741825, 4, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1, 1, 1, 1, 1, 1073741825, 1073741825, 2147483651, 2, 2, 2, 2147483652, 4, 2, 2, 2, 3, 1073741825, 1073741825, 1, 1, 1, 1, 1, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1073741825, 1073741825, 4, 2147483652, 1073741825, 1073741825, 1073741825, 1073741825, 1073741825, 2147483651, 2, 2, 2, 2, 3, 1073741825, 1073741825, 1073741825, 1073741825, 1073741825, 4, 2147483652, 1073741825, 1073741825, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1073741825, 1073741825, 2, 2, 2, 2147483652, 1073741825, 1073741825, 1073741825, 1073741825, 2147483651, 2, 2, 3, 1073741825, 1073741825, 1073741825, 1073741825, 4, 2, 2, 2, 1073741825, 1073741825, 1, 1, 1, 2,
|
||||
2, 1, 1, 1, 1073741825, 4, 2, 2, 2, 2, 2, 2147483652, 1073741825, 1073741825, 1073741825, 1073741825, 1073741825, 1073741825, 1073741825, 1073741825, 4, 2, 2, 2, 2, 2, 2147483652, 1073741825, 1, 1, 1, 2,
|
||||
2, 2147483652, 1, 1, 1073741825, 2, 2, 2, 2, 2, 2, 2, 2, 2147483652, 1073741825, 1073741825, 1073741825, 1073741825, 4, 2, 2, 2, 2, 2, 2, 2, 2, 1073741825, 1, 1, 4, 2,
|
||||
2, 2, 2147483652, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2147483652, 1073741825, 1073741825, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2147483652, 1, 4, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
|
||||
"height":18,
|
||||
"id":1,
|
||||
"name":"main",
|
||||
"opacity":1,
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":32,
|
||||
"x":0,
|
||||
"y":0
|
||||
}],
|
||||
"nextlayerid":2,
|
||||
"nextobjectid":1,
|
||||
"orientation":"orthogonal",
|
||||
"renderorder":"right-down",
|
||||
"tiledversion":"1.11.2",
|
||||
"tileheight":64,
|
||||
"tilesets":[
|
||||
{
|
||||
"columns":10,
|
||||
"firstgid":1,
|
||||
"image":"terrain.png",
|
||||
"imageheight":640,
|
||||
"imagewidth":640,
|
||||
"margin":0,
|
||||
"name":"terrain",
|
||||
"spacing":0,
|
||||
"tilecount":100,
|
||||
"tileheight":64,
|
||||
"tilewidth":64
|
||||
}],
|
||||
"tilewidth":64,
|
||||
"type":"map",
|
||||
"version":"1.10",
|
||||
"width":32
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Battle Game</title>
|
||||
<style>
|
||||
body { margin: 0; background-color: black; }
|
||||
canvas { display: block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="game-container"></div>
|
||||
<script src="./src/phaser.min.js"></script>
|
||||
<script type="module" src="./src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.10" tiledversion="1.11.2" orientation="orthogonal" renderorder="right-down" width="32" height="18" tilewidth="64" tileheight="64" infinite="0" nextlayerid="2" nextobjectid="1">
|
||||
<editorsettings>
|
||||
<export target="../assets/night-woods.json" format="json"/>
|
||||
</editorsettings>
|
||||
<tileset firstgid="1" name="terrain" tilewidth="64" tileheight="64" tilecount="100" columns="10">
|
||||
<image source="../assets/terrain.png" width="640" height="640"/>
|
||||
</tileset>
|
||||
<layer id="1" name="main" width="32" height="18">
|
||||
<data encoding="csv">
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,3,1,2147483651,2,2,2,2,2,2,2,2,2,3,1,1,2147483651,2,2,2,2,2,2,2,2,2,3,1,2147483651,2,2,
|
||||
2,3,1,1,1,2,2,2,2,2,2,2,2,3,1,1,1,1,2147483651,2,2,2,2,2,2,2,2,1,1,1,2147483651,2,
|
||||
2,1,1,1,1,2147483651,2,2,2,2,2,3,1,1,1,1,1,1,1,1,2147483651,2,2,2,2,2,3,1,1,1,1,2,
|
||||
2,1,1,1,1,1,2,2,2,3,1,1,1,1,4,2,2,2147483652,1,1,1,1,2147483651,2,2,2,1,1,1,1,1,2,
|
||||
2,1,1,1,1,1,2147483651,3,1,1,1,1,1,4,2,2,2,2,2147483652,1,1,1,1,1,2147483651,3,1,1,1,1,1,2,
|
||||
2,1,1,1,1,1,1,1,1,1,1,4,2,2,2,3,2147483651,2,2,2,2147483652,1,1,1,1,1,1,1,1,1,1,2,
|
||||
2,1,1,1,1,1,1,1,1,4,2,2,2,3,1,1,1,1,2147483651,2,2,2,2147483652,1,1,1,1,1,1,1,1,2,
|
||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
||||
2,1,1,1,1,1,1,1,1,2147483651,2,2,2,2147483652,1073741825,1073741825,1073741825,1073741825,4,2,2,2,3,1,1,1,1,1,1,1,1,2,
|
||||
2,1,1,1,1,1,1,1,1,1073741825,1073741825,2147483651,2,2,2,2147483652,4,2,2,2,3,1073741825,1073741825,1,1,1,1,1,1,1,1,2,
|
||||
2,1,1,1,1073741825,1073741825,4,2147483652,1073741825,1073741825,1073741825,1073741825,1073741825,2147483651,2,2,2,2,3,1073741825,1073741825,1073741825,1073741825,1073741825,4,2147483652,1073741825,1073741825,1,1,1,2,
|
||||
2,1,1,1,1073741825,1073741825,2,2,2,2147483652,1073741825,1073741825,1073741825,1073741825,2147483651,2,2,3,1073741825,1073741825,1073741825,1073741825,4,2,2,2,1073741825,1073741825,1,1,1,2,
|
||||
2,1,1,1,1073741825,4,2,2,2,2,2,2147483652,1073741825,1073741825,1073741825,1073741825,1073741825,1073741825,1073741825,1073741825,4,2,2,2,2,2,2147483652,1073741825,1,1,1,2,
|
||||
2,2147483652,1,1,1073741825,2,2,2,2,2,2,2,2,2147483652,1073741825,1073741825,1073741825,1073741825,4,2,2,2,2,2,2,2,2,1073741825,1,1,4,2,
|
||||
2,2,2147483652,1,4,2,2,2,2,2,2,2,2,2,2147483652,1073741825,1073741825,4,2,2,2,2,2,2,2,2,2,2147483652,1,4,2,2,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
|
||||
</data>
|
||||
</layer>
|
||||
</map>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
export const FACTION_CONFIG = {
|
||||
'dark-ages': {
|
||||
0: {
|
||||
name: 'Knight',
|
||||
description: 'Ye Magesty\'s base unit',
|
||||
stats: {
|
||||
type: 'melee',
|
||||
health: 5,
|
||||
attackMin: 1,
|
||||
attackMax: 4,
|
||||
meleeDefense: 1,
|
||||
rangeDefense: 2,
|
||||
magicDefense: 1,
|
||||
sight: 150,
|
||||
range: 64
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
export const PATH_CONFIG = {
|
||||
'left': {
|
||||
1: {
|
||||
0: {
|
||||
'x': 4,
|
||||
'y': 5,
|
||||
},
|
||||
1: {
|
||||
'x': 6,
|
||||
'y': 8,
|
||||
},
|
||||
2: {
|
||||
'x': 11,
|
||||
'y': 4,
|
||||
},
|
||||
3: {
|
||||
'x': 15,
|
||||
'y': 2,
|
||||
},
|
||||
4: {
|
||||
'x': 19,
|
||||
'y': 4,
|
||||
},
|
||||
5: {
|
||||
'x': 27,
|
||||
'y': 8,
|
||||
},
|
||||
}
|
||||
},
|
||||
'right': {
|
||||
1: {
|
||||
0: {
|
||||
'x': 27,
|
||||
'y': 4,
|
||||
},
|
||||
1: {
|
||||
'x': 25,
|
||||
'y': 7,
|
||||
},
|
||||
2: {
|
||||
'x': 20,
|
||||
'y': 4,
|
||||
},
|
||||
3: {
|
||||
'x': 16,
|
||||
'y': 2,
|
||||
},
|
||||
4: {
|
||||
'x': 11,
|
||||
'y': 5,
|
||||
},
|
||||
5: {
|
||||
'x': 5,
|
||||
'y': 7,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
import { PATH_CONFIG } from "../config/night-woods-config.js";
|
||||
import { FACTION_CONFIG } from "../config/faction.js";
|
||||
|
||||
export class Faction extends Phaser.GameObjects.Sprite {
|
||||
constructor(scene, x, y, texture, frame, side, path, faction) {
|
||||
super(scene, x, y, texture, frame);
|
||||
this.scene = scene;
|
||||
|
||||
scene.add.existing(this);
|
||||
scene.physics.world.enable(this);
|
||||
this.body.setCollideWorldBounds(true);
|
||||
if (side === 'left') {
|
||||
scene.factionLeft.add(this);
|
||||
}
|
||||
if (side === 'right') {
|
||||
scene.factionRight.add(this);
|
||||
}
|
||||
|
||||
// Stats
|
||||
this.stats = {};
|
||||
Object.entries(FACTION_CONFIG[faction][frame].stats).forEach(([key, value]) => {
|
||||
this.stats[key] = value;
|
||||
});
|
||||
console.log(this);
|
||||
|
||||
// Path following properties
|
||||
this.path = path;
|
||||
this.side = side;
|
||||
this.currentWaypoint = 0;
|
||||
this.speed = 50;
|
||||
this.arrived = false;
|
||||
this.isPathPaused = false;
|
||||
|
||||
this.animKey = `${texture}-${frame}`;
|
||||
this.createAnim();
|
||||
this.play(this.animKey);
|
||||
|
||||
// Initialize path following
|
||||
this.initializePath();
|
||||
}
|
||||
|
||||
createAnim() {
|
||||
if (!this.scene.anims.get(this.animKey)) {
|
||||
this.scene.anims.create({
|
||||
key: this.animKey,
|
||||
frames: [
|
||||
{ key: this.texture.key, frame: this.frame.name },
|
||||
{ key: this.texture.key, frame: this.frame.name+1 }
|
||||
],
|
||||
frameRate: 2,
|
||||
repeat: -1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
initializePath() {
|
||||
// Get the path data from config
|
||||
const pathData = PATH_CONFIG[this.side][this.path];
|
||||
if (pathData) {
|
||||
this.waypoints = [];
|
||||
for (let i = 0; i < Object.keys(pathData).length; i++) {
|
||||
this.waypoints.push({
|
||||
x: pathData[i].x*64,
|
||||
y: pathData[i].y*64
|
||||
});
|
||||
}
|
||||
|
||||
// Start moving towards first waypoint
|
||||
if (this.waypoints.length > 0) {
|
||||
this.moveToWaypoint(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moveToWaypoint(waypointIndex) {
|
||||
if (this.isPathPaused) return;
|
||||
|
||||
if (waypointIndex >= this.waypoints.length) {
|
||||
this.arrived = true;
|
||||
this.body.setVelocity(0, 0);
|
||||
this.stop(this.animKey);
|
||||
return;
|
||||
}
|
||||
|
||||
const target = this.waypoints[waypointIndex];
|
||||
const distance = Phaser.Math.Distance.Between(this.x, this.y, target.x, target.y);
|
||||
|
||||
if (distance < 5) { // Threshold for reaching waypoint
|
||||
this.currentWaypoint = waypointIndex + 1;
|
||||
this.moveToWaypoint(this.currentWaypoint);
|
||||
} else {
|
||||
// Calculate direction vector
|
||||
const angle = Phaser.Math.Angle.Between(this.x, this.y, target.x, target.y);
|
||||
|
||||
// Set velocity based on angle and speed
|
||||
this.body.setVelocity(
|
||||
Math.cos(angle) * this.speed,
|
||||
Math.sin(angle) * this.speed
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pausePath() {
|
||||
this.isPathPaused = true;
|
||||
this.body.setVelocity(0, 0);
|
||||
}
|
||||
|
||||
resumePath() {
|
||||
this.isPathPaused = false;
|
||||
// Resume from current waypoint
|
||||
this.moveToWaypoint(this.currentWaypoint);
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
// Flip sprite based on movement direction
|
||||
if (this.body && this.body.velocity) {
|
||||
if (this.body.velocity.x > 0) {
|
||||
this.setFlipX(true); // Moving right, normal orientation
|
||||
} else if (this.body.velocity.x < 0) {
|
||||
this.setFlipX(false); // Moving left, flipped
|
||||
}
|
||||
}
|
||||
|
||||
// Move towards next waypoint if not arrived and path is not paused
|
||||
if (!this.arrived && !this.isPathPaused) {
|
||||
this.moveToWaypoint(this.currentWaypoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { Level } from './scenes/level.js'
|
||||
|
||||
const GAME_CONFIG = {
|
||||
type: Phaser.AUTO,
|
||||
scale: {
|
||||
mode: Phaser.Scale.FIT,
|
||||
autoCenter: Phaser.Scale.CENTER_BOTH,
|
||||
width: 1600,
|
||||
height: 900,
|
||||
parent: 'game-container'
|
||||
},
|
||||
parent: 'game-container',
|
||||
backgroundColor: '#bb7432ff',
|
||||
scene: [
|
||||
Level,
|
||||
],
|
||||
physics: {
|
||||
default: 'arcade',
|
||||
arcade: {
|
||||
gravity: { y: 0 },
|
||||
debug: false
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Create the game instance
|
||||
const game = new Phaser.Game(GAME_CONFIG);
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,312 @@
|
|||
export class AudioManager extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'AudioManager', active: true });
|
||||
this.soundInstances = {};
|
||||
this.currentTrackIndex = 0;
|
||||
this.isShuffled = false;
|
||||
this.trackQueue = [];
|
||||
this.currentSoundtrack = null;
|
||||
|
||||
this.tracks = {
|
||||
'levelMusic1': {
|
||||
'title': 'Kevin be Wack',
|
||||
'artist': 'The Scrum Masta',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic2': {
|
||||
'title': 'ClienTek is Coming!',
|
||||
'artist': 'Tha Day-Lee St4nd',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic3': {
|
||||
'title': 'How Would Amazon Do it?',
|
||||
'artist': 'Billy Gitpull Jr.',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic4': {
|
||||
'title': 'Commit to the Git',
|
||||
'artist': 'Peer Review',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic5': {
|
||||
'title': 'ClienTek C4shin\' Checks',
|
||||
'artist': 'MC Cr4iG V',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic6': {
|
||||
'title': 'Solutions of the Heart',
|
||||
'artist': 'Kevin Smooth',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic7': {
|
||||
'title': 'Keepin\' Your Website Country',
|
||||
'artist': 'Git-e-up Gang',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic8': {
|
||||
'title': 'Hello Humans',
|
||||
'artist': 'Robotic Bryce',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusic9': {
|
||||
'title': '2 o\'clock Zoo o\'clock',
|
||||
'artist': 'The HR Brothers',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusicA': {
|
||||
'title': 'Best Launch Ever',
|
||||
'artist': 'Syntax',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusicB': {
|
||||
'title': 'Town Hall',
|
||||
'artist': 'The KEGR Krew',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusicC': {
|
||||
'title': 'It\'s Stupid',
|
||||
'artist': 'The Burlimonsters',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusicD': {
|
||||
'title': 'Fat Hawk',
|
||||
'artist': 'Oliver Quantum',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
'levelMusicE': {
|
||||
'title': 'Kevin Ghould Dance',
|
||||
'artist': 'Hema-to-logic',
|
||||
'misc': '2025 - IT Records'
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.audio('pickup', 'assets/sounds/pickup.mp3');
|
||||
this.load.audio('catFight1', 'assets/sounds/catFight1.mp3');
|
||||
this.load.audio('catFight2', 'assets/sounds/catFight2.mp3');
|
||||
this.load.audio('catFight3', 'assets/sounds/catFight3.mp3');
|
||||
this.load.audio('chain', 'assets/sounds/chain.mp3');
|
||||
this.load.audio('monster', 'assets/sounds/monster.mp3');
|
||||
this.load.audio('hobbies', 'assets/sounds/hobbies.mp3');
|
||||
this.load.audio('bread', 'assets/sounds/bread.mp3');
|
||||
this.load.audio('freeze', 'assets/sounds/freeze.mp3');
|
||||
this.load.audio('launch', 'assets/sounds/launch.mp3');
|
||||
this.load.audio('banana', 'assets/sounds/banana.mp3');
|
||||
this.load.audio('bonusDonut', 'assets/sounds/bonusDonut.mp3');
|
||||
this.load.audio('bonusFreeze', 'assets/sounds/bonusFreeze.mp3');
|
||||
this.load.audio('bonusKill', 'assets/sounds/bonusKill.mp3');
|
||||
this.load.audio('explosion', 'assets/sounds/explosion.mp3');
|
||||
|
||||
this.load.audio('levelMusic1', 'assets/levelMusic1.mp3');
|
||||
this.load.audio('levelMusic2', 'assets/menuMusic.mp3');
|
||||
this.load.audio('levelMusic3', 'assets/levelMusic3.mp3');
|
||||
this.load.audio('levelMusic4', 'assets/levelMusic4.mp3');
|
||||
this.load.audio('levelMusic5', 'assets/levelMusic5.mp3');
|
||||
this.load.audio('levelMusic6', 'assets/levelMusic6.mp3');
|
||||
this.load.audio('levelMusic7', 'assets/levelMusic7.mp3');
|
||||
this.load.audio('levelMusic8', 'assets/levelMusic8.mp3');
|
||||
this.load.audio('levelMusic9', 'assets/levelMusic9.mp3');
|
||||
this.load.audio('levelMusicA', 'assets/levelMusicA.mp3');
|
||||
this.load.audio('levelMusicB', 'assets/levelMusicB.mp3');
|
||||
this.load.audio('levelMusicC', 'assets/levelMusicC.mp3');
|
||||
this.load.audio('levelMusicD', 'assets/levelMusicD.mp3');
|
||||
this.load.audio('levelMusicE', 'assets/levelMusicE.mp3');
|
||||
|
||||
this.load.spritesheet('cassette', 'assets/cassette.png', {
|
||||
frameWidth: 424,
|
||||
frameHeight: 240
|
||||
});
|
||||
this.load.audio('playerHit', 'assets/sounds/playerHit.mp3');
|
||||
this.load.audio('hit', 'assets/sounds/hit.mp3');
|
||||
}
|
||||
|
||||
create() {
|
||||
|
||||
}
|
||||
|
||||
playManagedSound(key, maxInstances = 1, volume = 1) {
|
||||
if (!this.soundInstances[key]) {
|
||||
this.soundInstances[key] = [];
|
||||
}
|
||||
|
||||
// Clean up old sound instances that have finished playing
|
||||
this.soundInstances[key] = this.soundInstances[key].filter(s => s.isPlaying);
|
||||
|
||||
// If we have not reached the max limit, play a new instance
|
||||
if (this.soundInstances[key].length < maxInstances) {
|
||||
const sound = this.sound.add(key, { volume: volume });
|
||||
sound.play();
|
||||
this.soundInstances[key].push(sound);
|
||||
}
|
||||
}
|
||||
|
||||
playSoundtrack() {
|
||||
if (this.trackQueue.length === 0) {
|
||||
// Reinitialize queue if empty
|
||||
this.initializeTrackQueue();
|
||||
}
|
||||
|
||||
if (!this.audioInterface) {
|
||||
this.initializeInterface();
|
||||
}
|
||||
|
||||
const currentKey = this.trackQueue[this.currentTrackIndex];
|
||||
|
||||
// Play the current track
|
||||
this.showTrack(currentKey);
|
||||
const sound = this.sound.add(currentKey);
|
||||
sound.play();
|
||||
|
||||
// Keep reference to current soundtrack for stopping
|
||||
this.currentSoundtrack = sound;
|
||||
|
||||
// Set up callback for when track finishes
|
||||
sound.on('complete', () => {
|
||||
this.nextTrack();
|
||||
});
|
||||
|
||||
// Move to next track in queue
|
||||
this.currentTrackIndex = (this.currentTrackIndex + 1) % this.trackQueue.length;
|
||||
}
|
||||
|
||||
toggleSoundtrackPause(pause = true) {
|
||||
if (this.currentSoundtrack) {
|
||||
if (pause && this.currentSoundtrack.isPlaying) {
|
||||
this.currentSoundtrack.pause();
|
||||
} else if (!pause && !this.currentSoundtrack.isPlaying) {
|
||||
this.currentSoundtrack.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopSoundtrack() {
|
||||
if (this.currentSoundtrack) {
|
||||
this.currentSoundtrack.stop();
|
||||
this.currentSoundtrack = null;
|
||||
|
||||
// Hide the cassette interface if it's visible
|
||||
if (this.cassette && this.cassette.alpha > 0) {
|
||||
this.tweens.add({
|
||||
targets: this.cassette,
|
||||
alpha: 0,
|
||||
duration: 500,
|
||||
onComplete: () => {
|
||||
this.cassette.x = 1655;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initializeTrackQueue() {
|
||||
// Create a copy of track keys and shuffle them
|
||||
this.trackQueue = Object.keys(this.tracks);
|
||||
this.shuffleArray(this.trackQueue);
|
||||
this.isShuffled = true;
|
||||
}
|
||||
|
||||
shuffleArray(array) {
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[array[i], array[j]] = [array[j], array[i]];
|
||||
}
|
||||
}
|
||||
|
||||
nextTrack() {
|
||||
if (this.trackQueue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentKey = this.trackQueue[this.currentTrackIndex];
|
||||
|
||||
// Play the next track
|
||||
this.showTrack(currentKey);
|
||||
const sound = this.sound.add(currentKey);
|
||||
sound.play();
|
||||
|
||||
// Keep reference to current soundtrack for stopping
|
||||
this.currentSoundtrack = sound;
|
||||
|
||||
// Set up callback for when track finishes
|
||||
sound.on('complete', () => {
|
||||
this.nextTrack();
|
||||
});
|
||||
|
||||
// Move to next track in queue
|
||||
this.currentTrackIndex = (this.currentTrackIndex + 1) % this.trackQueue.length;
|
||||
}
|
||||
|
||||
initializeInterface() {
|
||||
this.audioInterface = true;
|
||||
this.cassette = this.add.container(1655, 675).setScrollFactor(0).setAlpha(0);
|
||||
const cassetteSprite = this.add.sprite(0, 0, 'cassette', 0).setOrigin(0.5);//.setScale(.7);
|
||||
this.cassette.add(cassetteSprite);
|
||||
|
||||
this.anims.create({
|
||||
key: 'cassette-play',
|
||||
frames: [
|
||||
{ key: 'cassette', frame: 0 },
|
||||
{ key: 'cassette', frame: 1 },
|
||||
{ key: 'cassette', frame: 2 },
|
||||
],
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
});
|
||||
cassetteSprite.play('cassette-play', true);
|
||||
|
||||
this.trackTitle = this.add.text(-125, -88, 'Track Title Here', {
|
||||
fontSize: '20px',
|
||||
fill: '#000000ff',
|
||||
stroke: '#8d3131ff',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
}).setOrigin(0, 0.5);
|
||||
this.cassette.add(this.trackTitle);
|
||||
|
||||
this.trackSub1 = this.add.text(-125, -78, 'By: Artist', {
|
||||
fontSize: '18px',
|
||||
fill: '#000000ff',
|
||||
stroke: '#8d3131ff',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
});
|
||||
this.cassette.add(this.trackSub1);
|
||||
}
|
||||
|
||||
showTrack(track) {
|
||||
this.trackTitle.setText(this.tracks[track].title);
|
||||
this.trackSub1.setText(`By: ${this.tracks[track].artist}`);
|
||||
|
||||
this.tweens.add({
|
||||
targets: this.cassette,
|
||||
alpha: 1,
|
||||
x: 1355,
|
||||
ease: 'Cubic.Out',
|
||||
duration: 1000,
|
||||
onComplete: () => {
|
||||
this.tweens.add({
|
||||
targets: this.cassette,
|
||||
alpha: 0,
|
||||
duration: 2000,
|
||||
delay: 5000,
|
||||
onComplete: () => {
|
||||
this.cassette.x = 1655;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
export const EVENT_CONFIG = {
|
||||
'time_events': {
|
||||
'nightfall': {
|
||||
//'start': 16, // number of minutes into the game
|
||||
//'end': 19, // number of minutes into the game
|
||||
'waveStart': 11,
|
||||
//'waveEnd': 2,
|
||||
'bossEnd': 'bossGhould',
|
||||
'event': 'evNightfall', // name of event function to start
|
||||
},
|
||||
'zoo': {
|
||||
'waveStart': 14,
|
||||
'bossEnd': 'bossBollini',
|
||||
'event': 'evZoo'
|
||||
},
|
||||
'matrix': {
|
||||
'waveStart': 9,
|
||||
'bossEnd': 'bossJennifer',
|
||||
'event': 'evMatrix'
|
||||
},
|
||||
'cyber': {
|
||||
'waveStart': 16,
|
||||
'bossEnd': 'bossBryce',
|
||||
'event': 'evCyber'
|
||||
},
|
||||
'hiphop': {
|
||||
'waveStart': 3,
|
||||
'bossEnd': 'bossCraig',
|
||||
'event': 'evHipHop'
|
||||
},
|
||||
'princess': {
|
||||
'waveStart': 18,
|
||||
'bossEnd': 'bossFreya',
|
||||
'event': 'evPrincess'
|
||||
},
|
||||
'mechaKevin': {
|
||||
'waveStart': 21,
|
||||
'bossEnd': 'bossMechaKevin',
|
||||
'event': 'evMechaKevin'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,755 @@
|
|||
import { EVENT_CONFIG } from "./eventConfig.js";
|
||||
|
||||
export class EventManager extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'EventManager', active: true });
|
||||
this.schedule = {};
|
||||
this.triggers = [];
|
||||
this.currentEvents = [];
|
||||
this.levelSceneReference = null;
|
||||
this.lightningTimer = 0;
|
||||
this.lightningInterval = 2000;
|
||||
this.evTimer = 0;
|
||||
}
|
||||
|
||||
preload() {
|
||||
for (let i = 1; i < 10; i++) {
|
||||
this.load.audio(`zoo${i}`, `assets/sounds/zoo${i}.mp3`);
|
||||
}
|
||||
this.load.audio('zooOclockIntro', 'assets/sounds/zooOclockIntro.mp3');
|
||||
this.load.audio('lightning-1', 'assets/sounds/lightning-1.mp3');
|
||||
this.load.audio('lightning-2', 'assets/sounds/lightning-2.mp3');
|
||||
this.load.audio('lightning-3', 'assets/sounds/lightning-3.mp3');
|
||||
this.load.audio('cyberIntro', 'assets/sounds/cyberIntro.mp3');
|
||||
this.load.audio('wolfHowl', 'assets/sounds/wolfHowl.mp3');
|
||||
this.load.audio('hipHop', 'assets/sounds/hipHop.mp3');
|
||||
this.load.audio('hipHopBeat', 'assets/sounds/hipHopBeat.mp3');
|
||||
this.load.audio('princess', 'assets/sounds/princess.mp3');
|
||||
this.load.image('evNightfall', 'assets/evNightfall.png');
|
||||
this.load.image('ev2Zoo', 'assets/ev2Zoo.png');
|
||||
this.load.image('ev2ZooSides', 'assets/ev2ZooSides.png');
|
||||
this.load.image('evMatrix', 'assets/evMatrix.png');
|
||||
this.load.image('evCyber', 'assets/evCyber.png');
|
||||
this.load.image('evPrincess', 'assets/evPrincess.png');
|
||||
this.load.image('blueParticle', 'assets/blueParticle.png');
|
||||
this.load.spritesheet('graffiti', 'assets/graffiti.png', {
|
||||
frameWidth: 400,
|
||||
frameHeight: 250
|
||||
});
|
||||
}
|
||||
|
||||
create() {
|
||||
// Build the Event Schedule
|
||||
Object.values(EVENT_CONFIG.time_events).forEach(event => {
|
||||
if (event.start) {
|
||||
const start = event.start * 60 * 1000;
|
||||
this.schedule[start] = [event.event, 'start'];
|
||||
}
|
||||
if (event.end) {
|
||||
const end = event.end * 60 * 1000;
|
||||
this.schedule[end] = [event.event, 'end'];
|
||||
}
|
||||
if (event.waveStart) {
|
||||
this.triggers.push([event.waveStart, event.event, 'start']);
|
||||
}
|
||||
if (event.waveEnd) {
|
||||
this.triggers.push([event.waveEnd, event.event, 'end']);
|
||||
}
|
||||
if (event.bossEnd) {
|
||||
this.triggers.push([event.bossEnd, event.event, 'end']);
|
||||
}
|
||||
});
|
||||
|
||||
// Store reference to Level scene for later use
|
||||
this.levelSceneReference = this.scene.get('Level');
|
||||
this.AudioManager = this.scene.get('AudioManager');
|
||||
}
|
||||
|
||||
waveTrigger(wave) {
|
||||
this.triggers.forEach((event) => {
|
||||
if (event[0] === wave) {
|
||||
const eventFunction = event[1];
|
||||
const eventType = event[2];
|
||||
if (typeof this[eventFunction] === 'function') {
|
||||
this[eventFunction](eventType);
|
||||
} else {
|
||||
console.log('Not A Function', eventFunction);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bossEndTrigger(boss) {
|
||||
this.triggers.forEach((event) => {
|
||||
if (event[0] === boss) {
|
||||
const eventFunction = event[1];
|
||||
const eventType = event[2];
|
||||
if (typeof this[eventFunction] === 'function') {
|
||||
this[eventFunction](eventType);
|
||||
} else {
|
||||
console.log('Not A Function', eventFunction);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
evMechaKevin(event = 'start') {
|
||||
if (event === 'start') {
|
||||
this.levelSceneReference.UI.kevinFinal();
|
||||
this.time.delayedCall(500, () => {
|
||||
Object.values(this.levelSceneReference.player.weapons).forEach(weapon => {
|
||||
weapon.destroy();
|
||||
});
|
||||
this.levelSceneReference.player.weapons = {};
|
||||
this.levelSceneReference.drops.children.iterate(drop => {
|
||||
if (drop && drop.active) {
|
||||
drop.destroy();
|
||||
}
|
||||
});
|
||||
this.levelSceneReference.enemies.children.iterate(enemy => {
|
||||
if (enemy && enemy.active) {
|
||||
enemy.destroy();
|
||||
}
|
||||
});
|
||||
this.levelSceneReference.bonusManager.spawnMaxedWeapons();
|
||||
this.levelSceneReference.waveManager.spawnMechaKevin();
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
evPrincess(event = 'start') {
|
||||
let levelScene = this.levelSceneReference || this.scene.get('Level');
|
||||
|
||||
if (levelScene && levelScene.mainLayer && levelScene.wallsLayer) {
|
||||
if (event === 'start') {
|
||||
this.currentEvents.push('princess');
|
||||
|
||||
// Create pink particle system for princess effect
|
||||
this.princessParticles = this.add.particles(0, 0, 'blueParticle', {
|
||||
speed: { min: -50, max: 50 },
|
||||
angle: { min: 0, max: 360 },
|
||||
scale: { start: 0.5, end: 0 },
|
||||
quantity: 1,
|
||||
lifespan: 1000,
|
||||
emitZone: { type: 'random', source: new Phaser.Geom.Rectangle(0, 0, 1600, 900) },
|
||||
blendMode: 'ADD',
|
||||
tint: 0xff69b4
|
||||
});
|
||||
|
||||
// Create sparkle effects
|
||||
this.sparkles = [];
|
||||
for (let i = 0; i < 20; i++) {
|
||||
const sparkle = this.add.circle(
|
||||
Phaser.Math.Between(0, 1600),
|
||||
Phaser.Math.Between(0, 900),
|
||||
Phaser.Math.Between(2, 8),
|
||||
0xff69b4,
|
||||
0.8
|
||||
);
|
||||
sparkle.setOrigin(0.5);
|
||||
this.sparkles.push(sparkle);
|
||||
}
|
||||
|
||||
// Create floating hearts
|
||||
this.hearts = [];
|
||||
for (let i = 0; i < 15; i++) {
|
||||
const heart = this.add.circle(
|
||||
Phaser.Math.Between(0, 1600),
|
||||
Phaser.Math.Between(0, 900),
|
||||
Phaser.Math.Between(10, 20),
|
||||
0xff69b4,
|
||||
0.6
|
||||
);
|
||||
heart.setOrigin(0.5);
|
||||
this.hearts.push(heart);
|
||||
}
|
||||
|
||||
const logo = this.add.image(800, 200, 'evPrincess').setOrigin(0.5);
|
||||
this.tweens.add({
|
||||
targets: logo,
|
||||
delay: 2000,
|
||||
duration: 5000,
|
||||
scale: 0,
|
||||
onComplete: () => {
|
||||
logo.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
// Set princess tint
|
||||
levelScene.mainLayer.setTint(0xff69b4);
|
||||
levelScene.wallsLayer.setTint(0xff69b4);
|
||||
|
||||
// Play princess sound effect
|
||||
this.AudioManager.playManagedSound('princess', 1, 1.5);
|
||||
|
||||
// Start particle animation
|
||||
this.princessTimer = 0;
|
||||
this.princessInterval = 200;
|
||||
|
||||
} else if (event === 'end') {
|
||||
this.currentEvents = this.currentEvents.filter(e => e !== 'princess');
|
||||
|
||||
// Clean up princess effects
|
||||
levelScene.mainLayer.setTint(0xFFFFFF);
|
||||
levelScene.wallsLayer.setTint(0xFFFFFF);
|
||||
|
||||
if (this.princessParticles) {
|
||||
this.princessParticles.destroy();
|
||||
this.princessParticles = null;
|
||||
}
|
||||
|
||||
if (this.sparkles) {
|
||||
this.sparkles.forEach(sparkle => {
|
||||
sparkle.destroy();
|
||||
});
|
||||
this.sparkles = [];
|
||||
}
|
||||
|
||||
if (this.hearts) {
|
||||
this.hearts.forEach(heart => {
|
||||
heart.destroy();
|
||||
});
|
||||
this.hearts = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evHipHop(event = 'start') {
|
||||
let levelScene = this.levelSceneReference || this.scene.get('Level');
|
||||
|
||||
if (levelScene && levelScene.mainLayer && levelScene.wallsLayer) {
|
||||
if (event === 'start') {
|
||||
this.currentEvents.push('hiphop');
|
||||
|
||||
// Create beat drop effect
|
||||
this.beatDrop = this.add.rectangle(0, 0, 1600, 900, 0x000000, 0.7);
|
||||
this.beatDrop.setOrigin(0);
|
||||
|
||||
// Create beat pulse effect
|
||||
this.beatPulse = this.add.circle(800, 450, 100, 0xffffff, 0.3);
|
||||
this.beatPulse.setOrigin(0.5);
|
||||
|
||||
// Animate beat drop
|
||||
this.tweens.add({
|
||||
targets: this.beatDrop,
|
||||
alpha: 0,
|
||||
duration: 300,
|
||||
ease: 'Linear',
|
||||
onComplete: () => {
|
||||
this.beatDrop.destroy();
|
||||
this.beatDrop = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Animate beat pulse
|
||||
this.tweens.add({
|
||||
targets: this.beatPulse,
|
||||
scale: 3,
|
||||
alpha: 0,
|
||||
duration: 500,
|
||||
ease: 'Linear',
|
||||
onComplete: () => {
|
||||
this.beatPulse.destroy();
|
||||
this.beatPulse = null;
|
||||
}
|
||||
});
|
||||
|
||||
// Set hip hop tint
|
||||
levelScene.mainLayer.setTint(0xff6600);
|
||||
levelScene.wallsLayer.setTint(0xff6600);
|
||||
|
||||
// Create hip hop visual elements
|
||||
this.hipHopElements = [];
|
||||
this.graffitiTimer = 0;
|
||||
|
||||
// Create beat visualization
|
||||
this.beatVisualizer = [];
|
||||
for (let i = 0; i < 20; i++) {
|
||||
const bar = this.add.rectangle(
|
||||
100 + i * 30,
|
||||
800,
|
||||
20,
|
||||
Phaser.Math.Between(20, 100),
|
||||
0x00ffff
|
||||
);
|
||||
bar.setOrigin(0, 1);
|
||||
this.beatVisualizer.push(bar);
|
||||
}
|
||||
|
||||
const logo = this.add.sprite(800, 200, 'graffiti', 5).setOrigin(0.5);
|
||||
this.AudioManager.playManagedSound('hipHop', 1, 1.5);
|
||||
this.tweens.add({
|
||||
targets: logo,
|
||||
delay: 2000,
|
||||
duration: 5000,
|
||||
scale: 0,
|
||||
onComplete: () => {
|
||||
logo.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
// Start beat animation
|
||||
this.beatTimer = 0;
|
||||
this.beatInterval = 200;
|
||||
|
||||
} else if (event === 'end') {
|
||||
this.currentEvents = this.currentEvents.filter(e => e !== 'hiphop');
|
||||
|
||||
// Clean up hip hop effects
|
||||
levelScene.mainLayer.setTint(0xFFFFFF);
|
||||
levelScene.wallsLayer.setTint(0xFFFFFF);
|
||||
|
||||
if (this.beatDrop) {
|
||||
this.beatDrop.destroy();
|
||||
this.beatDrop = null;
|
||||
}
|
||||
|
||||
if (this.beatPulse) {
|
||||
this.beatPulse.destroy();
|
||||
this.beatPulse = null;
|
||||
}
|
||||
|
||||
if (this.hipHopElements) {
|
||||
this.hipHopElements.forEach(element => {
|
||||
element.destroy();
|
||||
});
|
||||
this.hipHopElements = [];
|
||||
}
|
||||
|
||||
if (this.beatVisualizer) {
|
||||
this.beatVisualizer.forEach(bar => {
|
||||
bar.destroy();
|
||||
});
|
||||
this.beatVisualizer = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evCyber(event = 'start') {
|
||||
if (event === 'start') {
|
||||
this.currentEvents.push('cyber');
|
||||
this.createVHSEffect();
|
||||
this.AudioManager.playManagedSound('cyberIntro', 1, 1);
|
||||
|
||||
const logo = this.add.image(800, 300, 'evCyber').setOrigin(0.5);
|
||||
this.tweens.add({
|
||||
targets: logo,
|
||||
delay: 2000,
|
||||
duration: 5000,
|
||||
scale: 0,
|
||||
y: 200,
|
||||
onComplete: () => {
|
||||
logo.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.currentEvents = this.currentEvents.filter(e => e !== 'cyber');
|
||||
|
||||
// Remove VHS effect
|
||||
if (this.vhsOverlay) {
|
||||
this.vhsOverlay.destroy();
|
||||
this.vhsOverlay = null;
|
||||
}
|
||||
|
||||
// Remove scanlines
|
||||
if (this.scanlines && this.scanlines.length > 0) {
|
||||
this.scanlines.forEach(scanline => {
|
||||
if (scanline && scanline.destroy) {
|
||||
scanline.destroy();
|
||||
}
|
||||
});
|
||||
this.scanlines = [];
|
||||
}
|
||||
|
||||
// Remove color fringing effect
|
||||
if (this.colorFringing) {
|
||||
this.colorFringing.destroy();
|
||||
this.colorFringing = null;
|
||||
}
|
||||
|
||||
// Remove vignette
|
||||
if (this.vignette) {
|
||||
this.vignette.destroy();
|
||||
this.vignette = null;
|
||||
}
|
||||
|
||||
this.levelSceneReference.mainLayer.setTint(0xffffff);
|
||||
this.levelSceneReference.wallsLayer.setTint(0xffffff);
|
||||
}
|
||||
}
|
||||
|
||||
createVHSEffect() {
|
||||
// Create overlay for VHS effect
|
||||
this.vhsOverlay = this.add.rectangle(0, 0, 1600, 900, 0x000000, 0.1);
|
||||
this.vhsOverlay.setOrigin(0);
|
||||
|
||||
// Create scanlines
|
||||
this.scanlines = [];
|
||||
const scanlineCount = 100;
|
||||
for (let i = 0; i < scanlineCount; i++) {
|
||||
const scanline = this.add.rectangle(0, i * (900 / scanlineCount), 1600, 1, 0x000000, 0.1);
|
||||
scanline.setOrigin(0);
|
||||
this.scanlines.push(scanline);
|
||||
}
|
||||
|
||||
// Create color fringing effect
|
||||
this.colorFringing = this.add.rectangle(0, 0, 1600, 900, 0x000000, 0);
|
||||
this.colorFringing.setOrigin(0);
|
||||
|
||||
// Create vignette
|
||||
this.vignette = this.add.rectangle(0, 0, 1600, 900, 0x000000, 0.3);
|
||||
this.vignette.setOrigin(0);
|
||||
|
||||
// Add VHS distortion effect
|
||||
this.vhsDistortion = 0;
|
||||
this.vhsDistortionSpeed = 0.02;
|
||||
|
||||
// Start VHS animation
|
||||
this.vhsTimer = 0;
|
||||
}
|
||||
|
||||
evMatrix(event = 'start') {
|
||||
let levelScene = this.levelSceneReference || this.scene.get('Level');
|
||||
|
||||
if (levelScene && levelScene.mainLayer && levelScene.wallsLayer) {
|
||||
if (event === 'start') {
|
||||
this.currentEvents.push('matrix');
|
||||
|
||||
const matrixImage = this.add.image(800, 200, 'evMatrix').setOrigin(0.5).setScale(2);
|
||||
this.tweens.add({
|
||||
targets: matrixImage,
|
||||
scale: 1,
|
||||
duration: 1000,
|
||||
onComplete: () => {
|
||||
this.AudioManager.playManagedSound('thud', 1, 2);
|
||||
this.tweens.add({
|
||||
targets: matrixImage,
|
||||
delay: 1000,
|
||||
duration: 5000,
|
||||
scale: 0,
|
||||
onComplete: () => {
|
||||
matrixImage.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
levelScene.mainLayer.setTint(0xc3ffcd);
|
||||
levelScene.wallsLayer.setTint(0xc3ffcd);
|
||||
|
||||
// Create matrix rain effect
|
||||
this.matrixChars = [];
|
||||
this.matrixSpeed = 200;
|
||||
this.matrixFontSize = 16;
|
||||
|
||||
// Create columns of characters
|
||||
const columns = Math.ceil(1600 / this.matrixFontSize);
|
||||
for (let i = 0; i < columns; i++) {
|
||||
const column = {
|
||||
x: i * this.matrixFontSize,
|
||||
y: Phaser.Math.Between(-1000, 0),
|
||||
speed: Phaser.Math.Between(2, 8),
|
||||
chars: []
|
||||
};
|
||||
|
||||
// Create a random number of characters for this column
|
||||
const charCount = Phaser.Math.Between(10, 30);
|
||||
for (let j = 0; j < charCount; j++) {
|
||||
const char = this.add.text(column.x, column.y + (j * this.matrixFontSize),
|
||||
this.getRandomMatrixChar(),
|
||||
{
|
||||
fontSize: this.matrixFontSize + 'px',
|
||||
fill: '#00ff41',
|
||||
stroke: '#000000',
|
||||
strokeThickness: 2
|
||||
}
|
||||
);
|
||||
char.setAlpha(0.8);
|
||||
column.chars.push(char);
|
||||
}
|
||||
|
||||
this.matrixChars.push(column);
|
||||
}
|
||||
|
||||
// Start the animation
|
||||
this.matrixTimer = 0;
|
||||
} else if (event === 'end') {
|
||||
this.currentEvents = this.currentEvents.filter(e => e !== 'matrix');
|
||||
|
||||
levelScene.mainLayer.setTint(0xFFFFFF);
|
||||
levelScene.wallsLayer.setTint(0xFFFFFF);
|
||||
|
||||
if (this.matrixChars) {
|
||||
this.matrixChars.forEach(column => {
|
||||
column.chars.forEach(char => {
|
||||
char.destroy();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evNightfall(event = 'start') {
|
||||
// Use stored reference or get it dynamically
|
||||
let levelScene = this.levelSceneReference || this.scene.get('Level');
|
||||
|
||||
if (levelScene && levelScene.mainLayer && levelScene.wallsLayer) {
|
||||
if (event === 'start') {
|
||||
this.currentEvents.push('nightfall');
|
||||
levelScene.mainLayer.setTint(0x2f2f69);
|
||||
levelScene.wallsLayer.setTint(0x2f2f69);
|
||||
const nightfallImage = this.add.image(800, 200, 'evNightfall').setOrigin(0.5);
|
||||
this.AudioManager.playManagedSound('wolfHowl', 1, 1);
|
||||
this.tweens.add({
|
||||
targets: nightfallImage,
|
||||
delay: 2000,
|
||||
duration: 5000,
|
||||
scale: 0,
|
||||
onComplete: () => {
|
||||
nightfallImage.destroy();
|
||||
}
|
||||
});
|
||||
} else if (event === 'end') {
|
||||
this.currentEvents = this.currentEvents.filter(e => e !== 'nightfall');
|
||||
levelScene.mainLayer.setTint(0xFFFFFF);
|
||||
levelScene.wallsLayer.setTint(0xFFFFFF);
|
||||
}
|
||||
} else {
|
||||
console.warn('Level scene or layers not found for nightfall event');
|
||||
}
|
||||
}
|
||||
|
||||
evZoo(event = 'start') {
|
||||
let levelScene = this.levelSceneReference || this.scene.get('Level');
|
||||
if (event === 'start') {
|
||||
this.currentEvents.push('zoo');
|
||||
levelScene.mainLayer.setTint(0xffcc92);
|
||||
levelScene.wallsLayer.setTint(0xffcc92);
|
||||
const zooImage = this.add.image(800, 200, 'ev2Zoo').setOrigin(0.5);
|
||||
this.zooSide1 = this.add.image(-108, 450, 'ev2ZooSides').setOrigin(0.5);
|
||||
this.zooSide2 = this.add.image(1708, 450, 'ev2ZooSides').setOrigin(0.5);
|
||||
this.AudioManager.playManagedSound('zooOclockIntro', 1, 1);
|
||||
this.zooTimer = 0;
|
||||
this.tweens.add({
|
||||
targets: zooImage,
|
||||
delay: 2000,
|
||||
duration: 5000,
|
||||
scale: 0,
|
||||
onComplete: () => {
|
||||
zooImage.destroy();
|
||||
}
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: this.zooSide1,
|
||||
delay: 2000,
|
||||
duration: 5000,
|
||||
x: 0
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: this.zooSide2,
|
||||
delay: 2000,
|
||||
duration: 5000,
|
||||
x: 1600
|
||||
});
|
||||
}
|
||||
else if (event === 'end' && this.zooSide1 && this.zooSide2) {
|
||||
levelScene.mainLayer.setTint(0xFFFFFF);
|
||||
levelScene.wallsLayer.setTint(0xFFFFFF);
|
||||
this.currentEvents = this.currentEvents.filter(e => e !== 'zoo');
|
||||
this.tweens.add({
|
||||
targets: this.zooSide1,
|
||||
duration: 5000,
|
||||
x: -108,
|
||||
onComplete: () => {
|
||||
this.zooSide1.destroy();
|
||||
}
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: this.zooSide2,
|
||||
duration: 5000,
|
||||
x: 1708,
|
||||
onComplete: () => {
|
||||
this.zooSide2.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
// Create a copy of keys to avoid modification during iteration
|
||||
const scheduleKeys = Object.keys(this.schedule);
|
||||
|
||||
scheduleKeys.forEach(schedule => {
|
||||
if (time >= parseInt(schedule)) {
|
||||
const details = this.schedule[schedule];
|
||||
const eventFunction = details[0];
|
||||
const eventType = details[1];
|
||||
delete this.schedule[schedule];
|
||||
|
||||
if (typeof this[eventFunction] === 'function') {
|
||||
this[eventFunction](eventType);
|
||||
} else {
|
||||
console.log('Not A Function', eventFunction);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Hip hop beat animation
|
||||
if (this.currentEvents.includes('hiphop') && this.beatVisualizer) {
|
||||
this.beatTimer += delta;
|
||||
this.graffitiTimer += delta;
|
||||
if (this.beatTimer > this.beatInterval) {
|
||||
this.beatTimer = 0;
|
||||
|
||||
// Animate beat bars
|
||||
this.beatVisualizer.forEach((bar, index) => {
|
||||
const height = Phaser.Math.Between(20, 100);
|
||||
this.tweens.add({
|
||||
targets: bar,
|
||||
height: height,
|
||||
duration: 100,
|
||||
ease: 'Power2'
|
||||
});
|
||||
});
|
||||
}
|
||||
if (this.graffitiTimer > 5000) {
|
||||
this.graffitiTimer = 0;
|
||||
const frame = Phaser.Math.Between(0,4);
|
||||
const quadrant = Phaser.Math.Between(1,4);
|
||||
const quadCords = {
|
||||
1: { 'x': 400, 'y': 225 },
|
||||
2: { 'x': 1200, 'y': 225 },
|
||||
3: { 'x': 400, 'y': 675 },
|
||||
4: { 'x': 1200, 'y': 675 }
|
||||
}
|
||||
const quadX = Phaser.Math.Between(-100, 100);
|
||||
const quadY = Phaser.Math.Between(-100, 100);
|
||||
const graffiti = this.add.sprite(quadCords[quadrant].x + quadX, quadCords[quadrant].y + quadY, 'graffiti', frame)
|
||||
.setOrigin(0.5).setAlpha(0.8);
|
||||
this.hipHopElements.push(graffiti);
|
||||
this.AudioManager.playManagedSound('hipHopBeat', 1, 1);
|
||||
this.tweens.add({
|
||||
targets: graffiti,
|
||||
scale: { from: 1, to: .8 },
|
||||
alpha: { from: 0.8, to: 0.4 },
|
||||
duration: 500,
|
||||
repeat: 3,
|
||||
onComplete: () => {
|
||||
if (graffiti && graffiti.active) {
|
||||
this.tweens.add({
|
||||
targets: graffiti,
|
||||
scale: { from: 1, to: .2 },
|
||||
alpha: 0,
|
||||
duration: 5000,
|
||||
onComplete: () => {
|
||||
if (graffiti && graffiti.active) {
|
||||
graffiti.destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// VHS effect update
|
||||
if (this.currentEvents.includes('cyber') && this.vhsOverlay) {
|
||||
this.vhsTimer += delta;
|
||||
|
||||
// Animate scanlines
|
||||
this.scanlines.forEach((scanline, index) => {
|
||||
scanline.y = (index * (900 / 100)) + (Math.sin(this.vhsTimer * 0.005 + index * 0.1) * 5);
|
||||
});
|
||||
|
||||
// Animate color fringing
|
||||
if (this.vhsTimer % 200 < 100) {
|
||||
this.colorFringing.setFillStyle(0xff0000, 0.02);
|
||||
} else {
|
||||
this.colorFringing.setFillStyle(0x0000ff, 0.02);
|
||||
}
|
||||
|
||||
// Animate VHS distortion
|
||||
this.vhsDistortion = Math.sin(this.vhsTimer * 0.01) * 0.5;
|
||||
|
||||
// Apply distortion to main layers
|
||||
if (this.levelSceneReference && this.levelSceneReference.mainLayer) {
|
||||
this.levelSceneReference.mainLayer.setTint(0x00ffff);
|
||||
this.levelSceneReference.wallsLayer.setTint(0x00ffff);
|
||||
}
|
||||
}
|
||||
|
||||
// Nightfall Event
|
||||
if (this.currentEvents.includes('nightfall')) {
|
||||
this.lightningTimer += delta;
|
||||
if (this.lightningTimer >= this.lightningInterval) {
|
||||
this.lightningTimer = 0;
|
||||
this.lightningInterval = Phaser.Math.Between(2000,5000);
|
||||
this.createLightning();
|
||||
}
|
||||
}
|
||||
|
||||
// Zoo O'clock
|
||||
if (this.currentEvents.includes('zoo')) {
|
||||
this.zooTimer += delta;
|
||||
if (this.zooTimer >= 1000) {
|
||||
this.zooTimer = 0;
|
||||
this.AudioManager.playManagedSound(`zoo${Phaser.Math.Between(1,9)}`, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Matrix effect update
|
||||
if (this.currentEvents.includes('matrix') && this.matrixChars) {
|
||||
this.matrixTimer += delta;
|
||||
if (this.matrixTimer > this.matrixSpeed) {
|
||||
this.matrixTimer = 0;
|
||||
|
||||
this.matrixChars.forEach(column => {
|
||||
column.y += column.speed;
|
||||
|
||||
// Reset column if it goes off screen
|
||||
if (column.y > 900) {
|
||||
column.y = Phaser.Math.Between(-1000, -100);
|
||||
}
|
||||
|
||||
// Update character positions
|
||||
column.chars.forEach((char, index) => {
|
||||
char.y = column.y + (index * this.matrixFontSize);
|
||||
char.x = column.x;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createLightning() {
|
||||
let levelScene = this.levelSceneReference || this.scene.get('Level');
|
||||
|
||||
if (levelScene && levelScene.mainLayer && levelScene.wallsLayer) {
|
||||
levelScene.mainLayer.setTint(0xFFFFFF);
|
||||
levelScene.wallsLayer.setTint(0xFFFFFF);
|
||||
const lightningRand = Phaser.Math.Between(1,3);
|
||||
this.AudioManager.playManagedSound(`lightning-${lightningRand}`, 2, 1);
|
||||
|
||||
this.time.delayedCall(Phaser.Math.Between(100, 300), () => {
|
||||
if (this.currentEvents.includes('nightfall')) {
|
||||
levelScene.mainLayer.setTint(0x2f2f69);
|
||||
levelScene.wallsLayer.setTint(0x2f2f69);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getRandomMatrixChar() {
|
||||
// Matrix-style characters (Latin, numbers, symbols)
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$#@%&*';
|
||||
return chars.charAt(Phaser.Math.Between(0, chars.length - 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
import { Faction } from '../faction/factions.js';
|
||||
|
||||
export class Level extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'Level' });
|
||||
this.map = 'night-woods';
|
||||
this.isDragging = false;
|
||||
this.dragStartX = 0;
|
||||
this.dragStartY = 0;
|
||||
}
|
||||
|
||||
init(data) {
|
||||
|
||||
}
|
||||
|
||||
preload() {
|
||||
// Map Stuff
|
||||
this.load.tilemapTiledJSON('map', `./assets/${this.map}.json`);
|
||||
this.load.image('terrain', './assets/terrain.png');
|
||||
this.load.spritesheet('dark-ages', './assets/dark-ages.png', {
|
||||
frameWidth: 64,
|
||||
frameHeight: 64
|
||||
});
|
||||
}
|
||||
|
||||
create() {
|
||||
const map = this.make.tilemap({ key: 'map' });
|
||||
const tiles = map.addTilesetImage('terrain', 'terrain');
|
||||
this.mainLayer = map.createLayer('main', tiles, 0, 0)
|
||||
this.physics.world.setBounds(0, 0, this.mainLayer.width, this.mainLayer.height);
|
||||
|
||||
// Add input listeners for dragging
|
||||
this.input.on('pointerdown', this.onPointerDown, this);
|
||||
this.input.on('pointermove', this.onPointerMove, this);
|
||||
this.input.on('pointerup', this.onPointerUp, this);
|
||||
|
||||
this.factionLeft = this.add.group();
|
||||
this.factionRight = this.add.group();
|
||||
|
||||
const test = new Faction(this, 4*64, 5*64, 'dark-ages', 0, 'left', 1, 'dark-ages').setOrigin(0.5);
|
||||
const test2 = new Faction(this, 27*64, 4*64, 'dark-ages', 0, 'right', 1, 'dark-ages').setOrigin(0.5);
|
||||
|
||||
// Add collision detection
|
||||
this.physics.add.overlap(this.factionLeft, this.factionRight, this.handleFactionCollision, null, this);
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
this.factionLeft.getChildren().forEach(faction => {
|
||||
if (faction.update) {
|
||||
faction.update(time, delta);
|
||||
}
|
||||
});
|
||||
|
||||
this.factionRight.getChildren().forEach(faction => {
|
||||
if (faction.update) {
|
||||
faction.update(time, delta);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleFactionCollision(faction1, faction2) {
|
||||
// Check if factions are on opposite sides
|
||||
if (faction1.side !== faction2.side) {
|
||||
// Calculate distance between factions
|
||||
const distance = Phaser.Math.Distance.Between(faction1.x, faction1.y, faction2.x, faction2.y);
|
||||
|
||||
// If within attack range
|
||||
if (distance < 150) {
|
||||
// Pause path following and move towards each other
|
||||
faction1.pausePath();
|
||||
faction2.pausePath();
|
||||
|
||||
// Move towards each other
|
||||
const angle = Phaser.Math.Angle.Between(faction1.x, faction1.y, faction2.x, faction2.y);
|
||||
const speed = 50;
|
||||
|
||||
faction1.body.setVelocity(
|
||||
Math.cos(angle) * speed,
|
||||
Math.sin(angle) * speed
|
||||
);
|
||||
|
||||
faction2.body.setVelocity(
|
||||
Math.cos(angle + Math.PI) * speed,
|
||||
Math.sin(angle + Math.PI) * speed
|
||||
);
|
||||
|
||||
// Flip sprites based on movement direction
|
||||
if (faction1.body.velocity.x > 0) {
|
||||
faction1.setFlipX(true);
|
||||
} else {
|
||||
faction1.setFlipX(false);
|
||||
}
|
||||
|
||||
if (faction2.body.velocity.x > 0) {
|
||||
faction2.setFlipX(true);
|
||||
} else {
|
||||
faction2.setFlipX(false);
|
||||
}
|
||||
} else {
|
||||
// If they're not close enough, resume normal path following
|
||||
faction1.resumePath();
|
||||
faction2.resumePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPointerDown(pointer) {
|
||||
this.isDragging = true;
|
||||
this.dragStartX = pointer.x;
|
||||
this.dragStartY = pointer.y;
|
||||
}
|
||||
|
||||
onPointerMove(pointer) {
|
||||
if (this.isDragging) {
|
||||
const deltaX = pointer.x - this.dragStartX;
|
||||
const deltaY = pointer.y - this.dragStartY;
|
||||
|
||||
// Update camera position
|
||||
this.cameras.main.scrollX -= deltaX;
|
||||
this.cameras.main.scrollY -= deltaY;
|
||||
|
||||
// Update drag start position for next move
|
||||
this.dragStartX = pointer.x;
|
||||
this.dragStartY = pointer.y;
|
||||
}
|
||||
}
|
||||
|
||||
onPointerUp(pointer) {
|
||||
this.isDragging = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
import { PLAYER_CONFIG } from '../characters/playerConfig.js';
|
||||
import { WEAPONS_CONFIG } from '../characters/weaponsConfig.js';
|
||||
|
||||
export class Menu extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'Menu' });
|
||||
}
|
||||
|
||||
preload() {
|
||||
// Player
|
||||
this.load.spritesheet('players', './assets/players.png', {
|
||||
frameWidth: 200,
|
||||
frameHeight: 200
|
||||
});
|
||||
|
||||
// Weapons
|
||||
this.load.image('chainWallet', 'assets/weapons/chainWallet.png');
|
||||
this.load.image('monster', 'assets/weapons/monster.png');
|
||||
this.load.image('hobbies', 'assets/weapons/hobbies.png');
|
||||
this.load.spritesheet('hobbie-sprites', 'assets/weapons/hobbie-sprites.png', {
|
||||
frameWidth: 100,
|
||||
frameHeight: 100
|
||||
});
|
||||
this.load.image('catFight', 'assets/weapons/catFight.png');
|
||||
this.load.image('bread', 'assets/weapons/bread.png');
|
||||
this.load.image('leftovers', 'assets/weapons/leftovers.png');
|
||||
this.load.spritesheet('catFight-sprites', 'assets/weapons/catFight-sprites.png', {
|
||||
frameWidth: 100,
|
||||
frameHeight: 100
|
||||
});
|
||||
this.load.spritesheet('leftovers-sprites', 'assets/weapons/leftovers-sprites.png', {
|
||||
frameWidth: 100,
|
||||
frameHeight: 100
|
||||
});
|
||||
this.load.spritesheet('bread-sprites', 'assets/weapons/bread-sprites.png', {
|
||||
frameWidth: 100,
|
||||
frameHeight: 100
|
||||
});
|
||||
this.load.image('freezeLaunch', 'assets/weapons/freezeLaunch.png');
|
||||
this.load.spritesheet('freezeLaunch-sprites', 'assets/weapons/freezeLaunch-sprites.png', {
|
||||
frameWidth: 200,
|
||||
frameHeight: 100
|
||||
});
|
||||
this.load.image('pickles', 'assets/weapons/pickles.png');
|
||||
this.load.image('pickleCloud1', 'assets/weapons/pickleCloud1.png');
|
||||
this.load.image('pickleCloud2', 'assets/weapons/pickleCloud2.png');
|
||||
this.load.image('banana', 'assets/weapons/banana.png');
|
||||
this.load.spritesheet('banana-sprites', 'assets/weapons/banana-sprites.png', {
|
||||
frameWidth: 100,
|
||||
frameHeight: 100
|
||||
});
|
||||
|
||||
// Items
|
||||
this.load.spritesheet('items', './assets/items.png', {
|
||||
frameWidth: 100,
|
||||
frameHeight: 100
|
||||
});
|
||||
|
||||
// Menu
|
||||
this.load.image('menuLogo', 'assets/menuLogo.png');
|
||||
this.load.font('Bitwise', 'assets/Bitwise.ttf');
|
||||
this.load.video('menuVideo', 'assets/menuVideo.mp4');
|
||||
this.load.audio('menuMusic', 'assets/menuMusic.mp3');
|
||||
this.load.audio('menuInterface', 'assets/sounds/menuInterface.mp3');
|
||||
this.load.audio('menuInterfaceUp', 'assets/sounds/menuInterfaceUp.mp3');
|
||||
this.load.audio('select', 'assets/sounds/select.mp3');
|
||||
this.load.image('menuKevin', 'assets/menuKevin.png');
|
||||
this.load.image('menuPanel', 'assets/menuPanel.png');
|
||||
this.load.image('arrow', 'assets/arrow.png');
|
||||
}
|
||||
|
||||
create() {
|
||||
// Create video sprite that fills the screen
|
||||
const video = this.add.video(0, 0, 'menuVideo');
|
||||
video.setOrigin(0);
|
||||
video.setScale(this.game.config.width / 848, this.game.config.height / 480);
|
||||
video.setDepth(-1);
|
||||
video.play(true);
|
||||
|
||||
// Create audio and play in a loop
|
||||
this.bgMusic = this.sound.add('menuMusic');
|
||||
this.bgMusic.loop = true;
|
||||
this.bgMusic.play();
|
||||
|
||||
this.menuLogo = this.add.image(800, 350, 'menuLogo').setOrigin(0.5);
|
||||
|
||||
// Add start text
|
||||
this.startPanel = this.add.image(500, 750, 'menuPanel').setOrigin(0.5).setInteractive();
|
||||
this.startText = this.add.text(500, 750, 'Click Here to Start', {
|
||||
fontSize: '32px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#ffffff',
|
||||
align: 'center'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Add fullscreen text
|
||||
this.fsPanel = this.add.image(1100, 750, 'menuPanel').setOrigin(0.5).setInteractive();
|
||||
this.fullscreenText = this.add.text(1100, 750, 'Toggle Fullscreen', {
|
||||
fontSize: '32px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#f6ff78ff',
|
||||
align: 'center'
|
||||
}).setOrigin(0.5);
|
||||
|
||||
// Add fullscreen functionality
|
||||
this.fsPanel.on('pointerdown', () => {
|
||||
if (this.scale.isFullscreen) {
|
||||
this.scale.stopFullscreen();
|
||||
} else {
|
||||
this.scale.startFullscreen();
|
||||
}
|
||||
});
|
||||
this.fsPanel.on('pointerover', () => {
|
||||
this.tweens.add({
|
||||
targets: [this.fsPanel, this.fullscreenText],
|
||||
scale: 1.1,
|
||||
y: 730,
|
||||
duration: 200
|
||||
});
|
||||
});
|
||||
this.fsPanel.on('pointerout', () => {
|
||||
this.tweens.add({
|
||||
targets: [this.fsPanel, this.fullscreenText],
|
||||
scale: 1,
|
||||
y: 750,
|
||||
duration: 200
|
||||
});
|
||||
});
|
||||
|
||||
this.characters = this.add.container();
|
||||
this.menuBackground = this.add.rectangle(1000, 450, 1200, 800, 0xFFFFFF, 0.5).setOrigin(0.5);
|
||||
this.menuCharacterText = this.add.text(425, 75, 'Choose Your Character', {
|
||||
fontSize: '32px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#00a2ffff',
|
||||
stroke: '#005e94ff',
|
||||
align: 'left',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
});
|
||||
this.characters.add(this.menuBackground);
|
||||
this.characters.add(this.menuCharacterText);
|
||||
|
||||
let i = 1;
|
||||
let charX = 0;
|
||||
let charY = 0;
|
||||
Object.entries(PLAYER_CONFIG).forEach(([key, character]) => {
|
||||
if (key === 'base') return;
|
||||
|
||||
const charContainer = this.add.container(425 + charX, 125 + charY);
|
||||
const charBox = this.add.rectangle(0, 0, 370, 225, 0x000000, 0.6).setOrigin(0).setInteractive();
|
||||
// Add hover effect
|
||||
charBox.on('pointerover', () => {
|
||||
charBox.setFillStyle(0x555555, 0.9);
|
||||
});
|
||||
|
||||
charBox.on('pointerout', () => {
|
||||
charBox.setFillStyle(0x333333, 0.9);
|
||||
});
|
||||
charBox.on('pointerdown', () => {
|
||||
this.bgMusic.stop();
|
||||
this.cameras.main.fadeOut();
|
||||
this.sound.play('select');
|
||||
this.time.delayedCall(1000, () => {
|
||||
//this.sound.play('menuInterface');
|
||||
this.scene.start('Level', {
|
||||
character: key
|
||||
});
|
||||
});
|
||||
});
|
||||
const charImage = this.add.sprite(-30, 12.5, character.texture, character.frame).setOrigin(0);
|
||||
const charWeapon = this.add.image(80, 115, character.weapon).setOrigin(0).setDisplaySize(100, 100);
|
||||
charWeapon.postFX.addGlow(0xff3c00);
|
||||
const charName = this.add.text(130, 10, character.name, {
|
||||
fontSize: '36px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#fffb00ff',
|
||||
stroke: '#919400ff',
|
||||
align: 'left',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
});
|
||||
const charLikes = this.add.text(130, 60, `Likes:\n${character.likes}`, {
|
||||
fontSize: '20px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#ffffffff',
|
||||
stroke: '#2e2e2eff',
|
||||
align: 'left',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
});
|
||||
const charWeaponTitle = this.add.text(190, 110, 'Starting Weapon:', {
|
||||
fontSize: '20px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#ff3c00',
|
||||
stroke: '#8f2100ff',
|
||||
align: 'left',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
});
|
||||
const charWeaponInfo = this.add.text(190, 140, `${WEAPONS_CONFIG[character.weapon].info.name}`, {
|
||||
fontSize: '20px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#ffffffff',
|
||||
stroke: '#2e2e2eff',
|
||||
align: 'left',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
});
|
||||
const charWeaponInfo2 = this.add.text(190, 160, `${WEAPONS_CONFIG[character.weapon].info.desc}`, {
|
||||
fontSize: '16px',
|
||||
fontFamily: 'Bitwise',
|
||||
fill: '#ffffffff',
|
||||
stroke: '#2e2e2eff',
|
||||
align: 'left',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 2,
|
||||
offsetY: 2,
|
||||
color: '#000000',
|
||||
blur: 4,
|
||||
fill: true
|
||||
}
|
||||
});
|
||||
charContainer.add(charBox);
|
||||
charContainer.add(charImage);
|
||||
charContainer.add(charWeapon);
|
||||
charContainer.add(charName);
|
||||
charContainer.add(charLikes);
|
||||
charContainer.add(charWeaponTitle);
|
||||
charContainer.add(charWeaponInfo);
|
||||
charContainer.add(charWeaponInfo2);
|
||||
this.characters.add(charContainer);
|
||||
charX += 390;
|
||||
if (i % 3 === 0) {
|
||||
charY += 245;
|
||||
charX = 0;
|
||||
}
|
||||
i++;
|
||||
});
|
||||
this.characters.y = 1000;
|
||||
|
||||
this.kevinMenu = this.add.image(-250, 550, 'menuKevin').setOrigin(0.5, 0.5).setScale(.8).setFlipX(true);
|
||||
|
||||
this.startPanel.on('pointerdown', () => {
|
||||
this.sound.play('menuInterface');
|
||||
this.tweens.add({
|
||||
targets: this.kevinMenu,
|
||||
x: 200,
|
||||
duration: 2000,
|
||||
scale: .5,
|
||||
ease: 'Cubic.Out'
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: [this.startText, this.fullscreenText, this.startPanel, this.fsPanel],
|
||||
alpha: 0,
|
||||
duration: 1000,
|
||||
onComplete: () => {
|
||||
this.startText.destroy();
|
||||
}
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: this.menuLogo,
|
||||
scale: .3,
|
||||
x: 200,
|
||||
y: 140,
|
||||
duration: 1000
|
||||
});
|
||||
this.tweens.add({
|
||||
targets: this.characters,
|
||||
y: 0,
|
||||
delay: 500,
|
||||
ease: 'Cubic.Out',
|
||||
duration: 2000
|
||||
});
|
||||
});
|
||||
this.startPanel.on('pointerover', () => {
|
||||
this.tweens.add({
|
||||
targets: [this.startPanel, this.startText],
|
||||
scale: 1.1,
|
||||
y: 730,
|
||||
duration: 200
|
||||
});
|
||||
});
|
||||
this.startPanel.on('pointerout', () => {
|
||||
this.tweens.add({
|
||||
targets: [this.startPanel, this.startText],
|
||||
scale: 1,
|
||||
y: 750,
|
||||
duration: 200
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1 @@
|
|||
python -m http.server 8000
|
||||
Loading…
Reference in New Issue