User prompt
Kısa tiklamayla gear olusturma.
User prompt
Gear ekledigimde ona ait sesi surekli çal. Gear tek kısa tıklamayla silinsin ve sesi sussun.
User prompt
Herbir gear çeşidi icin bir ses ekle
User prompt
Sesler gear olduğu surece surekli tekrar etsin.
User prompt
Gearin üstüne cift tıklayinca gear silinsin ve ses sussun.
User prompt
5 farklı gear için 5 farkli ses ekle
User prompt
5 farklı gear için 5 farkli ses ekle
User prompt
Tümünü 2 kat büyüt.
User prompt
dişli dişi yerine sadece dişli ifadesini kullan tüm isimleri değiştir
User prompt
5 farklı dişli asset olsun.
User prompt
Üst üste gelmesinler dişli içini kaldır. Büyüklük dokunma süresiyle orantılı olsun.
User prompt
Dişliler her defasında farklı boyut olsun. 5 farklı dönme sesi ekle
Code edit (1 edits merged)
Please save this source code
User prompt
Dönen Dişliler
Initial prompt
Tıkladıkca dişli ekleyeyim. Oluşan dişli çevirdiğim tarafa sürekli dönsün.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Gear class: represents a single gear that rotates in a given direction and speed var Gear = Container.expand(function () { var self = Container.call(this); // Randomly select one of 5 gear assets var gearAssetIdx = Math.floor(Math.random() * 5) + 1; var gear = self.attachAsset('gear' + gearAssetIdx, { anchorX: 0.5, anchorY: 0.5 }); // Assign unique sound for this gear type // Ensure gear5 uses the correct unique sound asset if (gearAssetIdx === 5) { self._sound = LK.getSound('gearRotate5'); self._soundName = 'gearRotate5'; } else { self._sound = LK.getSound('gearRotate' + gearAssetIdx); self._soundName = 'gearRotate' + gearAssetIdx; } self._gearAssetIdx = gearAssetIdx; // Set up default size for asset (will be overridden externally) gear.width = 270 * 2; gear.height = 270 * 2; // Rotation speed in radians per frame (set externally) self.rotationSpeed = 0; // Removed all gear sound logic // Update method: rotates the gear self.update = function () { // Track last rotation for step detection if (typeof self._lastRotation === "undefined") { self._lastRotation = self.rotation; } self.rotation += self.rotationSpeed; // Play unique sound for this gear type on each full step (e.g. every 1/12 turn) var step = Math.PI / 6; // 30 degrees per step var lastStep = Math.floor(self._lastRotation / step); var currentStep = Math.floor(self.rotation / step); if (self.rotationSpeed !== 0 && self._sound && lastStep !== currentStep) { // Only play sound if at least one gear of this type is present on screen var found = false; for (var i = 0; i < gears.length; i++) { if (gears[i] && gears[i]._gearAssetIdx === self._gearAssetIdx) { found = true; break; } } if (found) { self._sound.play(); } // Score logic: Only update score when a half rotation is completed if (typeof score !== "undefined" && typeof scoreTxt !== "undefined") { // Track completed half turns if (typeof self._lastHalfTurns === "undefined") { self._lastHalfTurns = Math.floor(self._lastRotation / Math.PI); } var currentHalfTurns = Math.floor(self.rotation / Math.PI); if (currentHalfTurns !== self._lastHalfTurns) { // Only update score when a half rotation is completed if (self.rotationSpeed > 0) { score += 1; } else if (self.rotationSpeed < 0) { score -= 1; } animateScoreTo(score); self._lastHalfTurns = currentHalfTurns; } } } self._lastRotation = self.rotation; }; // Handle down event for single tap: remove gear and stop sound self.down = function (x, y, obj) { // Stop the unique sound for this gear if playing if (self._sound && typeof self._sound.stop === "function") { self._sound.stop(); self._soundPlaying = false; } // Remove from game and gears array if (self.parent) { self.parent.removeChild(self); } for (var i = 0; i < gears.length; i++) { if (gears[i] === self) { gears.splice(i, 1); break; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xffffff // White background for clarity }); /**** * Game Code ****/ // We need tween for smooth rotation animations // Add background image (covers the whole game area) var bg = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(bg); // --- Animated gear at game start --- // Add finger asset for swipe animation var introGear = new Gear(); introGear.x = 2048 / 2; introGear.y = 2732 / 2; introGear.rotation = 0; introGear.rotationSpeed = 0; introGear.children[0].width = 900; introGear.children[0].height = 900; introGear.alpha = 0; game.addChild(introGear); var finger = LK.getAsset('finger', { anchorX: 0.5, anchorY: 0.5, width: 320, height: 320, x: introGear.x - 300, y: introGear.y + 350, alpha: 0 }); game.addChild(finger); // Animate: finger and gear intro at the same time (parallel animation), but start after 1 second delay LK.setTimeout(function () { // Determine direction based on targetSign var fingerStartX, fingerEndX; if (targetSign < 0) { // Right to left fingerStartX = introGear.x + 300; fingerEndX = introGear.x - 200; } else { // Left to right (default) fingerStartX = introGear.x - 300; fingerEndX = introGear.x + 200; } finger.x = fingerStartX; tween(finger, { alpha: 1 }, { duration: 200, onFinish: function onFinish() { // Start finger swipe and gear animation in parallel tween(finger, { x: fingerEndX }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(finger, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { if (finger.parent) finger.parent.removeChild(finger); } }); } }); // Start gear animation at the same time as finger swipe tween(introGear, { alpha: 1, scaleX: 1.2, scaleY: 1.2, rotation: targetSign < 0 ? -Math.PI * 2 : Math.PI * 2 // Animate right-to-left if negative }, { duration: 900, easing: tween.easeOut, onFinish: function onFinish() { // Fade out gear after animation tween(introGear, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { if (introGear.parent) introGear.parent.removeChild(introGear); } }); } }); } }); }, 1000); // Play background music for the whole game LK.playMusic('backgroundSong'); // List of all gears in the game var gears = []; // Score variable and score text var score = 0; var displayScore = 0; var scoreTween = null; function formatScore(val) { var s = Math.abs(Math.round(val)).toString().padStart(4, "0"); return (val < 0 ? "-" : "") + s; } // Add random target to top left at game start var targetSign = Math.random() < 0.5 ? -1 : 1; var targetValue = Math.floor(Math.random() * 10000); // 0 to 9999 var targetText = (targetSign < 0 ? "-" : "") + targetValue.toString().padStart(4, "0"); var targetTxt = new Text2(targetText, { size: 150, fill: 0xFFD600 // yellow }); targetTxt.anchor.set(0, 0); // top left LK.gui.topLeft.addChild(targetTxt); // Place with margin to avoid menu icon targetTxt.x = 410; targetTxt.y = 10; var scoreTxt = new Text2(formatScore(displayScore), { size: 170, fill: 0xFFFFFF }); // Anchor to top right scoreTxt.anchor.set(1, 0); // right-top LK.gui.topRight.addChild(scoreTxt); // Place at top right, with a small margin from the edge scoreTxt.x = -40; scoreTxt.y = 10; // Helper: animate score change smoothly, one by one function animateScoreTo(target) { if (scoreTween) { tween.stop(scoreTween); scoreTween = null; } var start = displayScore; var end = target; if (start === end) { displayScore = end; scoreTxt.setText(formatScore(displayScore)); return; } var step = start < end ? 1 : -1; var steps = Math.abs(end - start); var durationPerStep = 30; // ms per step, adjust for speed var current = start; function stepTween() { if (current === end) { scoreTween = null; return; } current += step; displayScore = current; scoreTxt.setText(formatScore(displayScore)); scoreTween = LK.setTimeout(stepTween, durationPerStep); } stepTween(); } // For drag/hold/tap detection var dragStart = null; // {x, y, t} var dragCurrent = null; // {x, y} var dragTimer = null; var dragHold = false; var dragGearPreview = null; var dragPreviewGearType = 1; // type of gear to preview/create this drag var dragDirection = 1; // 1: CW, -1: CCW var dragSize = 240; // default var tapThreshold = 200; // ms var holdThreshold = 220; // ms var minGear = 120, // 2x smaller than before maxGear = 390 * 4; //{G} // Allow up to 2x larger gears // Helper: calculate angle between two points (in radians) function getAngle(x1, y1, x2, y2) { return Math.atan2(y2 - y1, x2 - x1); } // Helper: clamp rotation speed function clamp(val, min, max) { if (val < min) return min; if (val > max) return max; return val; } // Helper: find gear at (x, y) function findGearAt(x, y) { for (var i = 0; i < gears.length; i++) { var g = gears[i]; var dx = g.x - x; var dy = g.y - y; var r = g.children[0].width / 2; if (dx * dx + dy * dy <= r * r) return g; } return null; } // On press down: start drag/tap/hold detection game.down = function (x, y, obj) { dragStart = { x: x, y: y, t: Date.now() }; dragCurrent = { x: x, y: y }; dragHold = false; dragDirection = 1; // Default size is mid-way between min and max dragSize = (minGear + maxGear) / 2; // If tap on existing gear, mark for possible removal var gear = findGearAt(x, y); if (gear) { dragGearPreview = gear; return; } // Start hold timer for gear creation dragTimer = LK.setTimeout(function () { dragHold = true; // Show preview gear // Pick a random gear type and remember it for this drag dragPreviewGearType = Math.floor(Math.random() * 5) + 1; dragGearPreview = new Gear(); dragGearPreview.x = dragStart.x; dragGearPreview.y = dragStart.y; dragGearPreview.rotationSpeed = 0; dragGearPreview.children[0].width = dragSize; dragGearPreview.children[0].height = dragSize; dragGearPreview.alpha = 0.5; // Replace the gear asset with the selected type if (dragGearPreview.children.length > 0) { dragGearPreview.removeChild(dragGearPreview.children[0]); } var previewAsset = dragGearPreview.attachAsset('gear' + dragPreviewGearType, { anchorX: 0.5, anchorY: 0.5 }); previewAsset.width = dragSize; previewAsset.height = dragSize; game.addChild(dragGearPreview); }, holdThreshold); }; // On move: update drag current position, update preview gear size/direction game.move = function (x, y, obj) { if (!dragStart) return; dragCurrent.x = x; dragCurrent.y = y; if (dragHold && dragGearPreview) { // Calculate drag vector var dx = dragCurrent.x - dragStart.x; var dy = dragCurrent.y - dragStart.y; var dist = Math.sqrt(dx * dx + dy * dy); // Size: proportional to drag distance, clamp to min/max // Map drag distance from 0..(max possible) to minGear..maxGear // Let's use up to 900px drag for full range (since maxGear is now 2x larger) var maxDragDist = 900; var size = clamp(minGear + (maxGear - minGear) * Math.min(dist, maxDragDist) / maxDragDist, minGear, maxGear); dragSize = size; dragGearPreview.children[0].width = size; dragGearPreview.children[0].height = size; // Direction: right is CW, left is CCW dragDirection = dx >= 0 ? 1 : -1; dragGearPreview.scale.x = dragDirection; // No speed text shown during drag preview } }; // On release: decide tap/hold/drag action game.up = function (x, y, obj) { if (dragTimer) { LK.clearTimeout(dragTimer); dragTimer = null; } var now = Date.now(); var dt = now - (dragStart ? dragStart.t : now); // Tap on existing gear: remove it if (dragGearPreview && gears.indexOf(dragGearPreview) !== -1) { // Remove gear if (dragGearPreview.parent) dragGearPreview.parent.removeChild(dragGearPreview); var idx = gears.indexOf(dragGearPreview); if (idx !== -1) gears.splice(idx, 1); dragGearPreview = null; dragStart = null; return; } // Short tap: do nothing (no gear created) if (!dragHold && dt < tapThreshold) { // No speed text to remove dragStart = null; dragGearPreview = null; return; } // Hold/drag: create gear at dragStart, with size/direction if (dragHold && dragGearPreview) { // No speed text to remove // Remove preview if (dragGearPreview.parent) dragGearPreview.parent.removeChild(dragGearPreview); dragGearPreview = null; // Prevent overlapping: check if new gear would overlap any existing gear var overlap = false; for (var i = 0; i < gears.length; i++) { var other = gears[i]; var dxg = dragStart.x - other.x; var dyg = dragStart.y - other.y; var distg = Math.sqrt(dxg * dxg + dyg * dyg); var otherGear = other.children[0].width; if (distg < (dragSize + otherGear) / 2 + 10) { overlap = true; break; } } if (!overlap) { var gear = new Gear(); gear.x = dragStart.x; gear.y = dragStart.y; // Assign random speed between 0.01 and 0.06, use dragDirection for direction var minSpeed = 0.01, maxSpeed = 0.06; var randomSpeed = minSpeed + Math.random() * (maxSpeed - minSpeed); gear.rotationSpeed = randomSpeed * dragDirection; // Replace the gear asset with the previewed type if (gear.children.length > 0) { gear.removeChild(gear.children[0]); } var asset = gear.attachAsset('gear' + dragPreviewGearType, { anchorX: 0.5, anchorY: 0.5 }); asset.width = dragSize; asset.height = dragSize; // Set correct sound for this gear type if (dragPreviewGearType === 5) { gear._sound = LK.getSound('gearRotate5'); gear._soundName = 'gearRotate5'; } else { gear._sound = LK.getSound('gearRotate' + dragPreviewGearType); gear._soundName = 'gearRotate' + dragPreviewGearType; } gear._gearAssetIdx = dragPreviewGearType; game.addChild(gear); gears.push(gear); } } dragStart = null; dragGearPreview = null; }; // Update loop: update all gears game.update = function () { for (var i = 0; i < gears.length; i++) { if (gears[i].update) { gears[i].update(); } } // Check win condition: score is greater than or equal to target (with sign) if (targetSign > 0 && score >= targetValue || targetSign < 0 && score <= -targetValue) { LK.showYouWin(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Gear class: represents a single gear that rotates in a given direction and speed
var Gear = Container.expand(function () {
var self = Container.call(this);
// Randomly select one of 5 gear assets
var gearAssetIdx = Math.floor(Math.random() * 5) + 1;
var gear = self.attachAsset('gear' + gearAssetIdx, {
anchorX: 0.5,
anchorY: 0.5
});
// Assign unique sound for this gear type
// Ensure gear5 uses the correct unique sound asset
if (gearAssetIdx === 5) {
self._sound = LK.getSound('gearRotate5');
self._soundName = 'gearRotate5';
} else {
self._sound = LK.getSound('gearRotate' + gearAssetIdx);
self._soundName = 'gearRotate' + gearAssetIdx;
}
self._gearAssetIdx = gearAssetIdx;
// Set up default size for asset (will be overridden externally)
gear.width = 270 * 2;
gear.height = 270 * 2;
// Rotation speed in radians per frame (set externally)
self.rotationSpeed = 0;
// Removed all gear sound logic
// Update method: rotates the gear
self.update = function () {
// Track last rotation for step detection
if (typeof self._lastRotation === "undefined") {
self._lastRotation = self.rotation;
}
self.rotation += self.rotationSpeed;
// Play unique sound for this gear type on each full step (e.g. every 1/12 turn)
var step = Math.PI / 6; // 30 degrees per step
var lastStep = Math.floor(self._lastRotation / step);
var currentStep = Math.floor(self.rotation / step);
if (self.rotationSpeed !== 0 && self._sound && lastStep !== currentStep) {
// Only play sound if at least one gear of this type is present on screen
var found = false;
for (var i = 0; i < gears.length; i++) {
if (gears[i] && gears[i]._gearAssetIdx === self._gearAssetIdx) {
found = true;
break;
}
}
if (found) {
self._sound.play();
}
// Score logic: Only update score when a half rotation is completed
if (typeof score !== "undefined" && typeof scoreTxt !== "undefined") {
// Track completed half turns
if (typeof self._lastHalfTurns === "undefined") {
self._lastHalfTurns = Math.floor(self._lastRotation / Math.PI);
}
var currentHalfTurns = Math.floor(self.rotation / Math.PI);
if (currentHalfTurns !== self._lastHalfTurns) {
// Only update score when a half rotation is completed
if (self.rotationSpeed > 0) {
score += 1;
} else if (self.rotationSpeed < 0) {
score -= 1;
}
animateScoreTo(score);
self._lastHalfTurns = currentHalfTurns;
}
}
}
self._lastRotation = self.rotation;
};
// Handle down event for single tap: remove gear and stop sound
self.down = function (x, y, obj) {
// Stop the unique sound for this gear if playing
if (self._sound && typeof self._sound.stop === "function") {
self._sound.stop();
self._soundPlaying = false;
}
// Remove from game and gears array
if (self.parent) {
self.parent.removeChild(self);
}
for (var i = 0; i < gears.length; i++) {
if (gears[i] === self) {
gears.splice(i, 1);
break;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xffffff // White background for clarity
});
/****
* Game Code
****/
// We need tween for smooth rotation animations
// Add background image (covers the whole game area)
var bg = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(bg);
// --- Animated gear at game start ---
// Add finger asset for swipe animation
var introGear = new Gear();
introGear.x = 2048 / 2;
introGear.y = 2732 / 2;
introGear.rotation = 0;
introGear.rotationSpeed = 0;
introGear.children[0].width = 900;
introGear.children[0].height = 900;
introGear.alpha = 0;
game.addChild(introGear);
var finger = LK.getAsset('finger', {
anchorX: 0.5,
anchorY: 0.5,
width: 320,
height: 320,
x: introGear.x - 300,
y: introGear.y + 350,
alpha: 0
});
game.addChild(finger);
// Animate: finger and gear intro at the same time (parallel animation), but start after 1 second delay
LK.setTimeout(function () {
// Determine direction based on targetSign
var fingerStartX, fingerEndX;
if (targetSign < 0) {
// Right to left
fingerStartX = introGear.x + 300;
fingerEndX = introGear.x - 200;
} else {
// Left to right (default)
fingerStartX = introGear.x - 300;
fingerEndX = introGear.x + 200;
}
finger.x = fingerStartX;
tween(finger, {
alpha: 1
}, {
duration: 200,
onFinish: function onFinish() {
// Start finger swipe and gear animation in parallel
tween(finger, {
x: fingerEndX
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(finger, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
if (finger.parent) finger.parent.removeChild(finger);
}
});
}
});
// Start gear animation at the same time as finger swipe
tween(introGear, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2,
rotation: targetSign < 0 ? -Math.PI * 2 : Math.PI * 2 // Animate right-to-left if negative
}, {
duration: 900,
easing: tween.easeOut,
onFinish: function onFinish() {
// Fade out gear after animation
tween(introGear, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
if (introGear.parent) introGear.parent.removeChild(introGear);
}
});
}
});
}
});
}, 1000);
// Play background music for the whole game
LK.playMusic('backgroundSong');
// List of all gears in the game
var gears = [];
// Score variable and score text
var score = 0;
var displayScore = 0;
var scoreTween = null;
function formatScore(val) {
var s = Math.abs(Math.round(val)).toString().padStart(4, "0");
return (val < 0 ? "-" : "") + s;
}
// Add random target to top left at game start
var targetSign = Math.random() < 0.5 ? -1 : 1;
var targetValue = Math.floor(Math.random() * 10000); // 0 to 9999
var targetText = (targetSign < 0 ? "-" : "") + targetValue.toString().padStart(4, "0");
var targetTxt = new Text2(targetText, {
size: 150,
fill: 0xFFD600 // yellow
});
targetTxt.anchor.set(0, 0); // top left
LK.gui.topLeft.addChild(targetTxt);
// Place with margin to avoid menu icon
targetTxt.x = 410;
targetTxt.y = 10;
var scoreTxt = new Text2(formatScore(displayScore), {
size: 170,
fill: 0xFFFFFF
});
// Anchor to top right
scoreTxt.anchor.set(1, 0); // right-top
LK.gui.topRight.addChild(scoreTxt);
// Place at top right, with a small margin from the edge
scoreTxt.x = -40;
scoreTxt.y = 10;
// Helper: animate score change smoothly, one by one
function animateScoreTo(target) {
if (scoreTween) {
tween.stop(scoreTween);
scoreTween = null;
}
var start = displayScore;
var end = target;
if (start === end) {
displayScore = end;
scoreTxt.setText(formatScore(displayScore));
return;
}
var step = start < end ? 1 : -1;
var steps = Math.abs(end - start);
var durationPerStep = 30; // ms per step, adjust for speed
var current = start;
function stepTween() {
if (current === end) {
scoreTween = null;
return;
}
current += step;
displayScore = current;
scoreTxt.setText(formatScore(displayScore));
scoreTween = LK.setTimeout(stepTween, durationPerStep);
}
stepTween();
}
// For drag/hold/tap detection
var dragStart = null; // {x, y, t}
var dragCurrent = null; // {x, y}
var dragTimer = null;
var dragHold = false;
var dragGearPreview = null;
var dragPreviewGearType = 1; // type of gear to preview/create this drag
var dragDirection = 1; // 1: CW, -1: CCW
var dragSize = 240; // default
var tapThreshold = 200; // ms
var holdThreshold = 220; // ms
var minGear = 120,
// 2x smaller than before
maxGear = 390 * 4; //{G} // Allow up to 2x larger gears
// Helper: calculate angle between two points (in radians)
function getAngle(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
}
// Helper: clamp rotation speed
function clamp(val, min, max) {
if (val < min) return min;
if (val > max) return max;
return val;
}
// Helper: find gear at (x, y)
function findGearAt(x, y) {
for (var i = 0; i < gears.length; i++) {
var g = gears[i];
var dx = g.x - x;
var dy = g.y - y;
var r = g.children[0].width / 2;
if (dx * dx + dy * dy <= r * r) return g;
}
return null;
}
// On press down: start drag/tap/hold detection
game.down = function (x, y, obj) {
dragStart = {
x: x,
y: y,
t: Date.now()
};
dragCurrent = {
x: x,
y: y
};
dragHold = false;
dragDirection = 1;
// Default size is mid-way between min and max
dragSize = (minGear + maxGear) / 2;
// If tap on existing gear, mark for possible removal
var gear = findGearAt(x, y);
if (gear) {
dragGearPreview = gear;
return;
}
// Start hold timer for gear creation
dragTimer = LK.setTimeout(function () {
dragHold = true;
// Show preview gear
// Pick a random gear type and remember it for this drag
dragPreviewGearType = Math.floor(Math.random() * 5) + 1;
dragGearPreview = new Gear();
dragGearPreview.x = dragStart.x;
dragGearPreview.y = dragStart.y;
dragGearPreview.rotationSpeed = 0;
dragGearPreview.children[0].width = dragSize;
dragGearPreview.children[0].height = dragSize;
dragGearPreview.alpha = 0.5;
// Replace the gear asset with the selected type
if (dragGearPreview.children.length > 0) {
dragGearPreview.removeChild(dragGearPreview.children[0]);
}
var previewAsset = dragGearPreview.attachAsset('gear' + dragPreviewGearType, {
anchorX: 0.5,
anchorY: 0.5
});
previewAsset.width = dragSize;
previewAsset.height = dragSize;
game.addChild(dragGearPreview);
}, holdThreshold);
};
// On move: update drag current position, update preview gear size/direction
game.move = function (x, y, obj) {
if (!dragStart) return;
dragCurrent.x = x;
dragCurrent.y = y;
if (dragHold && dragGearPreview) {
// Calculate drag vector
var dx = dragCurrent.x - dragStart.x;
var dy = dragCurrent.y - dragStart.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Size: proportional to drag distance, clamp to min/max
// Map drag distance from 0..(max possible) to minGear..maxGear
// Let's use up to 900px drag for full range (since maxGear is now 2x larger)
var maxDragDist = 900;
var size = clamp(minGear + (maxGear - minGear) * Math.min(dist, maxDragDist) / maxDragDist, minGear, maxGear);
dragSize = size;
dragGearPreview.children[0].width = size;
dragGearPreview.children[0].height = size;
// Direction: right is CW, left is CCW
dragDirection = dx >= 0 ? 1 : -1;
dragGearPreview.scale.x = dragDirection;
// No speed text shown during drag preview
}
};
// On release: decide tap/hold/drag action
game.up = function (x, y, obj) {
if (dragTimer) {
LK.clearTimeout(dragTimer);
dragTimer = null;
}
var now = Date.now();
var dt = now - (dragStart ? dragStart.t : now);
// Tap on existing gear: remove it
if (dragGearPreview && gears.indexOf(dragGearPreview) !== -1) {
// Remove gear
if (dragGearPreview.parent) dragGearPreview.parent.removeChild(dragGearPreview);
var idx = gears.indexOf(dragGearPreview);
if (idx !== -1) gears.splice(idx, 1);
dragGearPreview = null;
dragStart = null;
return;
}
// Short tap: do nothing (no gear created)
if (!dragHold && dt < tapThreshold) {
// No speed text to remove
dragStart = null;
dragGearPreview = null;
return;
}
// Hold/drag: create gear at dragStart, with size/direction
if (dragHold && dragGearPreview) {
// No speed text to remove
// Remove preview
if (dragGearPreview.parent) dragGearPreview.parent.removeChild(dragGearPreview);
dragGearPreview = null;
// Prevent overlapping: check if new gear would overlap any existing gear
var overlap = false;
for (var i = 0; i < gears.length; i++) {
var other = gears[i];
var dxg = dragStart.x - other.x;
var dyg = dragStart.y - other.y;
var distg = Math.sqrt(dxg * dxg + dyg * dyg);
var otherGear = other.children[0].width;
if (distg < (dragSize + otherGear) / 2 + 10) {
overlap = true;
break;
}
}
if (!overlap) {
var gear = new Gear();
gear.x = dragStart.x;
gear.y = dragStart.y;
// Assign random speed between 0.01 and 0.06, use dragDirection for direction
var minSpeed = 0.01,
maxSpeed = 0.06;
var randomSpeed = minSpeed + Math.random() * (maxSpeed - minSpeed);
gear.rotationSpeed = randomSpeed * dragDirection;
// Replace the gear asset with the previewed type
if (gear.children.length > 0) {
gear.removeChild(gear.children[0]);
}
var asset = gear.attachAsset('gear' + dragPreviewGearType, {
anchorX: 0.5,
anchorY: 0.5
});
asset.width = dragSize;
asset.height = dragSize;
// Set correct sound for this gear type
if (dragPreviewGearType === 5) {
gear._sound = LK.getSound('gearRotate5');
gear._soundName = 'gearRotate5';
} else {
gear._sound = LK.getSound('gearRotate' + dragPreviewGearType);
gear._soundName = 'gearRotate' + dragPreviewGearType;
}
gear._gearAssetIdx = dragPreviewGearType;
game.addChild(gear);
gears.push(gear);
}
}
dragStart = null;
dragGearPreview = null;
};
// Update loop: update all gears
game.update = function () {
for (var i = 0; i < gears.length; i++) {
if (gears[i].update) {
gears[i].update();
}
}
// Check win condition: score is greater than or equal to target (with sign)
if (targetSign > 0 && score >= targetValue || targetSign < 0 && score <= -targetValue) {
LK.showYouWin();
}
};
red gear top view tranparent. In-Game asset. 2d. High contrast. No shadows
yellow gear top view tranparent. In-Game asset. 2d. High contrast. No shadows
Green gear top view tranparent. In-Game asset. 2d. High contrast. No shadows
Mavi renk deniz manzarası. In-Game asset. 2d. High contrast. No shadows
Just a finger top view. In-Game asset. 2d. High contrast. No shadows