User prompt
Do you expect us To be able to draw A perfect circle for twist it? Make twist it easier!
User prompt
I can't see the other 4 actions, Add them in and make the order random
Code edit (1 edits merged)
Please save this source code
User prompt
Bop It Challenge
Initial prompt
Make a game inspired by the Bop it with The Actions: Bop it, Twist it, Pull It, Flick it and spin it
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GameElement = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('centerElement', {
anchorX: 0.5,
anchorY: 0.5
});
self.originalColor = 0x4CAF50;
self.isActive = false;
self.currentCommand = '';
self.startAngle = 0;
self.isDragging = false;
self.dragStartX = 0;
self.dragStartY = 0;
self.originalX = 0;
self.originalY = 0;
self.setColor = function (color) {
graphics.tint = color;
};
self.flashCorrect = function () {
self.setColor(0x00FF00);
LK.setTimeout(function () {
self.setColor(self.originalColor);
}, 200);
};
self.flashWrong = function () {
self.setColor(0xFF0000);
LK.setTimeout(function () {
self.setColor(self.originalColor);
}, 500);
};
self.resetPosition = function () {
tween(self, {
x: self.originalX,
y: self.originalY,
rotation: 0
}, {
duration: 300
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2E2E2E
});
/****
* Game Code
****/
var commands = ['Bop it', 'Twist it', 'Pull it', 'Flick it', 'Spin it'];
var currentCommandIndex = 0;
var gameSpeed = 3000; // Starting time limit in ms
var isWaitingForAction = false;
var commandTimer = null;
var gameActive = false;
var lastGestureTime = 0;
var minGestureInterval = 100; // Minimum time between gestures
// Create main game element
var gameElement = game.addChild(new GameElement());
gameElement.x = 1024;
gameElement.y = 1366;
gameElement.originalX = gameElement.x;
gameElement.originalY = gameElement.y;
// Create command text
var commandText = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
commandText.anchor.set(0.5, 0.5);
commandText.x = 1024;
commandText.y = 800;
game.addChild(commandText);
// Create instruction text
var instructionText = new Text2('', {
size: 40,
fill: 0xCCCCCC
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 900;
game.addChild(instructionText);
// Create timer indicator
var timerBar = LK.getAsset('indicator', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 1
});
timerBar.x = 200;
timerBar.y = 400;
timerBar.tint = 0xFFFF00;
game.addChild(timerBar);
// Create score display
var scoreText = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Game state variables
var gestureStartX = 0;
var gestureStartY = 0;
var gestureStartAngle = 0;
var minSwipeDistance = 100;
var minCircularMotion = Math.PI;
function startNewCommand() {
if (!gameActive) return;
// Ensure we don't repeat the same command twice in a row
var newCommandIndex;
do {
newCommandIndex = Math.floor(Math.random() * commands.length);
} while (newCommandIndex === currentCommandIndex && commands.length > 1);
currentCommandIndex = newCommandIndex;
var command = commands[currentCommandIndex];
commandText.setText(command);
gameElement.currentCommand = command;
isWaitingForAction = true;
// Set instruction text based on command
var instruction = '';
switch (command) {
case 'Bop it':
instruction = 'Tap the circle!';
break;
case 'Twist it':
instruction = 'Move around it in a curve!';
break;
case 'Pull it':
instruction = 'Drag it away from center!';
break;
case 'Flick it':
instruction = 'Swipe across it quickly!';
break;
case 'Spin it':
instruction = 'Rotate it in a circle!';
break;
}
instructionText.setText(instruction);
// Start timer
var timerDuration = gameSpeed;
tween(timerBar, {
scaleX: 0
}, {
duration: timerDuration,
easing: tween.linear,
onFinish: function onFinish() {
if (isWaitingForAction) {
gameOver();
}
}
});
// Play tick sound
LK.getSound('tick').play();
}
function commandSuccess() {
if (!isWaitingForAction) return;
isWaitingForAction = false;
tween.stop(timerBar);
// Update score
LK.setScore(LK.getScore() + 1);
scoreText.setText(LK.getScore());
// Flash correct
gameElement.flashCorrect();
LK.getSound('correct').play();
// Increase difficulty
gameSpeed = Math.max(800, gameSpeed - 50);
// Reset timer bar
timerBar.scaleX = 20;
// Start next command after brief delay
LK.setTimeout(function () {
startNewCommand();
}, 500);
}
function commandFailed() {
if (!isWaitingForAction) return;
gameElement.flashWrong();
LK.getSound('wrong').play();
gameOver();
}
function gameOver() {
gameActive = false;
isWaitingForAction = false;
tween.stop(timerBar);
commandText.setText('Game Over!');
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
function startGame() {
gameActive = true;
LK.setScore(0);
scoreText.setText('0');
gameSpeed = 3000;
commandText.setText('Get Ready!');
LK.setTimeout(function () {
startNewCommand();
}, 1000);
}
// Distance calculation helper
function getDistance(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
// Angle calculation helper
function getAngle(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
// Check if point is inside game element
function isInsideElement(x, y) {
var distance = getDistance(x, y, gameElement.x, gameElement.y);
return distance <= 150; // Radius of game element
}
// Touch/mouse event handlers
game.down = function (x, y, obj) {
if (!gameActive || !isWaitingForAction) return;
var currentTime = Date.now();
if (currentTime - lastGestureTime < minGestureInterval) return;
if (isInsideElement(x, y)) {
gestureStartX = x;
gestureStartY = y;
gestureStartAngle = getAngle(gameElement.x, gameElement.y, x, y);
gameElement.isDragging = true;
// Check for "Bop it" command
if (gameElement.currentCommand === 'Bop it') {
lastGestureTime = currentTime;
commandSuccess();
}
}
};
game.move = function (x, y, obj) {
if (!gameActive || !isWaitingForAction || !gameElement.isDragging) return;
var currentTime = Date.now();
if (currentTime - lastGestureTime < minGestureInterval) return;
var deltaX = x - gestureStartX;
var deltaY = y - gestureStartY;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Check for "Pull it" command - drag outward from center
if (gameElement.currentCommand === 'Pull it' && distance > minSwipeDistance) {
gameElement.x = gameElement.originalX + deltaX * 0.3;
gameElement.y = gameElement.originalY + deltaY * 0.3;
lastGestureTime = currentTime;
commandSuccess();
return;
}
// Check for "Flick it" command - fast swipe in any direction
if (gameElement.currentCommand === 'Flick it' && distance > minSwipeDistance) {
lastGestureTime = currentTime;
commandSuccess();
return;
}
// Check for circular motion for "Twist it" and "Spin it"
var currentAngle = getAngle(gameElement.x, gameElement.y, x, y);
var angleDiff = Math.abs(currentAngle - gestureStartAngle);
if (angleDiff > Math.PI) {
angleDiff = 2 * Math.PI - angleDiff;
}
// "Twist it" - much easier circular motion detection (just need to move around the element a bit)
if (gameElement.currentCommand === 'Twist it' && distance > 50 && angleDiff > Math.PI * 0.2) {
lastGestureTime = currentTime;
commandSuccess();
return;
}
// "Spin it" - circular motion with visual rotation
if (gameElement.currentCommand === 'Spin it' && distance > 80 && angleDiff > minCircularMotion * 0.5) {
gameElement.rotation += angleDiff * 0.8;
lastGestureTime = currentTime;
commandSuccess();
return;
}
};
game.up = function (x, y, obj) {
if (gameElement.isDragging) {
gameElement.isDragging = false;
gameElement.resetPosition();
// If we're still waiting for action and released, it might be a failed gesture
if (isWaitingForAction && gameElement.currentCommand !== 'Bop it') {
var distance = getDistance(gestureStartX, gestureStartY, x, y);
if (distance < minSwipeDistance) {
commandFailed();
}
}
}
};
// Start the game
startGame(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GameElement = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('centerElement', {
anchorX: 0.5,
anchorY: 0.5
});
self.originalColor = 0x4CAF50;
self.isActive = false;
self.currentCommand = '';
self.startAngle = 0;
self.isDragging = false;
self.dragStartX = 0;
self.dragStartY = 0;
self.originalX = 0;
self.originalY = 0;
self.setColor = function (color) {
graphics.tint = color;
};
self.flashCorrect = function () {
self.setColor(0x00FF00);
LK.setTimeout(function () {
self.setColor(self.originalColor);
}, 200);
};
self.flashWrong = function () {
self.setColor(0xFF0000);
LK.setTimeout(function () {
self.setColor(self.originalColor);
}, 500);
};
self.resetPosition = function () {
tween(self, {
x: self.originalX,
y: self.originalY,
rotation: 0
}, {
duration: 300
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2E2E2E
});
/****
* Game Code
****/
var commands = ['Bop it', 'Twist it', 'Pull it', 'Flick it', 'Spin it'];
var currentCommandIndex = 0;
var gameSpeed = 3000; // Starting time limit in ms
var isWaitingForAction = false;
var commandTimer = null;
var gameActive = false;
var lastGestureTime = 0;
var minGestureInterval = 100; // Minimum time between gestures
// Create main game element
var gameElement = game.addChild(new GameElement());
gameElement.x = 1024;
gameElement.y = 1366;
gameElement.originalX = gameElement.x;
gameElement.originalY = gameElement.y;
// Create command text
var commandText = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
commandText.anchor.set(0.5, 0.5);
commandText.x = 1024;
commandText.y = 800;
game.addChild(commandText);
// Create instruction text
var instructionText = new Text2('', {
size: 40,
fill: 0xCCCCCC
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 900;
game.addChild(instructionText);
// Create timer indicator
var timerBar = LK.getAsset('indicator', {
anchorX: 0,
anchorY: 0.5,
scaleX: 20,
scaleY: 1
});
timerBar.x = 200;
timerBar.y = 400;
timerBar.tint = 0xFFFF00;
game.addChild(timerBar);
// Create score display
var scoreText = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Game state variables
var gestureStartX = 0;
var gestureStartY = 0;
var gestureStartAngle = 0;
var minSwipeDistance = 100;
var minCircularMotion = Math.PI;
function startNewCommand() {
if (!gameActive) return;
// Ensure we don't repeat the same command twice in a row
var newCommandIndex;
do {
newCommandIndex = Math.floor(Math.random() * commands.length);
} while (newCommandIndex === currentCommandIndex && commands.length > 1);
currentCommandIndex = newCommandIndex;
var command = commands[currentCommandIndex];
commandText.setText(command);
gameElement.currentCommand = command;
isWaitingForAction = true;
// Set instruction text based on command
var instruction = '';
switch (command) {
case 'Bop it':
instruction = 'Tap the circle!';
break;
case 'Twist it':
instruction = 'Move around it in a curve!';
break;
case 'Pull it':
instruction = 'Drag it away from center!';
break;
case 'Flick it':
instruction = 'Swipe across it quickly!';
break;
case 'Spin it':
instruction = 'Rotate it in a circle!';
break;
}
instructionText.setText(instruction);
// Start timer
var timerDuration = gameSpeed;
tween(timerBar, {
scaleX: 0
}, {
duration: timerDuration,
easing: tween.linear,
onFinish: function onFinish() {
if (isWaitingForAction) {
gameOver();
}
}
});
// Play tick sound
LK.getSound('tick').play();
}
function commandSuccess() {
if (!isWaitingForAction) return;
isWaitingForAction = false;
tween.stop(timerBar);
// Update score
LK.setScore(LK.getScore() + 1);
scoreText.setText(LK.getScore());
// Flash correct
gameElement.flashCorrect();
LK.getSound('correct').play();
// Increase difficulty
gameSpeed = Math.max(800, gameSpeed - 50);
// Reset timer bar
timerBar.scaleX = 20;
// Start next command after brief delay
LK.setTimeout(function () {
startNewCommand();
}, 500);
}
function commandFailed() {
if (!isWaitingForAction) return;
gameElement.flashWrong();
LK.getSound('wrong').play();
gameOver();
}
function gameOver() {
gameActive = false;
isWaitingForAction = false;
tween.stop(timerBar);
commandText.setText('Game Over!');
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
function startGame() {
gameActive = true;
LK.setScore(0);
scoreText.setText('0');
gameSpeed = 3000;
commandText.setText('Get Ready!');
LK.setTimeout(function () {
startNewCommand();
}, 1000);
}
// Distance calculation helper
function getDistance(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
// Angle calculation helper
function getAngle(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
// Check if point is inside game element
function isInsideElement(x, y) {
var distance = getDistance(x, y, gameElement.x, gameElement.y);
return distance <= 150; // Radius of game element
}
// Touch/mouse event handlers
game.down = function (x, y, obj) {
if (!gameActive || !isWaitingForAction) return;
var currentTime = Date.now();
if (currentTime - lastGestureTime < minGestureInterval) return;
if (isInsideElement(x, y)) {
gestureStartX = x;
gestureStartY = y;
gestureStartAngle = getAngle(gameElement.x, gameElement.y, x, y);
gameElement.isDragging = true;
// Check for "Bop it" command
if (gameElement.currentCommand === 'Bop it') {
lastGestureTime = currentTime;
commandSuccess();
}
}
};
game.move = function (x, y, obj) {
if (!gameActive || !isWaitingForAction || !gameElement.isDragging) return;
var currentTime = Date.now();
if (currentTime - lastGestureTime < minGestureInterval) return;
var deltaX = x - gestureStartX;
var deltaY = y - gestureStartY;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Check for "Pull it" command - drag outward from center
if (gameElement.currentCommand === 'Pull it' && distance > minSwipeDistance) {
gameElement.x = gameElement.originalX + deltaX * 0.3;
gameElement.y = gameElement.originalY + deltaY * 0.3;
lastGestureTime = currentTime;
commandSuccess();
return;
}
// Check for "Flick it" command - fast swipe in any direction
if (gameElement.currentCommand === 'Flick it' && distance > minSwipeDistance) {
lastGestureTime = currentTime;
commandSuccess();
return;
}
// Check for circular motion for "Twist it" and "Spin it"
var currentAngle = getAngle(gameElement.x, gameElement.y, x, y);
var angleDiff = Math.abs(currentAngle - gestureStartAngle);
if (angleDiff > Math.PI) {
angleDiff = 2 * Math.PI - angleDiff;
}
// "Twist it" - much easier circular motion detection (just need to move around the element a bit)
if (gameElement.currentCommand === 'Twist it' && distance > 50 && angleDiff > Math.PI * 0.2) {
lastGestureTime = currentTime;
commandSuccess();
return;
}
// "Spin it" - circular motion with visual rotation
if (gameElement.currentCommand === 'Spin it' && distance > 80 && angleDiff > minCircularMotion * 0.5) {
gameElement.rotation += angleDiff * 0.8;
lastGestureTime = currentTime;
commandSuccess();
return;
}
};
game.up = function (x, y, obj) {
if (gameElement.isDragging) {
gameElement.isDragging = false;
gameElement.resetPosition();
// If we're still waiting for action and released, it might be a failed gesture
if (isWaitingForAction && gameElement.currentCommand !== 'Bop it') {
var distance = getDistance(gestureStartX, gestureStartY, x, y);
if (distance < minSwipeDistance) {
commandFailed();
}
}
}
};
// Start the game
startGame();