User prompt
Create tower class
User prompt
Move line 1 up 15
User prompt
Move score display right 250
User prompt
Move guidelines up 25
User prompt
Ensure guidelines in level2 remain in same place as level1
User prompt
In level2 ensure guidelines are used and enemies travel down middle of guidelines ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When level2 is reached ensure that backdrop2 fills entire screen and replaces original level1 backdrop
User prompt
Click skip wave in wave2 to move to wave3, wave 3 to wave4, wave4 to wave5 , wave5 to Cutscene,
User prompt
After Cutscene level1 will be officially over and level2 will begin using backdrop2 as the new backdrop for level2 game play ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
After UFO boss is defeated game will transition to a Cutscene using the story5 asset ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Once 40 robots are defeated wave4 ends and wave5 asset will fade in for 1.5 seconds then fade out again. Wave 5 is the first boss stage and the boss enemy will use the UFO asset and there will be just 1 of them. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When the first robot appears in wave4 play probedroid2 sound
User prompt
Once 30 spacedrones are defeated wave3 ends and wave4 asset will fade in for 1.5 seconds then fade out again. Wave 4 enemies will use the robot asset and there will be 40 of them. Spawn robot asset 3 seconds apart ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Once 20 drones are defeated wave2 ends and wave3 asset will fade in for 1.5 seconds then fade out again. Wave 3 enemies will use the SpaceDrones asset and there will be 30 of them. Spawn spacedrones asset 5 seconds apart ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Start wave2 if skip wave button is pressed in wave1 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add skip wave button under score that can skip waves for debugging and creative purposes
User prompt
Once wave1 starts add score display lives display and cash display at the top of screen
User prompt
Wave1 asset should only stay on screen for 2 seconds before fading out ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Once 10 probedroids are defeated wave1 ends and wave2 asset will fade in for 1.5 seconds then fade out again. Wave 2 enemies will use the drone asset and there will be 20 of them. Spawn drone asset 5 seconds apart ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Wave1 will have 10 probedroids
User prompt
Make sure enemies travel straight down the middle of the guidelines
User prompt
If skip intro is pressed on intro2 scene play intro music
User prompt
Add skip intro button on intro2 scene
User prompt
When the first probedroid appears play probedroid sound
User prompt
Wave1 enemies use probedroid assets
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Cutscene class var Cutscene = Container.expand(function () { var self = Container.call(this); // Properties self.scenes = []; self.currentSceneIndex = 0; self.isPlaying = false; // Add a scene to the cutscene self.addScene = function (sceneData) { self.scenes.push(sceneData); }; // Start playing the cutscene self.play = function () { if (self.scenes.length === 0) return; self.isPlaying = true; self.currentSceneIndex = 0; self.playCurrentScene(); }; // Play the current scene self.playCurrentScene = function () { if (self.currentSceneIndex >= self.scenes.length) { self.finish(); return; } var scene = self.scenes[self.currentSceneIndex]; if (scene.onStart) { scene.onStart(); } // Auto-advance to next scene after duration if (scene.duration) { LK.setTimeout(function () { self.nextScene(); }, scene.duration); } }; // Move to next scene self.nextScene = function () { var scene = self.scenes[self.currentSceneIndex]; if (scene.onEnd) { scene.onEnd(); } self.currentSceneIndex++; self.playCurrentScene(); }; // Skip to specific scene self.skipToScene = function (index) { if (index >= 0 && index < self.scenes.length) { self.currentSceneIndex = index; self.playCurrentScene(); } }; // Finish cutscene self.finish = function () { self.isPlaying = false; if (self.onFinish) { self.onFinish(); } }; // Stop cutscene self.stop = function () { self.isPlaying = false; // Stop any running tweens or timeouts tween.stopAll(); }; return self; }); // Defense class var Defense = Container.expand(function () { var self = Container.call(this); var defenseGraphics = self.attachAsset('defense', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Defense logic goes here }; }); // Enemy class for tower defense var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('Probedroid', { anchorX: 0.5, anchorY: 0.5 }); // Enemy properties self.health = 100; self.maxHealth = 100; self.speed = 2; self.targetX = -100; // Move to left side of screen self.lastX = self.x; self.update = function () { // Store last position for collision detection self.lastX = self.x; // Move towards target (right to left) if (self.x > self.targetX) { self.x -= self.speed; } // Check if enemy reached the end if (self.lastX > 0 && self.x <= 0) { // Enemy reached the end - remove from game if (self.parent) { self.destroy(); // Remove from enemies array for (var i = enemies.length - 1; i >= 0; i--) { if (enemies[i] === self) { enemies.splice(i, 1); break; } } } } }; return self; }); // Assets will be automatically created and loaded by the LK engine // Tower class var Tower = Container.expand(function () { var self = Container.call(this); var towerGraphics = self.attachAsset('tower', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Tower logic goes here }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ // Tower Defense Game Variables var enemies = []; var towers = []; var waveActive = false; var enemySpawnTimer = 0; var enemySpawnInterval = 420; // Spawn every 7 seconds at 60fps var enemiesSpawned = 0; var maxEnemiesInWave = 10; var guidelineYPositions = []; var firstEnemySpawned = false; // Create intro cutscene using intro2 asset var introCutscene = new Cutscene(); // Add intro2 scene introCutscene.addScene({ onStart: function onStart() { // Create intro2 asset var intro2Asset = game.addChild(LK.getAsset('Intro2', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Create cell asset in middle of intro2 var cellAsset = game.addChild(LK.getAsset('cell', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Store references for cleanup introCutscene.intro2Asset = intro2Asset; introCutscene.cellAsset = cellAsset; // Fade in intro2 tween(intro2Asset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Fade in cell asset tween(cellAsset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Add skip intro button var skipIntroButton = new Text2('SKIP INTRO', { size: 60, fill: 0xFFFFFF }); skipIntroButton.anchor.set(0.5, 0); skipIntroButton.x = 2048 / 2; skipIntroButton.y = 200; skipIntroButton.alpha = 0; game.addChild(skipIntroButton); // Store reference for cleanup introCutscene.skipIntroButton = skipIntroButton; // Fade in skip button tween(skipIntroButton, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Add click event handler to skip button skipIntroButton.down = function (x, y, obj) { // Play intro music LK.playMusic('Intro', { loop: false }); // Clean up intro2 assets tween.stop(intro2Asset); tween.stop(cellAsset); tween.stop(skipIntroButton); intro2Asset.destroy(); cellAsset.destroy(); skipIntroButton.destroy(); // Skip directly to title screen showTitleScreen(); }; // Add click event handler to cell asset cellAsset.down = function (x, y, obj) { // Play intro music LK.playMusic('Intro', { loop: false }); // Transition to story1 scene var story1Asset = game.addChild(LK.getAsset('Story1', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Fade out current assets tween(intro2Asset, { alpha: 0 }, { duration: 500, easing: tween.easeInOut }); tween(cellAsset, { alpha: 0 }, { duration: 500, easing: tween.easeInOut }); // Fade in story1 asset tween(story1Asset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Add click event handler to story1 asset to transition to story2 story1Asset.down = function (x, y, obj) { // Create story2 asset var story2Asset = game.addChild(LK.getAsset('Story2', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Fade out story1 asset tween(story1Asset, { alpha: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { story1Asset.destroy(); } }); // Fade in story2 asset tween(story2Asset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Add click event handler to story2 asset to transition to story3 story2Asset.down = function (x, y, obj) { // Create story3 asset var story3Asset = game.addChild(LK.getAsset('Story3', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Fade out story2 asset tween(story2Asset, { alpha: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { story2Asset.destroy(); } }); // Fade in story3 asset tween(story3Asset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Add click event handler to story3 asset to transition to story4 story3Asset.down = function (x, y, obj) { // Create story4 asset var story4Asset = game.addChild(LK.getAsset('Story4', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Fade out story3 asset tween(story3Asset, { alpha: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { story3Asset.destroy(); } }); // Fade in story4 asset tween(story4Asset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); // Add click event handler to story4 asset to transition to titlescreen story4Asset.down = function (x, y, obj) { // Fade out story4 asset tween(story4Asset, { alpha: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { story4Asset.destroy(); // Show title screen showTitleScreen(); } }); }; }; }; }; }; } }); // Set what happens when cutscene finishes introCutscene.onFinish = function () { // Cutscene finished - no automatic transition }; // Function to show title screen function showTitleScreen() { // Display the title // Import tween plugin var titleImage = game.addChild(LK.getAsset('Title', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 + 1400 })); // Add skip intro button to top of title screen var skipButton = new Text2('SKIP INTRO', { size: 60, fill: 0xFFFFFF }); skipButton.anchor.set(0.5, 0); skipButton.x = 2048 / 2; skipButton.y = 150; game.addChild(skipButton); // Function to skip directly to backdrop scene function skipToBackdrop() { // Stop all tweens tween.stop(titleImage); tween.stop(flybyImage); // Remove title and flyby titleImage.destroy(); flybyImage.destroy(); skipButton.destroy(); // Add backdrop asset to game var backdropAsset = game.addChild(LK.getAsset('backdrop', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 1, scaleX: 0.5, scaleY: 0.5 })); // Add flyby asset to backdrop var backdropFlyby = game.addChild(LK.getAsset('Flyby', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 800, alpha: 1, scaleX: 0.2, scaleY: 0.2 })); // Zoom flyby to final size tween(backdropFlyby, { scaleX: 0.8, scaleY: 0.8 }, { duration: 1000, easing: tween.easeInOut }); // Store the original Y position for backdrop flyby var backdropFlybyOriginalY = backdropFlyby.y; // Make flyby move off the right side of backdrop scene tween(backdropFlyby, { x: 2048 + 375 }, { duration: 6000, easing: tween.linear, onFinish: function onFinish() { // After flyby has left the backdrop scene, fade in wave1 asset var wave1Asset = game.addChild(LK.getAsset('Wave1', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Fade in wave1 asset tween(wave1Asset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Keep wave1 visible for 3 seconds then fade out LK.setTimeout(function () { tween(wave1Asset, { alpha: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { wave1Asset.destroy(); // Start first tower defense wave startWave1(); } }); }, 3000); } }); } }); // Add 6 horizontal guide lines immediately var lineSpacing = 2732 / 7; for (var i = 1; i <= 6; i++) { var yPosition = lineSpacing * i; if (i === 1) { yPosition += 600; // Move guideline 1 down by 600 pixels } else if (i === 2) { yPosition += 420; // Move guideline 2 down by 420 pixels } else if (i === 3) { yPosition += 250; // Move guideline 3 down by 250 pixels } else if (i === 4) { yPosition += 120; // Move guideline 4 down by 120 pixels } else if (i === 5) { yPosition -= 50; // Move guideline 5 up by 50 pixels } else if (i === 6) { yPosition -= 200; // Move guideline 6 up by 200 pixels } var guideLine = game.addChild(LK.getAsset('guideLine', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: yPosition, alpha: 0.5 })); } } // Add touch event to skip button skipButton.down = function (x, y, obj) { skipToBackdrop(); }; // Add flyby asset to title - start at right side of screen var flybyImage = game.addChild(LK.getAsset('Flyby', { anchorX: 0.5, anchorY: 0.5, x: 2048 + 375, y: 2732 / 2 + 1400 - 500 })); // Store the original Y position for flyby var flybyOriginalY = flybyImage.y; // Create hover animation function function startFlybyHover() { // Tween up 50 pixels over 2 seconds tween(flybyImage, { y: flybyOriginalY - 50 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { // Tween down 50 pixels over 2 seconds tween(flybyImage, { y: flybyOriginalY + 50 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { // Start the cycle again startFlybyHover(); } }); } }); } // Start the hover animation startFlybyHover(); // Start flyby movement from right to left tween(flybyImage, { x: -375 }, { duration: 8000, easing: tween.linear, onFinish: function onFinish() { // After flyby has left the screen, slowly scroll title up tween(titleImage, { y: titleImage.y - titleImage.height }, { duration: 20000, easing: tween.easeOut }); // Stop the title scrolling after 5 seconds LK.setTimeout(function () { tween.stop(titleImage, { y: true }); // Fade in intro asset in the middle of the screen var introAsset = game.addChild(LK.getAsset('intro', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Tween alpha from 0 to 1 for fade-in effect tween(introAsset, { alpha: 1 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { // After intro has faded in, make flyby move from left to right flybyImage.x = -375; // Reset flyby to left side flybyImage.y = 2732 / 2; // Center vertically tween(flybyImage, { x: 2048 + 375 }, { duration: 6000, easing: tween.linear, onFinish: function onFinish() { // After flyby has left the screen, fade out intro and fade in backdrop tween(introAsset, { alpha: 0 }, { duration: 2000, easing: tween.easeInOut }); // Add backdrop asset to game var backdropAsset = game.addChild(LK.getAsset('backdrop', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0, scaleX: 0.5, scaleY: 0.5 })); // Add flyby asset to backdrop var backdropFlyby = game.addChild(LK.getAsset('Flyby', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 - 800, alpha: 0, scaleX: 0.2, scaleY: 0.2 })); // Store the original Y position for backdrop flyby var backdropFlybyOriginalY = backdropFlyby.y; // Make flyby move off the right side of backdrop scene function startBackdropFlybyHover() { tween(backdropFlyby, { x: 2048 + 375 }, { duration: 6000, easing: tween.linear, onFinish: function onFinish() { // After flyby has left the backdrop scene, fade in wave1 asset var wave1Asset = game.addChild(LK.getAsset('Wave1', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0 })); // Fade in wave1 asset tween(wave1Asset, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Keep wave1 visible for 3 seconds then fade out LK.setTimeout(function () { tween(wave1Asset, { alpha: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { wave1Asset.destroy(); // Start first tower defense wave startWave1(); } }); }, 3000); } }); } }); } // Fade in backdrop tween(backdropAsset, { alpha: 1 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { // Fade in backdrop flyby and zoom to position tween(backdropFlyby, { alpha: 1, scaleX: 0.8, scaleY: 0.8 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { // Start flyby movement to right side after fade in startBackdropFlybyHover(); } }); // Add 6 horizontal guide lines after backdrop fades in var lineSpacing = 2732 / 7; // Divide screen height by 7 to get 6 lines with margins for (var i = 1; i <= 6; i++) { var yPosition = lineSpacing * i; if (i === 1) { yPosition += 600; // Move guideline 1 down by 600 pixels } else if (i === 2) { yPosition += 420; // Move guideline 2 down by 420 pixels } else if (i === 3) { yPosition += 250; // Move guideline 3 down by 250 pixels } else if (i === 4) { yPosition += 120; // Move guideline 4 down by 120 pixels } else if (i === 5) { yPosition -= 50; // Move guideline 5 up by 50 pixels } else if (i === 6) { yPosition -= 200; // Move guideline 6 up by 200 pixels } var guideLine = game.addChild(LK.getAsset('guideLine', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: yPosition, alpha: 0.5 })); } } }); } }); } }); }, 5000); } }); } // Calculate guideline Y positions for enemy spawning function calculateGuidelinePositions() { var lineSpacing = 2732 / 7; guidelineYPositions = []; for (var i = 1; i <= 6; i++) { var yPosition = lineSpacing * i; if (i === 1) { yPosition += 600; // Move guideline 1 down by 600 pixels } else if (i === 2) { yPosition += 420; // Move guideline 2 down by 420 pixels } else if (i === 3) { yPosition += 250; // Move guideline 3 down by 250 pixels } else if (i === 4) { yPosition += 120; // Move guideline 4 down by 120 pixels } else if (i === 5) { yPosition -= 50; // Move guideline 5 up by 50 pixels } else if (i === 6) { yPosition -= 200; // Move guideline 6 up by 200 pixels } guidelineYPositions.push(yPosition); } } // Start first wave of tower defense function startWave1() { calculateGuidelinePositions(); waveActive = true; enemySpawnTimer = 0; enemiesSpawned = 0; } // Spawn enemy on random guideline function spawnEnemy() { if (guidelineYPositions.length === 0) return; // Pick random guideline with better distribution var randomIndex = Math.floor(Math.random() * guidelineYPositions.length); var spawnY = guidelineYPositions[randomIndex]; // Add some vertical variation to make movement less predictable var verticalVariation = (Math.random() - 0.5) * 60; // +/- 30 pixels variation spawnY += verticalVariation; // Create new enemy var enemy = new Enemy(); enemy.x = 2048 + 100; // Start off right side of screen enemy.y = spawnY; // Store which guideline this enemy is following for reference enemy.guidelineIndex = randomIndex; enemy.baseY = guidelineYPositions[randomIndex]; enemies.push(enemy); game.addChild(enemy); // Play probedroid sound when first enemy appears if (!firstEnemySpawned) { LK.getSound('Probedroid').play(); firstEnemySpawned = true; } } // Update tower defense game game.update = function () { // Only run tower defense logic when wave is active if (!waveActive) return; // Spawn enemies if (enemiesSpawned < maxEnemiesInWave) { enemySpawnTimer++; if (enemySpawnTimer >= enemySpawnInterval) { spawnEnemy(); enemiesSpawned++; enemySpawnTimer = 0; } } // Check if wave is complete if (enemiesSpawned >= maxEnemiesInWave && enemies.length === 0) { waveActive = false; // Wave complete - could start next wave or show completion } }; // Start the intro cutscene introCutscene.play(); ; ;
===================================================================
--- original.js
+++ change.js
@@ -211,8 +211,12 @@
easing: tween.easeInOut
});
// Add click event handler to skip button
skipIntroButton.down = function (x, y, obj) {
+ // Play intro music
+ LK.playMusic('Intro', {
+ loop: false
+ });
// Clean up intro2 assets
tween.stop(intro2Asset);
tween.stop(cellAsset);
tween.stop(skipIntroButton);
White circle with two eyes, seen from above.. In-Game asset. 2d. High contrast. No shadows
White simple circular enemy seen from above, black outline. Black eyes, with a single shield in-font of it. Black and white only. Blue background.
White circle with black outline. Blue background.. In-Game asset. 2d. High contrast. No shadows
Fire hydrant. In-Game asset. 2d. High contrast. No shadows
Water spraying forward In-Game asset. 2d. High contrast. No shadows
Fan blades symmetrical. In-Game asset. 2d. High contrast. No shadows
Plasma ball. In-Game asset. 2d. High contrast. No shadows
Make picture transparent
Bug zapper on a pole. In-Game asset. 2d. High contrast. No shadows
Probe droid. In-Game asset. 2d. High contrast. No shadows
Space drone. In-Game asset. 2d. High contrast. No shadows
Remove propellers and make them symmetrical
Add more rows to gris
Make this picture with more night sky above the city skyline
Change text to say wave 1
Make button grey and say ??????
Make it say Wave 2
Make it say wave 3
Make it say wave 4
WiFi symbol. In-Game asset. 2d. High contrast. No shadows
explosion effect In-Game asset. 2d. High contrast. No shadows
Make it say wave 5
Remove laser beam
Make button hot pink and say 'Reflect $20'
Make button blue and change text to say 'Water $10' in a retro style font
Make button green and change test to say 'Gas $20'
Make button orange and change test to say 'Fire $40'
Make button very light blue and change test to say 'Air $30'
Make button gold and change text to say 'Electric $50'
Make button purple and change test to say 'Plasma $60'
Make button Teal and change test to say 'Slingshot $100'
Make button silver and change test to say 'WiFi $150'
Remove little kick so it's just a smooth oval shape
Make grid 6x8
Hand should be holding the gun by the Handle
Place laser cannon in both hands holding it like a shotgun
Make it stand still
Remove the words 5g
Make sure spelling in speech bubble is correct "We have found the earthlings weakness"
Fix the spelling of the word Planet
Slingshot. In-Game asset. 2d. High contrast. No shadows
Red button with a 'X' on it. In-Game asset. 2d. High contrast. No shadows
Green button with a tick on it
Fix the spelling of word saw
Display icon that says score sci fi comic style font. In-Game asset. 2d. High contrast. No shadows
Display icon that says cash sci fi comic style font. In-Game asset. 2d. High contrast. No shadows
Display icon that says X2 speed sci fi comic style font. In-Game asset. 2d. High contrast. No shadows
Make it say x1 speed and make the x1 blue
Canvasser
Sound effect
Alien1
Sound effect
Alien2
Sound effect
Alien3
Sound effect
Intro
Music
Probedroid
Sound effect
Probedroid2
Sound effect
Towerselect
Sound effect
Water
Sound effect
Explosion
Sound effect
Confirm
Sound effect
Fart
Sound effect
Electric
Sound effect
Fireball
Sound effect