User prompt
add many fish to the scene but make them run for the bait and eat the bait thrown ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
wants to eat fish food.
User prompt
When I click anywhere with the mouse, drop a bait there and the fish eats that bait and then swims freely again. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Aqua Betta - Virtual Fish Tank
Initial prompt
I want to make a betta fish swim. Let the betta fish swim freely in the water. Let there be realistic movements. Let the fish be colorful and have realistic details.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BettaFish = Container.expand(function () {
var self = Container.call(this);
// Create fish body parts
var body = self.attachAsset('bettaBody', {
anchorX: 0.5,
anchorY: 0.5
});
var tail = self.attachAsset('bettaTail', {
anchorX: 0.8,
anchorY: 0.5,
x: -60,
scaleX: 1.2
});
var topFin = self.attachAsset('bettaFin', {
anchorX: 0.5,
anchorY: 0.8,
y: -30,
scaleX: 0.8,
scaleY: 0.6
});
var bottomFin = self.attachAsset('bettaFin', {
anchorX: 0.5,
anchorY: 0.2,
y: 25,
scaleX: 0.6,
scaleY: 0.5
});
// Randomize colors
var colors = [0xff4444, 0x4444ff, 0x44ff44, 0xff44ff, 0xffff44, 0x44ffff, 0xff8844];
var mainColor = colors[Math.floor(Math.random() * colors.length)];
var finColor = mainColor + 0x222222;
body.tint = mainColor;
tail.tint = finColor;
topFin.tint = finColor;
bottomFin.tint = finColor;
// Movement properties
self.targetX = 1024;
self.targetY = 1366;
self.speed = 2;
self.direction = 0;
self.isGliding = true;
self.glideDuration = 0;
self.maxGlideDuration = 180;
self.dartCooldown = 0;
// Animation properties
self.finAnimationOffset = Math.random() * Math.PI * 2;
function setNewTarget() {
self.targetX = Math.random() * 1400 + 324;
self.targetY = Math.random() * 800 + 466;
}
function startDart() {
self.isGliding = false;
self.speed = 8;
self.dartCooldown = 60;
setNewTarget();
}
self.update = function () {
// Calculate distance to target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Movement logic
if (distance > 20) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
self.x += moveX;
self.y += moveY;
// Update direction for visual orientation
self.direction = Math.atan2(dy, dx);
self.rotation = self.direction;
} else {
// Reached target, start gliding
if (!self.isGliding && self.dartCooldown <= 0) {
self.isGliding = true;
self.speed = 1;
self.glideDuration = 0;
setNewTarget();
}
}
// Gliding behavior
if (self.isGliding) {
self.glideDuration++;
if (self.glideDuration > self.maxGlideDuration && Math.random() < 0.02) {
startDart();
}
}
// Dart cooldown
if (self.dartCooldown > 0) {
self.dartCooldown--;
}
// Fin animations
var finWave = Math.sin((LK.ticks + self.finAnimationOffset) * 0.1) * 0.1;
tail.scaleY = 1.2 + finWave;
topFin.rotation = finWave * 0.5;
bottomFin.rotation = -finWave * 0.3;
// Body subtle movement
body.scaleY = 1 + Math.sin((LK.ticks + self.finAnimationOffset) * 0.05) * 0.05;
};
self.reactToTouch = function (touchX, touchY) {
var dx = touchX - self.x;
var dy = touchY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Fish swims away from touch
self.targetX = self.x - dx / distance * 300;
self.targetY = self.y - dy / distance * 300;
} else {
// Fish is curious and swims toward touch
self.targetX = touchX + (Math.random() - 0.5) * 100;
self.targetY = touchY + (Math.random() - 0.5) * 100;
}
// Clamp targets to tank boundaries
self.targetX = Math.max(324, Math.min(1724, self.targetX));
self.targetY = Math.max(466, Math.min(1666, self.targetY));
startDart();
};
return self;
});
var Bubble = Container.expand(function () {
var self = Container.call(this);
var bubbleGraphics = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6
});
self.speed = Math.random() * 2 + 1;
self.floatSpeed = Math.random() * 0.5 + 0.5;
self.update = function () {
self.y -= self.floatSpeed;
self.x += Math.sin(LK.ticks * 0.02 + self.speed) * 0.5;
if (self.y < -50) {
self.y = 2800;
self.x = Math.random() * 1800 + 124;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001122
});
/****
* Game Code
****/
// Create tank background
var tankBackground = game.attachAsset('tank', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
alpha: 0.3
});
// Create betta fish
var bettaFish = new BettaFish();
bettaFish.x = 1024;
bettaFish.y = 1366;
game.addChild(bettaFish);
// Create bubbles
var bubbles = [];
for (var i = 0; i < 8; i++) {
var bubble = new Bubble();
bubble.x = Math.random() * 1800 + 124;
bubble.y = Math.random() * 1200 + 466;
bubbles.push(bubble);
game.addChild(bubble);
}
// Touch interaction
game.down = function (x, y, obj) {
bettaFish.reactToTouch(x, y);
};
// Spawn new bubbles occasionally
var bubbleSpawnTimer = 0;
game.update = function () {
// Spawn new bubbles
bubbleSpawnTimer++;
if (bubbleSpawnTimer > 300 && Math.random() < 0.1) {
if (bubbles.length < 12) {
var newBubble = new Bubble();
newBubble.x = Math.random() * 1800 + 124;
newBubble.y = 2800;
bubbles.push(newBubble);
game.addChild(newBubble);
}
bubbleSpawnTimer = 0;
}
// Clean up bubbles that are too far off screen
for (var i = bubbles.length - 1; i >= 0; i--) {
if (bubbles[i].y < -100) {
bubbles[i].destroy();
bubbles.splice(i, 1);
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,205 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var BettaFish = Container.expand(function () {
+ var self = Container.call(this);
+ // Create fish body parts
+ var body = self.attachAsset('bettaBody', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var tail = self.attachAsset('bettaTail', {
+ anchorX: 0.8,
+ anchorY: 0.5,
+ x: -60,
+ scaleX: 1.2
+ });
+ var topFin = self.attachAsset('bettaFin', {
+ anchorX: 0.5,
+ anchorY: 0.8,
+ y: -30,
+ scaleX: 0.8,
+ scaleY: 0.6
+ });
+ var bottomFin = self.attachAsset('bettaFin', {
+ anchorX: 0.5,
+ anchorY: 0.2,
+ y: 25,
+ scaleX: 0.6,
+ scaleY: 0.5
+ });
+ // Randomize colors
+ var colors = [0xff4444, 0x4444ff, 0x44ff44, 0xff44ff, 0xffff44, 0x44ffff, 0xff8844];
+ var mainColor = colors[Math.floor(Math.random() * colors.length)];
+ var finColor = mainColor + 0x222222;
+ body.tint = mainColor;
+ tail.tint = finColor;
+ topFin.tint = finColor;
+ bottomFin.tint = finColor;
+ // Movement properties
+ self.targetX = 1024;
+ self.targetY = 1366;
+ self.speed = 2;
+ self.direction = 0;
+ self.isGliding = true;
+ self.glideDuration = 0;
+ self.maxGlideDuration = 180;
+ self.dartCooldown = 0;
+ // Animation properties
+ self.finAnimationOffset = Math.random() * Math.PI * 2;
+ function setNewTarget() {
+ self.targetX = Math.random() * 1400 + 324;
+ self.targetY = Math.random() * 800 + 466;
+ }
+ function startDart() {
+ self.isGliding = false;
+ self.speed = 8;
+ self.dartCooldown = 60;
+ setNewTarget();
+ }
+ self.update = function () {
+ // Calculate distance to target
+ var dx = self.targetX - self.x;
+ var dy = self.targetY - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ // Movement logic
+ if (distance > 20) {
+ var moveX = dx / distance * self.speed;
+ var moveY = dy / distance * self.speed;
+ self.x += moveX;
+ self.y += moveY;
+ // Update direction for visual orientation
+ self.direction = Math.atan2(dy, dx);
+ self.rotation = self.direction;
+ } else {
+ // Reached target, start gliding
+ if (!self.isGliding && self.dartCooldown <= 0) {
+ self.isGliding = true;
+ self.speed = 1;
+ self.glideDuration = 0;
+ setNewTarget();
+ }
+ }
+ // Gliding behavior
+ if (self.isGliding) {
+ self.glideDuration++;
+ if (self.glideDuration > self.maxGlideDuration && Math.random() < 0.02) {
+ startDart();
+ }
+ }
+ // Dart cooldown
+ if (self.dartCooldown > 0) {
+ self.dartCooldown--;
+ }
+ // Fin animations
+ var finWave = Math.sin((LK.ticks + self.finAnimationOffset) * 0.1) * 0.1;
+ tail.scaleY = 1.2 + finWave;
+ topFin.rotation = finWave * 0.5;
+ bottomFin.rotation = -finWave * 0.3;
+ // Body subtle movement
+ body.scaleY = 1 + Math.sin((LK.ticks + self.finAnimationOffset) * 0.05) * 0.05;
+ };
+ self.reactToTouch = function (touchX, touchY) {
+ var dx = touchX - self.x;
+ var dy = touchY - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < 200) {
+ // Fish swims away from touch
+ self.targetX = self.x - dx / distance * 300;
+ self.targetY = self.y - dy / distance * 300;
+ } else {
+ // Fish is curious and swims toward touch
+ self.targetX = touchX + (Math.random() - 0.5) * 100;
+ self.targetY = touchY + (Math.random() - 0.5) * 100;
+ }
+ // Clamp targets to tank boundaries
+ self.targetX = Math.max(324, Math.min(1724, self.targetX));
+ self.targetY = Math.max(466, Math.min(1666, self.targetY));
+ startDart();
+ };
+ return self;
+});
+var Bubble = Container.expand(function () {
+ var self = Container.call(this);
+ var bubbleGraphics = self.attachAsset('bubble', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.6
+ });
+ self.speed = Math.random() * 2 + 1;
+ self.floatSpeed = Math.random() * 0.5 + 0.5;
+ self.update = function () {
+ self.y -= self.floatSpeed;
+ self.x += Math.sin(LK.ticks * 0.02 + self.speed) * 0.5;
+ if (self.y < -50) {
+ self.y = 2800;
+ self.x = Math.random() * 1800 + 124;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x001122
+});
+
+/****
+* Game Code
+****/
+// Create tank background
+var tankBackground = game.attachAsset('tank', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1366,
+ alpha: 0.3
+});
+// Create betta fish
+var bettaFish = new BettaFish();
+bettaFish.x = 1024;
+bettaFish.y = 1366;
+game.addChild(bettaFish);
+// Create bubbles
+var bubbles = [];
+for (var i = 0; i < 8; i++) {
+ var bubble = new Bubble();
+ bubble.x = Math.random() * 1800 + 124;
+ bubble.y = Math.random() * 1200 + 466;
+ bubbles.push(bubble);
+ game.addChild(bubble);
+}
+// Touch interaction
+game.down = function (x, y, obj) {
+ bettaFish.reactToTouch(x, y);
+};
+// Spawn new bubbles occasionally
+var bubbleSpawnTimer = 0;
+game.update = function () {
+ // Spawn new bubbles
+ bubbleSpawnTimer++;
+ if (bubbleSpawnTimer > 300 && Math.random() < 0.1) {
+ if (bubbles.length < 12) {
+ var newBubble = new Bubble();
+ newBubble.x = Math.random() * 1800 + 124;
+ newBubble.y = 2800;
+ bubbles.push(newBubble);
+ game.addChild(newBubble);
+ }
+ bubbleSpawnTimer = 0;
+ }
+ // Clean up bubbles that are too far off screen
+ for (var i = bubbles.length - 1; i >= 0; i--) {
+ if (bubbles[i].y < -100) {
+ bubbles[i].destroy();
+ bubbles.splice(i, 1);
+ }
+ }
+};
\ No newline at end of file