User prompt
Fix the first 2 slots, they have slots behind them that spin instead of the actual slot
User prompt
Make Loaf slot spin βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Loaf slot and loaf wenda βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add Loaf Wenda with Loaf mixing slot, Loaf wenda uses reversed version of horror wenda sound.
User prompt
Add Loaf Wenda with Loaf mixing slot, Loaf wenda uses reversed version of horror wenda sound. Loaf slots are not excluded from spin. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make mixing slots exept alternating and lily slots spin βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove drag to remove function but keep drag to add function, only way to remove is tapping, remember keep drag fomadd
User prompt
Remove drag to remove function, only tap. But drag to add is needed!
User prompt
Remove drag to remove function, only tap
User prompt
Fix, all horro chars alternate horror and lily, only horror lily should alternate, other horrors static horror, and lily static lily
User prompt
Move all chars up 80 more px and add continuous dance animation for all characters βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Move all chars up 40 more px and add continuous dance animation for all characters βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Move all chars up 20 px
User prompt
Make horror lily be in same line as lily, it can fit 1 more char.
User prompt
Add horror lily sound asset
User prompt
Add horror lily, Lily slot and horror slot alternate every second for character, and make dance happen always for all chars. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add mixing slot for lily placed.
User prompt
Add mixing slot just for lily.
User prompt
Add new character, Lily
User prompt
Make title dance βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Bg asset
User prompt
New character
User prompt
Add 5th mixing slot
User prompt
New character
User prompt
New active mixing slot variation for if a horror character other than horror inky is placed in a slot.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Character = Container.expand(function (characterData) {
var self = Container.call(this);
self.characterData = characterData;
self.isOnBoard = false;
self.originalPosition = {
x: 0,
y: 0
};
self.boardSlot = null;
self.soundInstance = null;
self.soundTimer = null;
var characterGraphics = self.attachAsset(characterData.assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Make character interactive
self.interactive = true;
// Add character name text
var nameText = new Text2(characterData.name, {
size: 45,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = 90;
self.addChild(nameText);
self.playSound = function () {
if (self.soundInstance) {
self.soundInstance.stop();
}
// Clear any existing sound timer
if (self.soundTimer) {
LK.clearInterval(self.soundTimer);
}
// Function to play sound once
function playSoundOnce() {
self.soundInstance = LK.getSound(characterData.soundId);
self.soundInstance.play({
loop: false
}); // Play without looping
}
// Play sound immediately
playSoundOnce();
// Set up timer to play sound every 1.3 seconds
self.soundTimer = LK.setInterval(function () {
playSoundOnce();
}, 1300);
// Visual feedback - bounce animation
tween(characterGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(characterGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Continuous singing animation
self.singAnimation = LK.setInterval(function () {
// Wobble effect
tween(characterGraphics, {
rotation: 0.1
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(characterGraphics, {
rotation: -0.1
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(characterGraphics, {
rotation: 0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
});
// Pulsing effect based on sound type
if (characterData.type === 'beat') {
tween(characterGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(characterGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
} else if (characterData.type === 'voice') {
// Smooth scaling for voice
tween(characterGraphics, {
scaleY: 1.15
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(characterGraphics, {
scaleY: 1.0
}, {
duration: 400,
easing: tween.easeInOut
});
}
});
}
}, 600);
};
self.stopSound = function () {
if (self.soundInstance) {
self.soundInstance.stop();
self.soundInstance = null;
}
// Clear sound timer
if (self.soundTimer) {
LK.clearInterval(self.soundTimer);
self.soundTimer = null;
}
// Stop singing animation
if (self.singAnimation) {
LK.clearInterval(self.singAnimation);
self.singAnimation = null;
}
// Reset rotation
tween(characterGraphics, {
rotation: 0
}, {
duration: 200,
easing: tween.easeOut
});
};
self.returnToOriginalPosition = function () {
tween(self, {
x: self.originalPosition.x,
y: self.originalPosition.y
}, {
duration: 300,
easing: tween.easeOut
});
};
return self;
});
var MixingSlot = Container.expand(function (slotIndex) {
var self = Container.call(this);
self.slotIndex = slotIndex;
self.character = null;
self.isEmpty = true;
var slotGraphics = self.attachAsset('mixing_slot', {
anchorX: 0.5,
anchorY: 0.5
});
self.addCharacter = function (character) {
if (self.character) {
self.removeCharacter();
}
self.character = character;
self.isEmpty = false;
character.isOnBoard = true;
character.boardSlot = self;
// Store the character's parent container
var characterParent = character.parent;
// Check if character is Lily
var isLilyCharacter = character.characterData.name === "Lily";
// Check if character is a horror character (but not Horror Inky)
var isHorrorCharacter = character.characterData.name.indexOf("Horror") !== -1 && character.characterData.name !== "Horror Inky";
// Check if character is Loaf Wenda
var isLoafCharacter = character.characterData.name === "Loaf Wenda";
if (isLilyCharacter) {
// Replace slot graphics with lily version
self.removeChild(slotGraphics);
slotGraphics = self.attachAsset('mixing_slot_active_lily', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (isHorrorCharacter) {
// Replace slot graphics with horror version
self.removeChild(slotGraphics);
slotGraphics = self.attachAsset('mixing_slot_active_horror', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (isLoafCharacter) {
// Replace slot graphics with loaf version
self.removeChild(slotGraphics);
slotGraphics = self.attachAsset('mixing_slot_active_loaf', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
// Use regular active slot
self.removeChild(slotGraphics);
slotGraphics = self.attachAsset('mixing_slot_active', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Visual feedback - glow effect
tween(slotGraphics, {
tint: 0x888888,
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(slotGraphics, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Position character directly to slot position (both are in game coordinates)
tween(character, {
x: self.x,
y: self.y - 50
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(character, {
y: self.y
}, {
duration: 200,
easing: tween.bounceOut,
onFinish: function onFinish() {
character.playSound();
}
});
}
});
};
self.removeCharacter = function () {
if (self.character) {
var characterToRemove = self.character;
self.character.stopSound();
self.character.isOnBoard = false;
self.character.boardSlot = null;
// Animate character up before returning
tween(characterToRemove, {
y: characterToRemove.y - 100,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
characterToRemove.returnToOriginalPosition();
// Reset scale after returning
tween(characterToRemove, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
}
});
self.character = null;
}
self.isEmpty = true;
// Reset slot graphics to default mixing slot
self.removeChild(slotGraphics);
slotGraphics = self.attachAsset('mixing_slot', {
anchorX: 0.5,
anchorY: 0.5
});
// Fade slot back to normal
tween(slotGraphics, {
tint: 0xFFFFFF,
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(slotGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
};
self.containsPoint = function (x, y) {
// Use fixed size for slot hit detection
var halfWidth = 90; // Half of slot width
var halfHeight = 90; // Half of slot height
return x >= self.x - halfWidth && x <= self.x + halfWidth && y >= self.y - halfHeight && y <= self.y + halfHeight;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Add background image
var bgImage = game.attachAsset('Bg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.27
});
bgImage.x = 2048 / 2;
bgImage.y = 2732 / 2;
// Sound assets for each character
// Character data
// Characters
// Mixing board slots
// Sounds
var characterData = [{
name: "Oren",
assetId: "oren",
soundId: "oren_beat",
type: "beat"
}, {
name: "Horror Oren",
assetId: "horror_oren",
soundId: "horror_oren_beat",
type: "beat"
}, {
name: "Raddy",
assetId: "raddy",
soundId: "raddy_beat",
type: "beat"
}, {
name: "Horror Raddy",
assetId: "horror_raddy",
soundId: "horror_raddy_effect",
type: "effect"
}, {
name: "Wenda",
assetId: "wenda",
soundId: "wenda_voice",
type: "voice"
}, {
name: "Horror Wenda",
assetId: "horror_wenda",
soundId: "horror_wenda_voice",
type: "voice"
}, {
name: "Alt Horror Wenda",
assetId: "alt_horror_wenda",
soundId: "alt_horror_wenda_effect",
type: "effect"
}, {
name: "Jevin",
assetId: "jevin",
soundId: "jevin_voice",
type: "voice"
}, {
name: "Horror Jevin",
assetId: "horror_jevin",
soundId: "horror_jevin_voice",
type: "voice"
}, {
name: "Inky",
assetId: "inky",
soundId: "inky_effect",
type: "effect"
}, {
name: "Horror Inky",
assetId: "horror_inky",
soundId: "horror_inky_effect",
type: "effect"
}, {
//{3r_new}
name: "Alt Horror Jevin",
assetId: "alt_horror_jevin",
soundId: "alt_horror_jevin_voice",
type: "voice" //{3s_new}
}, {
name: "Cool Guy",
assetId: "Cool_Guy",
soundId: "Cool_Guy_voice",
type: "voice"
}, {
name: "Horror Cool Guy",
assetId: "horror_cool_guy",
soundId: "horror_cool_guy_voice",
type: "voice"
}, {
//{3O_new}
name: "Lily",
assetId: "lily",
soundId: "lily_voice",
type: "voice" //{3P_new}
}, {
name: "Horror Lily",
assetId: "horror_lily",
soundId: "horror_lily_voice",
type: "voice"
}, {
name: "Loaf Wenda",
assetId: "Loaf_wenda",
soundId: "loaf_wenda_voice",
type: "voice"
}];
// Game elements
var characters = [];
var mixingSlots = [];
var draggedCharacter = null;
var dragOffset = {
x: 0,
//{3t_new}
y: 0 //{3u_new}
}; //{3v_new}
// Title
var titleText = new Text2("Sprunki Beat Mixer", {
size: 120,
fill: 0xFFFFFF //{3w_new}
}); //{3x_new}
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 100;
game.addChild(titleText);
// Title dance animation
LK.setInterval(function () {
// Bounce effect
tween(titleText, {
scaleX: 1.1,
scaleY: 1.1,
y: 80
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1.0,
scaleY: 1.0,
y: 100
}, {
duration: 400,
easing: tween.bounceOut
});
}
});
// Color pulse effect
tween(titleText, {
tint: 0x00ff88
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
tint: 0xffffff
}, {
duration: 600,
easing: tween.easeInOut
});
}
});
}, 1200);
// Subtle rotation wobble
LK.setInterval(function () {
tween(titleText, {
rotation: 0.05
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
rotation: -0.05
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
rotation: 0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
});
}, 1800);
// Create mixing board slots
var slotStartX = 2048 / 2 - 5 * 300 / 2;
var slotY = 800;
for (var i = 0; i < 5; i++) {
var slot = new MixingSlot(i);
slot.x = slotStartX + i * 300;
slot.y = slotY;
mixingSlots.push(slot);
game.addChild(slot);
} //{3y_new}
// Create characters
var charactersPerRow = 5;
var characterStartX = 2048 / 2 - charactersPerRow * 300 / 2;
var characterStartY = 1660;
for (var i = 0; i < characterData.length; i++) {
var character = new Character(characterData[i]);
var row = Math.floor(i / charactersPerRow);
var col = i % charactersPerRow;
character.x = characterStartX + col * 300;
character.y = characterStartY + row * 300;
character.originalPosition.x = character.x;
character.originalPosition.y = character.y;
characters.push(character);
game.addChild(character);
// Start continuous dance animation for all characters
var characterGraphics = character.children[0]; // Get the attached asset
(function (charGraphics, charData) {
LK.setInterval(function () {
// Wobble effect
tween(charGraphics, {
rotation: 0.05
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(charGraphics, {
rotation: -0.05
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(charGraphics, {
rotation: 0
}, {
duration: 300,
easing: tween.easeInOut
});
}
});
}
});
// Pulsing effect based on sound type
if (charData.type === 'beat') {
tween(charGraphics, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(charGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
} else if (charData.type === 'voice') {
// Smooth scaling for voice
tween(charGraphics, {
scaleY: 1.1
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(charGraphics, {
scaleY: 1.0
}, {
duration: 400,
easing: tween.easeInOut
});
}
});
}
}, 600);
})(characterGraphics, character.characterData);
} //{3z_new}
// Slot alternation timer - only Horror Lily alternates between horror/lily slots every second
var slotAlternationState = false;
LK.setInterval(function () {
slotAlternationState = !slotAlternationState;
for (var i = 0; i < mixingSlots.length; i++) {
var slot = mixingSlots[i];
if (slot.character) {
// Only Horror Lily should alternate between horror and lily slots
var isHorrorLily = slot.character.characterData.name === "Horror Lily";
var isLily = slot.character.characterData.name === "Lily";
if (isHorrorLily) {
var currentSlotGraphics = slot.children[0];
slot.removeChild(currentSlotGraphics);
var newAssetId;
if (slotAlternationState) {
newAssetId = 'mixing_slot_active_horror';
} else {
newAssetId = 'mixing_slot_active_lily';
}
var newSlotGraphics = slot.attachAsset(newAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
} else if (!isLily) {
// Spin other mixing slots (not lily, not alternating horror lily)
var slotGraphics = slot.children[0];
tween(slotGraphics, {
rotation: slotGraphics.rotation + Math.PI * 2
}, {
duration: 1000,
easing: tween.linear
});
}
} else {
// Spin empty slots
var slotGraphics = slot.children[0];
tween(slotGraphics, {
rotation: slotGraphics.rotation + Math.PI * 2
}, {
duration: 1000,
easing: tween.linear
});
}
}
}, 1000);
// Instructions
var instructionText = new Text2("Drag characters to mixing slots to create beats!", {
size: 60,
fill: 0xFFFFFF //{3A_new}
}); //{3B_new}
instructionText.anchor.set(0.5, 0);
instructionText.x = 2048 / 2;
instructionText.y = 1200;
game.addChild(instructionText);
// Helper functions
function getCharacterAt(x, y) {
for (var i = characters.length - 1; i >= 0; i--) {
var character = characters[i];
// Use character position and asset dimensions for hit detection
var characterAsset = character.children[0]; // The attached asset
if (characterAsset) {
var halfWidth = characterAsset.width / 2;
var halfHeight = characterAsset.height / 2;
if (x >= character.x - halfWidth && x <= character.x + halfWidth && y >= character.y - halfHeight && y <= character.y + halfHeight) {
return character;
}
}
}
return null;
}
function getMixingSlotAt(x, y) {
for (var i = 0; i < mixingSlots.length; i++) {
if (mixingSlots[i].containsPoint(x, y)) {
return mixingSlots[i];
}
}
return null;
}
// Event handlers
game.down = function (x, y, obj) {
// Check if we're tapping on a character first (prioritize character interaction)
var character = getCharacterAt(x, y);
if (character) {
// If character is on board, only allow tap to remove (no dragging)
if (character.isOnBoard && character.boardSlot) {
// Remove character from slot with a single tap
character.boardSlot.removeCharacter();
return;
}
// If character is not on board, start dragging
if (!character.isOnBoard) {
draggedCharacter = character;
dragOffset.x = x - character.x;
dragOffset.y = y - character.y;
// Bring to front - store parent reference before removing
var parentContainer = character.parent;
parentContainer.removeChild(character);
parentContainer.addChild(character);
// Visual feedback
tween(character, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
easing: tween.easeOut
});
return;
}
}
// If no character found, check if we're tapping on a slot with a character
var slot = getMixingSlotAt(x, y);
if (slot && !slot.isEmpty) {
// Remove character from slot with a single tap
slot.removeCharacter();
return;
}
};
game.move = function (x, y, obj) {
if (draggedCharacter && draggedCharacter.parent) {
// Ensure the dragged character follows the cursor smoothly
draggedCharacter.x = x - dragOffset.x;
draggedCharacter.y = y - dragOffset.y;
// Highlight slot when hovering
var hoverSlot = getMixingSlotAt(x, y);
for (var i = 0; i < mixingSlots.length; i++) {
var slot = mixingSlots[i];
if (slot === hoverSlot && slot.isEmpty) {
tween(slot, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
easing: tween.easeOut
});
} else {
tween(slot, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
}
}
} else if (!draggedCharacter) {
// Hover effect for characters only when not dragging
var hoverCharacter = getCharacterAt(x, y);
for (var i = 0; i < characters.length; i++) {
var character = characters[i];
if (character === hoverCharacter && !character.isOnBoard) {
tween(character, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 100,
easing: tween.easeOut
});
} else if (!character.isOnBoard) {
tween(character, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
}
}
}
};
game.up = function (x, y, obj) {
if (draggedCharacter) {
var slot = getMixingSlotAt(x, y);
// Check if we're dropping on an empty slot
if (slot && slot.isEmpty) {
slot.addCharacter(draggedCharacter);
} else if (slot && !slot.isEmpty) {
// Handle swapping characters between slots
var swapCharacter = slot.character;
// Remove character from slot
slot.removeCharacter();
// Add dragged character to slot
slot.addCharacter(draggedCharacter);
// Return swapped character to original position
if (swapCharacter) swapCharacter.returnToOriginalPosition();
} else {
// Return to original position if not dropped on a valid slot
draggedCharacter.returnToOriginalPosition();
}
// Reset scale
tween(draggedCharacter, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeIn
});
draggedCharacter = null;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -634,8 +634,17 @@
duration: 1000,
easing: tween.linear
});
}
+ } else {
+ // Spin empty slots
+ var slotGraphics = slot.children[0];
+ tween(slotGraphics, {
+ rotation: slotGraphics.rotation + Math.PI * 2
+ }, {
+ duration: 1000,
+ easing: tween.linear
+ });
}
}
}, 1000);
// Instructions
oren_beat
Sound effect
horror_oren_beat
Sound effect
raddy_beat
Sound effect
horror_raddy_effect
Sound effect
wenda_voice
Sound effect
horror_wenda_voice
Sound effect
alt_horror_wenda_effect
Sound effect
jevin_voice
Sound effect
horror_jevin_voice
Sound effect
inky_effect
Sound effect
alt_horror_jevin_voice
Sound effect
horror_inky_effect
Sound effect
Cool_Guy_voice
Sound effect
horror_cool_guy_voice
Sound effect
lily_voice
Sound effect
horror_lily_voice
Sound effect
loaf_wenda_voice
Sound effect