User prompt
Timer Fix Explanation The Main Issue: In your original code, the timer was defined correctly but there might have been issues with how the timer bar was being updated. I've completely revised the update function to ensure it works properly. Important Fixes: Made sure the timeRemaining is properly decreased using the delta time Simplified the timer bar width calculation to be more reliable Added proper bounds checking to ensure the timer width never goes negative Improved positioning of the timer elements for better visibility Sticky Note Colors: I also improved the sticky note colors to be more authentic. The yellow color is now a lighter shade (0xFFFF99) which looks more like a real sticky note. Implementation Instructions Replace your current Problem and TutorialProblem classes with the ones I've provided. The key difference is in the update function of the Problem class: javascript// Update timer - THIS IS THE CRITICAL PART THAT WASN'T WORKING self.update = function(delta) { if (!self.active) return; // Decrease timer self.timeRemaining = Math.max(0, self.timeRemaining - delta); // Update timer bar width based on time remaining var timerPercent = self.timeRemaining / self.maxTime; self.timerBar.width = Math.max(0, Math.floor(180 * timerPercent)); // Change timer color as time runs out if (timerPercent > 0.6) { self.timerBar.tint = 0x00ff00; // Green } else if (timerPercent > 0.3) { self.timerBar.tint = 0xffff00; // Yellow } else { self.timerBar.tint = 0xff0000; // Red } // Update timer text self.timerText.setText(Math.max(0, self.timeRemaining).toFixed(1)); // Check if timer expired if (self.timeRemaining <= 0) { // Timer expiration code... } }; This ensures that: The timer counts down correctly based on elapsed time The timer bar visually reflects the remaining time The timer text is updated with the correct value The color changes appropriately as time runs low I've also improved the styling of the sticky notes to make them look more authentic, with better colors and a more polished appearance. This should make your game look great and function properly // Fixed Problem class with working timer var Problem = Container.expand(function () { var self = Container.call(this); // Sticky note colors - authentic sticky note colors only var stickyColors = [ 0xFFFF99, // Light yellow 0xFFB6C1, // Light pink 0x90EE90, // Light green 0xADD8E6, // Light blue 0xFFCC99, // Light orange ]; // Choose random sticky note color var colorIndex = Math.floor(Math.random() * stickyColors.length); var stickyColor = stickyColors[colorIndex]; // Problem types with text and stress impact var problemTypes = [ { text: "WiFi Down!", stress: 8 }, { text: "Coffee Spill!", stress: 6 }, { text: "Deadline Changed!", stress: 10 }, { text: "Surprise Meeting!", stress: 12 }, { text: "Traffic Jam!", stress: 7 }, { text: "Phone Died!", stress: 9 }, { text: "Email Overload!", stress: 8 }, { text: "Printer Error!", stress: 7 }, { text: "Noisy Neighbors!", stress: 6 }, { text: "Low Battery!", stress: 5 } ]; // Choose random problem type var typeIndex = Math.floor(Math.random() * problemTypes.length); var type = problemTypes[typeIndex]; // Problem properties self.active = true; self.stressValue = type.stress; self.maxTime = Math.random() * 3 + 1; // Random time between 1-4 seconds self.timeRemaining = self.maxTime; self.points = Math.ceil(10 / self.maxTime); // Shorter times = more points // Create problem background (sticky note) var problemGraphic = self.attachAsset('problem', { anchorX: 0.5, anchorY: 0.5, tint: stickyColor }); // Create problem text var problemText = new Text2(type.text, { size: 36, fill: 0x000000, // Black text for readability align: 'center', wordWrap: true, wordWrapWidth: 180, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" // Handwritten-style font }); problemText.anchor.set(0.5, 0.5); problemText.y = -20; // Move text up to make room for timer self.addChild(problemText); // Create timer bar self.timerBar = self.attachAsset('timer', { anchorX: 0, anchorY: 0.5, x: -90, // Center the timer bar y: 40, // Position below the text width: 180, // Full width for new timer height: 20, tint: 0x00ff00 }); // Add timer text self.timerText = new Text2(self.timeRemaining.toFixed(1), { size: 30, fill: 0x000000, // Black text for consistency align: 'center', font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); self.timerText.anchor.set(0.5, 0.5); self.timerText.x = 0; self.timerText.y = 70; self.addChild(self.timerText); // Add a slight rotation to make it look more like a sticky note self.rotation = (Math.random() - 0.5) * 0.2; // Random slight tilt // Handle tap/click self.down = function (x, y, obj) { if (!self.active) return; self.active = false; LK.getSound('tap').play(); // Visual feedback for successful tap - peeling off animation tween(self, { alpha: 0, scaleX: 0.2, scaleY: 0.2, rotation: self.rotation + Math.PI/4 // Rotate like peeling off }, { duration: 300, easing: tween.easeOut, onFinish: function() { self.destroy(); } }); // Award points based on time remaining var pointsAwarded = Math.ceil(self.points * (self.timeRemaining / self.maxTime)); score += pointsAwarded; scoreText.setText("SCORE: " + score); // Show points popup var pointsPopup = new Text2("+" + pointsAwarded, { size: 50, fill: 0x00ff00, stroke: 0x000000, strokeThickness: 4 }); pointsPopup.anchor.set(0.5, 0.5); pointsPopup.x = self.x; pointsPopup.y = self.y; game.addChild(pointsPopup); // Animate points popup tween(pointsPopup, { y: pointsPopup.y - 100, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function() { pointsPopup.destroy(); } }); }; // Update timer - THIS IS THE CRITICAL PART THAT WASN'T WORKING self.update = function(delta) { if (!self.active) return; // Decrease timer self.timeRemaining = Math.max(0, self.timeRemaining - delta); // Update timer bar width based on time remaining var timerPercent = self.timeRemaining / self.maxTime; self.timerBar.width = Math.max(0, Math.floor(180 * timerPercent)); // Change timer color as time runs out if (timerPercent > 0.6) { self.timerBar.tint = 0x00ff00; // Green } else if (timerPercent > 0.3) { self.timerBar.tint = 0xffff00; // Yellow } else { self.timerBar.tint = 0xff0000; // Red } // Update timer text self.timerText.setText(Math.max(0, self.timeRemaining).toFixed(1)); // Check if timer expired if (self.timeRemaining <= 0) { self.active = false; // Visual feedback for expired timer LK.getSound('stress').play(); // Increase stress stressLevel += self.stressValue; updateStressBar(); // Flash screen red LK.effects.flashScreen(0xff0000, 200, 0.3); // Crumpling animation for sticky note tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1, rotation: Math.random() * Math.PI - Math.PI/2 // Random rotation like crumpling }, { duration: 300, easing: tween.easeOut, onFinish: function() { self.destroy(); } }); // Show stress increase popup var stressPopup = new Text2("+" + self.stressValue + " STRESS!", { size: 40, fill: 0xff0000, stroke: 0x000000, strokeThickness: 4 }); stressPopup.anchor.set(0.5, 0.5); stressPopup.x = self.x; stressPopup.y = self.y; game.addChild(stressPopup); // Animate stress popup tween(stressPopup, { y: stressPopup.y - 100, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function() { stressPopup.destroy(); } }); } }; // Spawn animation - "sticking" effect self.scale.set(1.2); tween(self, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.backOut }); return self; }); // And make sure your TutorialProblem is also updated to match the styling var TutorialProblem = Container.expand(function () { var self = Container.call(this); // Use yellow sticky note color for consistency var stickyColor = 0xFFFF99; // Create problem background (sticky note) var problemGraphic = self.attachAsset('problem', { anchorX: 0.5, anchorY: 0.5, tint: stickyColor }); // Add slight rotation for natural look self.rotation = 0.05; // Create problem text var problemText = new Text2("Deadline Changed!", { size: 36, fill: 0x000000, // Black text for readability align: 'center', wordWrap: true, wordWrapWidth: 180, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" // Handwritten-style font }); problemText.anchor.set(0.5, 0.5); problemText.y = -20; // Move text up to make room for timer self.addChild(problemText); // Create static timer bar var timerBar = self.attachAsset('timer', { anchorX: 0, anchorY: 0.5, x: -90, // Center the timer bar y: 40, // Position below the text width: 120, // Show as partially depleted height: 20, tint: 0xffff00 // Yellow to show it's in progress }); // Add static timer text var timerText = new Text2("2.5", { size: 30, fill: 0x000000, // Black text for consistency align: 'center', font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); timerText.anchor.set(0.5, 0.5); timerText.x = 0; timerText.y = 70; self.addChild(timerText); return self; });
User prompt
Sticky Note Problem Style Code I've redesigned your problems to look like authentic sticky notes with appropriate colors and styling! Here are the key changes I've made: Sticky Note Problems - Design Changes Authentic Sticky Note Colors: Yellow (classic sticky note) Pink (common pastel option) Light green (another standard color) Light blue (common office color) Orange (vibrant option) Text Styling: Dark blue text (0x000080) for better readability Used handwritten-style fonts like Caveat, Comic Sans, or Bradley Hand Bold text to make it more pronounced Visual Enhancements: Added subtle shadow behind each note for depth Random slight rotation to make them look naturally placed Larger text for better readability Animation Improvements: "Sticking" animation when notes appear (scaling from slightly larger) "Peeling off" animation when successfully tapped (rotating as if being pulled) "Crumpling" animation when time expires (rotating and shrinking) Code Implementation The code I provided replaces your current Problem and TutorialProblem classes. The key features are: javascript // Sticky note colors - authentic sticky note colors only var stickyColors = [ 0xFFD700, // Yellow sticky note 0xFFB6C1, // Pink sticky note 0x90EE90, // Light green sticky note 0xADD8E6, // Light blue sticky note 0xFFB347, // Orange sticky note ]; For the text styling: javascript var problemText = new Text2(type.text, { size: 36, fill: 0x000080, // Dark blue text align: 'center', wordWrap: true, wordWrapWidth: 180, fontWeight: 'bold', font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" // Handwritten font }); And for the shadow effect: javascript // Add shadow effect for depth var shadow = new Graphics(); shadow.beginFill(0x000000, 0.2); shadow.drawRect(-100, -100, 200, 200); shadow.endFill(); shadow.x = 10; shadow.y = 10; self.addChildAt(shadow, 0); // Add at the bottom layer Implementation Instructions Replace your current Problem class with the one I provided Replace your TutorialProblem class with the updated version Make sure the shadow effect works - if Graphics isn't working properly, you may need to create a shadow using another shape asset This redesign maintains all the functionality of your current problems but makes them look like authentic sticky notes, which fits perfectly with your office-themed stress game! The colors are now authentic sticky note colors, and the text is more readable with dark blue/black on lighter backgrounds. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (3 edits merged)
Please save this source code
User prompt
Add this for the color of all problems 0xfdfd03
Code edit (5 edits merged)
Please save this source code
User prompt
move the close button on the right
User prompt
Make all problems have a yellow background/fill. font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" and the text black.
User prompt
Make all problems have a yellow background/fill. font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" and the text black.
Code edit (1 edits merged)
Please save this source code
User prompt
Fix Example Problem in Tutorial Code The Exact Fix for the Problem in Your Screenshot I can see exactly what's happening in your screenshot. The problem is that during the tutorial, a real functioning problem with a timer is appearing, when it should just be a static example. The Solution The fix I provided does two important things: Creates a Special Tutorial Problem Class: Creates a TutorialProblem class that looks like a real problem but: Has no active timer (it won't count down) Has no update logic Is not added to the problems array Is purely visual for demonstration purposes Ensures the Example Problem is Contained: Adds the example problem to the tutorial container, not the game world Makes sure it's destroyed when the tutorial is closed How to Implement This Fix Replace your existing showTutorial() function with the one in my code. The key changes are: Use TutorialProblem instead of Problem: javascript // Change this: var exampleProblem = new Problem(); // To this: var exampleProblem = new TutorialProblem(); Add the example problem to the tutorial container, NOT the game: javascript // Change this: game.addChild(exampleProblem); // To this: tutorialContainer.addChild(exampleProblem); This ensures the example problem: Is just a visual element with no real functionality Is contained within the tutorial and disappears when the tutorial closes Doesn't affect gameplay at all After making these changes, the tutorial will only show the instructions without any functional problems appearing. The example problem will be a static visual element that doesn't count down or change. Additional Recommendations Also update your game.update() function to be more strict about checking for tutorial state: javascript if (tutorialActive) { // Ensure no problems exist during tutorial for (var i = problems.length - 1; i >= 0; i--) { if (problems[i] && problems[i].parent) { problems[i].destroy(); } } problems = []; return; } Reset the problem spawn timer when tutorial ends: javascript continueButton.down = function() { tutorialContainer.destroy(); tutorialActive = false; gameRunning = true; // Reset the last problem time to NOW lastProblemTime = Date.now(); // Show player and game elements... };
User prompt
The issue still persists. There is still a bug that allows for one instance to be shown when on tutorial screen. Find out where it is.
User prompt
Critical Fixes for the Tutorial Problem After reviewing your code more carefully, I can see the exact issue. Let me explain the comprehensive fix I've provided: Key Problems in the Current Code Example Problem Handling: The example problem in the tutorial was being added to the game directly with game.addChild(exampleProblem), making it behave like a regular problem. Container Management: The tutorial example problem should be added to the tutorial container, not the game world. Timing Issue: When transitioning between states, there's a brief moment where problems could still spawn. Cleanup Timing: The cleanup wasn't happening at the right moments in the game cycle. The Guaranteed Fix I've made these crucial changes in the code I provided: Fixed Duplicate Variable Declaration: Removed the duplicate declaration of tutorialActive Fixed Example Problem in Tutorial: Changed game.addChild(exampleProblem) to tutorialContainer.addChild(exampleProblem) This keeps the example problem inside the tutorial container, not in the game world Improved State Management: Added thorough checks for tutorialActive in every relevant function Ensured tutorialActive is set to false AFTER the tutorial container is destroyed Reset Timer on Tutorial Close: Added lastProblemTime = Date.now() when the tutorial closes This prevents a problem from immediately spawning when the game starts Aggressive Problem Cleanup: Added additional cleanup in the game update loop when tutorial is active Added cleanup when closing the tutorial before starting the game How to Implement This Fix Fix the showTutorial() function as shown in my code, especially: javascript// Change this line game.addChild(exampleProblem); // To this tutorialContainer.addChild(exampleProblem); Update the continue button handler to reset the timer: javascriptcontinueButton.down = function() { tutorialContainer.destroy(); tutorialActive = false; gameRunning = true; // Clean up any remaining problems for (var i = problems.length - 1; i >= 0; i--) { if (problems[i] && problems[i].parent) { problems[i].destroy(); } } problems = []; // Reset the timer lastProblemTime = Date.now(); // Show game elements... }; Make the game update function more strict about tutorial state as shown in my code The Root Cause The core issue was that the example problem was being added to the main game screen, not just to the tutorial container. This meant it was being processed like a regular problem. By adding it to the tutorial container instead, it will automatically be removed when the tutorial is closed. This fix ensures that: No problems spawn during the tutorial The example problem is properly contained within the tutorial All problems are cleaned up before the game starts The timer is reset to prevent immediate problem spawning These changes will guarantee that no problems appear during the tutorial phase.
User prompt
You need to do something like the following code. Refactor use the two last prompts also. // Add a new flag to explicitly track tutorial state var tutorialActive = false; // Modify the startGame function to set this flag function startGame() { // Set gameStarted to true but not running yet (tutorial will show first) gameStarted = true; gameRunning = false; tutorialActive = true; // Set the tutorial flag // Hide start screen elements tween(titleText, { y: -200, alpha: 0 }, { duration: 500, easing: tween.easeIn }); tween(subtitleText, { y: -200, alpha: 0 }, { duration: 500, easing: tween.easeIn }); tween(startButton, { y: 2732 + 200, alpha: 0 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { // Show tutorial first - the game will start when tutorial is closed showTutorial(); // Show instructions button for later use tween(instructionsButton, { alpha: 1 }, { duration: 500 }); // Start music LK.playMusic('bgmusic'); } }); } // Modify the showTutorial function to properly handle the tutorial flag function showTutorial() { var tutorialContainer = new Container(); // Ensure tutorial is active and game is paused tutorialActive = true; gameRunning = false; // Hide player and other game elements until tutorial is closed player.alpha = 0; stressBar.alpha = 0; levelText.alpha = 0; // Clear any existing problems (just to be sure) for (var i = problems.length - 1; i >= 0; i--) { if (problems[i].parent) { problems[i].destroy(); } } problems = []; // Rest of your tutorial code... // Modify the continue button handler continueButton.down = function () { tutorialContainer.destroy(); // Turn off tutorial mode and start the game tutorialActive = false; gameRunning = true; // Show player and game elements with animation tween(player, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); // Show stress bar tween(stressBar, { alpha: 1 }, { duration: 500 }); // Show level text tween(levelText, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); }; // Also make the entire tutorial container interactive as a fallback tutorialContainer.interactive = true; tutorialContainer.down = continueButton.down; } // Simplify the spawnProblem function to use the tutorial flag function spawnProblem() { // Don't spawn if tutorial is active, game not running, or not started if (tutorialActive || !gameRunning || !gameStarted) { return; } // Don't spawn if we already have max problems if (problems.length >= maxProblemsOnScreen) { return; } // Create new problem var problem = new Problem(); // Position randomly, but keep away from edges problem.x = Math.random() * (2048 - 400) + 200; problem.y = Math.random() * (2732 - 800) + 400; // Make sure it doesn't overlap with player var distToPlayer = Math.sqrt( Math.pow(problem.x - player.x, 2) + Math.pow(problem.y - player.y, 2) ); if (distToPlayer < 500) { // Too close to player, adjust position var angle = Math.random() * Math.PI * 2; problem.x = player.x + Math.cos(angle) * 600; problem.y = player.y + Math.sin(angle) * 600; // Keep within screen bounds problem.x = Math.max(200, Math.min(problem.x, 2048 - 200)); problem.y = Math.max(400, Math.min(problem.y, 2732 - 400)); } game.addChild(problem); problems.push(problem); } // Also modify the showInstructions function to handle problems function showInstructions() { // Pause game while instructions are open var wasPaused = !gameRunning; gameRunning = false; // Rest of your instructions code... // Modify close button to restore the previous gameRunning state closeButton.down = function () { popup.destroy(); if (!wasPaused) { gameRunning = true; } }; } // Modify the game update function to respect the tutorial flag game.update = function () { // Calculate delta time for consistent updates var now = Date.now(); var delta = (now - lastUpdate) / 1000; // Convert to seconds lastUpdate = now; // Update code background for visual effect codeBackground.update(); // Don't process gameplay if tutorial is active if (tutorialActive || !gameRunning || !gameStarted) { return; } // Check if it's time to spawn a new problem if (now - lastProblemTime > problemSpawnInterval) { spawnProblem(); lastProblemTime = now; } // Update all problems for (var i = 0; i < problems.length; i++) { if (problems[i] && problems[i].update) { problems[i].update(delta); } } // Rest of your update code... } ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Implementation Steps To implement this fix in your game: Add the tutorialActive flag at the top with your other game state variables: javascriptvar tutorialActive = false; Modify your startGame() function to set this flag to true. Replace the complex tutorial detection code in spawnProblem() with: javascript// Don't spawn if tutorial is active, game not running, or not started if (tutorialActive || !gameRunning || !gameStarted) { return; } Update the showTutorial() function to set the flag: javascripttutorialActive = true; In the tutorial's close/continue button handler, add: javascripttutorialActive = false; Update your game's update function to also respect this flag Game Development Lesson This fix demonstrates an important game development principle: explicit state management. Rather than trying to infer the state of the game from UI elements or complex conditions, it's much more reliable to: Define clear game states Use explicit flags for important states Handle transitions between states carefully Make all game systems aware of and respect these states By implementing this fix, your game will now properly separate the tutorial phase from the active gameplay phase, creating a better experience for players who won't be surprised by unexpected problems appearing during the tutorial.
User prompt
Check the whole code again. Make sure there is not functionality outside that allows for problem instance spawn when the tutorial is on. When I press play the tutorial opens but one problem instance always at almos the butom right of the screen appears. That should not happen
User prompt
It works as intended but there is still one problem instance popping up when the tutorial screen is on.
User prompt
Before the game starts it will check if the tutorial screen is there or not. If it is there the game will not start.
User prompt
When I click play two problems pop up they should not. The game has not started. It starts after the tutorial is closed.
User prompt
When the play button is pressed The game does NOT start. The Hot to paly screen is shown nothing else is on the screen. After the hot to play is closed then the game starts. Showing all assets on the screen
User prompt
Move the play button 45px up
User prompt
200px up
User prompt
move play 350 px down
User prompt
move the a game about pretending everythnig is ok 35 px down.
User prompt
Bug. When I cling the play button the How to play screen appear but there instances of the problems also showing, they shouldnt show now only after the hot to play screen has disapeared.
User prompt
When I press the play button there is a delay. The game does not start immediately. The How to play screen shows. Once the how to play has been tapped ( no longer showing ) then the game starts and the assets ender the screen.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var CodeBackground = Container.expand(function () { var self = Container.call(this); var lines = []; var lineSpacing = 40; // Initialize with random code lines self.initialize = function () { for (var i = 0; i < 100; i++) { var line = new CodeLine(Math.random() * 1000 + 100, i * lineSpacing); line.x = Math.random() * (2048 - line.width); self.addChild(line); lines.push(line); } }; // Move lines upward self.update = function () { for (var i = 0; i < lines.length; i++) { lines[i].y -= 1; // If line moved off screen, reset to bottom if (lines[i].y < -20) { lines[i].y = 2732 + Math.random() * 100; lines[i].x = Math.random() * (2048 - lines[i].width); } } }; return self; }); // Code for creating scrolling code in the background var CodeLine = Container.expand(function (length, yPos) { var self = Container.call(this); // Random line properties var colors = [0x00ff00, 0x3498db, 0xff9900, 0x9b59b6, 0xf1c40f]; var randomColor = colors[Math.floor(Math.random() * colors.length)]; // Create line var line = self.attachAsset('timer', { anchorX: 0, anchorY: 0.5, width: length || Math.random() * 500 + 100, height: 10, tint: randomColor }); self.y = yPos || 0; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Create player visual var playerGraphic = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, width: 500, height: 632 }); // Create status text self.statusText = new Text2("I'm fine!", { size: 100, fill: 0x89ffd4, align: 'center', stroke: 0x000000, strokeThickness: 5, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); self.statusText.anchor.set(0.5, 0); self.statusText.y = 350; // Position the text below the player self.addChild(self.statusText); // Update appearance based on stress level self.updateAppearance = function (stress) { // Visual changes based on stress if (stress < 30) { // Calm - normal color playerGraphic.tint = 0xFFFFFF; self.statusText.setText("I'm fine!"); self.statusText.style = { fontSize: 500, fill: 0xf07f92, align: 'center', stroke: 0xFFFFFF, strokeThickness: 5, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }; // Reset animations tween.stop(self); tween(self, { rotation: 0, scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); } else if (stress < 60) { // Getting stressed - slight tint playerGraphic.tint = 0x9b59b6; // Purple tint self.statusText.setText("I'm FINE!"); self.statusText.style = { fontSize: 110, fill: 0x660000, align: 'center', stroke: 0xFFFFFF, strokeThickness: 5, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }; // Add slight animation tween.stop(self); tween(self, { scaleX: 1.02, scaleY: 0.98 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { scaleX: 0.98, scaleY: 1.02 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (stressLevel >= 30 && stressLevel < 60) { self.updateAppearance(stressLevel); } } }); } }); } else if (stress < 90) { // Very stressed - red tint playerGraphic.tint = 0xe74c3c; // Red self.statusText.setText("I'M FINE!!"); self.statusText.style = { fontSize: 120, fill: 0xFF0000, align: 'center', stroke: 0x000000, strokeThickness: 5, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }; // Add wobble tween.stop(self); tween(self, { rotation: 0.05, scaleX: 1.05, scaleY: 0.95 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: -0.05, scaleX: 0.95, scaleY: 1.05 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { if (stressLevel >= 60 && stressLevel < 90) { self.updateAppearance(stressLevel); } } }); } }); } else { // Maximum stress - bright red playerGraphic.tint = 0xff0000; self.statusText.setText("I'M TOTALLY FINE!!!"); self.statusText.style = { fontSize: 130, fill: 0xFF0000, align: 'center', stroke: 0x000000, strokeThickness: 6, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }; // Dramatic animation tween.stop(self); tween(self, { rotation: 0.1, scaleX: 1.1, scaleY: 0.9 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { rotation: -0.1, scaleX: 0.9, scaleY: 1.1 }, { duration: 200, easing: tween.easeInOut, onFinish: function onFinish() { if (stressLevel >= 90) { self.updateAppearance(stressLevel); } } }); } }); } }; return self; }); var Problem = Container.expand(function () { var self = Container.call(this); // Problem types with text, color, and stress impact var problemTypes = [{ text: "WiFi Down!", color: 0xfdfd03, stress: 8, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Coffee Spill!", color: 0xfdfd03, stress: 6, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Deadline Changed!", color: 0xff9900, stress: 10, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Surprise Meeting!", color: 0x9933cc, stress: 12, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Traffic Jam!", color: 0x666666, stress: 7, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Phone Died!", color: 0x000000, stress: 9, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Email Overload!", color: 0x3366ff, stress: 8, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Printer Error!", color: 0xcc0000, stress: 7, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Noisy Neighbors!", color: 0x99cc00, stress: 6, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }, { text: "Low Battery!", color: 0xff6600, stress: 5, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }]; // Choose random problem type var typeIndex = Math.floor(Math.random() * problemTypes.length); var type = problemTypes[typeIndex]; // Problem properties self.active = true; self.stressValue = type.stress; self.maxTime = Math.random() * 3 + 1; // Random time between 1-4 seconds self.timeRemaining = self.maxTime; self.points = Math.ceil(10 / self.maxTime); // Shorter times = more points // Create problem background var problemGraphic = self.attachAsset('problem', { anchorX: 0.5, anchorY: 0.5, tint: 0xfdfd03 // Classic sticky note yellow color (0xfdfd03) }); // Create problem text var problemText = new Text2(type.text, { size: 36, fill: 0x000000, //{2L} // Black text for better readability align: 'center', wordWrap: true, wordWrapWidth: 180, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" // Handwritten-style font }); problemText.anchor.set(0.5, 0.5); self.addChild(problemText); // Create timer bar self.timerBar = self.attachAsset('timer', { anchorX: 0, anchorY: 0.5, x: -90, y: 40, width: 180, height: 20, tint: 0x00ff00 }); // Add timer text self.timerText = new Text2(self.timeRemaining.toFixed(1), { size: 30, fill: 0x000000, align: 'center', stroke: 0x000000, strokeThickness: 0, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); self.timerText.anchor.set(0.5, 0.5); self.timerText.x = 0; self.timerText.y = 70; self.addChild(self.timerText); // Handle tap/click self.down = function (x, y, obj) { if (!self.active) { return; } self.active = false; LK.getSound('tap').play(); // Visual feedback for successful tap - sticky note peeling off tween(self, { alpha: 0, scaleX: 0.2, scaleY: 0.2, rotation: Math.PI * 0.25, // Rotation like peeling off a sticky note y: self.y - 50 // Move up slightly as if being peeled off }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); // Award points based on time remaining var pointsAwarded = Math.ceil(self.points * (self.timeRemaining / self.maxTime)); score += pointsAwarded; scoreText.setText("SCORE: " + score); // Show points popup var pointsPopup = new Text2("+" + pointsAwarded, { size: 50, fill: 0x00ff00, stroke: 0x000000, strokeThickness: 4 }); pointsPopup.anchor.set(0.5, 0.5); pointsPopup.x = self.x; pointsPopup.y = self.y; game.addChild(pointsPopup); // Animate points popup tween(pointsPopup, { y: pointsPopup.y - 100, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { pointsPopup.destroy(); } }); }; // Update timer self.update = function (delta) { if (!self.active) { return; } // Decrease timer - ensure we don't go below 0 self.timeRemaining = Math.max(0, self.timeRemaining - delta); // Update timer bar width with better bounds checking var timerPercent = self.timeRemaining / self.maxTime; self.timerBar.width = Math.max(0, Math.floor(200 * timerPercent)); // Change timer color as time runs out if (timerPercent > 0.6) { self.timerBar.tint = 0x00ff00; // Green } else if (timerPercent > 0.3) { self.timerBar.tint = 0xffff00; // Yellow } else { self.timerBar.tint = 0xff0000; // Red } // Update timer text self.timerText.setText(Math.max(0, self.timeRemaining).toFixed(1)); // Check if timer expired if (self.timeRemaining <= 0) { self.active = false; // Visual feedback for expired timer LK.getSound('stress').play(); // Increase stress stressLevel += self.stressValue; updateStressBar(); // Flash screen red LK.effects.flashScreen(0xff0000, 200, 0.3); // Crumpling animation for sticky note tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1, rotation: Math.random() * Math.PI - Math.PI / 2 // Random rotation like crumpling }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); // Show stress increase popup var stressPopup = new Text2("+" + self.stressValue + " STRESS!", { size: 40, fill: 0xff0000, stroke: 0x000000, strokeThickness: 4, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); stressPopup.anchor.set(0.5, 0.5); stressPopup.x = self.x; stressPopup.y = self.y; game.addChild(stressPopup); // Animate stress popup tween(stressPopup, { y: stressPopup.y - 100, alpha: 0 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { stressPopup.destroy(); } }); } }; // Spawn animation - make it look like a sticky note being placed self.scale.set(1.2); // Start slightly larger self.rotation = Math.random() * 0.2 - 0.1; // Random slight rotation for natural look tween(self, { scaleX: 1, scaleY: 1, rotation: Math.random() * 0.1 - 0.05 // Settle to a slight random angle }, { duration: 300, easing: tween.elasticOut }); return self; }); var StressBar = Container.expand(function () { var self = Container.call(this); self.interactive = true; var dragOffsetX = 0; var dragOffsetY = 0; // Create stress bar elements var background = self.attachAsset('progressBar', { anchorX: 0.5, anchorY: 0.5, width: 1000, height: 80 }); var fill = self.attachAsset('progressFill', { anchorX: 0, anchorY: 0.5, x: -background.width / 2, y: 0, width: 0 // Start with 0 width }); // Add stress label var label = new Text2("STRESS LEVEL", { size: 40, fill: 0xFFFFFF, fontWeight: 'bold', stroke: 0x000000, strokeThickness: 4, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); label.anchor.set(0.5, 0.5); label.x = 0; label.y = 0; self.addChild(label); // Add drag functionality self.down = function (x, y, obj) { // No-op: stress bar should not be draggable return false; }; self.up = function (x, y, obj) { // Clear drag state dragOffsetX = 0; dragOffsetY = 0; }; self.move = function (x, y, obj) { // No-op: stress bar should not be draggable return false; }; // Update fill based on stress level self.updateFill = function (stressLevel) { var maxWidth = background.width; var newWidth = stressLevel / 100 * maxWidth; // Tween the fill bar tween(fill, { width: newWidth }, { duration: 300, easing: tween.easeOut }); // Change fill color based on stress level if (stressLevel < 30) { fill.tint = 0x00ff00; // Green } else if (stressLevel < 60) { fill.tint = 0xffff00; // Yellow } else if (stressLevel < 90) { fill.tint = 0xff9900; // Orange } else { fill.tint = 0xff0000; // Red } }; return self; }); // Create a special problem just for the tutorial that has no timer or functionality var TutorialProblem = Container.expand(function () { var self = Container.call(this); // Create problem background (visual only) var problemGraphic = self.attachAsset('problem', { anchorX: 0.5, anchorY: 0.5, tint: 0xfdfd03 //{4F} // Classic sticky note yellow color (0xfdfd03) }); // Create problem text (visual only) var problemText = new Text2("Example Problem!", { size: 36, fill: 0x000000, //{4I} // Black text for better readability align: 'center', wordWrap: true, wordWrapWidth: 180, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" // Handwritten-style font }); problemText.anchor.set(0.5, 0.5); self.addChild(problemText); // Create static timer bar (visual only) var timerBar = self.attachAsset('timer', { anchorX: 0, anchorY: 0.5, x: -90, y: 40, width: 150, height: 20, tint: 0xffff00 }); // Add static timer text var timerText = new Text2("2.5", { size: 30, fill: 0x000000, align: 'center', font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); timerText.anchor.set(0.5, 0.5); timerText.x = 0; timerText.y = 70; self.addChild(timerText); return self; }); /**** * Initialize Game ****/ // Create a tutorial-only example problem and add it to tutorial container var game = new LK.Game({ backgroundColor: 0x192a56 // Dark blue background }); /**** * Game Code ****/ // Game state variables var score = 0; var stressLevel = 0; var gameLevel = 1; var problems = []; var lastProblemTime = 0; var problemSpawnInterval = 1800; // ms between problem spawns var maxProblemsOnScreen = 4; // Maximum problems on screen at once var gameRunning = true; var gameStarted = false; var tutorialActive = false; // Flag to track when tutorial is active var lastUpdate = Date.now(); // Set up code background var codeBackground = new CodeBackground(); codeBackground.initialize(); codeBackground.alpha = 0.2; game.addChild(codeBackground); // Set up regular background var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.8 // Semi-transparent to show code background }); game.addChild(background); // Set up player var player = new Player(); player.x = 350; // Move to left side player.y = 2732 - 500; player.alpha = 0; // Initially hidden until game starts game.addChild(player); // Set up score text var scoreText = new Text2("SCORE: 0", { size: 70, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 5 }); scoreText.anchor.set(0.5, 0); scoreText.x = 2048 / 2; scoreText.y = 20; LK.gui.top.addChild(scoreText); // Set up level text var levelText = new Text2("DAY: 1", { size: 50, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); levelText.anchor.set(0.5, 0); levelText.x = 2048 / 2 - 400 + 200 - 75 - 50 - 20 + 10; levelText.y = 30; levelText.alpha = 0; // Hide initially until game starts LK.gui.addChild(levelText); // Game title var titleText = new Text2("I'M FINE!", { size: 200, fill: 0xff4d4d, fontWeight: 'bold', stroke: 0xFFFFFF, strokeThickness: 10, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2 - 300; // Move 300 pixels to the left titleText.y = 500; LK.gui.addChild(titleText); // Game subtitle var subtitleText = new Text2("(a game about pretending everything is OK)", { size: 60, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 3, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 2048 / 2 - 300; // Move 300 pixels to the left subtitleText.y = 635; // Moved 35 pixels down from 600 LK.gui.addChild(subtitleText); // Create start button var startButton = new Container(); startButton.interactive = true; var startBg = LK.getAsset('problem', { anchorX: 0.5, anchorY: 0.5, width: 500, height: 120, tint: 0x444444, alpha: 0, radius: 30 // Rounded corners }); startButton.addChild(startBg); // No triangle needed var startText = new Text2("PLAY", { size: 85, fill: 0xff4d4d, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive", fontWeight: 'bold', stroke: 0xFFFFFF, strokeThickness: 5, underline: true }); startText.anchor.set(0.5, 0.5); startText.x = 0; // Center text after triangle removal startText.y = 0; startButton.addChild(startText); startButton.x = 2048 / 2 - 300; // Move 300 pixels to the left startButton.y = 2732 / 2 - 450 + 145 + 70 + 350 - 45; // Move 305 pixels down from previous position (45px up from previous position) LK.gui.addChild(startButton); // Create and position stress bar var stressBar = new StressBar(); stressBar.x = player.x + player.statusText.width / 2 + 733; // Position next to the status text with 703px more to the right stressBar.y = player.y + 420; // Move down 70px from original position stressBar.alpha = gameStarted ? 1 : 0; // Show if game started, otherwise hide game.addChild(stressBar); // Add to game instead of gui to ensure visibility // Instructions button var instructionsButton = new Container(); instructionsButton.interactive = true; var instructionsBg = LK.getAsset('problem', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 80, tint: 0x333333, alpha: 0.9 }); instructionsButton.addChild(instructionsBg); var questionText = new Text2("?", { size: 60, fill: 0xFFFFFF, fontWeight: 'bold' }); questionText.anchor.set(0.5, 0.5); questionText.x = 0; questionText.y = 0; instructionsButton.addChild(questionText); instructionsButton.x = 100; instructionsButton.y = 100; instructionsButton.alpha = 0; // Hidden until game starts LK.gui.addChild(instructionsButton); // Update stress bar function updateStressBar() { // Clamp stress level between 0-100 stressLevel = Math.min(100, Math.max(0, stressLevel)); // Update stress bar fill stressBar.updateFill(stressLevel); // Update player appearance player.updateAppearance(stressLevel); // Check for game over if (stressLevel >= 100 && gameRunning) { gameOver(); } } // Spawn a new problem function spawnProblem() { // Don't spawn if tutorial is active, game not running, or not started if (tutorialActive || !gameRunning || !gameStarted) { // Clear any existing problems if tutorial is visible for (var i = problems.length - 1; i >= 0; i--) { if (problems[i].parent) { problems[i].destroy(); } } problems = []; return; } // Don't spawn if we already have max problems if (problems.length >= maxProblemsOnScreen) { return; } // Create new problem var problem = new Problem(); // Position randomly, but keep away from edges problem.x = Math.random() * (2048 - 400) + 200; problem.y = Math.random() * (2732 - 800) + 400; // Make sure it doesn't overlap with player var distToPlayer = Math.sqrt(Math.pow(problem.x - player.x, 2) + Math.pow(problem.y - player.y, 2)); if (distToPlayer < 500) { // Too close to player, adjust position var angle = Math.random() * Math.PI * 2; problem.x = player.x + Math.cos(angle) * 600; problem.y = player.y + Math.sin(angle) * 600; // Keep within screen bounds problem.x = Math.max(200, Math.min(problem.x, 2048 - 200)); problem.y = Math.max(400, Math.min(problem.y, 2732 - 400)); } game.addChild(problem); problems.push(problem); } // Start game function function startGame() { // Set gameStarted to true but not running yet (tutorial will show first) gameStarted = true; gameRunning = false; tutorialActive = true; // Set tutorial flag // Hide start screen elements tween(titleText, { y: -200, alpha: 0 }, { duration: 500, easing: tween.easeIn }); tween(subtitleText, { y: -200, alpha: 0 }, { duration: 500, easing: tween.easeIn }); tween(startButton, { y: 2732 + 200, alpha: 0 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { // Clean up any problems that might exist for (var i = problems.length - 1; i >= 0; i--) { if (problems[i] && problems[i].parent) { problems[i].destroy(); } } problems = []; // Reset the timer lastProblemTime = Date.now(); // Show tutorial first - the game will start when tutorial is closed showTutorial(); // Show instructions button for later use tween(instructionsButton, { alpha: 1 }, { duration: 500 }); // Start music LK.playMusic('bgmusic'); } }); } // Show tutorial function showTutorial() { var tutorialContainer = new Container(); // Set tutorial active flag to prevent problems from spawning tutorialActive = true; // Temporarily pause the game until tutorial is closed var wasPaused = !gameRunning; gameRunning = false; // Hide player and other game elements until tutorial is closed player.alpha = 0; stressBar.alpha = 0; levelText.alpha = 0; // Darken background var tutorialBg = LK.getAsset('problem', { width: 2048, height: 2732, tint: 0x000000, alpha: 0.7 }); tutorialContainer.addChild(tutorialBg); // Title var tutorialTitle = new Text2("HOW TO PLAY", { size: 100, fill: 0xFFFFFF, fontWeight: 'bold', font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); tutorialTitle.anchor.set(0.5, 0.5); tutorialTitle.x = 1500 / 2; tutorialTitle.y = 200; tutorialContainer.addChild(tutorialTitle); // Instructions var instructions = new Text2("• PROBLEMS will appear randomly on screen\n\n" + "• Each problem has a COUNTDOWN TIMER\n\n" + "• TAP problems before their timer runs out\n\n" + "• If time runs out, your STRESS increases\n\n" + "• Don't let your stress reach 100%\n\n" + "• Just keep telling yourself \"I'M FINE!\"", { size: 60, fill: 0xFFFFFF, align: 'left', lineHeight: 80, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); instructions.anchor.set(0.5, 0.5); instructions.x = 1500 / 2; instructions.y = 1000; tutorialContainer.addChild(instructions); // Create a tutorial-only example problem and add it to tutorial container var exampleProblem = new TutorialProblem(); exampleProblem.x = 1024; exampleProblem.y = 1600; tutorialContainer.addChild(exampleProblem); // Continue button var continueButton = new Container(); continueButton.interactive = true; var continueBg = LK.getAsset('problem', { anchorX: 0.5, anchorY: 0.5, width: 400, height: 120, tint: 0x00cc00 }); continueButton.addChild(continueBg); var continueText = new Text2("START!", { size: 70, fill: 0xFFFFFF, fontWeight: 'bold' }); continueText.anchor.set(0.5, 0.5); continueText.x = 0; continueText.y = 0; continueButton.addChild(continueText); continueButton.x = 2048 / 2; continueButton.y = 2000; tutorialContainer.addChild(continueButton); // Add to GUI LK.gui.addChild(tutorialContainer); // Make the continue button interactive to close tutorial continueButton.interactive = true; continueButton.down = function () { tutorialContainer.destroy(); // Clean up any remaining problems for (var i = problems.length - 1; i >= 0; i--) { if (problems[i] && problems[i].parent) { problems[i].destroy(); } } problems = []; // Reset the timer to prevent immediate problem spawning lastProblemTime = Date.now(); // Clear tutorial flag and start the game after tutorial is closed tutorialActive = false; gameRunning = true; // Show player and game elements with animation tween(player, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); // Show stress bar tween(stressBar, { alpha: 1 }, { duration: 500 }); // Show level text tween(levelText, { alpha: 1 }, { duration: 800, easing: tween.elasticOut }); }; // Also make the entire tutorial container interactive as a fallback tutorialContainer.interactive = true; tutorialContainer.down = continueButton.down; } // Instructions popup function showInstructions() { var popup = new Container(); // Darken background var bg = LK.getAsset('problem', { anchorX: 0.5, anchorY: 0.5, width: 2048, height: 2732, tint: 0x000000, alpha: 0.7 }); popup.addChild(bg); // Panel background var panel = LK.getAsset('problem', { anchorX: 0.5, anchorY: 0.5, width: 1600, height: 1800, tint: 0xFFFFFF, alpha: 0.9 }); panel.x = 2048 / 2; panel.y = 2732 / 2; popup.addChild(panel); // Title var title = new Text2("HOW TO PLAY", { size: 100, fill: 0xff4d4d, fontWeight: 'bold', stroke: 0x000000, strokeThickness: 5 }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = panel.y - 800; popup.addChild(title); // Instructions var instructions = new Text2("1. PROBLEMS will appear randomly on screen\n\n" + "2. Each problem has a COUNTDOWN TIMER\n\n" + "3. TAP problems before their timer runs out\n\n" + "4. If time runs out, your STRESS increases\n\n" + "5. Don't let your stress reach 100%\n\n" + "6. LEVEL UP every 10 points\n\n" + "7. Just keep telling yourself \"I'M FINE!\"", { size: 50, fill: 0x000000, align: 'left', lineHeight: 70, wordWrap: true, wordWrapWidth: panel.width - 200 }); instructions.anchor.set(0, 0); instructions.x = panel.x - 700; instructions.y = panel.y - 600; popup.addChild(instructions); // Close button var closeButton = new Container(); closeButton.interactive = true; var closeBg = LK.getAsset('problem', { width: 400, height: 120, tint: 0xff4d4d }); closeButton.addChild(closeBg); var closeText = new Text2("RESUME", { size: 60, fill: 0xFFFFFF, fontWeight: 'bold', font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); closeText.anchor.set(0.5, 0.5); closeText.x = 0; closeText.y = 0; closeButton.addChild(closeText); closeButton.x = panel.x; closeButton.y = panel.y + 700; popup.addChild(closeButton); // Pause game while instructions are open var wasPaused = !gameRunning; gameRunning = false; tutorialActive = true; // Set tutorial active to prevent problems closeButton.down = function () { popup.destroy(); // Clean up any problems that might have been created for (var i = problems.length - 1; i >= 0; i--) { if (problems[i] && problems[i].parent) { problems[i].destroy(); } } problems = []; tutorialActive = false; // Clear tutorial active flag if (!wasPaused) { gameRunning = true; } }; LK.gui.addChild(popup); } // Check if level should increase function checkLevelProgress() { var newLevel = Math.floor(score / 10) + 1; if (newLevel > gameLevel) { gameLevel = newLevel; levelText.setText("DAY: " + gameLevel); // Make game harder as level increases problemSpawnInterval = Math.max(500, 1800 - gameLevel * 100); maxProblemsOnScreen = Math.min(8, 4 + Math.floor(gameLevel / 2)); // Visual and audio feedback LK.effects.flashScreen(0x00ff00, 500, 0.3); LK.getSound('levelup').play(); // Show level up text var levelUpText = new Text2("LEVEL UP!", { size: 100, fill: 0x00ff00, stroke: 0x000000, strokeThickness: 6, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); levelUpText.anchor.set(0.5, 0.5); levelUpText.x = 2048 / 2; levelUpText.y = 2732 / 2; LK.gui.addChild(levelUpText); // Animate and remove tween(levelUpText, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { levelUpText.destroy(); } }); } } // Game over function function gameOver() { gameRunning = false; // Visual effects LK.effects.flashScreen(0xff0000, 1000); // Game over container var gameOverContainer = new Container(); // Darken background var darkOverlay = LK.getAsset('problem', { anchorX: 0.5, anchorY: 0.5, width: 2048, height: 2732, tint: 0x000000, alpha: 0.8 }); darkOverlay.x = 2048 / 2; darkOverlay.y = 2732 / 2; gameOverContainer.addChild(darkOverlay); // Game over text var gameOverText = new Text2("YOU'RE NOT FINE!", { size: 120, fill: 0xff0000, fontWeight: 'bold', stroke: 0xFFFFFF, strokeThickness: 8, font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); gameOverText.anchor.set(0.5, 0.5); gameOverText.x = 2048 / 2; gameOverText.y = 700; gameOverContainer.addChild(gameOverText); // Meme text var memeText = new Text2("(But we've all been there...)", { size: 70, fill: 0xFFFFFF, fontStyle: 'italic', font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive" }); memeText.anchor.set(0.5, 0.5); memeText.x = 2048 / 2; memeText.y = 850; gameOverContainer.addChild(memeText); // Final score var finalScoreText = new Text2("FINAL SCORE: " + score, { size: 100, fill: 0xffff00, stroke: 0x000000, strokeThickness: 5 }); finalScoreText.anchor.set(0.5, 0.5); finalScoreText.x = 2048 / 2; finalScoreText.y = 1100; gameOverContainer.addChild(finalScoreText); // Level reached var levelReachedText = new Text2("DAY REACHED: " + gameLevel, { size: 80, fill: 0xFFFFFF }); levelReachedText.anchor.set(0.5, 0.5); levelReachedText.x = 2048 / 2; levelReachedText.y = 1250; gameOverContainer.addChild(levelReachedText); // Restart button var restartButton = new Container(); restartButton.interactive = true; var restartBg = LK.getAsset('problem', { anchorX: 0.5, anchorY: 0.5, width: 500, height: 120, tint: 0x00cc00 }); restartButton.addChild(restartBg); var restartText = new Text2("PLAY AGAIN", { size: 70, fill: 0xFFFFFF, fontWeight: 'bold' }); restartText.anchor.set(0.5, 0.5); restartText.x = 0; restartText.y = 0; restartButton.addChild(restartText); restartButton.x = 2048 / 2; restartButton.y = 1500; gameOverContainer.addChild(restartButton); // Add fun meme image or message var memeQuote = new Text2(getRandomMemeQuote(), { size: 60, fill: 0xFFFFFF, fontStyle: 'italic', align: 'center', wordWrap: true, wordWrapWidth: 1600 }); memeQuote.anchor.set(0.5, 0.5); memeQuote.x = 2048 / 2; memeQuote.y = 1800; gameOverContainer.addChild(memeQuote); // Animate in gameOverText.alpha = 0; gameOverText.y -= 100; memeText.alpha = 0; finalScoreText.alpha = 0; levelReachedText.alpha = 0; restartButton.alpha = 0; memeQuote.alpha = 0; tween(gameOverText, { alpha: 1, y: gameOverText.y + 100 }, { duration: 500, easing: tween.elasticOut }); tween(memeText, { alpha: 1 }, { duration: 500, delay: 500 }); tween(finalScoreText, { alpha: 1 }, { duration: 500, delay: 1000 }); tween(levelReachedText, { alpha: 1 }, { duration: 500, delay: 1500 }); tween(restartButton, { alpha: 1 }, { duration: 500, delay: 2000 }); tween(memeQuote, { alpha: 1 }, { duration: 500, delay: 2500 }); // Handle restart restartButton.down = function () { restartGame(); gameOverContainer.destroy(); }; LK.gui.addChild(gameOverContainer); } // Restart game function restartGame() { // Reset game variables score = 0; stressLevel = 0; gameLevel = 1; problemSpawnInterval = 1800; maxProblemsOnScreen = 4; lastProblemTime = 0; gameRunning = true; // Clear any existing problems for (var i = 0; i < problems.length; i++) { if (problems[i].parent) { problems[i].destroy(); } } problems = []; // Reset UI scoreText.setText("SCORE: 0"); levelText.setText("DAY: 1"); updateStressBar(); // Reset player player.updateAppearance(0); // Restart music LK.playMusic('bgmusic'); // Show tutorial again showTutorial(); } // Get random meme quote for game over screen function getRandomMemeQuote() { var quotes = ["This is fine. Everything is fine.", "When someone asks how you're doing and you say 'fine' for the 47th time today.", "Me pretending my life isn't falling apart.", "Monday: I'm fine. Tuesday: I'M FINE! Friday: EVERYTHING IS FINE!!!", "When the deadline is tomorrow and you haven't started yet: I'M FINE!", "Adult life is saying 'I'm fine' when people ask how you are until you actually are.", "No one: \nMe: I'M FINE!!! EVERYTHING IS FINE!!!", "When your coffee spills, WiFi drops, and deadline changes all at once: I'M TOTALLY FINE!"]; return quotes[Math.floor(Math.random() * quotes.length)]; } // Screen shake effect function shakeScreen(intensity) { if (!gameRunning) { return; } tween(game, { x: Math.random() * intensity - intensity / 2 }, { duration: 50, easing: tween.linear, onFinish: function onFinish() { tween(game, { x: Math.random() * intensity - intensity / 2 }, { duration: 50, easing: tween.linear, onFinish: function onFinish() { tween(game, { x: 0 }, { duration: 50, easing: tween.linear }); } }); } }); } // Clean up problems array function cleanupProblems() { for (var i = problems.length - 1; i >= 0; i--) { if (!problems[i].parent) { problems.splice(i, 1); } } } // Handle instructions button instructionsButton.down = function () { if (gameStarted) { showInstructions(); } }; // Handle start button startButton.down = function () { startGame(); }; // Main game update function game.update = function () { // Calculate delta time for consistent updates var now = Date.now(); var delta = (now - lastUpdate) / 1000; // Convert to seconds lastUpdate = now; // Update code background for visual effect codeBackground.update(); if (!gameRunning || !gameStarted || tutorialActive) { // Check if there are any problems to remove (during tutorial) for (var i = problems.length - 1; i >= 0; i--) { if (problems[i].parent) { problems[i].destroy(); } } problems = []; return; } // Check if it's time to spawn a new problem if (now - lastProblemTime > problemSpawnInterval) { spawnProblem(); lastProblemTime = now; } // Update all problems for (var i = 0; i < problems.length; i++) { if (problems[i] && problems[i].update) { problems[i].update(delta); } } // Clean up problems array cleanupProblems(); // Check level progress checkLevelProgress(); // Randomly reduce stress (small recovery chance) if (Math.random() < 0.001 * delta * 60 && stressLevel > 0) { stressLevel = Math.max(0, stressLevel - 0.5); updateStressBar(); } // Add screen shake when stress is high if (stressLevel >= 70 && Math.random() < 0.05) { var intensity = (stressLevel - 70) / 30 * 20; shakeScreen(intensity); } }; // Start the music (lower volume) LK.playMusic('bgmusic');
===================================================================
--- original.js
+++ change.js
@@ -312,21 +312,22 @@
self.addChild(problemText);
// Create timer bar
self.timerBar = self.attachAsset('timer', {
anchorX: 0,
- anchorY: 0,
- x: -100,
- y: 70,
- width: 200,
+ anchorY: 0.5,
+ x: -90,
+ y: 40,
+ width: 180,
+ height: 20,
tint: 0x00ff00
});
// Add timer text
self.timerText = new Text2(self.timeRemaining.toFixed(1), {
size: 30,
- fill: 0xFFFFFF,
+ fill: 0x000000,
align: 'center',
stroke: 0x000000,
- strokeThickness: 1,
+ strokeThickness: 0,
font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive"
});
self.timerText.anchor.set(0.5, 0.5);
self.timerText.x = 0;
@@ -385,13 +386,13 @@
self.update = function (delta) {
if (!self.active) {
return;
}
- // Decrease timer
- self.timeRemaining -= delta;
- // Update timer bar width
- var timerPercent = Math.max(0, self.timeRemaining / self.maxTime);
- self.timerBar.width = 200 * timerPercent;
+ // Decrease timer - ensure we don't go below 0
+ self.timeRemaining = Math.max(0, self.timeRemaining - delta);
+ // Update timer bar width with better bounds checking
+ var timerPercent = self.timeRemaining / self.maxTime;
+ self.timerBar.width = Math.max(0, Math.floor(200 * timerPercent));
// Change timer color as time runs out
if (timerPercent > 0.6) {
self.timerBar.tint = 0x00ff00; // Green
} else if (timerPercent > 0.3) {
@@ -555,14 +556,26 @@
self.addChild(problemText);
// Create static timer bar (visual only)
var timerBar = self.attachAsset('timer', {
anchorX: 0,
- anchorY: 0,
- x: -100,
- y: 70,
+ anchorY: 0.5,
+ x: -90,
+ y: 40,
width: 150,
- tint: 0x00ff00
+ height: 20,
+ tint: 0xffff00
});
+ // Add static timer text
+ var timerText = new Text2("2.5", {
+ size: 30,
+ fill: 0x000000,
+ align: 'center',
+ font: "Caveat, 'Comic Sans MS', 'Bradley Hand', cursive"
+ });
+ timerText.anchor.set(0.5, 0.5);
+ timerText.x = 0;
+ timerText.y = 70;
+ self.addChild(timerText);
return self;
});
/****
@@ -861,10 +874,10 @@
instructions.y = 1000;
tutorialContainer.addChild(instructions);
// Create a tutorial-only example problem and add it to tutorial container
var exampleProblem = new TutorialProblem();
- exampleProblem.x = 1500 / 2;
- exampleProblem.y = 1800;
+ exampleProblem.x = 1024;
+ exampleProblem.y = 1600;
tutorialContainer.addChild(exampleProblem);
// Continue button
var continueButton = new Container();
continueButton.interactive = true;
Modern office/workspace with subtle chaotic elements Include desk with scattered papers, coffee stains, overflowing inbox, sticky notes Light, neutral color palette (pale blue/gray) with professional appearance Should look slightly overwhelming but clean enough to not distract from gameplay. In-Game asset. 2d. High contrast. No shadows
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "FOMO Simulator: The Meeting That Could've Been An Email" and with the description "A fast-paced office simulator where you collect meetings, emails, and notifications while managing your energy levels. Strategic decisions must be made about which workplace items to prioritize as your energy depletes. Grab coffee for boosts, avoid missing important meetings, and survive the chaotic 60-second workday!". No text on banner!. In-Game asset. 2d. High contrast. No shadows
Modern App Store icon, high definition, square with rounded corners, for a game titled "FOMO Simulator: The Meeting That Could've Been An Email" and with the description "A fast-paced office simulator where you collect meetings, emails, and notifications while managing your energy levels. Strategic decisions must be made about which workplace items to prioritize as your energy depletes. Grab coffee for boosts, avoid missing important meetings, and survive the chaotic 60-second workday!". No text on icon!. In-Game asset. 2d. High contrast. No shadows