Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;' Line Number: 359
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;' Line Number: 359
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (18 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ggame is not defined' in or related to this line: 'ggame.update = function () {' Line Number: 1468
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'height')' in or related to this line: 'LK.gui.top.add(new Text2('SONG ENDED', {' Line Number: 920
Code edit (11 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'height')' in or related to this line: 'playerHpBarContainer.y = LK.data.height - 80; // Pozycja Y na dole (LK.data.height to wysokość ekranu)' Line Number: 698
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'stringify')' in or related to this line: 'console.log("Swipe BBox:", JSON.stringify(swipeBoundingBox));' Line Number: 497
Code edit (6 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'stringify')' in or related to this line: 'console.log("Swipe BBox:", JSON.stringify(swipeBoundingBox));' Line Number: 497
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Graphics is not a constructor' in or related to this line: 'var hitZoneLine = new Graphics();' Line Number: 242
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: LK.getTime is not a function' in or related to this line: 'var now = LK.getTime();' Line Number: 535
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Note = Container.expand(function (noteType, swipeDir, targetHitTimeFull, centerXVal) {
var self = Container.call(this);
self.noteType = noteType || 'tap';
self.swipeDir = swipeDir || null;
self.targetHitTime = targetHitTimeFull;
self.visualSpawnTime = self.targetHitTime - noteTravelTime;
self.hit = false;
self.judged = false;
self.scaleStart = 0.3;
self.scaleEnd = 1.2;
self.centerX = centerXVal;
self.centerY = 1800;
self.startY = 600;
self.noteAsset = null;
self.isWiderSwipePart = false; // Flag for wider swipe rendering if needed later
// Store original columnIndex if available, for potential debugging or advanced logic
if (this.mapData && this.mapData.originalColumnHint !== undefined) {
self.originalColumnHint = this.mapData.originalColumnHint;
}
if (self.noteType === 'tap') {
self.noteAsset = self.attachAsset('tapNote', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.noteType === 'swipe') {
self.noteAsset = self.attachAsset('swipeNote', {
anchorX: 0.5,
anchorY: 0.5
});
if (self.swipeDir) {
var arrow = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
arrow.anchor.set(0.5, 0.5);
if (self.swipeDir === 'left') {
arrow.setText('←');
} else if (self.swipeDir === 'right') {
arrow.setText('→');
} else if (self.swipeDir === 'up') {
arrow.setText('↑');
} else if (self.swipeDir === 'down') {
arrow.setText('↓');
}
self.addChild(arrow);
self.arrow = arrow;
}
} else if (self.noteType === 'trap') {
self.noteAsset = self.attachAsset('trapNote', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.alpha = 0;
self.showHitFeedback = function (result) {
// Existing circular feedback
var feedbackCircle = LK.getAsset('hitFeedback', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
// Relative to the note's center
y: 0,
// Relative to the note's center
scaleX: 0.7,
scaleY: 0.7,
alpha: 0.7
});
var feedbackTextContent = "";
var feedbackTextColor = 0xFFFFFF; // Default white
if (result === 'perfect') {
feedbackCircle.tint = 0xffff00; // Yellow
feedbackTextContent = "Perfect!"; // Or "+100"
feedbackTextColor = 0xffff00;
} else if (result === 'good') {
feedbackCircle.tint = 0x00ff00; // Green
feedbackTextContent = "Good!"; // Or "+50"
feedbackTextColor = 0x00ff00;
} else {
// 'miss'
feedbackCircle.tint = 0xff0000; // Red
feedbackTextContent = "Miss";
feedbackTextColor = 0xff0000;
}
self.addChild(feedbackCircle); // Add circle to the note container
tween(feedbackCircle, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 350,
easing: tween.easeOut,
onFinish: function onFinish() {
if (feedbackCircle.parent) {
feedbackCircle.destroy();
}
}
});
// New text feedback
if (feedbackTextContent) {
var scorePopup = new Text2(feedbackTextContent, {
size: 60,
// Możemy dostosować rozmiar
fill: feedbackTextColor,
stroke: 0x000000,
// Czarny kontur dla lepszej czytelności
strokeThickness: 3
});
scorePopup.anchor.set(0.5, 0.5);
scorePopup.x = 0; // W centrum notatki (tam gdzie feedbackCircle)
scorePopup.y = -SWIPE_NOTE_WIDTH / 2 - 30; // Trochę nad notatką (zakładając, że notatka ma środek w 0,0)
// Możemy potrzebować dostosować Y, jeśli anchor notatki jest inny
// Add to the main game layer (or LK.gui.top) so it's not affected by note's alpha/scale changes later
// If added to self (note), it would disappear if note is quickly destroyed.
// Let's add it to the note's parent (which should be 'game')
if (self.parent) {
// Ensure note has a parent
// Position needs to be absolute if added to game layer
scorePopup.x = self.x + 0; // (self.x (Note's absolute X) + relative X (0))
scorePopup.y = self.y - SWIPE_NOTE_WIDTH * self.scale.y / 2 - 30; // (self.y (Note's absolute Y) + relative Y)
self.parent.addChild(scorePopup); // Add to the same layer as the note
}
tween(scorePopup, {
y: scorePopup.y - 80,
// Animacja w górę
alpha: 0
}, {
duration: 700,
// Dłuższy czas trwania animacji
easing: tween.easeOut,
onFinish: function onFinish() {
if (scorePopup.parent) {
scorePopup.destroy();
}
}
});
}
};
self.update = function () {
var now = Date.now();
if (self.judged) {
// If judged (hit or missed), it might still be moving for a bit
if (now > self.targetHitTime + 500) {// Time after hit/miss to be fully removed by removeOldNotes
// This note is done, removeOldNotes will handle it.
// If it was hit, its alpha might be 0 from feedback animation.
// If it was missed and had flash, it's visible.
// We can explicitly hide it here if we want it to disappear sooner than removeOldNotes.
// self.alpha = 0; // Opcjonalnie, aby szybciej zniknęła po ocenie
}
// Allow it to continue moving based on original trajectory if needed for visual effect
// For simplicity, if judged, we mostly let removeOldNotes handle it.
// However, if we want it to continue moving PAST the hit line visibly:
if (this.alpha > 0) {
// Only update position if visible
var elapsedTimeSinceSpawn = now - self.visualSpawnTime;
var currentProgress = elapsedTimeSinceSpawn / noteTravelTime;
// No clamping progress to 1 here, so it can go beyond
self.x = self.centerX;
self.y = self.startY + (self.centerY - self.startY) * currentProgress;
// Keep scale at max after passing hit line
var currentScale = currentProgress >= 1 ? self.scaleEnd : self.scaleStart + (self.scaleEnd - self.scaleStart) * currentProgress;
self.scale.x = Math.max(0.01, currentScale);
self.scale.y = Math.max(0.01, currentScale);
}
return;
}
if (now < self.visualSpawnTime) {
self.alpha = 0;
return;
}
if (self.alpha === 0 && !self.judged) {
self.alpha = 1;
}
var elapsedTimeSinceSpawn = now - self.visualSpawnTime;
var progress = elapsedTimeSinceSpawn / noteTravelTime;
// Notatka leci dalej, więc progress może być > 1
// Nie ograniczamy już progress do 1 tutaj dla pozycji i skali
// Skala osiąga self.scaleEnd przy progress = 1 i tak pozostaje
var scale;
if (progress >= 1) {
scale = self.scaleEnd;
} else if (progress < 0) {
// Powinno być obsłużone przez visualSpawnTime check, ale dla pewności
scale = self.scaleStart;
progress = 0; // Clamp progress for position if it was somehow negative
} else {
scale = self.scaleStart + (self.scaleEnd - self.scaleStart) * progress;
}
self.scale.x = Math.max(0.01, scale);
self.scale.y = Math.max(0.01, scale);
self.x = self.centerX;
self.y = self.startY + (self.centerY - self.startY) * progress; // Pozwalamy Y iść dalej
// Oznacz jako miss, jeśli nie została oceniona i minął czas + okno tolerancji
if (!self.judged && now > self.targetHitTime + hitWindowGood) {
self.judged = true; // Oznaczona jako oceniona (w tym przypadku jako miss)
if (self.noteType !== 'trap') {
game.onNoteMiss(self); // Wywołaj logikę miss
}
// Notatka będzie dalej widoczna i usuwana przez removeOldNotes
}
};
self.isInHitWindow = function () {
var now = Date.now();
var dt = Math.abs(now - self.targetHitTime);
return dt <= hitWindowGood;
};
self.getHitAccuracy = function () {
var now = Date.now();
var dt = Math.abs(now - self.targetHitTime);
if (dt <= hitWindowPerfect) {
return 'perfect';
}
if (dt <= hitWindowGood) {
return 'good';
}
return 'miss';
};
return self;
});
var PowerUpItem = Container.expand(function (powerUpType, centerXVal) {
var self = Container.call(this);
self.itemType = powerUpType;
self.centerX = centerXVal;
self.startY = 600;
self.centerY = 1800; // Linia uderzenia/zbierania
self.visualAsset = null;
self.collected = false;
self.spawnTime = Date.now();
self.isAtDestinationAndPotentiallyMissed = false; // Nowa flaga
if (self.itemType === 'potion') {
self.visualAsset = self.attachAsset('hpPotionAsset', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.itemType === 'shield') {
self.visualAsset = self.attachAsset('shieldAsset', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.itemType === 'swipeToTap') {
self.visualAsset = self.attachAsset('swipeToTapBuffAsset', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
console.log("Error: Nieznany typ PowerUpa przy tworzeniu assetu: " + self.itemType);
self.visualAsset = self.attachAsset('hpPotionAsset', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.alpha = 1;
self.scale.set(1);
self.x = self.centerX; // Ustawienie początkowej pozycji X
self.y = self.startY; // Ustawienie początkowej pozycji Y
self.update = function () {
if (self.collected) {
// Jeśli zebrany, nic więcej nie rób (zostanie usunięty przez managePowerUpItems)
return;
}
// Jeśli w poprzedniej klatce dotarł do celu i nie został zebrany, teraz go usuwamy
if (self.isAtDestinationAndPotentiallyMissed) {
if (!self.collected) {
// Podwójne sprawdzenie, na wszelki wypadek
console.log("PowerUp " + self.itemType + " ostatecznie minięty i niszczony");
if (self.parent) {
self.destroy();
}
}
return; // Kończymy update dla tego obiektu
}
var now = Date.now();
var progress = (now - self.spawnTime) / noteTravelTime;
if (progress >= 1) {
self.y = self.centerY; // Ustawiamy dokładnie na linii uderzenia
// Dotarł do linii. Ustawiamy flagę, ale nie niszczymy od razu.
// Zniszczenie (jeśli nie zebrany) nastąpi w następnej klatce update().
// Daje to szansę na zarejestrowanie kliknięcia w tej klatce.
self.isAtDestinationAndPotentiallyMissed = true;
// Na tym etapie jeszcze nie logujemy "minięty", bo może zostać kliknięty w tej klatce.
} else {
// Nadal w ruchu
self.y = self.startY + (self.centerY - self.startY) * progress;
}
};
self.collect = function () {
if (self.collected) {
return;
}
self.collected = true;
console.log("PowerUp " + self.itemType + " zebrany!");
if (collectedPowerUps.hasOwnProperty(self.itemType)) {
collectedPowerUps[self.itemType]++;
console.log("Masz teraz " + collectedPowerUps[self.itemType] + " x " + self.itemType);
updatePowerUpDisplayCounts(); // NOWE: Aktualizuj UI po zebraniu
}
if (self.parent) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181828
});
/****
* Game Code
****/
// Niebieski dla obszaru specjalnego bossa (jak poprzednio)
// Żółty dla kart (jak poprzednio 'bossCardPlaceholderAsset')
// Ciemnoczerwony dla ramki (placeholder)
// Ciemnoszare tło dla galerii
// Niebieski dla ramki specjalnego bossa
// Żółty dla kart
// Maska, kolor nieważny
/**** * Game Code
****/
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function showStartScreen() {
currentScreenState = 'start';
if (gameUIContainer) {
gameUIContainer.visible = false;
}
if (hitZoneLine) {
hitZoneLine.visible = false;
}
// Usunięte linie ukrywające shieldTimerDisplayContainer i swipeToTapTimerDisplayContainer,
// ponieważ teraz nie powinny być w ogóle tworzone w tym stanie.
game.setBackgroundColor(0x000000);
var startButton = new Text2("MAKE SOME NOISEE", {
size: 150,
fill: 0xFFFFFF
});
startButton.anchor.set(0.5, 0.5);
startButton.x = gameScreenWidth / 2;
startButton.y = gameScreenHeight / 2;
startButton.interactive = true;
startButton.cursor = "pointer";
game.addChild(startButton);
startButton.down = function () {
if (startButton.parent) {
startButton.destroy();
}
showIntro();
};
}
function showMainMenu() {
currentScreenState = 'mainmenu';
if (gameUIContainer) {
gameUIContainer.visible = false;
}
if (hitZoneLine) {
hitZoneLine.visible = false;
}
if (shieldTimerDisplayContainer) {
shieldTimerDisplayContainer.visible = false;
}
if (swipeToTapTimerDisplayContainer) {
swipeToTapTimerDisplayContainer.visible = false;
}
game.setBackgroundColor(0x2a2a2a); // Inny kolor tła dla menu głównego
var menuItems = []; // Tablica do przechowywania elementów menu dla łatwego czyszczenia
var titleText = new Text2("MAIN MENU", {
// Dodajmy tytuł ekranu
size: 180,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = gameScreenWidth / 2;
titleText.y = 300; // Na górze ekranu
game.addChild(titleText);
menuItems.push(titleText);
var buttonYStart = 700;
var buttonYSpacing = 250;
var buttonFontSize = 120;
// Przycisk "Music Battle"
var musicBattleButton = new Text2("Music Battle", {
size: buttonFontSize,
fill: 0xFFD700 // Złoty kolor dla wyróżnienia
});
musicBattleButton.anchor.set(0.5, 0.5);
musicBattleButton.x = gameScreenWidth / 2;
musicBattleButton.y = buttonYStart;
musicBattleButton.interactive = true;
musicBattleButton.cursor = "pointer";
game.addChild(musicBattleButton);
menuItems.push(musicBattleButton);
musicBattleButton.down = function () {
menuItems.forEach(function (item) {
if (item.parent) {
item.destroy();
}
});
showBossSelectionScreen();
};
// Przycisk "How To Play"
var howToPlayButton = new Text2("How To Play", {
size: buttonFontSize,
fill: 0xFFFFFF
});
howToPlayButton.anchor.set(0.5, 0.5);
howToPlayButton.x = gameScreenWidth / 2;
howToPlayButton.y = buttonYStart + buttonYSpacing;
howToPlayButton.interactive = true;
howToPlayButton.cursor = "pointer";
game.addChild(howToPlayButton);
menuItems.push(howToPlayButton);
howToPlayButton.down = function () {
menuItems.forEach(function (item) {
if (item.parent) {
item.destroy();
}
});
showTutorial();
};
// Przycisk "Credits"
var creditsButton = new Text2("Credits", {
size: buttonFontSize,
fill: 0xFFFFFF
});
creditsButton.anchor.set(0.5, 0.5);
creditsButton.x = gameScreenWidth / 2;
creditsButton.y = buttonYStart + buttonYSpacing * 2;
creditsButton.interactive = true;
creditsButton.cursor = "pointer";
game.addChild(creditsButton);
menuItems.push(creditsButton);
creditsButton.down = function () {
menuItems.forEach(function (item) {
if (item.parent) {
item.destroy();
}
});
showCreditsScreen();
};
}
function showBossSelectionScreen() {
currentScreenState = 'bossselection';
if (gameUIContainer) {
gameUIContainer.visible = false;
}
if (hitZoneLine) {
hitZoneLine.visible = false;
}
if (shieldTimerDisplayContainer) {
shieldTimerDisplayContainer.visible = false;
}
if (swipeToTapTimerDisplayContainer) {
swipeToTapTimerDisplayContainer.visible = false;
}
game.setBackgroundColor(0x000000);
var screenElements = [];
var viewportX = (gameScreenWidth - 900) / 2;
var viewportY = 150;
var viewportWidth = 900;
var viewportHeight = 1800;
var cardsViewport = new Container();
cardsViewport.x = viewportX;
cardsViewport.y = viewportY;
game.addChild(cardsViewport);
screenElements.push(cardsViewport);
var allCardsContainer = new Container();
cardsViewport.addChild(allCardsContainer);
// Using your new image asset for the mask
var viewportMaskObject = LK.getAsset('viewportImageMaskAsset', {
width: viewportWidth,
height: viewportHeight
});
cardsViewport.addChild(viewportMaskObject);
cardsViewport.mask = viewportMaskObject;
var cardWidth = (viewportWidth - 150) / 2;
var cardHeight = 500;
var spacingX = 50;
var spacingY = 50;
var numRegularBosses = 8;
for (var i = 0; i < numRegularBosses; i++) {
var card = LK.getAsset('bossCardPlaceholderAsset', {
width: cardWidth,
height: cardHeight
});
var col = i % 2;
var row = Math.floor(i / 2);
card.x = spacingX + col * (cardWidth + spacingX);
card.y = spacingY + row * (cardHeight + spacingY);
var cardText = new Text2("Boss " + (i + 1), {
size: 70,
fill: 0x000000
});
cardText.anchor.set(0.5, 0.5);
cardText.x = cardWidth / 2;
cardText.y = cardHeight / 2;
card.addChild(cardText);
card.interactive = true;
card.cursor = "pointer";
card.bossData = {
id: "regular_boss_" + (i + 1),
name: "Boss " + (i + 1)
};
card.down = function () {
console.log("Wybrano: " + this.bossData.name);
};
allCardsContainer.addChild(card);
}
var specialBossFrameWidth = viewportWidth;
var specialBossFrameHeight = 200;
var specialBossAssetPlaceholder = LK.getAsset('specialBossFramePlaceholderAsset', {
width: specialBossFrameWidth,
height: specialBossFrameHeight
});
specialBossAssetPlaceholder.x = viewportX;
specialBossAssetPlaceholder.y = viewportY + viewportHeight + 30;
game.addChild(specialBossAssetPlaceholder);
screenElements.push(specialBossAssetPlaceholder);
var specialBossText = new Text2("SPECIAL BOSS", {
size: 60,
fill: 0xFFFFFF,
align: 'center'
});
specialBossText.anchor.set(0.5, 0.5);
specialBossText.x = specialBossFrameWidth / 2;
specialBossText.y = specialBossFrameHeight / 2;
specialBossAssetPlaceholder.addChild(specialBossText);
specialBossAssetPlaceholder.interactive = true;
specialBossAssetPlaceholder.cursor = "pointer";
specialBossAssetPlaceholder.down = function () {
var infoPopup = new Text2("Pokonaj wszystkich pozostałych bossów!", {
size: 50,
fill: 0xFF0000
});
infoPopup.anchor.set(0.5, 0.5);
infoPopup.x = gameScreenWidth / 2;
infoPopup.y = gameScreenHeight / 2;
game.addChild(infoPopup);
var popupRef = infoPopup;
LK.setTimeout(function () {
if (popupRef.parent) {
popupRef.destroy();
}
}, 2500);
};
var backButton = new Text2("Back to Menu", {
size: 80,
fill: 0xCCCCCC
});
backButton.anchor.set(0.5, 1);
backButton.x = gameScreenWidth / 2;
backButton.y = gameScreenHeight - 40;
backButton.interactive = true;
backButton.cursor = "pointer";
game.addChild(backButton);
screenElements.push(backButton);
backButton.down = function () {
while (allCardsContainer.children.length > 0) {
var childCard = allCardsContainer.getChildAt(0);
allCardsContainer.removeChild(childCard);
if (childCard.destroy) {
childCard.destroy();
}
}
if (cardsViewport) {
if (cardsViewport.mask) {
// cardsViewport.mask is viewportMaskObject
var maskObj = cardsViewport.mask;
cardsViewport.mask = null;
if (maskObj.parent) {
maskObj.parent.removeChild(maskObj);
}
if (maskObj.destroy) {
maskObj.destroy();
}
}
}
screenElements.forEach(function (item) {
if (item.parent) {
item.destroy();
}
});
screenElements = [];
showMainMenu();
};
allCardsContainer.y = 0;
}
function showCreditsScreen() {
currentScreenState = 'credits';
if (gameUIContainer) {
gameUIContainer.visible = false;
}
if (hitZoneLine) {
hitZoneLine.visible = false;
}
game.setBackgroundColor(0x1a1a1a); // Ciemnoszary dla creditsów
var elements = [];
var creditsText = new Text2("Gra stworzona przez:\nNasz Wspaniały Duet!", {
size: 90,
fill: 0xFFFFFF,
align: 'center' // Wyśrodkowanie tekstu wieloliniowego
});
creditsText.anchor.set(0.5, 0.5);
creditsText.x = gameScreenWidth / 2;
creditsText.y = gameScreenHeight / 2 - 100;
game.addChild(creditsText);
elements.push(creditsText);
var backButton = new Text2("Back to Menu", {
size: 80,
fill: 0xCCCCCC
});
backButton.anchor.set(0.5, 0.5);
backButton.x = gameScreenWidth / 2;
backButton.y = gameScreenHeight - 200;
backButton.interactive = true;
backButton.cursor = "pointer";
game.addChild(backButton);
elements.push(backButton);
backButton.down = function () {
elements.forEach(function (item) {
if (item.parent) {
item.destroy();
}
});
showMainMenu();
};
}
function showIntro() {
currentScreenState = 'intro';
if (gameUIContainer) {
gameUIContainer.visible = false;
}
if (hitZoneLine) {
hitZoneLine.visible = false;
}
if (shieldTimerDisplayContainer) {
shieldTimerDisplayContainer.visible = false;
}
if (swipeToTapTimerDisplayContainer) {
swipeToTapTimerDisplayContainer.visible = false;
}
game.setBackgroundColor(0x111111);
var introPlaceholderText = new Text2("Intro Sequence Placeholder", {
size: 100,
fill: 0xFFFFFF
});
introPlaceholderText.anchor.set(0.5, 0.5);
introPlaceholderText.x = gameScreenWidth / 2;
introPlaceholderText.y = gameScreenHeight / 2;
game.addChild(introPlaceholderText);
LK.setTimeout(function () {
if (introPlaceholderText.parent) {
introPlaceholderText.destroy();
}
showMainMenu(); // <<<< ZMIANA TUTAJ
}, 1000);
}
function showTutorial() {
currentScreenState = 'tutorial';
if (gameUIContainer) {
gameUIContainer.visible = false;
}
if (hitZoneLine) {
hitZoneLine.visible = false;
}
if (shieldTimerDisplayContainer) {
shieldTimerDisplayContainer.visible = false;
} // Pozostawiam na wszelki wypadek
if (swipeToTapTimerDisplayContainer) {
swipeToTapTimerDisplayContainer.visible = false;
} // Pozostawiam na wszelki wypadek
game.setBackgroundColor(0x222222);
var elements = [];
var tutorialPlaceholderText = new Text2("Tutorial Placeholder\n(Tu będzie super tutorial!)", {
size: 100,
fill: 0xFFFFFF,
align: 'center'
});
tutorialPlaceholderText.anchor.set(0.5, 0.5);
tutorialPlaceholderText.x = gameScreenWidth / 2;
tutorialPlaceholderText.y = gameScreenHeight / 2 - 100;
game.addChild(tutorialPlaceholderText);
elements.push(tutorialPlaceholderText);
var backButton = new Text2("Back to Menu", {
size: 80,
fill: 0xCCCCCC
});
backButton.anchor.set(0.5, 0.5);
backButton.x = gameScreenWidth / 2;
backButton.y = gameScreenHeight - 200;
backButton.interactive = true;
backButton.cursor = "pointer";
game.addChild(backButton);
elements.push(backButton);
backButton.down = function () {
elements.forEach(function (item) {
if (item.parent) {
item.destroy();
}
});
showMainMenu();
};
}
var currentScreenState = '';
var gameScreenWidth = 2048;
var gameScreenHeight = Math.round(gameScreenWidth * (2732 / 2048)); // iPad-like proportions
var playfieldWidth = 1408;
var playfieldStartX = (gameScreenWidth - playfieldWidth) / 2;
var NUM_COLUMNS = 4;
var columnWidth = playfieldWidth / NUM_COLUMNS;
var columnCenterXs = [];
for (var i = 0; i < NUM_COLUMNS; i++) {
columnCenterXs.push(playfieldStartX + i * columnWidth + columnWidth / 2);
}
var SWIPE_NOTE_WIDTH = 160;
// HP System Variables
var playerMaxHP = 10;
var playerCurrentHP = 10;
var bossMaxHP = 30;
var bossCurrentHP = 30;
var gameOverFlag = false;
// HP Bar UI Elements Configuration (actual elements created in setupHpBars)
var hpBarWidth = 400;
var hpBarHeight = 30;
// UI Container
var gameUIContainer; // Declare gameUIContainer
// HP Bar Containers (will be initialized in setupHpBars)
var playerHpBarContainer;
var playerHpBarFill;
var bossHpBarContainer;
var bossHpBarFill;
var POWERUP_SPAWN_INTERVAL = 2000; // Co 6 sekund
var lastPowerUpSpawnAttemptTime = 0;
var POWERUP_SPAWN_CHANCE = 0.75; // 15% szansy
var POTION_HEAL_AMOUNT = 2;
var activePowerUpItems = [];
var SHIELD_DURATION = 6000;
var isShieldActive = false;
var shieldEndTime = 0;
var SWIPE_TO_TAP_BUFF_DURATION = 5000; // Czas trwania buffa w ms (5 sekund)
var isSwipeToTapBuffActive = false;
var swipeToTapBuffEndTime = 0;
var shieldTimerDisplayContainer;
var smallShieldIconDisplay;
var shieldTimerTextDisplay;
var shieldTimerDisplayContainer;
var smallShieldIconDisplay;
var shieldTimerTextDisplay;
var swipeToTapTimerDisplayContainer; // Kontener na ikonkę timera i tekst dla buffa
var smallSwipeToTapIconDisplay; // Mniejsza ikonka buffa dla timera
var swipeToTapTimerTextDisplay;
var currentBossSprite;
var powerUpDisplayContainer; // Główny kontener na UI power-upów
var hpPotionIcon, shieldIcon, swipeToTapIcon; // Referencje do ikon
var hpPotionCountText, shieldCountText, swipeToTapCountText; // Referencje do tekstów z ilością
var collectedPowerUps = {
potion: 0,
shield: 0,
swipeToTap: 0 // Klucz 'swipeToTap' dla spójności
};
// Game State & Rhythm Logic Variables
var allSongData = {
"defaultTestTrack": {
musicAsset: null,
bossAssetKey: 'Boss1_Asset',
// <<--- NOWA WŁAŚCIWOŚĆ
config: {
playerMaxHP: 10,
//
bossMaxHP: 20 //
},
rawRhythmMap: [
// Istniejące nuty
{
time: 1000,
type: 'tap',
columnIndex: 0
}, {
time: 1800,
type: 'tap',
columnIndex: 1
}, {
time: 2600,
type: 'swipe',
swipeDir: 'left',
columnIndex: 2
}, {
time: 3400,
type: 'tap',
columnIndex: 3
}, {
time: 4200,
type: 'swipe',
swipeDir: 'right',
columnIndex: 0
}, {
time: 5000,
type: 'trap',
columnIndex: 1
}, {
time: 5800,
type: 'tap',
columnIndex: 2
}, {
time: 6600,
type: 'swipe',
swipeDir: 'right',
columnIndex: 1
}, {
time: 6600,
type: 'swipe',
swipeDir: 'right',
columnIndex: 2
}, {
time: 7400,
type: 'tap',
columnIndex: 0
},
// Dodatkowe nuty dla przedłużenia mapy
{
time: 9000,
type: 'tap',
columnIndex: 1
}, {
time: 10000,
type: 'swipe',
swipeDir: 'left',
columnIndex: 2
}, {
time: 11000,
type: 'tap',
columnIndex: 3
}, {
time: 12000,
type: 'swipe',
swipeDir: 'right',
columnIndex: 0
}, {
time: 13000,
type: 'tap',
columnIndex: 1
}, {
time: 14000,
type: 'trap',
columnIndex: 2
}, {
time: 15000,
type: 'tap',
columnIndex: 3
}, {
time: 16000,
type: 'swipe',
swipeDir: 'up',
columnIndex: 0
}, {
time: 17000,
type: 'swipe',
swipeDir: 'down',
columnIndex: 1
}, {
time: 18000,
type: 'tap',
columnIndex: 2
}, {
time: 19000,
type: 'swipe',
swipeDir: 'left',
columnIndex: 3
}, {
time: 20000,
type: 'tap',
columnIndex: 0
}, {
time: 21000,
type: 'tap',
columnIndex: 1
}, {
time: 22000,
type: 'swipe',
swipeDir: 'right',
columnIndex: 2
}, {
time: 23000,
type: 'tap',
columnIndex: 3
}, {
time: 24000,
type: 'swipe',
swipeDir: 'up',
columnIndex: 1
}, {
time: 25000,
type: 'swipe',
swipeDir: 'down',
columnIndex: 2
}, {
time: 26000,
type: 'tap',
columnIndex: 0
}, {
time: 27000,
type: 'tap',
columnIndex: 3
}]
},
"test3": {
// Pozostaje bez zmian, chyba że też chcesz go modyfikować
musicAsset: "test3",
config: {
playerMaxHP: 10,
bossMaxHP: 30
}
}
};
var currentActiveRhythmMap = null;
var currentMusic = null;
var noteTravelTime = 2200;
var hitWindowPerfect = 190;
var hitWindowGood = 260;
var MIN_SWIPE_DISTANCE = 60;
var notes = [];
var nextNoteIdx = 0;
var gameStartTime = 0;
var score = 0;
var combo = 0;
var maxCombo = 0;
var swipeStart = null;
var inputLocked = false;
var hpBarsInitialized = false;
// Initialize and add gameUIContainer to the game scene
gameUIContainer = new Container();
game.addChild(gameUIContainer);
// Function to process raw rhythm map data (remains unchanged, ensure it's here)
function processRawRhythmMap(rawMapData, songKeyForLogging) {
console.log("Processing raw map for: " + songKeyForLogging + " with " + rawMapData.length + " initial notes.");
var processedMap = [];
var tempMap = [];
for (var k = 0; k < rawMapData.length; k++) {
var originalNote = rawMapData[k];
var copiedNote = {};
for (var key in originalNote) {
if (originalNote.hasOwnProperty(key)) {
copiedNote[key] = originalNote[key];
}
}
tempMap.push(copiedNote);
}
for (var i = 0; i < tempMap.length; i++) {
var note = tempMap[i];
if (note.type === 'swipe' && note.swipeDir) {
var dir = note.swipeDir.toLowerCase();
if (dir.includes('right')) {
note.swipeDir = 'right';
} else if (dir.includes('left')) {
note.swipeDir = 'left';
} else if (dir.includes('up')) {
note.swipeDir = 'up';
} else if (dir.includes('down')) {
note.swipeDir = 'down';
}
}
}
var timeGroupedNotes = {};
tempMap.forEach(function (note) {
if (!timeGroupedNotes[note.time]) {
timeGroupedNotes[note.time] = [];
}
timeGroupedNotes[note.time].push(note);
});
var finalMapNotes = [];
var sortedTimes = Object.keys(timeGroupedNotes).map(Number).sort(function (a, b) {
return a - b;
});
for (var tIdx = 0; tIdx < sortedTimes.length; tIdx++) {
var time = sortedTimes[tIdx];
var notesAtThisTime = timeGroupedNotes[time];
var notesToKeepAtThisTime = [];
var processedForWiderSwipeConversion = [];
var colsWithVerticalSwipes = [null, null, null, null];
notesAtThisTime.forEach(function (note) {
if (note.type === 'swipe' && (note.swipeDir === 'up' || note.swipeDir === 'down')) {
if (note.columnIndex >= 0 && note.columnIndex < NUM_COLUMNS) {
var alreadyConverted = false;
for (var convIdx = 0; convIdx < processedForWiderSwipeConversion.length; convIdx++) {
if (processedForWiderSwipeConversion[convIdx].originalTime === note.time && processedForWiderSwipeConversion[convIdx].originalColumn === note.columnIndex) {
alreadyConverted = true;
break;
}
}
if (!alreadyConverted) {
colsWithVerticalSwipes[note.columnIndex] = note.swipeDir;
}
}
}
});
for (var c = 0; c < NUM_COLUMNS - 1; c++) {
if (colsWithVerticalSwipes[c] && colsWithVerticalSwipes[c + 1] && colsWithVerticalSwipes[c] === colsWithVerticalSwipes[c + 1]) {
var randomHorizontalDir = Math.random() < 0.5 ? 'left' : 'right';
var pairCenterX = (columnCenterXs[c] + columnCenterXs[c + 1]) / 2;
notesToKeepAtThisTime.push({
time: time,
type: 'swipe',
swipeDir: randomHorizontalDir,
partOfWiderSwipe: 'leftHalf',
widerSwipePairCenterX: pairCenterX,
originalColumnHint: c
});
notesToKeepAtThisTime.push({
time: time,
type: 'swipe',
swipeDir: randomHorizontalDir,
partOfWiderSwipe: 'rightHalf',
widerSwipePairCenterX: pairCenterX,
originalColumnHint: c + 1
});
processedForWiderSwipeConversion.push({
originalTime: time,
originalColumn: c
});
processedForWiderSwipeConversion.push({
originalTime: time,
originalColumn: c + 1
});
colsWithVerticalSwipes[c] = null;
colsWithVerticalSwipes[c + 1] = null;
c++;
}
}
notesAtThisTime.forEach(function (note) {
var wasConverted = false;
for (var convIdx = 0; convIdx < processedForWiderSwipeConversion.length; convIdx++) {
if (processedForWiderSwipeConversion[convIdx].originalTime === note.time && processedForWiderSwipeConversion[convIdx].originalColumn === note.columnIndex && (note.swipeDir === 'up' || note.swipeDir === 'down')) {
wasConverted = true;
break;
}
}
if (!wasConverted) {
notesToKeepAtThisTime.push(note);
}
});
var horizontalWiderSwipePairs = {};
var notesForFinalProcessing = [];
var uniqueNotesAtThisTime = [];
var seenNotesKeysAtThisTime = {};
notesToKeepAtThisTime.forEach(function (note) {
var key = "" + note.type + "_" + (note.columnIndex !== undefined ? note.columnIndex : note.partOfWiderSwipe ? note.widerSwipePairCenterX + note.partOfWiderSwipe : '') + "_" + (note.swipeDir || '');
if (!seenNotesKeysAtThisTime[key]) {
uniqueNotesAtThisTime.push(note);
seenNotesKeysAtThisTime[key] = true;
}
});
uniqueNotesAtThisTime.sort(function (a, b) {
var valA = a.originalColumnHint !== undefined ? a.originalColumnHint : a.columnIndex !== undefined ? a.columnIndex : a.widerSwipePairCenterX || 0;
var valB = b.originalColumnHint !== undefined ? b.originalColumnHint : b.columnIndex !== undefined ? b.columnIndex : b.widerSwipePairCenterX || 0;
return valA - valB;
});
for (var nIdx = 0; nIdx < uniqueNotesAtThisTime.length; nIdx++) {
var note = uniqueNotesAtThisTime[nIdx];
if (note.partOfWiderSwipe) {
notesForFinalProcessing.push(note);
continue;
}
var potentialPartner = null;
if (nIdx + 1 < uniqueNotesAtThisTime.length) {
potentialPartner = uniqueNotesAtThisTime[nIdx + 1];
}
if (note.type === 'swipe' && (note.swipeDir === 'left' || note.swipeDir === 'right') && potentialPartner && potentialPartner.type === 'swipe' && potentialPartner.time === note.time && potentialPartner.swipeDir === note.swipeDir && potentialPartner.columnIndex === note.columnIndex + 1) {
var pairCenterX = (columnCenterXs[note.columnIndex] + columnCenterXs[potentialPartner.columnIndex]) / 2;
notesForFinalProcessing.push({
time: note.time,
type: 'swipe',
swipeDir: note.swipeDir,
partOfWiderSwipe: 'leftHalf',
widerSwipePairCenterX: pairCenterX,
originalColumnHint: note.columnIndex
});
notesForFinalProcessing.push({
time: potentialPartner.time,
type: 'swipe',
swipeDir: potentialPartner.swipeDir,
partOfWiderSwipe: 'rightHalf',
widerSwipePairCenterX: pairCenterX,
originalColumnHint: potentialPartner.columnIndex
});
nIdx++;
} else {
notesForFinalProcessing.push(note);
}
}
finalMapNotes.push.apply(finalMapNotes, notesForFinalProcessing);
}
var uniqueNotesOverall = [];
var seenNotesOverall = {};
finalMapNotes.sort(function (a, b) {
return a.time - b.time;
});
finalMapNotes.forEach(function (note) {
var cX;
var keyPartForColumn;
if (note.partOfWiderSwipe) {
cX = note.widerSwipePairCenterX + (note.partOfWiderSwipe === 'leftHalf' ? -(SWIPE_NOTE_WIDTH / 2) : SWIPE_NOTE_WIDTH / 2);
keyPartForColumn = "pC" + note.widerSwipePairCenterX + "h" + (note.partOfWiderSwipe === 'leftHalf' ? 'L' : 'R');
} else if (note.columnIndex !== undefined) {
cX = columnCenterXs[note.columnIndex];
keyPartForColumn = "c" + note.columnIndex;
} else {
cX = gameScreenWidth / 2;
keyPartForColumn = "cX" + cX;
}
var key = "" + note.time + "_" + note.type + "_" + keyPartForColumn + "_" + (note.swipeDir || '');
if (!seenNotesOverall[key]) {
uniqueNotesOverall.push(note);
seenNotesOverall[key] = true;
} else {
// console.log("Filtered final duplicate note: " + key);
}
});
console.log("Processed map for: " + songKeyForLogging + " FINALLY contains " + uniqueNotesOverall.length + " notes.");
return uniqueNotesOverall;
}
var hpBarsInitialized = false;
var scoreTxt = new Text2('Score: 0', {
size: 100,
fill: 0xFFFFFF,
alpha: 1
});
scoreTxt.anchor.set(1, 0); // Anchor center-top
scoreTxt.x = gameScreenWidth / 1;
scoreTxt.y = 20; // Position from the top of its container (gameUIContainer)
gameUIContainer.addChild(scoreTxt);
console.log("Restored scoreTxt: X=" + scoreTxt.x + " Y=" + scoreTxt.y + " Visible:" + scoreTxt.visible + " Parent: gameUIContainer");
var comboTxt = new Text2('Combo: 0', {
size: 50,
// Możesz dostosować rozmiar tekstu combo
fill: 0xFFFF00,
// Żółty kolor
alpha: 0.5
});
comboTxt.anchor.set(0, 0.5);
comboTxt.x = 100;
comboTxt.y = 1000;
comboTxt.rotation = -0.26;
gameUIContainer.addChild(comboTxt);
console.log("ComboTxt positioned: X=" + comboTxt.x + " Y=" + comboTxt.y + " Visible:" + comboTxt.visible + " Parent: gameUIContainer");
var hitZoneY = 1800;
var hitZoneVisualWidth = playfieldWidth;
var hitZoneLine = LK.getAsset('lineAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: gameScreenWidth / 2,
y: hitZoneY,
width: hitZoneVisualWidth,
height: 4,
alpha: 0.6
});
game.addChild(hitZoneLine);
function rectsIntersect(r1, r2) {
return !(r2.x > r1.x + r1.width || r2.x + r2.width < r1.x || r2.y > r1.y + r1.height || r2.y + r2.height < r1.y);
}
function resetGameState() {
notes.forEach(function (n) {
if (n && n.parent) {
n.destroy();
}
});
notes = [];
nextNoteIdx = 0;
score = 0;
combo = 0;
maxCombo = 0;
swipeStart = null;
inputLocked = false;
scoreTxt.setText('Score: 0');
comboTxt.setText('Combo: 0');
gameOverFlag = false;
playerCurrentHP = playerMaxHP;
bossCurrentHP = bossMaxHP;
collectedPowerUps.potion = 0;
collectedPowerUps.shield = 0;
collectedPowerUps.swipeToTap = 0;
hpBarsInitialized = false;
if (hpBarsInitialized) {
updatePowerUpDisplayCounts();
}
if (isShieldActive) {
isShieldActive = false;
if (shieldIcon) {
shieldIcon.alpha = 1.0;
}
}
if (shieldTimerDisplayContainer) {
shieldTimerDisplayContainer.visible = false;
}
if (isSwipeToTapBuffActive) {
isSwipeToTapBuffActive = false;
if (swipeToTapIcon) {
swipeToTapIcon.alpha = 1.0;
}
}
// NOWE: Ukryj timer buffa Swipe-to-Tap przy resecie
if (swipeToTapTimerDisplayContainer) {
swipeToTapTimerDisplayContainer.visible = false;
}
// Koniec NOWE
if (playerHpBarFill && bossHpBarFill) {
updatePlayerHpDisplay();
updateBossHpDisplay();
}
}
function loadSong(songKey) {
if (gameUIContainer) {
gameUIContainer.visible = true;
}
if (gameUIContainer) {
gameUIContainer.visible = true;
}
if (hitZoneLine) {
hitZoneLine.visible = true;
}
var songData = allSongData[songKey]; //
if (!songData) {
//
console.log("Error: Song data not found for key: " + songKey); //
if (allSongData["defaultTestTrack"]) {
//
songData = allSongData["defaultTestTrack"]; //
console.log("Fallback to defaultTestTrack"); //
} else {
//
currentActiveRhythmMap = []; //
console.log("No fallback song data found."); //
return; //
}
}
if (songData.config) {
//
playerMaxHP = songData.config.playerMaxHP || 10; //
bossMaxHP = songData.config.bossMaxHP || 50; //
} else {
//
playerMaxHP = 10; //
bossMaxHP = 50; //
}
if (currentMusic && typeof currentMusic.stop === 'function') {
//
currentMusic.stop(); //
}
currentMusic = null; //
// hpBarsInitialized = false; // Tę linię prawdopodobnie chcemy zostawić, aby UI się odświeżało poprawnie dla nowej piosenki, ale paski HP bossa/gracza są resetowane w resetGameState
resetGameState();
if (gameUIContainer) {
gameUIContainer.visible = true;
}
hpBarsInitialized = false; // Resetujemy flagę, aby paski HP i UI power-upów mogły się poprawnie zainicjalizować na nowo w game.update
nextNoteIdx = 0; //
// NOWA SEKCJA: Ładowanie i wyświetlanie Bossa
if (currentBossSprite && currentBossSprite.parent) {
currentBossSprite.destroy(); // Usuń poprzedniego bossa, jeśli istnieje
currentBossSprite = null;
}
if (songData.bossAssetKey) {
currentBossSprite = LK.getAsset(songData.bossAssetKey, {
anchorX: 0.5,
anchorY: 0.5
});
currentBossSprite.x = gameScreenWidth / 2;
currentBossSprite.y = 350; // Możesz dostosować tę pozycję Y
currentBossSprite.alpha = 0.8; // Możesz dostosować alpha
game.addChildAt(currentBossSprite, 0); // Dodajemy na spód sceny gry
console.log("Boss sprite '" + songData.bossAssetKey + "' loaded and added to scene.");
} else {
console.log("No bossAssetKey defined for song: " + songKey);
}
// KONIEC NOWEJ SEKCJI
if (songData.rawRhythmMap) {
//
currentActiveRhythmMap = processRawRhythmMap(songData.rawRhythmMap, songKey); //
} else {
//
currentActiveRhythmMap = []; //
console.log("Warning: No rawRhythmMap for song: " + songKey + ". Game will have no notes."); //
}
gameStartTime = Date.now(); //
if (songData.musicAsset) {
//
currentMusic = LK.getSound(songData.musicAsset); //
if (currentMusic && typeof currentMusic.play === 'function') {
//
currentMusic.play(); //
console.log("Music asset for " + songKey + " PLAYING. gameStartTime: " + gameStartTime); //
} else {
//
console.log("Warning: Music asset '" + songData.musicAsset + "' not found or not playable."); //
}
} else {
//
console.log("No musicAsset defined for " + songKey + ". Map will run on system time only."); //
}
console.log("Loaded and processed song: " + songKey + " PlayerHP: " + playerMaxHP + " BossHP: " + bossMaxHP); //
}
function setupHpBars() {
if (bossHpBarContainer) {
bossHpBarContainer.destroy();
}
bossHpBarContainer = new Container();
bossHpBarContainer.x = gameScreenWidth / 2;
bossHpBarContainer.y = 100; // Adjusted Y slightly lower than scoreTxt for clarity
gameUIContainer.addChild(bossHpBarContainer); // Add to gameUIContainer
var bossBg = LK.getAsset('hpBarBackground', {
width: hpBarWidth,
height: hpBarHeight,
anchorX: 0.5,
anchorY: 0.5
});
bossHpBarContainer.addChild(bossBg);
bossHpBarFill = LK.getAsset('bossHpFill', {
width: hpBarWidth,
height: hpBarHeight,
anchorX: 0,
anchorY: 0.5,
x: -hpBarWidth / 2
});
bossHpBarContainer.addChild(bossHpBarFill);
if (playerHpBarContainer) {
playerHpBarContainer.destroy();
}
playerHpBarContainer = new Container();
playerHpBarContainer.x = gameScreenWidth / 2;
playerHpBarContainer.y = gameScreenHeight - 80;
gameUIContainer.addChild(playerHpBarContainer); // Add to gameUIContainer
var playerBg = LK.getAsset('hpBarBackground', {
width: hpBarWidth,
height: hpBarHeight,
anchorX: 0.5,
anchorY: 0.5
});
playerHpBarContainer.addChild(playerBg);
playerHpBarFill = LK.getAsset('playerHpFill', {
width: hpBarWidth,
height: hpBarHeight,
anchorX: 0,
anchorY: 0.5,
x: -hpBarWidth / 2
});
playerHpBarContainer.addChild(playerHpBarFill);
updateBossHpDisplay();
updatePlayerHpDisplay();
console.log("HP Bars setup and added to gameUIContainer. PlayerHP Y: " + playerHpBarContainer.y + " BossHP Y: " + bossHpBarContainer.y);
}
function setupPowerUpDisplay() {
powerUpDisplayContainer = new Container();
powerUpDisplayContainer.x = gameScreenWidth / 2;
powerUpDisplayContainer.y = 2450; // Twoja ustawiona wartość
gameUIContainer.addChild(powerUpDisplayContainer);
var iconSize = 150; // Twoja ustawiona wartość
var iconSpacing = 450; // Twoja ustawiona wartość
var textOffsetY = iconSize / 2 + 15;
// 1. Mikstura HP (bez zmian)
hpPotionIcon = LK.getAsset('hpPotionAsset', {
anchorX: 0.5,
anchorY: 0.5,
width: iconSize,
height: iconSize * 1.2
});
hpPotionIcon.x = -iconSpacing;
powerUpDisplayContainer.addChild(hpPotionIcon);
hpPotionCountText = new Text2("x0", {
size: 40,
fill: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0
});
hpPotionCountText.x = hpPotionIcon.x;
hpPotionCountText.y = textOffsetY;
powerUpDisplayContainer.addChild(hpPotionCountText);
hpPotionIcon.interactive = true;
hpPotionIcon.down = function () {
if (collectedPowerUps.potion > 0 && !gameOverFlag) {
collectedPowerUps.potion--;
updatePowerUpDisplayCounts();
playerCurrentHP += POTION_HEAL_AMOUNT;
if (playerCurrentHP > playerMaxHP) {
playerCurrentHP = playerMaxHP;
}
updatePlayerHpDisplay();
console.log("Użyto Mikstury HP! Aktualne HP gracza: " + playerCurrentHP);
} else if (collectedPowerUps.potion <= 0 && !gameOverFlag) {
console.log("Brak mikstur HP do użycia.");
}
};
// 2. Tarcza (bez zmian)
shieldIcon = LK.getAsset('shieldAsset', {
anchorX: 0.5,
anchorY: 0.5,
width: iconSize,
height: iconSize
});
shieldIcon.x = 0;
powerUpDisplayContainer.addChild(shieldIcon);
shieldCountText = new Text2("x0", {
size: 40,
fill: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0
});
shieldCountText.x = shieldIcon.x;
shieldCountText.y = textOffsetY;
powerUpDisplayContainer.addChild(shieldCountText);
shieldIcon.interactive = true;
shieldIcon.down = function () {
if (collectedPowerUps.shield > 0 && !isShieldActive && !gameOverFlag) {
collectedPowerUps.shield--;
updatePowerUpDisplayCounts();
isShieldActive = true;
shieldEndTime = Date.now() + SHIELD_DURATION;
shieldIcon.alpha = 0.5;
console.log("Tarcza AKTYWOWANA na " + SHIELD_DURATION / 1000 + " sekund!");
if (shieldTimerDisplayContainer) {
shieldTimerDisplayContainer.visible = true;
var remainingSeconds = SHIELD_DURATION / 1000;
shieldTimerTextDisplay.setText(remainingSeconds.toFixed(1) + "s");
}
} else if (isShieldActive && !gameOverFlag) {
console.log("Tarcza jest już aktywna.");
} else if (collectedPowerUps.shield <= 0 && !gameOverFlag) {
console.log("Brak Tarcz do użycia.");
}
};
// 3. Buff Swipe-to-Tap
swipeToTapIcon = LK.getAsset('swipeToTapBuffAsset', {
anchorX: 0.5,
anchorY: 0.5,
width: iconSize * 1.1,
height: iconSize * 1.1
});
swipeToTapIcon.x = iconSpacing;
powerUpDisplayContainer.addChild(swipeToTapIcon);
swipeToTapCountText = new Text2("x0", {
size: 40,
fill: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0
});
swipeToTapCountText.x = swipeToTapIcon.x;
swipeToTapCountText.y = textOffsetY;
powerUpDisplayContainer.addChild(swipeToTapCountText);
swipeToTapIcon.interactive = true;
swipeToTapIcon.down = function () {
console.log("--- SwipeToTap Icon (pełna logika) KLIKNIĘTA! ---");
console.log("Stan przed aktywacją: collected=" + collectedPowerUps.swipeToTap + ", isActive=" + isSwipeToTapBuffActive + ", gameOver=" + gameOverFlag);
if (collectedPowerUps.swipeToTap > 0 && !isSwipeToTapBuffActive && !gameOverFlag) {
collectedPowerUps.swipeToTap--;
updatePowerUpDisplayCounts();
isSwipeToTapBuffActive = true;
swipeToTapBuffEndTime = Date.now() + SWIPE_TO_TAP_BUFF_DURATION;
swipeToTapIcon.alpha = 0.5;
console.log("Buff Swipe-to-Tap AKTYWOWANY na " + SWIPE_TO_TAP_BUFF_DURATION / 1000 + " sekund!");
// NOWE: Pokaż timer buffa Swipe-to-Tap
if (swipeToTapTimerDisplayContainer) {
swipeToTapTimerDisplayContainer.visible = true;
var remainingSecondsBuff = SWIPE_TO_TAP_BUFF_DURATION / 1000;
swipeToTapTimerTextDisplay.setText(remainingSecondsBuff.toFixed(1) + "s");
}
} else {
console.log("Buff Swipe-to-Tap NIE został aktywowany. Analiza warunków:");
if (!(collectedPowerUps.swipeToTap > 0)) {
console.log(" - Powód: Brak zebranych buffów (ilość: " + collectedPowerUps.swipeToTap + ")");
}
if (isSwipeToTapBuffActive) {
console.log(" - Powód: Buff Swipe-to-Tap jest już aktywny.");
}
if (gameOverFlag) {
console.log(" - Powód: Gra jest zakończona (gameOverFlag = " + gameOverFlag + ")");
}
}
};
// UI dla timera tarczy (bez zmian)
shieldTimerDisplayContainer = new Container();
shieldTimerDisplayContainer.x = gameScreenWidth - 120;
shieldTimerDisplayContainer.y = 150;
gameUIContainer.addChild(shieldTimerDisplayContainer);
var smallIconSize = 60; // Wspólny rozmiar dla małych ikon w timerach
smallShieldIconDisplay = LK.getAsset('shieldAsset', {
anchorX: 0.5,
anchorY: 0.5,
width: smallIconSize,
height: smallIconSize
});
shieldTimerDisplayContainer.addChild(smallShieldIconDisplay);
shieldTimerTextDisplay = new Text2("", {
size: 35,
fill: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0
});
shieldTimerTextDisplay.y = smallIconSize / 2 + 5;
shieldTimerDisplayContainer.addChild(shieldTimerTextDisplay);
shieldTimerDisplayContainer.visible = false;
// NOWE: Tworzenie UI dla timera buffa Swipe-to-Tap (początkowo niewidoczne)
swipeToTapTimerDisplayContainer = new Container();
swipeToTapTimerDisplayContainer.x = gameScreenWidth - 120; // Ta sama pozycja X co timer tarczy
// Pozycja Y poniżej timera tarczy (wysokość timera tarczy to ok. smallIconSize + wysokość tekstu + odstęp)
// Zakładając, że shieldTimerDisplayContainer ma ok. 100-110px wysokości:
swipeToTapTimerDisplayContainer.y = shieldTimerDisplayContainer.y + smallIconSize + 40 + 10; // np. 150 + 60 + 40 + 10 = 260
gameUIContainer.addChild(swipeToTapTimerDisplayContainer);
smallSwipeToTapIconDisplay = LK.getAsset('swipeToTapBuffAsset', {
anchorX: 0.5,
anchorY: 0.5,
width: smallIconSize * 1.1,
// Zachowujemy proporcje jak dla dużej ikony
height: smallIconSize * 1.1
});
swipeToTapTimerDisplayContainer.addChild(smallSwipeToTapIconDisplay);
swipeToTapTimerTextDisplay = new Text2("", {
// Początkowo pusty tekst
size: 35,
fill: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0
});
swipeToTapTimerTextDisplay.y = smallIconSize * 1.1 / 2 + 5; // Umiejscowienie pod małą ikonką buffa
swipeToTapTimerDisplayContainer.addChild(swipeToTapTimerTextDisplay);
swipeToTapTimerDisplayContainer.visible = false; // Początkowo niewidoczny
console.log("PowerUp Display UI created. All PowerUp Icons are interactive. Shield & SwipeToTap Timer UI created.");
}
function updatePowerUpDisplayCounts() {
if (hpPotionCountText) {
// Sprawdzamy, czy UI zostało już zainicjalizowane
hpPotionCountText.setText("x" + collectedPowerUps.potion);
shieldCountText.setText("x" + collectedPowerUps.shield);
swipeToTapCountText.setText("x" + collectedPowerUps.swipeToTap);
}
}
function updatePlayerHpDisplay() {
if (playerHpBarFill) {
var healthPercent = playerCurrentHP / playerMaxHP;
playerHpBarFill.width = hpBarWidth * Math.max(0, healthPercent);
}
}
function updateBossHpDisplay() {
if (bossHpBarFill) {
var healthPercent = bossCurrentHP / bossMaxHP;
bossHpBarFill.width = hpBarWidth * Math.max(0, healthPercent);
}
}
function spawnNotes() {
var now = Date.now();
if (!currentActiveRhythmMap) {
return;
}
while (nextNoteIdx < currentActiveRhythmMap.length) {
var noteData = currentActiveRhythmMap[nextNoteIdx];
var noteTargetHitTime = gameStartTime + noteData.time;
if (noteTargetHitTime - noteTravelTime <= now) {
var targetCenterX;
// ... (logika ustalania targetCenterX pozostaje bez zmian, linie ) ...
if (noteData.partOfWiderSwipe && noteData.widerSwipePairCenterX !== undefined) {
if (noteData.partOfWiderSwipe === 'leftHalf') {
targetCenterX = noteData.widerSwipePairCenterX - SWIPE_NOTE_WIDTH / 2;
} else if (noteData.partOfWiderSwipe === 'rightHalf') {
targetCenterX = noteData.widerSwipePairCenterX + SWIPE_NOTE_WIDTH / 2;
} else {
targetCenterX = columnCenterXs[noteData.originalColumnHint !== undefined ? noteData.originalColumnHint : Math.floor(NUM_COLUMNS / 2)];
}
} else if (noteData.columnIndex !== undefined && noteData.columnIndex >= 0 && noteData.columnIndex < NUM_COLUMNS) {
targetCenterX = columnCenterXs[noteData.columnIndex];
} else {
targetCenterX = playfieldStartX + playfieldWidth / 2;
}
// NOWE: Logika zmiany typu nuty, jeśli buff Swipe-to-Tap jest aktywny
var finalNoteType = noteData.type;
var finalSwipeDir = noteData.swipeDir;
if (isSwipeToTapBuffActive && noteData.type === 'swipe') {
finalNoteType = 'tap'; // Zmień typ na 'tap'
finalSwipeDir = null; // Tap nie ma kierunku swipe'a
console.log("Buff aktywny: Zmieniono swipe na tap dla nuty o czasie " + noteData.time);
}
// Koniec NOWE
var n = new Note(finalNoteType, finalSwipeDir, noteTargetHitTime, targetCenterX); // Używamy finalNoteType i finalSwipeDir
n.mapData = noteData;
if (noteData.partOfWiderSwipe) {
n.isWiderSwipePart = true;
}
n.alpha = 0;
notes.push(n);
game.addChild(n);
nextNoteIdx++;
} else {
break;
}
}
}
function removeOldNotes() {
var now = Date.now();
for (var i = notes.length - 1; i >= 0; i--) {
var n = notes[i];
var timeToRemoveAfterJudged = 700; // ms po targetHitTime dla ocenionych notatek
var timeToRemoveIfNotJudged = noteTravelTime / 2 + hitWindowGood + 500; // Dłuższy czas, jeśli nieoceniona, liczony od targetHitTime
if (n.judged && now > n.targetHitTime + timeToRemoveAfterJudged) {
if (n.parent) {
n.destroy();
}
notes.splice(i, 1);
} else if (!n.judged && now > n.targetHitTime + timeToRemoveIfNotJudged) {
if (n.noteType !== 'trap') {}
if (n.parent) {
n.destroy();
}
notes.splice(i, 1);
}
}
}
function findNoteAt(x, y, typeToFind) {
var now = Date.now();
var bestNote = null;
var smallestTimeDiff = hitWindowGood + 1;
for (var i = 0; i < notes.length; i++) {
var n = notes[i];
if (n.judged || n.noteType !== typeToFind) {
continue;
}
var timeDiff = Math.abs(now - n.targetHitTime);
if (timeDiff > hitWindowGood) {
continue;
}
var currentNoteAsset = n.noteAsset;
if (!currentNoteAsset) {
continue;
}
var currentNoteWidth = currentNoteAsset.width * n.scale.x;
var currentNoteHeight = currentNoteAsset.height * n.scale.y;
if (n.noteType === 'swipe') {
currentNoteWidth = SWIPE_NOTE_WIDTH * n.scale.x;
currentNoteHeight = SWIPE_NOTE_WIDTH * n.scale.y;
}
var dx = x - n.x;
var dy = y - n.y;
if (Math.abs(dx) <= currentNoteWidth / 2 && Math.abs(dy) <= currentNoteHeight / 2) {
if (timeDiff < smallestTimeDiff) {
bestNote = n;
smallestTimeDiff = timeDiff;
}
}
}
return bestNote;
}
function addScore(result) {
if (result === 'perfect') {
score += 100;
} else if (result === 'good') {
score += 50;
}
scoreTxt.setText('Score: ' + score);
}
function addCombo() {
combo += 1;
if (combo > maxCombo) {
maxCombo = combo;
}
comboTxt.setText('Combo: ' + combo);
// Animacja dla comboTxt
if (combo > 1) {
// Mała animacja tylko jeśli combo jest większe niż 1
var originalScale = comboTxt.scale.x; // Zakładamy, że skala X i Y jest taka sama
tween(comboTxt.scale, {
x: originalScale * 1.3,
y: originalScale * 1.3
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(comboTxt.scale, {
x: originalScale,
y: originalScale
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
}
function resetCombo() {
combo = 0;
comboTxt.setText('Combo: 0');
}
function checkGameEnd() {
if (gameOverFlag) {
return;
}
if (playerCurrentHP <= 0) {
gameOverFlag = true;
console.log("GAME OVER - Player HP depleted");
if (currentMusic && typeof currentMusic.stop === 'function') {
currentMusic.stop();
}
var gameOverText = new Text2('GAME OVER', {
x: gameScreenWidth / 2,
y: gameScreenHeight / 2,
anchorX: 0.5,
anchorY: 0.5,
// Ensure vertical centering
size: 100,
fill: 0xff0000
});
gameUIContainer.addChild(gameOverText); // Add to gameUIContainer
return;
}
if (bossCurrentHP <= 0) {
gameOverFlag = true;
console.log("YOU WIN - Boss HP depleted");
if (currentMusic && typeof currentMusic.stop === 'function') {
currentMusic.stop();
}
// LK.showYouWin(); // This is an engine specific function, we'll use a text display for now
var winText = new Text2('YOU WIN!', {
x: gameScreenWidth / 2,
y: gameScreenHeight / 2,
anchorX: 0.5,
anchorY: 0.5,
// Ensure vertical centering
size: 100,
fill: 0x00ff00
});
gameUIContainer.addChild(winText); // Add to gameUIContainer
return;
}
if (currentActiveRhythmMap && nextNoteIdx >= currentActiveRhythmMap.length && notes.length === 0) {
if (!gameOverFlag) {
// Check gameOverFlag again to prevent double messages if HP ran out simultaneously
gameOverFlag = true;
console.log("SONG ENDED - Boss might still be alive");
if (currentMusic && typeof currentMusic.stop === 'function') {
currentMusic.stop();
}
var songEndedText = new Text2('SONG ENDED', {
x: gameScreenWidth / 2,
y: gameScreenHeight / 2,
anchorX: 0.5,
anchorY: 0.5,
// Ensure vertical centering
size: 100,
fill: 0xffff00
});
gameUIContainer.addChild(songEndedText); // Add to gameUIContainer
}
}
}
function trySpawnRandomPowerUp() {
var now = Date.now();
if (now > lastPowerUpSpawnAttemptTime + POWERUP_SPAWN_INTERVAL) {
lastPowerUpSpawnAttemptTime = now;
if (Math.random() < POWERUP_SPAWN_CHANCE) {
var powerUpTypes = ['potion', 'shield', 'swipeToTap'];
var randomType = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
var randomColumnIndex = Math.floor(Math.random() * NUM_COLUMNS);
var spawnX = columnCenterXs[randomColumnIndex];
var newPowerUp = new PowerUpItem(randomType, spawnX);
game.addChild(newPowerUp);
activePowerUpItems.push(newPowerUp);
console.log("Spawnowano PowerUp: " + randomType + " w kolumnie " + (randomColumnIndex + 1));
}
}
}
function managePowerUpItems() {
for (var i = activePowerUpItems.length - 1; i >= 0; i--) {
var pItem = activePowerUpItems[i];
// Sprawdzamy, czy obiekt w ogóle istnieje i czy ma rodzica (czy jest na scenie)
// Jeśli został zebrany (collected=true) LUB nie ma rodzica (został zniszczony), to usuwamy z tablicy
if (!pItem || pItem.collected || !pItem.parent) {
activePowerUpItems.splice(i, 1);
} else {
pItem.update(); // Aktualizuj tylko, jeśli jest na scenie i niezebrany
}
}
}
game.onNoteMiss = function (note) {
if (!note) {
return;
}
note.showHitFeedback('miss');
// NOWA ZMIANA: Sprawdzamy, czy tarcza jest aktywna przed zresetowaniem combo
if (!isShieldActive) {
resetCombo();
} else {
console.log("Gracz ominął nutę, ale tarcza jest aktywna! Combo NIE zresetowane.");
}
// Koniec NOWA ZMIANA
if (isShieldActive) {
console.log("Gracz ominął nutę, ale tarcza jest aktywna! Brak utraty HP.");
} else if (!gameOverFlag) {
playerCurrentHP = Math.max(0, playerCurrentHP - 1);
updatePlayerHpDisplay();
console.log("Player HP after miss: " + playerCurrentHP);
}
if (note.parent) {
LK.effects.flashObject(note, 0xff0000, 300);
}
};
game.down = function (x, y, obj) {
// Logika zbierania PowerUpów (bez zmian)
for (var i = activePowerUpItems.length - 1; i >= 0; i--) {
var pItem = activePowerUpItems[i];
if (pItem && !pItem.collected && pItem.visualAsset && pItem.parent) {
var pWidth = pItem.visualAsset.width * pItem.scale.x;
var pHeight = pItem.visualAsset.height * pItem.scale.y;
if (x >= pItem.x - pWidth / 2 && x <= pItem.x + pWidth / 2 && y >= pItem.y - pHeight / 2 && y <= pItem.y + pHeight / 2) {
if (Math.abs(pItem.y - hitZoneY) < pHeight * 1.5) {
pItem.collect();
return;
}
}
}
}
if (inputLocked) {
return;
}
swipeStart = {
x: x,
y: y,
time: Date.now()
};
var noteUnderCursor = findNoteAt(x, y, 'trap');
if (noteUnderCursor && !noteUnderCursor.judged && noteUnderCursor.isInHitWindow()) {
noteUnderCursor.judged = true;
noteUnderCursor.showHitFeedback('miss');
if (isShieldActive) {
console.log("Gracz trafił w TRAP NOTE, ale tarcza jest aktywna! Brak utraty HP i combo NIE zresetowane.");
} else {
resetCombo(); // Reset combo tylko jeśli tarcza NIE jest aktywna
LK.effects.flashScreen(0xff0000, 400);
if (!gameOverFlag) {
playerCurrentHP = Math.max(0, playerCurrentHP - 1);
updatePlayerHpDisplay();
console.log("Player HP after TRAP: " + playerCurrentHP);
}
}
inputLocked = true;
LK.setTimeout(function () {
inputLocked = false;
}, 200);
return;
}
noteUnderCursor = findNoteAt(x, y, 'tap');
if (noteUnderCursor && !noteUnderCursor.judged && noteUnderCursor.isInHitWindow()) {
var result = noteUnderCursor.getHitAccuracy();
noteUnderCursor.judged = true;
noteUnderCursor.showHitFeedback(result);
if (result !== 'miss') {
addScore(result);
addCombo();
if (!gameOverFlag) {
if (result === 'perfect') {
bossCurrentHP = Math.max(0, bossCurrentHP - 2);
} else if (result === 'good') {
bossCurrentHP = Math.max(0, bossCurrentHP - 1);
}
updateBossHpDisplay();
console.log("Boss HP after TAP (" + result + "): " + bossCurrentHP);
}
} else {
// result JEST 'miss'
// NOWA ZMIANA: Sprawdzamy tarczę przed resetem combo za miss przy tapnięciu
if (!isShieldActive) {
resetCombo(); //
} else {
console.log("Tapnięcie nuty ocenione jako 'miss', ale tarcza jest aktywna! Combo NIE zresetowane.");
}
// Koniec NOWA ZMIANA
}
inputLocked = true;
LK.setTimeout(function () {
inputLocked = false;
}, 120);
return;
}
};
game.up = function (x, y, obj) {
if (inputLocked || !swipeStart) {
swipeStart = null;
return;
}
var swipeEndX = x;
var swipeEndY = y;
var swipeEndTime = Date.now();
var dx = swipeEndX - swipeStart.x;
var dy = swipeEndY - swipeStart.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var potentialSwipe = dist >= MIN_SWIPE_DISTANCE;
var swipedNoteSuccessfully = false;
if (potentialSwipe) {
var detectedDir = null;
if (Math.abs(dx) > Math.abs(dy)) {
detectedDir = dx > 0 ? 'right' : 'left';
} else {
detectedDir = dy > 0 ? 'down' : 'up';
}
var swipeBoundingBox = {
x: Math.min(swipeStart.x, swipeEndX),
y: Math.min(swipeStart.y, swipeEndY),
width: Math.abs(dx),
height: Math.abs(dy)
};
var notesHitThisSwipe = [];
for (var i = 0; i < notes.length; i++) {
var n = notes[i];
if (n.judged || n.noteType !== 'swipe') {
continue;
}
var overallSwipeTimeMatchesNote = false;
if (n.targetHitTime >= swipeStart.time - hitWindowGood && n.targetHitTime <= swipeEndTime + hitWindowGood) {
overallSwipeTimeMatchesNote = true;
}
if (!overallSwipeTimeMatchesNote) {
if (swipeStart.time >= n.targetHitTime - hitWindowGood && swipeStart.time <= n.targetHitTime + hitWindowGood || swipeEndTime >= n.targetHitTime - hitWindowGood && swipeEndTime <= n.targetHitTime + hitWindowGood) {
overallSwipeTimeMatchesNote = true;
}
}
if (!overallSwipeTimeMatchesNote) {
continue;
}
if (n.alpha === 0) {
continue;
}
var noteCurrentWidth = SWIPE_NOTE_WIDTH * n.scale.x;
var noteCurrentHeight = SWIPE_NOTE_WIDTH * n.scale.y;
var noteBoundingBox = {
x: n.x - noteCurrentWidth / 2,
y: n.y - noteCurrentHeight / 2,
width: noteCurrentWidth,
height: noteCurrentHeight
};
if (rectsIntersect(swipeBoundingBox, noteBoundingBox)) {
if (detectedDir === n.swipeDir) {
var verticalProximity = Math.abs(n.y - n.centerY);
var verticalTolerance = noteCurrentHeight / 1.5;
if (verticalProximity < verticalTolerance) {
notesHitThisSwipe.push(n);
}
}
}
}
if (notesHitThisSwipe.length > 0) {
notesHitThisSwipe.sort(function (a, b) {
var da = Math.abs(swipeEndTime - a.targetHitTime);
var db = Math.abs(swipeEndTime - b.targetHitTime);
return da - db;
});
var maxNotesToHitPerSwipe = 1;
if (notesHitThisSwipe.length > 0 && notesHitThisSwipe[0].isWiderSwipePart) {
maxNotesToHitPerSwipe = 2;
}
var notesActuallyHitCount = 0;
for (var k = 0; k < notesHitThisSwipe.length && notesActuallyHitCount < maxNotesToHitPerSwipe; k++) {
var noteToJudge = notesHitThisSwipe[k];
if (noteToJudge.judged) {
continue;
}
if (notesActuallyHitCount === 1 && notesHitThisSwipe[0].isWiderSwipePart) {
if (!noteToJudge.isWiderSwipePart || noteToJudge.mapData.widerSwipePairCenterX !== notesHitThisSwipe[0].mapData.widerSwipePairCenterX || noteToJudge.mapData.partOfWiderSwipe === notesHitThisSwipe[0].mapData.partOfWiderSwipe) {
continue;
}
}
var result = noteToJudge.getHitAccuracy();
noteToJudge.judged = true;
noteToJudge.showHitFeedback(result);
if (result !== 'miss') {
addScore(result);
addCombo();
if (!gameOverFlag) {
if (result === 'perfect') {
bossCurrentHP = Math.max(0, bossCurrentHP - 2);
} else if (result === 'good') {
bossCurrentHP = Math.max(0, bossCurrentHP - 1);
}
updateBossHpDisplay();
}
} else {
resetCombo();
}
swipedNoteSuccessfully = true;
notesActuallyHitCount++;
}
}
}
inputLocked = true;
LK.setTimeout(function () {
inputLocked = false;
}, 80);
swipeStart = null;
};
game.move = function (x, y, obj) {};
game.update = function () {
// KROK 1: Upewnij się, że krytyczne globalne tablice są zainicjalizowane
if (typeof notes === 'undefined' || !Array.isArray(notes)) {
console.log("[DIAGNOSTYKA] Globalna tablica 'notes' była: ", _typeof(notes), ". Ponowna inicjalizacja w game.update.");
notes = [];
}
if (typeof activePowerUpItems === 'undefined' || !Array.isArray(activePowerUpItems)) {
console.log("[DIAGNOSTYKA] Globalna tablica 'activePowerUpItems' była: ", _typeof(activePowerUpItems), ". Ponowna inicjalizacja w game.update.");
activePowerUpItems = [];
}
// KROK 2: Główna logika update w zależności od stanu ekranu
if (currentScreenState === 'gameplay') {
if (!hpBarsInitialized) {
setupHpBars();
setupPowerUpDisplay();
lastPowerUpSpawnAttemptTime = Date.now();
hpBarsInitialized = true;
updatePowerUpDisplayCounts();
}
var now = Date.now();
// Logika tarczy
if (isShieldActive) {
if (now > shieldEndTime) {
isShieldActive = false;
if (shieldIcon) {
shieldIcon.alpha = 1.0;
}
if (shieldTimerDisplayContainer) {
shieldTimerDisplayContainer.visible = false;
}
console.log("Tarcza WYGASŁA.");
} else {
if (shieldTimerDisplayContainer && shieldTimerDisplayContainer.visible) {
var remainingSecondsShield = (shieldEndTime - now) / 1000;
if (shieldTimerTextDisplay) {
shieldTimerTextDisplay.setText(remainingSecondsShield.toFixed(1) + "s");
}
}
}
} else {
if (shieldTimerDisplayContainer && shieldTimerDisplayContainer.visible) {
shieldTimerDisplayContainer.visible = false;
}
}
// Logika Swipe-to-Tap Buff
if (isSwipeToTapBuffActive) {
if (now > swipeToTapBuffEndTime) {
isSwipeToTapBuffActive = false;
if (swipeToTapIcon) {
swipeToTapIcon.alpha = 1.0;
}
if (swipeToTapTimerDisplayContainer) {
swipeToTapTimerDisplayContainer.visible = false;
}
console.log("Buff Swipe-to-Tap WYGASŁ.");
} else {
if (swipeToTapTimerDisplayContainer && swipeToTapTimerDisplayContainer.visible) {
var remainingSecondsBuff = (swipeToTapBuffEndTime - now) / 1000;
if (swipeToTapTimerTextDisplay) {
swipeToTapTimerTextDisplay.setText(remainingSecondsBuff.toFixed(1) + "s");
}
}
}
} else {
if (swipeToTapTimerDisplayContainer && swipeToTapTimerDisplayContainer.visible) {
swipeToTapTimerDisplayContainer.visible = false;
}
}
trySpawnRandomPowerUp();
managePowerUpItems();
spawnNotes();
for (var i = 0; i < notes.length; i++) {
if (notes[i] && notes[i].update) {
notes[i].update();
}
}
removeOldNotes();
checkGameEnd();
} else {
// Jesteśmy w stanie menu ('start', 'intro', 'tutorial', 'mainmenu', 'bossselection', 'credits')
console.log('[DIAGNOSTYKA] Stan menu, czyszczenie. currentScreenState:', currentScreenState);
// Czyszczenie 'notes'
console.log('[DIAGNOSTYKA] Przed czyszczeniem notes. typeof notes:', _typeof(notes), 'Array.isArray:', Array.isArray(notes));
if (notes && typeof notes.length !== 'undefined') {
// Dodatkowe zabezpieczenie przed notes.length
console.log('[DIAGNOSTYKA] notes.length:', notes.length);
}
if (Array.isArray(notes) && notes.length > 0) {
// Użyj Array.isArray dla pewności
console.log('[DIAGNOSTYKA] Czyszczenie notes. Liczba:', notes.length);
for (var i_notes = notes.length - 1; i_notes >= 0; i_notes--) {
var n = notes[i_notes];
if (n && n.parent) {
n.destroy();
}
}
notes = [];
} else {
console.log('[DIAGNOSTYKA] Brak notes do czyszczenia lub notes nie jest tablicą / jest pusta.');
if (!Array.isArray(notes)) {
notes = [];
} // Upewnij się, że jest tablicą na koniec
}
// Czyszczenie 'activePowerUpItems'
console.log('[DIAGNOSTYKA] Przed czyszczeniem activePowerUpItems. typeof:', _typeof(activePowerUpItems), 'Array.isArray:', Array.isArray(activePowerUpItems));
if (activePowerUpItems && typeof activePowerUpItems.length !== 'undefined') {
// Dodatkowe zabezpieczenie
console.log('[DIAGNOSTYKA] activePowerUpItems.length:', activePowerUpItems.length);
}
// TUTAJ JEST LINIA POWODUJĄCA BŁĄD (LUB TUŻ PRZED NIĄ)
if (typeof activePowerUpItems !== "undefined" && Array.isArray(activePowerUpItems) && typeof activePowerUpItems.length !== "undefined" && activePowerUpItems.length > 0) {
// To jest linia zgłaszana jako błąd
console.log('[DIAGNOSTYKA] Czyszczenie activePowerUpItems. Liczba:', activePowerUpItems.length);
for (var i_pwup = activePowerUpItems.length - 1; i_pwup >= 0; i_pwup--) {
var p = activePowerUpItems[i_pwup];
if (p && p.parent) {
p.destroy();
}
}
activePowerUpItems = [];
} else {
console.log('[DIAGNOSTYKA] Brak activePowerUpItems do czyszczenia lub activePowerUpItems nie jest tablicą / jest pusta.');
if (typeof activePowerUpItems === "undefined" || !Array.isArray(activePowerUpItems)) {
activePowerUpItems = [];
} // Upewnij się, że jest tablicą na koniec
}
console.log('[DIAGNOSTYKA] Po czyszczeniu. typeof activePowerUpItems:', _typeof(activePowerUpItems), 'Array.isArray:', Array.isArray(activePowerUpItems), 'Length:', activePowerUpItems ? activePowerUpItems.length : 'N/A');
}
};
// Load the specific song for testing
showStartScreen();
// loadSong("defaultTestTrack"); // Możesz to odkomentować, aby załadować starą mapę testową ===================================================================
--- original.js
+++ change.js
@@ -317,13 +317,17 @@
/****
* Game Code
****/
+// Niebieski dla obszaru specjalnego bossa (jak poprzednio)
+// Żółty dla kart (jak poprzednio 'bossCardPlaceholderAsset')
+// Ciemnoczerwony dla ramki (placeholder)
+// Ciemnoszare tło dla galerii
+// Niebieski dla ramki specjalnego bossa
+// Żółty dla kart
+// Maska, kolor nieważny
/**** * Game Code
****/
-// Maska, kolor nieważny
-// Żółty dla kart
-// Niebieski dla ramki specjalnego bossa
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
@@ -450,12 +454,20 @@
};
}
function showBossSelectionScreen() {
currentScreenState = 'bossselection';
- if (gameUIContainer) gameUIContainer.visible = false;
- if (hitZoneLine) hitZoneLine.visible = false;
- if (shieldTimerDisplayContainer) shieldTimerDisplayContainer.visible = false;
- if (swipeToTapTimerDisplayContainer) swipeToTapTimerDisplayContainer.visible = false;
+ if (gameUIContainer) {
+ gameUIContainer.visible = false;
+ }
+ if (hitZoneLine) {
+ hitZoneLine.visible = false;
+ }
+ if (shieldTimerDisplayContainer) {
+ shieldTimerDisplayContainer.visible = false;
+ }
+ if (swipeToTapTimerDisplayContainer) {
+ swipeToTapTimerDisplayContainer.visible = false;
+ }
game.setBackgroundColor(0x000000);
var screenElements = [];
var viewportX = (gameScreenWidth - 900) / 2;
var viewportY = 150;
@@ -539,9 +551,11 @@
infoPopup.y = gameScreenHeight / 2;
game.addChild(infoPopup);
var popupRef = infoPopup;
LK.setTimeout(function () {
- if (popupRef.parent) popupRef.destroy();
+ if (popupRef.parent) {
+ popupRef.destroy();
+ }
}, 2500);
};
var backButton = new Text2("Back to Menu", {
size: 80,