feat: Faza 1 Gameplay Loop - Kista, Sekanje, Gradnja, Kmetovanje, Dnevnik, Zombiji
- Starter Chest (Kista): Nov sprite asset (chest_closed.png), zamenjal rectangles z dejansko sliko, dodal axe reward ob odprtju - Sekanje dreves: Zahteva Sekiro v rokah, padec drevesa odvrze 3 kose lesa (pickup sistem), unlock dnevniska vnosa - Gradnja Barikad [B]: Nov wooden_fence.png asset, BuildingSystem posodobljen z leseno barikado (cena: 2 les), ghost preview z grid snappingom, deductItem() API - Farming zanka: Popravljen seed property v InventorySystem, unlock ob prvem sajenju in zetvi - Kaijev Dnevnik [J]: Novi JournalSystem.js s 6 vnosi, gotski UI z zlatimi okviri, animirano odpiranje, odklepanje ob napredku - Zombie nochni napadi: Stopnjevano po nochih (max 8, hitrost do 65px/s, krajsi spawn delay), unlock dnevnika ob prvi nochi - InventorySystem: Popravljen bug kjer tools niso bili dodani v hotbar, dodan axe in wood v ITEM_DEFS, nova deductItem() funkcija - Pomoznna remove_bg.py skripta za odstranjevanje belega ozadja assetov
This commit is contained in:
137
nova farma TRAE/src/systems/TwinBondSystem.js
Normal file
137
nova farma TRAE/src/systems/TwinBondSystem.js
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* TwinBondSystem.js
|
||||
*
|
||||
* Sistem, ki občasno pošlje srhljiv telepatski signal (spomin/klic) od Ane.
|
||||
* Ekran naključno utripne vijolično in se izpiše skrit tekst v glavi Kaja.
|
||||
*/
|
||||
|
||||
export default class TwinBondSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.isActive = false;
|
||||
|
||||
// Overlay za vijoličen blisk
|
||||
this.flashOverlay = scene.add.graphics()
|
||||
.setDepth(9999)
|
||||
.setScrollFactor(0);
|
||||
|
||||
// Tekst na sredini zaslona
|
||||
const cx = scene.cameras.main.width / 2;
|
||||
const cy = scene.cameras.main.height / 2;
|
||||
|
||||
this.messageText = scene.add.text(cx, cy - 100, '', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '42px',
|
||||
color: '#ff99ff',
|
||||
stroke: '#2b002b',
|
||||
strokeThickness: 8,
|
||||
align: 'center',
|
||||
fontStyle: 'bold'
|
||||
})
|
||||
.setOrigin(0.5, 0.5)
|
||||
.setDepth(10000)
|
||||
.setScrollFactor(0)
|
||||
.setAlpha(0);
|
||||
|
||||
// Nabor Aninih sporočil
|
||||
this.messages = [
|
||||
"K a i . . . n a j d i m e . . .",
|
||||
"T u k a j d o l j e t e m a . . .",
|
||||
"N e o b u p a j . . . T w i n B o n d d e l u j e .",
|
||||
"K a i . . . b o l i m e . . .",
|
||||
"P a z i s e n o č i . . ."
|
||||
];
|
||||
|
||||
// Tipka za testiranje (tipka T)
|
||||
this.keyT = scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.T);
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
// Testni sprožilec
|
||||
if (Phaser.Input.Keyboard.JustDown(this.keyT) && !this.isActive) {
|
||||
this.triggerBond();
|
||||
}
|
||||
|
||||
// Naključno sprožanje (zelo majhna možnost ob igranju)
|
||||
// 1 na 10,000 frejmov (~ vsake 3-5 minut)
|
||||
if (Math.random() < 0.0001 && !this.isActive) {
|
||||
// Samo če je zunaj spanja
|
||||
this.triggerBond();
|
||||
}
|
||||
}
|
||||
|
||||
triggerBond() {
|
||||
this.isActive = true;
|
||||
|
||||
// Zaustavi Kaja za kratek čas (šok)
|
||||
if (this.scene.kai) {
|
||||
this.scene.kai.canMove = false;
|
||||
this.scene.kai.setVelocity(0, 0);
|
||||
}
|
||||
|
||||
// 1. Zvok (Web Audio API srhljiv glitch freq)
|
||||
this._playGlitchSound();
|
||||
|
||||
// 2. Narisemo purple flash, ki pokrije zaslon
|
||||
const W = this.scene.cameras.main.width;
|
||||
const H = this.scene.cameras.main.height;
|
||||
this.flashOverlay.clear();
|
||||
this.flashOverlay.fillStyle(0x3a0055, 0.85); // Temno vijolična
|
||||
this.flashOverlay.fillRect(0, 0, W, H);
|
||||
|
||||
// Skrijemo čez 0.15s
|
||||
this.scene.time.delayedCall(150, () => {
|
||||
this.flashOverlay.clear();
|
||||
});
|
||||
|
||||
// 3. Izberi random text in naredi typewriter
|
||||
const text = Phaser.Utils.Array.GetRandom(this.messages);
|
||||
this.messageText.setText('');
|
||||
this.messageText.setAlpha(1);
|
||||
|
||||
let index = 0;
|
||||
const typeTimer = this.scene.time.addEvent({
|
||||
delay: 80,
|
||||
repeat: text.length - 1,
|
||||
callback: () => {
|
||||
this.messageText.setText(text.substring(0, index + 1));
|
||||
index++;
|
||||
}
|
||||
});
|
||||
|
||||
// 4. Fade out text in enable movement po 3 sekundah
|
||||
this.scene.time.delayedCall(3000, () => {
|
||||
this.scene.tweens.add({
|
||||
targets: this.messageText,
|
||||
alpha: 0,
|
||||
duration: 1000,
|
||||
onComplete: () => {
|
||||
this.isActive = false;
|
||||
if (this.scene.kai) {
|
||||
this.scene.kai.canMove = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_playGlitchSound() {
|
||||
if (!this.scene.sound.context) return;
|
||||
const ctx = this.scene.sound.context;
|
||||
const osc = ctx.createOscillator();
|
||||
const gain = ctx.createGain();
|
||||
|
||||
// Srhljiv nizek zvok s frekvenčno modulacijo
|
||||
osc.type = 'sawtooth';
|
||||
osc.frequency.setValueAtTime(120, ctx.currentTime);
|
||||
osc.frequency.linearRampToValueAtTime(40, ctx.currentTime + 1.5);
|
||||
|
||||
gain.gain.setValueAtTime(0.3, ctx.currentTime);
|
||||
gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 1.5);
|
||||
|
||||
osc.connect(gain);
|
||||
gain.connect(ctx.destination);
|
||||
osc.start();
|
||||
osc.stop(ctx.currentTime + 1.5);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user