User prompt
Make it so when the game detects the item it the tornado make it so it does not say The item missed the tornado.
User prompt
Make it so it tells you the result of the experiment after each time the item hits the tornado and fly's off the screen.
User prompt
Make it so when you launch it. it goes a bit higher.
User prompt
Can you make it so the tornado does not spin but if the block touches it. it will still act the same
User prompt
Make it so after you shoot the block and it goes off screen it teleports back.
Code edit (1 edits merged)
Please save this source code
User prompt
Tornado Twister Physics Lab
Initial prompt
Make a game that test's tornado physics
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Launchable object class var LaunchObject = Container.expand(function () { var self = Container.call(this); // Properties set on creation: type, mass self.type = 'box'; self.mass = 1.0; self.vx = 0; self.vy = 0; self.launched = false; self.inTornado = false; self.maxHeight = 0; self.arrow = null; // Attach correct asset var assetId = 'object_' + self.type; var objGfx = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Draw launch arrow (only before launch) self.showArrow = function (angle, power) { if (!self.arrow) { self.arrow = self.addChild(LK.getAsset('arrow', { anchorX: 0.0, anchorY: 0.5, alpha: 0.7 })); } self.arrow.rotation = angle; self.arrow.scaleX = Math.max(0.5, Math.min(power / 30, 2.5)); self.arrow.x = 0; self.arrow.y = 0; self.arrow.visible = true; }; self.hideArrow = function () { if (self.arrow) self.arrow.visible = false; }; // Called every tick self.update = function () { if (!self.launched) return; // Gravity self.vy += 0.18 * self.mass; // Tornado force if (tornado) { var force = tornado.getForce(self); self.vx += force.fx; self.vy += force.fy; // If inside tornado, mark var dx = self.x - tornado.centerX; var dy = self.y - tornado.centerY; var dist = Math.sqrt(dx * dx + dy * dy); self.inTornado = dist < tornado.radius; } // Move self.x += self.vx; self.y += self.vy; // Track max height if (self.y < self.maxHeight) self.maxHeight = self.y; // Out of bounds: below screen if (self.y > 2732 + 200) { self.destroyed = true; } }; return self; }); // Tornado class: swirling, applies force to objects inside var Tornado = Container.expand(function () { var self = Container.call(this); var tornadoGfx = self.attachAsset('tornado', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); // Tornado center self.centerX = 2048 / 2; self.centerY = 1700; self.radius = 300; self.strength = 1.0; // 1.0 = normal, can be changed per round self.rotationSpeed = 0.04; // radians per tick // Animate tornado swirl self.update = function () { tornadoGfx.rotation += self.rotationSpeed; }; // Returns force vector {fx, fy} for an object at (x, y) with mass self.getForce = function (obj) { var dx = obj.x - self.centerX; var dy = obj.y - self.centerY; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > self.radius) return { fx: 0, fy: 0 }; // Outside tornado // Swirl: perpendicular to radius, magnitude decreases with mass, increases with strength var angle = Math.atan2(dy, dx) + Math.PI / 2; var forceMag = self.strength * 2.5 * (1 - dist / self.radius) / (obj.mass || 1); return { fx: Math.cos(angle) * forceMag, fy: Math.sin(angle) * forceMag - 0.12 // Updraft: negative y }; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222233 }); /**** * Game Code ****/ // Sound for launch // Launch arrow // Object types: box, ball, cow, car (different colors/shapes) // Tornado: swirling ellipse, semi-transparent blue // --- Global variables --- var tornado = null; var currentObject = null; var launchedObjects = []; var round = 1; var roundActive = false; var dragStart = null; var dragPower = 0; var dragAngle = 0; var resultText = null; var infoText = null; var roundText = null; var nextButton = null; var objectTypes = [{ type: 'box', mass: 1.0, label: 'Box' }, { type: 'ball', mass: 0.7, label: 'Ball' }, { type: 'cow', mass: 1.8, label: 'Cow' }, { type: 'car', mass: 2.5, label: 'Car' }]; var tornadoStrengths = [1.0, 1.5, 0.7, 2.0, 0.5]; var objectIndex = 0; // --- UI Elements --- function showInfo(msg) { if (!infoText) { infoText = new Text2(msg, { size: 70, fill: "#fff" }); infoText.anchor.set(0.5, 0); LK.gui.top.addChild(infoText); } infoText.setText(msg); } function showResult(msg) { if (!resultText) { resultText = new Text2(msg, { size: 90, fill: "#fff" }); resultText.anchor.set(0.5, 0.5); LK.gui.center.addChild(resultText); } resultText.setText(msg); resultText.visible = true; } function hideResult() { if (resultText) resultText.visible = false; } function showRound() { if (!roundText) { roundText = new Text2('', { size: 60, fill: "#fff" }); roundText.anchor.set(0.5, 0); LK.gui.top.addChild(roundText); } roundText.setText("Round " + round + " / 5"); } function showNextButton() { if (!nextButton) { nextButton = new Text2('Next', { size: 80, fill: 0xFFEB3B }); nextButton.anchor.set(0.5, 0.5); nextButton.interactive = true; nextButton.buttonMode = true; nextButton.down = function (x, y, obj) { startRound(); }; LK.gui.bottom.addChild(nextButton); } nextButton.visible = true; } function hideNextButton() { if (nextButton) nextButton.visible = false; } // --- Game Logic --- // Place tornado in center lower half tornado = new Tornado(); tornado.centerX = 2048 / 2; tornado.centerY = 1700; tornado.x = tornado.centerX; tornado.y = tornado.centerY; game.addChild(tornado); // Start first round function startRound() { hideResult(); hideNextButton(); showRound(); roundActive = true; // Set tornado strength for this round tornado.strength = tornadoStrengths[(round - 1) % tornadoStrengths.length]; // Pick object type for this round objectIndex = (round - 1) % objectTypes.length; var objType = objectTypes[objectIndex]; // Place object at bottom center currentObject = new LaunchObject(); currentObject.type = objType.type; currentObject.mass = objType.mass; // Attach correct asset var assetId = 'object_' + currentObject.type; var objGfx = currentObject.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); currentObject.x = 2048 / 2; currentObject.y = 2732 - 200; currentObject.maxHeight = currentObject.y; currentObject.launched = false; currentObject.inTornado = false; currentObject.destroyed = false; game.addChild(currentObject); launchedObjects.push(currentObject); showInfo("Drag and release to launch the " + objType.label + "!\nTornado strength: " + tornado.strength.toFixed(1)); } // End round, show result, allow next function endRound() { roundActive = false; var obj = currentObject; var heightGain = Math.max(0, obj.y - obj.maxHeight); var msg = "Max height above launch: " + Math.round(heightGain) + " px"; if (obj.inTornado) { msg += "\nThe " + obj.type + " was caught by the tornado!"; } else { msg += "\nThe " + obj.type + " missed the tornado."; } showResult(msg); if (round < 5) { showNextButton(); round++; } else { showResult("Experiment complete!\nTry again to test more objects."); LK.setTimeout(function () { LK.showGameOver(); }, 2200); } } // --- Drag/Launch Controls --- // Only allow drag on currentObject before launch game.down = function (x, y, obj) { if (!roundActive || !currentObject || currentObject.launched) return; // Only allow drag if touch is near object var dx = x - currentObject.x; var dy = y - currentObject.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 120) { dragStart = { x: x, y: y }; dragPower = 0; dragAngle = 0; currentObject.showArrow(0, 0); } }; game.move = function (x, y, obj) { if (!dragStart || !currentObject || currentObject.launched) return; var dx = x - dragStart.x; var dy = y - dragStart.y; dragPower = Math.sqrt(dx * dx + dy * dy); dragAngle = Math.atan2(dy, dx); // Limit angle to upward launches only if (dragAngle > Math.PI / 2) dragAngle = Math.PI / 2; if (dragAngle < -Math.PI / 2) dragAngle = -Math.PI / 2; currentObject.showArrow(dragAngle, dragPower); }; game.up = function (x, y, obj) { if (!dragStart || !currentObject || currentObject.launched) return; // Calculate launch velocity (reverse direction: drag back to launch up) var dx = x - dragStart.x; var dy = y - dragStart.y; var power = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); // Only allow upward launches if (angle > Math.PI / 2) angle = Math.PI / 2; if (angle < -Math.PI / 2) angle = -Math.PI / 2; // Convert to velocity (reverse direction) var v = Math.min(power / 12, 38); // Cap velocity currentObject.vx = -Math.cos(angle) * v; currentObject.vy = -Math.sin(angle) * v; currentObject.launched = true; currentObject.hideArrow(); dragStart = null; LK.getSound('launch').play(); }; // --- Main update loop --- game.update = function () { // Animate tornado if (tornado) tornado.update(); // Update all objects for (var i = launchedObjects.length - 1; i >= 0; i--) { var obj = launchedObjects[i]; if (obj && obj.update) obj.update(); // End round if launched object is out of bounds if (obj === currentObject && obj.launched && !obj.destroyed) { // If object is below screen or has stopped moving if (obj.y > 2732 + 200 || Math.abs(obj.vx) < 0.2 && Math.abs(obj.vy) < 0.2 && obj.y > tornado.centerY + 400) { obj.destroyed = true; LK.setTimeout(endRound, 700); } } // Remove destroyed objects if (obj.destroyed) { obj.destroy(); launchedObjects.splice(i, 1); } } }; // --- Start game --- startRound(); showRound(); showInfo("Drag and release to launch the object into the tornado!");
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,349 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Launchable object class
+var LaunchObject = Container.expand(function () {
+ var self = Container.call(this);
+ // Properties set on creation: type, mass
+ self.type = 'box';
+ self.mass = 1.0;
+ self.vx = 0;
+ self.vy = 0;
+ self.launched = false;
+ self.inTornado = false;
+ self.maxHeight = 0;
+ self.arrow = null;
+ // Attach correct asset
+ var assetId = 'object_' + self.type;
+ var objGfx = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Draw launch arrow (only before launch)
+ self.showArrow = function (angle, power) {
+ if (!self.arrow) {
+ self.arrow = self.addChild(LK.getAsset('arrow', {
+ anchorX: 0.0,
+ anchorY: 0.5,
+ alpha: 0.7
+ }));
+ }
+ self.arrow.rotation = angle;
+ self.arrow.scaleX = Math.max(0.5, Math.min(power / 30, 2.5));
+ self.arrow.x = 0;
+ self.arrow.y = 0;
+ self.arrow.visible = true;
+ };
+ self.hideArrow = function () {
+ if (self.arrow) self.arrow.visible = false;
+ };
+ // Called every tick
+ self.update = function () {
+ if (!self.launched) return;
+ // Gravity
+ self.vy += 0.18 * self.mass;
+ // Tornado force
+ if (tornado) {
+ var force = tornado.getForce(self);
+ self.vx += force.fx;
+ self.vy += force.fy;
+ // If inside tornado, mark
+ var dx = self.x - tornado.centerX;
+ var dy = self.y - tornado.centerY;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ self.inTornado = dist < tornado.radius;
+ }
+ // Move
+ self.x += self.vx;
+ self.y += self.vy;
+ // Track max height
+ if (self.y < self.maxHeight) self.maxHeight = self.y;
+ // Out of bounds: below screen
+ if (self.y > 2732 + 200) {
+ self.destroyed = true;
+ }
+ };
+ return self;
+});
+// Tornado class: swirling, applies force to objects inside
+var Tornado = Container.expand(function () {
+ var self = Container.call(this);
+ var tornadoGfx = self.attachAsset('tornado', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.5
+ });
+ // Tornado center
+ self.centerX = 2048 / 2;
+ self.centerY = 1700;
+ self.radius = 300;
+ self.strength = 1.0; // 1.0 = normal, can be changed per round
+ self.rotationSpeed = 0.04; // radians per tick
+ // Animate tornado swirl
+ self.update = function () {
+ tornadoGfx.rotation += self.rotationSpeed;
+ };
+ // Returns force vector {fx, fy} for an object at (x, y) with mass
+ self.getForce = function (obj) {
+ var dx = obj.x - self.centerX;
+ var dy = obj.y - self.centerY;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist > self.radius) return {
+ fx: 0,
+ fy: 0
+ }; // Outside tornado
+ // Swirl: perpendicular to radius, magnitude decreases with mass, increases with strength
+ var angle = Math.atan2(dy, dx) + Math.PI / 2;
+ var forceMag = self.strength * 2.5 * (1 - dist / self.radius) / (obj.mass || 1);
+ return {
+ fx: Math.cos(angle) * forceMag,
+ fy: Math.sin(angle) * forceMag - 0.12 // Updraft: negative y
+ };
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222233
+});
+
+/****
+* Game Code
+****/
+// Sound for launch
+// Launch arrow
+// Object types: box, ball, cow, car (different colors/shapes)
+// Tornado: swirling ellipse, semi-transparent blue
+// --- Global variables ---
+var tornado = null;
+var currentObject = null;
+var launchedObjects = [];
+var round = 1;
+var roundActive = false;
+var dragStart = null;
+var dragPower = 0;
+var dragAngle = 0;
+var resultText = null;
+var infoText = null;
+var roundText = null;
+var nextButton = null;
+var objectTypes = [{
+ type: 'box',
+ mass: 1.0,
+ label: 'Box'
+}, {
+ type: 'ball',
+ mass: 0.7,
+ label: 'Ball'
+}, {
+ type: 'cow',
+ mass: 1.8,
+ label: 'Cow'
+}, {
+ type: 'car',
+ mass: 2.5,
+ label: 'Car'
+}];
+var tornadoStrengths = [1.0, 1.5, 0.7, 2.0, 0.5];
+var objectIndex = 0;
+// --- UI Elements ---
+function showInfo(msg) {
+ if (!infoText) {
+ infoText = new Text2(msg, {
+ size: 70,
+ fill: "#fff"
+ });
+ infoText.anchor.set(0.5, 0);
+ LK.gui.top.addChild(infoText);
+ }
+ infoText.setText(msg);
+}
+function showResult(msg) {
+ if (!resultText) {
+ resultText = new Text2(msg, {
+ size: 90,
+ fill: "#fff"
+ });
+ resultText.anchor.set(0.5, 0.5);
+ LK.gui.center.addChild(resultText);
+ }
+ resultText.setText(msg);
+ resultText.visible = true;
+}
+function hideResult() {
+ if (resultText) resultText.visible = false;
+}
+function showRound() {
+ if (!roundText) {
+ roundText = new Text2('', {
+ size: 60,
+ fill: "#fff"
+ });
+ roundText.anchor.set(0.5, 0);
+ LK.gui.top.addChild(roundText);
+ }
+ roundText.setText("Round " + round + " / 5");
+}
+function showNextButton() {
+ if (!nextButton) {
+ nextButton = new Text2('Next', {
+ size: 80,
+ fill: 0xFFEB3B
+ });
+ nextButton.anchor.set(0.5, 0.5);
+ nextButton.interactive = true;
+ nextButton.buttonMode = true;
+ nextButton.down = function (x, y, obj) {
+ startRound();
+ };
+ LK.gui.bottom.addChild(nextButton);
+ }
+ nextButton.visible = true;
+}
+function hideNextButton() {
+ if (nextButton) nextButton.visible = false;
+}
+// --- Game Logic ---
+// Place tornado in center lower half
+tornado = new Tornado();
+tornado.centerX = 2048 / 2;
+tornado.centerY = 1700;
+tornado.x = tornado.centerX;
+tornado.y = tornado.centerY;
+game.addChild(tornado);
+// Start first round
+function startRound() {
+ hideResult();
+ hideNextButton();
+ showRound();
+ roundActive = true;
+ // Set tornado strength for this round
+ tornado.strength = tornadoStrengths[(round - 1) % tornadoStrengths.length];
+ // Pick object type for this round
+ objectIndex = (round - 1) % objectTypes.length;
+ var objType = objectTypes[objectIndex];
+ // Place object at bottom center
+ currentObject = new LaunchObject();
+ currentObject.type = objType.type;
+ currentObject.mass = objType.mass;
+ // Attach correct asset
+ var assetId = 'object_' + currentObject.type;
+ var objGfx = currentObject.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ currentObject.x = 2048 / 2;
+ currentObject.y = 2732 - 200;
+ currentObject.maxHeight = currentObject.y;
+ currentObject.launched = false;
+ currentObject.inTornado = false;
+ currentObject.destroyed = false;
+ game.addChild(currentObject);
+ launchedObjects.push(currentObject);
+ showInfo("Drag and release to launch the " + objType.label + "!\nTornado strength: " + tornado.strength.toFixed(1));
+}
+// End round, show result, allow next
+function endRound() {
+ roundActive = false;
+ var obj = currentObject;
+ var heightGain = Math.max(0, obj.y - obj.maxHeight);
+ var msg = "Max height above launch: " + Math.round(heightGain) + " px";
+ if (obj.inTornado) {
+ msg += "\nThe " + obj.type + " was caught by the tornado!";
+ } else {
+ msg += "\nThe " + obj.type + " missed the tornado.";
+ }
+ showResult(msg);
+ if (round < 5) {
+ showNextButton();
+ round++;
+ } else {
+ showResult("Experiment complete!\nTry again to test more objects.");
+ LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 2200);
+ }
+}
+// --- Drag/Launch Controls ---
+// Only allow drag on currentObject before launch
+game.down = function (x, y, obj) {
+ if (!roundActive || !currentObject || currentObject.launched) return;
+ // Only allow drag if touch is near object
+ var dx = x - currentObject.x;
+ var dy = y - currentObject.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 120) {
+ dragStart = {
+ x: x,
+ y: y
+ };
+ dragPower = 0;
+ dragAngle = 0;
+ currentObject.showArrow(0, 0);
+ }
+};
+game.move = function (x, y, obj) {
+ if (!dragStart || !currentObject || currentObject.launched) return;
+ var dx = x - dragStart.x;
+ var dy = y - dragStart.y;
+ dragPower = Math.sqrt(dx * dx + dy * dy);
+ dragAngle = Math.atan2(dy, dx);
+ // Limit angle to upward launches only
+ if (dragAngle > Math.PI / 2) dragAngle = Math.PI / 2;
+ if (dragAngle < -Math.PI / 2) dragAngle = -Math.PI / 2;
+ currentObject.showArrow(dragAngle, dragPower);
+};
+game.up = function (x, y, obj) {
+ if (!dragStart || !currentObject || currentObject.launched) return;
+ // Calculate launch velocity (reverse direction: drag back to launch up)
+ var dx = x - dragStart.x;
+ var dy = y - dragStart.y;
+ var power = Math.sqrt(dx * dx + dy * dy);
+ var angle = Math.atan2(dy, dx);
+ // Only allow upward launches
+ if (angle > Math.PI / 2) angle = Math.PI / 2;
+ if (angle < -Math.PI / 2) angle = -Math.PI / 2;
+ // Convert to velocity (reverse direction)
+ var v = Math.min(power / 12, 38); // Cap velocity
+ currentObject.vx = -Math.cos(angle) * v;
+ currentObject.vy = -Math.sin(angle) * v;
+ currentObject.launched = true;
+ currentObject.hideArrow();
+ dragStart = null;
+ LK.getSound('launch').play();
+};
+// --- Main update loop ---
+game.update = function () {
+ // Animate tornado
+ if (tornado) tornado.update();
+ // Update all objects
+ for (var i = launchedObjects.length - 1; i >= 0; i--) {
+ var obj = launchedObjects[i];
+ if (obj && obj.update) obj.update();
+ // End round if launched object is out of bounds
+ if (obj === currentObject && obj.launched && !obj.destroyed) {
+ // If object is below screen or has stopped moving
+ if (obj.y > 2732 + 200 || Math.abs(obj.vx) < 0.2 && Math.abs(obj.vy) < 0.2 && obj.y > tornado.centerY + 400) {
+ obj.destroyed = true;
+ LK.setTimeout(endRound, 700);
+ }
+ }
+ // Remove destroyed objects
+ if (obj.destroyed) {
+ obj.destroy();
+ launchedObjects.splice(i, 1);
+ }
+ }
+};
+// --- Start game ---
+startRound();
+showRound();
+showInfo("Drag and release to launch the object into the tornado!");
\ No newline at end of file
Make a car. In-Game asset. 2d. High contrast. No shadows
Make this a tornado. In-Game asset. 2d. High contrast. No shadows
Make a ball. In-Game asset. 2d. High contrast. No shadows
Make a box. In-Game asset. 2d. High contrast. No shadows
Make a cow. In-Game asset. 2d. High contrast. No shadows
Make a arrow. In-Game asset. 2d. High contrast. No shadows