/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Button = Container.expand(function (text, assetType) { var self = Container.call(this); var buttonGraphics = self.attachAsset(assetType, { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2(text, { size: 30, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.down = function (x, y, obj) { LK.getSound('select').play(); tween(buttonGraphics, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(buttonGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeIn }); } }); if (text === 'Back') { switchToSelectionMode(); } }; return self; }); var Character = Container.expand(function (characterType) { var self = Container.call(this); self.characterType = characterType; self.isAnimating = false; var characterGraphics = self.attachAsset(characterType, { anchorX: 0.5, anchorY: 0.5 }); // Character name text var nameText = new Text2(characterType.charAt(0).toUpperCase() + characterType.slice(1), { size: 60, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.y = 250; self.addChild(nameText); self.animateSelection = function () { if (self.isAnimating) return; self.isAnimating = true; 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, onFinish: function onFinish() { self.isAnimating = false; } }); } }); }; self.down = function (x, y, obj) { if (gameState === 'selection') { LK.getSound('select').play(); self.animateSelection(); selectedCharacter = self.characterType; LK.setTimeout(function () { switchToGameMode(); }, 400); } else if (gameState === 'playing' && self.characterType === selectedCharacter) { performHulaHoopTrick(); } }; return self; }); var HulaHoop = Container.expand(function () { var self = Container.call(this); self.momentum = 1.0; self.rotationSpeed = 0.1; self.isActive = false; var hoopGraphics = self.attachAsset('hulaHoop', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { if (self.isActive) { hoopGraphics.rotation += self.rotationSpeed * self.momentum; // Gradually decrease momentum self.momentum *= 0.995; // Update rotation speed based on momentum self.rotationSpeed = 0.05 + self.momentum * 0.15; // Check if momentum is too low if (self.momentum < 0.3) { self.momentum = 0.3; // Slow down the hoop when momentum is low self.rotationSpeed = 0.02; } } }; self.boost = function () { self.momentum = Math.min(self.momentum + 0.4, 2.0); // Visual effect for boost tween(hoopGraphics, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(hoopGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeIn }); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2e2e2e }); /**** * Game Code ****/ var gameState = 'selection'; // 'selection' or 'playing' var selectedCharacter = null; var characters = []; var gameCharacter = null; var hulaHoop = null; var backButton = null; var scoreTxt = null; var comboCount = 0; var lastTapTime = 0; // Create title text var titleText = new Text2('Hula Hoop Stars', { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 400; game.addChild(titleText); // Create subtitle text var subtitleText = new Text2('Choose Your Character', { size: 60, fill: 0xCCCCCC }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 2048 / 2; subtitleText.y = 550; game.addChild(subtitleText); // Create characters for selection var characterTypes = ['blossom', 'buttercup', 'bliss']; var characterPositions = [{ x: 2048 / 2 - 400, y: 1200 }, { x: 2048 / 2, y: 1200 }, { x: 2048 / 2 + 400, y: 1200 }]; for (var i = 0; i < characterTypes.length; i++) { var character = new Character(characterTypes[i]); character.x = characterPositions[i].x; character.y = characterPositions[i].y; characters.push(character); game.addChild(character); } // Create score display scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.visible = false; LK.gui.top.addChild(scoreTxt); function switchToGameMode() { gameState = 'playing'; // Hide selection elements titleText.visible = false; subtitleText.visible = false; for (var i = 0; i < characters.length; i++) { characters[i].visible = false; } // Create game character gameCharacter = new Character(selectedCharacter); gameCharacter.x = 2048 / 2; gameCharacter.y = 1400; game.addChild(gameCharacter); // Create hula hoop hulaHoop = new HulaHoop(); hulaHoop.x = 2048 / 2; hulaHoop.y = 1400; hulaHoop.isActive = true; game.addChild(hulaHoop); // Create back button backButton = new Button('Back', 'backButton'); backButton.x = 150; backButton.y = 100; game.addChild(backButton); // Show score scoreTxt.visible = true; scoreTxt.setText('Score: ' + LK.getScore()); // Reset game variables comboCount = 0; lastTapTime = 0; } function switchToSelectionMode() { gameState = 'selection'; // Show selection elements titleText.visible = true; subtitleText.visible = true; for (var i = 0; i < characters.length; i++) { characters[i].visible = true; } // Hide/destroy game elements if (gameCharacter) { gameCharacter.destroy(); gameCharacter = null; } if (hulaHoop) { hulaHoop.destroy(); hulaHoop = null; } if (backButton) { backButton.destroy(); backButton = null; } // Hide score scoreTxt.visible = false; selectedCharacter = null; } function performHulaHoopTrick() { var currentTime = LK.ticks; var timeSinceLastTap = currentTime - lastTapTime; // Check for combo timing (within 30-90 ticks for good timing) if (timeSinceLastTap >= 30 && timeSinceLastTap <= 90) { comboCount++; LK.getSound('success').play(); // Bonus points for combos var points = 10 + comboCount * 5; LK.setScore(LK.getScore() + points); } else { comboCount = 0; LK.getSound('whoosh').play(); LK.setScore(LK.getScore() + 5); } lastTapTime = currentTime; // Boost hula hoop momentum if (hulaHoop) { hulaHoop.boost(); } // Update score display scoreTxt.setText('Score: ' + LK.getScore()); // Character animation if (gameCharacter) { var characterGraphics = gameCharacter.children[0]; tween(characterGraphics, { scaleX: 1.1, scaleY: 0.9 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(characterGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150, easing: tween.easeIn }); } }); } } game.update = function () { if (gameState === 'playing' && hulaHoop) { // Check if hula hoop momentum is too low for too long if (hulaHoop.momentum <= 0.3) { // Game gets harder over time - if player doesn't tap, they lose var timeSinceLastTap = LK.ticks - lastTapTime; if (timeSinceLastTap > 180) { // 3 seconds at 60fps LK.showGameOver(); } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Button = Container.expand(function (text, assetType) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset(assetType, {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(text, {
size: 30,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.down = function (x, y, obj) {
LK.getSound('select').play();
tween(buttonGraphics, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(buttonGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
if (text === 'Back') {
switchToSelectionMode();
}
};
return self;
});
var Character = Container.expand(function (characterType) {
var self = Container.call(this);
self.characterType = characterType;
self.isAnimating = false;
var characterGraphics = self.attachAsset(characterType, {
anchorX: 0.5,
anchorY: 0.5
});
// Character name text
var nameText = new Text2(characterType.charAt(0).toUpperCase() + characterType.slice(1), {
size: 60,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = 250;
self.addChild(nameText);
self.animateSelection = function () {
if (self.isAnimating) return;
self.isAnimating = true;
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,
onFinish: function onFinish() {
self.isAnimating = false;
}
});
}
});
};
self.down = function (x, y, obj) {
if (gameState === 'selection') {
LK.getSound('select').play();
self.animateSelection();
selectedCharacter = self.characterType;
LK.setTimeout(function () {
switchToGameMode();
}, 400);
} else if (gameState === 'playing' && self.characterType === selectedCharacter) {
performHulaHoopTrick();
}
};
return self;
});
var HulaHoop = Container.expand(function () {
var self = Container.call(this);
self.momentum = 1.0;
self.rotationSpeed = 0.1;
self.isActive = false;
var hoopGraphics = self.attachAsset('hulaHoop', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.isActive) {
hoopGraphics.rotation += self.rotationSpeed * self.momentum;
// Gradually decrease momentum
self.momentum *= 0.995;
// Update rotation speed based on momentum
self.rotationSpeed = 0.05 + self.momentum * 0.15;
// Check if momentum is too low
if (self.momentum < 0.3) {
self.momentum = 0.3;
// Slow down the hoop when momentum is low
self.rotationSpeed = 0.02;
}
}
};
self.boost = function () {
self.momentum = Math.min(self.momentum + 0.4, 2.0);
// Visual effect for boost
tween(hoopGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(hoopGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2e2e2e
});
/****
* Game Code
****/
var gameState = 'selection'; // 'selection' or 'playing'
var selectedCharacter = null;
var characters = [];
var gameCharacter = null;
var hulaHoop = null;
var backButton = null;
var scoreTxt = null;
var comboCount = 0;
var lastTapTime = 0;
// Create title text
var titleText = new Text2('Hula Hoop Stars', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 400;
game.addChild(titleText);
// Create subtitle text
var subtitleText = new Text2('Choose Your Character', {
size: 60,
fill: 0xCCCCCC
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 2048 / 2;
subtitleText.y = 550;
game.addChild(subtitleText);
// Create characters for selection
var characterTypes = ['blossom', 'buttercup', 'bliss'];
var characterPositions = [{
x: 2048 / 2 - 400,
y: 1200
}, {
x: 2048 / 2,
y: 1200
}, {
x: 2048 / 2 + 400,
y: 1200
}];
for (var i = 0; i < characterTypes.length; i++) {
var character = new Character(characterTypes[i]);
character.x = characterPositions[i].x;
character.y = characterPositions[i].y;
characters.push(character);
game.addChild(character);
}
// Create score display
scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
function switchToGameMode() {
gameState = 'playing';
// Hide selection elements
titleText.visible = false;
subtitleText.visible = false;
for (var i = 0; i < characters.length; i++) {
characters[i].visible = false;
}
// Create game character
gameCharacter = new Character(selectedCharacter);
gameCharacter.x = 2048 / 2;
gameCharacter.y = 1400;
game.addChild(gameCharacter);
// Create hula hoop
hulaHoop = new HulaHoop();
hulaHoop.x = 2048 / 2;
hulaHoop.y = 1400;
hulaHoop.isActive = true;
game.addChild(hulaHoop);
// Create back button
backButton = new Button('Back', 'backButton');
backButton.x = 150;
backButton.y = 100;
game.addChild(backButton);
// Show score
scoreTxt.visible = true;
scoreTxt.setText('Score: ' + LK.getScore());
// Reset game variables
comboCount = 0;
lastTapTime = 0;
}
function switchToSelectionMode() {
gameState = 'selection';
// Show selection elements
titleText.visible = true;
subtitleText.visible = true;
for (var i = 0; i < characters.length; i++) {
characters[i].visible = true;
}
// Hide/destroy game elements
if (gameCharacter) {
gameCharacter.destroy();
gameCharacter = null;
}
if (hulaHoop) {
hulaHoop.destroy();
hulaHoop = null;
}
if (backButton) {
backButton.destroy();
backButton = null;
}
// Hide score
scoreTxt.visible = false;
selectedCharacter = null;
}
function performHulaHoopTrick() {
var currentTime = LK.ticks;
var timeSinceLastTap = currentTime - lastTapTime;
// Check for combo timing (within 30-90 ticks for good timing)
if (timeSinceLastTap >= 30 && timeSinceLastTap <= 90) {
comboCount++;
LK.getSound('success').play();
// Bonus points for combos
var points = 10 + comboCount * 5;
LK.setScore(LK.getScore() + points);
} else {
comboCount = 0;
LK.getSound('whoosh').play();
LK.setScore(LK.getScore() + 5);
}
lastTapTime = currentTime;
// Boost hula hoop momentum
if (hulaHoop) {
hulaHoop.boost();
}
// Update score display
scoreTxt.setText('Score: ' + LK.getScore());
// Character animation
if (gameCharacter) {
var characterGraphics = gameCharacter.children[0];
tween(characterGraphics, {
scaleX: 1.1,
scaleY: 0.9
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(characterGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 150,
easing: tween.easeIn
});
}
});
}
}
game.update = function () {
if (gameState === 'playing' && hulaHoop) {
// Check if hula hoop momentum is too low for too long
if (hulaHoop.momentum <= 0.3) {
// Game gets harder over time - if player doesn't tap, they lose
var timeSinceLastTap = LK.ticks - lastTapTime;
if (timeSinceLastTap > 180) {
// 3 seconds at 60fps
LK.showGameOver();
}
}
}
};