posodobitve
This commit is contained in:
320
src/systems/CameraSystem.js
Normal file
320
src/systems/CameraSystem.js
Normal file
@@ -0,0 +1,320 @@
|
||||
class CameraSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.camera = scene.cameras.main;
|
||||
|
||||
// Camera modes
|
||||
this.mode = 'follow'; // 'follow', 'free', 'cinematic', 'screenshot'
|
||||
|
||||
// Free camera controls
|
||||
this.freeCamSpeed = 5;
|
||||
this.freeCamZoom = 1.0;
|
||||
|
||||
// Cinematic mode
|
||||
this.cinematicPath = [];
|
||||
this.cinematicIndex = 0;
|
||||
this.cinematicPlaying = false;
|
||||
|
||||
// Screenshot mode
|
||||
this.screenshotMode = false;
|
||||
this.uiHidden = false;
|
||||
|
||||
// Saved camera positions
|
||||
this.savedPositions = [];
|
||||
|
||||
this.setupControls();
|
||||
|
||||
console.log('📷 CameraSystem: Initialized');
|
||||
}
|
||||
|
||||
setupControls() {
|
||||
// F6 - Free Camera Mode
|
||||
this.scene.input.keyboard.on('keydown-F6', () => {
|
||||
this.toggleFreeCamera();
|
||||
});
|
||||
|
||||
// F7 - Screenshot Mode (hide UI)
|
||||
this.scene.input.keyboard.on('keydown-F7', () => {
|
||||
this.toggleScreenshotMode();
|
||||
});
|
||||
|
||||
// F8 - Save Camera Position
|
||||
this.scene.input.keyboard.on('keydown-F8', () => {
|
||||
this.saveCameraPosition();
|
||||
});
|
||||
|
||||
// F9 - Cinematic Mode
|
||||
this.scene.input.keyboard.on('keydown-F10', () => {
|
||||
this.toggleCinematicMode();
|
||||
});
|
||||
|
||||
// Arrow keys for free camera
|
||||
this.cursors = this.scene.input.keyboard.createCursorKeys();
|
||||
|
||||
// Page Up/Down for zoom
|
||||
this.scene.input.keyboard.on('keydown-PAGEUP', () => {
|
||||
this.adjustZoom(0.1);
|
||||
});
|
||||
|
||||
this.scene.input.keyboard.on('keydown-PAGEDOWN', () => {
|
||||
this.adjustZoom(-0.1);
|
||||
});
|
||||
}
|
||||
|
||||
// FREE CAMERA MODE
|
||||
toggleFreeCamera() {
|
||||
if (this.mode === 'free') {
|
||||
this.mode = 'follow';
|
||||
this.camera.startFollow(this.scene.player.sprite);
|
||||
console.log('📷 Camera: Follow mode');
|
||||
} else {
|
||||
this.mode = 'free';
|
||||
this.camera.stopFollow();
|
||||
console.log('📷 Camera: Free mode (Arrow keys to move, PgUp/PgDn to zoom)');
|
||||
}
|
||||
}
|
||||
|
||||
updateFreeCamera(delta) {
|
||||
if (this.mode !== 'free') return;
|
||||
|
||||
const speed = this.freeCamSpeed * (delta / 16);
|
||||
|
||||
if (this.cursors.left.isDown) {
|
||||
this.camera.scrollX -= speed;
|
||||
}
|
||||
if (this.cursors.right.isDown) {
|
||||
this.camera.scrollX += speed;
|
||||
}
|
||||
if (this.cursors.up.isDown) {
|
||||
this.camera.scrollY -= speed;
|
||||
}
|
||||
if (this.cursors.down.isDown) {
|
||||
this.camera.scrollY += speed;
|
||||
}
|
||||
}
|
||||
|
||||
adjustZoom(delta) {
|
||||
this.freeCamZoom = Phaser.Math.Clamp(this.freeCamZoom + delta, 0.3, 3.0);
|
||||
this.camera.setZoom(this.freeCamZoom);
|
||||
console.log(`📷 Zoom: ${this.freeCamZoom.toFixed(2)}x`);
|
||||
}
|
||||
|
||||
// SCREENSHOT MODE
|
||||
toggleScreenshotMode() {
|
||||
this.screenshotMode = !this.screenshotMode;
|
||||
|
||||
const uiScene = this.scene.scene.get('UIScene');
|
||||
if (!uiScene) return;
|
||||
|
||||
if (this.screenshotMode) {
|
||||
// Hide all UI
|
||||
uiScene.children.list.forEach(child => {
|
||||
if (child.setVisible) {
|
||||
child.wasVisible = child.visible;
|
||||
child.setVisible(false);
|
||||
}
|
||||
});
|
||||
this.uiHidden = true;
|
||||
console.log('📷 Screenshot mode: UI hidden (F7 to restore)');
|
||||
} else {
|
||||
// Restore UI
|
||||
uiScene.children.list.forEach(child => {
|
||||
if (child.setVisible && child.wasVisible !== undefined) {
|
||||
child.setVisible(child.wasVisible);
|
||||
}
|
||||
});
|
||||
this.uiHidden = false;
|
||||
console.log('📷 Screenshot mode: UI restored');
|
||||
}
|
||||
}
|
||||
|
||||
// SAVE CAMERA POSITION
|
||||
saveCameraPosition() {
|
||||
const pos = {
|
||||
x: this.camera.scrollX,
|
||||
y: this.camera.scrollY,
|
||||
zoom: this.camera.zoom
|
||||
};
|
||||
|
||||
this.savedPositions.push(pos);
|
||||
console.log(`📷 Camera position saved (${this.savedPositions.length}): x=${pos.x.toFixed(0)}, y=${pos.y.toFixed(0)}, zoom=${pos.zoom.toFixed(2)}`);
|
||||
}
|
||||
|
||||
loadCameraPosition(index) {
|
||||
if (index < 0 || index >= this.savedPositions.length) return;
|
||||
|
||||
const pos = this.savedPositions[index];
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this.camera,
|
||||
scrollX: pos.x,
|
||||
scrollY: pos.y,
|
||||
zoom: pos.zoom,
|
||||
duration: 1000,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
console.log(`📷 Camera position loaded (${index + 1})`);
|
||||
}
|
||||
|
||||
// CINEMATIC MODE
|
||||
toggleCinematicMode() {
|
||||
if (this.cinematicPlaying) {
|
||||
this.stopCinematic();
|
||||
} else {
|
||||
this.startCinematic();
|
||||
}
|
||||
}
|
||||
|
||||
startCinematic() {
|
||||
if (this.savedPositions.length < 2) {
|
||||
console.log('📷 Need at least 2 saved positions for cinematic!');
|
||||
return;
|
||||
}
|
||||
|
||||
this.cinematicPlaying = true;
|
||||
this.cinematicIndex = 0;
|
||||
this.mode = 'cinematic';
|
||||
|
||||
this.playCinematicStep();
|
||||
|
||||
console.log('📷 Cinematic mode: Playing...');
|
||||
}
|
||||
|
||||
playCinematicStep() {
|
||||
if (!this.cinematicPlaying) return;
|
||||
if (this.cinematicIndex >= this.savedPositions.length) {
|
||||
this.stopCinematic();
|
||||
return;
|
||||
}
|
||||
|
||||
const pos = this.savedPositions[this.cinematicIndex];
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this.camera,
|
||||
scrollX: pos.x,
|
||||
scrollY: pos.y,
|
||||
zoom: pos.zoom,
|
||||
duration: 3000,
|
||||
ease: 'Sine.easeInOut',
|
||||
onComplete: () => {
|
||||
this.cinematicIndex++;
|
||||
this.scene.time.delayedCall(500, () => {
|
||||
this.playCinematicStep();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
stopCinematic() {
|
||||
this.cinematicPlaying = false;
|
||||
this.mode = 'follow';
|
||||
this.camera.startFollow(this.scene.player.sprite);
|
||||
console.log('📷 Cinematic mode: Stopped');
|
||||
}
|
||||
|
||||
// PRESET CAMERA ANGLES
|
||||
setPresetAngle(preset) {
|
||||
const presets = {
|
||||
'overview': { zoom: 0.5, y: -200 },
|
||||
'closeup': { zoom: 1.5, y: 0 },
|
||||
'wide': { zoom: 0.3, y: -300 },
|
||||
'action': { zoom: 1.2, y: -50 }
|
||||
};
|
||||
|
||||
const p = presets[preset];
|
||||
if (!p) return;
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this.camera,
|
||||
zoom: p.zoom,
|
||||
scrollY: this.camera.scrollY + p.y,
|
||||
duration: 1000,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
|
||||
console.log(`📷 Preset angle: ${preset}`);
|
||||
}
|
||||
|
||||
// SHAKE EFFECTS
|
||||
shake(intensity = 0.005, duration = 200) {
|
||||
this.camera.shake(duration, intensity);
|
||||
}
|
||||
|
||||
// FLASH EFFECTS
|
||||
flash(color = 0xffffff, duration = 200) {
|
||||
this.camera.flash(duration,
|
||||
(color >> 16) & 0xff,
|
||||
(color >> 8) & 0xff,
|
||||
color & 0xff
|
||||
);
|
||||
}
|
||||
|
||||
// FADE EFFECTS
|
||||
fadeOut(duration = 1000, callback) {
|
||||
this.camera.fadeOut(duration, 0, 0, 0);
|
||||
if (callback) {
|
||||
this.camera.once('camerafadeoutcomplete', callback);
|
||||
}
|
||||
}
|
||||
|
||||
fadeIn(duration = 1000, callback) {
|
||||
this.camera.fadeIn(duration, 0, 0, 0);
|
||||
if (callback) {
|
||||
this.camera.once('camerafadeincomplete', callback);
|
||||
}
|
||||
}
|
||||
|
||||
// PAN TO LOCATION
|
||||
panTo(x, y, duration = 2000) {
|
||||
this.scene.tweens.add({
|
||||
targets: this.camera,
|
||||
scrollX: x - this.camera.width / 2,
|
||||
scrollY: y - this.camera.height / 2,
|
||||
duration: duration,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
}
|
||||
|
||||
// ZOOM TO
|
||||
zoomTo(zoom, duration = 1000) {
|
||||
this.scene.tweens.add({
|
||||
targets: this.camera,
|
||||
zoom: zoom,
|
||||
duration: duration,
|
||||
ease: 'Sine.easeInOut'
|
||||
});
|
||||
}
|
||||
|
||||
// UPDATE
|
||||
update(delta) {
|
||||
this.updateFreeCamera(delta);
|
||||
}
|
||||
|
||||
// EXPORT CAMERA DATA (for trailer editing)
|
||||
exportCameraData() {
|
||||
const data = {
|
||||
savedPositions: this.savedPositions,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
|
||||
const json = JSON.stringify(data, null, 2);
|
||||
console.log('📷 Camera data:', json);
|
||||
|
||||
// Copy to clipboard (if available)
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(json);
|
||||
console.log('📷 Camera data copied to clipboard!');
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// IMPORT CAMERA DATA
|
||||
importCameraData(data) {
|
||||
if (data.savedPositions) {
|
||||
this.savedPositions = data.savedPositions;
|
||||
console.log(`📷 Imported ${this.savedPositions.length} camera positions`);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user