/****
* 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();
}
}
}
};