User prompt
Let the anchor be as long as the box ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the anchor be Huge and come from the other side of the box to the other side and only 1 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add an anchor, sometimes it's blue, sometimes it's orange (When it's blue you have to stop, when it's orange you have to move. Damage:2) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Delete The Bone outline
User prompt
Let the text be at the top of the screen and be black
User prompt
Add lives (let us have 10 lives and bones hit 1)
User prompt
Let the bones come like an Undertale sans fight and draw a black line around the bones ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the bones come and try to attack us, and we will run away ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Speed up character
User prompt
Let the player control
User prompt
Add movement to character
Code edit (1 edits merged)
Please save this source code
User prompt
Heart in a Box
Initial prompt
Create a box and our character (Heart) Let him travel, but not go outside the box
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Anchor = Container.expand(function () {
var self = Container.call(this);
// Create anchor graphic
var anchorGraphics = self.attachAsset('anchor', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 13.33,
// 1600px / 120px = 13.33 to make anchor as long as box
scaleY: 4
});
self.isBlue = true; // true = blue (stop), false = orange (move)
self.damage = 2;
self.lastX = 0;
self.lastY = 0;
self.colorChangeTimer = 0;
self.colorChangeInterval = 180; // Change color every 3 seconds at 60fps
self.speed = 3;
self.movingRight = true;
// Update anchor color
self.updateColor = function () {
if (self.isBlue) {
anchorGraphics.tint = 0x0066ff; // Blue
} else {
anchorGraphics.tint = 0xff6600; // Orange
}
};
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Move horizontally across the box
if (self.movingRight) {
self.x += self.speed;
} else {
self.x -= self.speed;
}
// Change color periodically
self.colorChangeTimer++;
if (self.colorChangeTimer >= self.colorChangeInterval) {
self.isBlue = !self.isBlue;
self.updateColor();
self.colorChangeTimer = 0;
}
};
// Initialize with blue color
self.updateColor();
return self;
});
var Bone = Container.expand(function () {
var self = Container.call(this);
// Create bone graphic
var boneGraphics = self.attachAsset('bone', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.isAttacking = false;
self.lastX = 0;
self.lastY = 0;
self.attackPattern = 0; // 0=direct, 1=zigzag, 2=circle
self.startAttack = function (targetX, targetY) {
if (self.isAttacking) return;
self.isAttacking = true;
self.attackPattern = Math.floor(Math.random() * 3);
var duration = Math.random() * 800 + 1200; // 1.2-2.0 seconds
if (self.attackPattern === 0) {
// Direct attack like original
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.isAttacking = false;
}
});
} else if (self.attackPattern === 1) {
// Zigzag pattern - attack in multiple stages
var midX = (self.x + targetX) / 2 + (Math.random() - 0.5) * 300;
var midY = (self.y + targetY) / 2 + (Math.random() - 0.5) * 300;
tween(self, {
x: midX,
y: midY
}, {
duration: duration / 2,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration / 2,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isAttacking = false;
}
});
}
});
} else {
// Circular approach
var centerX = (self.x + targetX) / 2;
var centerY = (self.y + targetY) / 2;
var radius = Math.sqrt(Math.pow(targetX - self.x, 2) + Math.pow(targetY - self.y, 2)) / 3;
var angle = Math.atan2(self.y - centerY, self.x - centerX);
var circleX = centerX + Math.cos(angle + Math.PI) * radius;
var circleY = centerY + Math.sin(angle + Math.PI) * radius;
tween(self, {
x: circleX,
y: circleY
}, {
duration: duration / 2,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration / 2,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isAttacking = false;
}
});
}
});
}
};
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var BoxBoundary = Container.expand(function () {
var self = Container.call(this);
// Create four walls for the box
var topWall = self.attachAsset('boxBorder', {
anchorX: 0,
anchorY: 0,
width: 1600,
height: 8
});
var bottomWall = self.attachAsset('boxBorder', {
anchorX: 0,
anchorY: 0,
width: 1600,
height: 8
});
var leftWall = self.attachAsset('boxBorder', {
anchorX: 0,
anchorY: 0,
width: 8,
height: 1200
});
var rightWall = self.attachAsset('boxBorder', {
anchorX: 0,
anchorY: 0,
width: 8,
height: 1200
});
// Position walls
topWall.x = 0;
topWall.y = 0;
bottomWall.x = 0;
bottomWall.y = 1200 - 8;
leftWall.x = 0;
leftWall.y = 0;
rightWall.x = 1600 - 8;
rightWall.y = 0;
return self;
});
var Heart = Container.expand(function () {
var self = Container.call(this);
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf0f8ff
});
/****
* Game Code
****/
// Box dimensions
var boxX = 224; // Center the 1600px box in 2048px screen
var boxY = 766; // Center the 1200px box in 2732px screen
var boxWidth = 1600;
var boxHeight = 1200;
// Create box boundary
var boundary = game.addChild(new BoxBoundary());
boundary.x = boxX;
boundary.y = boxY;
// Create heart character
var heart = game.addChild(new Heart());
heart.x = boxX + boxWidth / 2; // Center of box
heart.y = boxY + boxHeight / 2; // Center of box
// Create lives display
var livesTxt = new Text2('Lives: 10', {
size: 80,
fill: 0x000000
});
livesTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(livesTxt);
// Dragging variables
var isDragging = false;
var dragOffsetX = 0;
var dragOffsetY = 0;
// Constraint function to keep heart within boundaries
function constrainHeartPosition() {
var heartRadius = 50; // Half of heart width/height
// Left boundary
if (heart.x - heartRadius < boxX + 8) {
heart.x = boxX + 8 + heartRadius;
}
// Right boundary
if (heart.x + heartRadius > boxX + boxWidth - 8) {
heart.x = boxX + boxWidth - 8 - heartRadius;
}
// Top boundary
if (heart.y - heartRadius < boxY + 8) {
heart.y = boxY + 8 + heartRadius;
}
// Bottom boundary
if (heart.y + heartRadius > boxY + boxHeight - 8) {
heart.y = boxY + boxHeight - 8 - heartRadius;
}
}
// Player control variables
var targetX = 0;
var targetY = 0;
var isPlayerControlling = false;
// Touch/mouse down event
game.down = function (x, y, obj) {
isPlayerControlling = true;
targetX = x;
targetY = y;
};
// Touch/mouse move event
game.move = function (x, y, obj) {
if (isPlayerControlling) {
targetX = x;
targetY = y;
}
};
// Touch/mouse up event
game.up = function (x, y, obj) {
isPlayerControlling = false;
};
// Lives system
var lives = 10;
// Movement variables
var heartSpeed = 8;
var movementDirection = {
x: 1,
y: 0.5
}; // Initial movement direction
var lastDirectionChangeTime = 0;
var directionChangeInterval = 2000; // Change direction every 2 seconds
// Bone enemy system
var bones = [];
var maxBones = 8;
var boneSpawnTimer = 0;
var boneSpawnInterval = 90; // Spawn every 1.5 seconds at 60fps
var waveIntensity = 1;
// Anchor system
var anchors = [];
var maxAnchors = 1;
var anchorSpawnTimer = 0;
var anchorSpawnInterval = 240; // Spawn every 4 seconds at 60fps
// Function to spawn a new bone at random edge position
function spawnBone() {
if (bones.length >= maxBones) return;
var bone = new Bone();
var edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
// Position bone at random point on selected edge
switch (edge) {
case 0:
// Top edge
bone.x = boxX + Math.random() * boxWidth;
bone.y = boxY - 50;
break;
case 1:
// Right edge
bone.x = boxX + boxWidth + 50;
bone.y = boxY + Math.random() * boxHeight;
break;
case 2:
// Bottom edge
bone.x = boxX + Math.random() * boxWidth;
bone.y = boxY + boxHeight + 50;
break;
case 3:
// Left edge
bone.x = boxX - 50;
bone.y = boxY + Math.random() * boxHeight;
break;
}
bone.lastX = bone.x;
bone.lastY = bone.y;
bones.push(bone);
game.addChild(bone);
// Start attacking the heart immediately
bone.startAttack(heart.x, heart.y);
}
// Function to spawn a new anchor at random position within the box
function spawnAnchor() {
if (anchors.length >= maxAnchors) return;
var anchor = new Anchor();
// Position anchor at left or right edge to travel across
var startFromLeft = Math.random() < 0.5;
if (startFromLeft) {
anchor.x = boxX - 800; // Start from left side (accounting for 1600px length)
anchor.movingRight = true;
} else {
anchor.x = boxX + boxWidth + 800; // Start from right side
anchor.movingRight = false;
}
// Random Y position within the box
anchor.y = boxY + Math.random() * boxHeight;
anchor.lastX = anchor.x;
anchor.lastY = anchor.y;
anchors.push(anchor);
game.addChild(anchor);
}
// Game update loop
game.update = function () {
// Increase wave intensity over time
if (LK.ticks % 600 === 0) {
// Every 10 seconds
waveIntensity = Math.min(waveIntensity + 0.5, 4);
maxBones = Math.min(Math.floor(4 + waveIntensity * 2), 12);
boneSpawnInterval = Math.max(Math.floor(90 - waveIntensity * 15), 30);
}
// Spawn bones periodically with wave patterns
boneSpawnTimer++;
if (boneSpawnTimer >= boneSpawnInterval) {
// Sometimes spawn multiple bones at once for Undertale feel
var spawnCount = Math.random() < 0.3 ? Math.floor(waveIntensity) : 1;
for (var s = 0; s < spawnCount && bones.length < maxBones; s++) {
spawnBone();
}
boneSpawnTimer = 0;
}
// Spawn anchors periodically
anchorSpawnTimer++;
if (anchorSpawnTimer >= anchorSpawnInterval) {
spawnAnchor();
anchorSpawnTimer = 0;
}
// Update all bones and check for collisions
for (var i = bones.length - 1; i >= 0; i--) {
var bone = bones[i];
// Check if bone hit the heart
if (bone.intersects(heart)) {
// Reduce lives by 1
lives -= 1;
livesTxt.setText('Lives: ' + lives);
// Flash screen red to indicate damage
LK.effects.flashScreen(0xff0000, 500);
// Check for game over
if (lives <= 0) {
LK.showGameOver();
return;
}
// Remove the bone that hit us
bone.destroy();
bones.splice(i, 1);
continue;
}
// Remove bones that are too far from the play area
var distanceFromCenter = Math.sqrt(Math.pow(bone.x - (boxX + boxWidth / 2), 2) + Math.pow(bone.y - (boxY + boxHeight / 2), 2));
if (distanceFromCenter > 2000) {
bone.destroy();
bones.splice(i, 1);
continue;
}
// Retarget bones that aren't currently attacking
if (!bone.isAttacking && Math.random() < 0.01) {
// 1% chance per frame
bone.startAttack(heart.x, heart.y);
}
}
// Update all anchors and check for collisions
for (var j = anchors.length - 1; j >= 0; j--) {
var anchor = anchors[j];
// Check if anchor hit the heart
if (anchor.intersects(heart)) {
var shouldTakeDamage = false;
// Blue anchor: damage if player is moving
if (anchor.isBlue && isPlayerControlling) {
shouldTakeDamage = true;
}
// Orange anchor: damage if player is not moving
else if (!anchor.isBlue && !isPlayerControlling) {
shouldTakeDamage = true;
}
if (shouldTakeDamage) {
// Reduce lives by anchor damage (2)
lives -= anchor.damage;
livesTxt.setText('Lives: ' + lives);
// Flash screen purple to indicate anchor damage
LK.effects.flashScreen(0x8800ff, 700);
// Check for game over
if (lives <= 0) {
LK.showGameOver();
return;
}
}
// Remove the anchor that hit us
anchor.destroy();
anchors.splice(j, 1);
continue;
}
// Remove anchors that have moved off screen
var anchorRadius = 800; // Half of scaled anchor size (1600px / 2)
if (anchor.movingRight && anchor.x > boxX + boxWidth + anchorRadius || !anchor.movingRight && anchor.x < boxX - anchorRadius) {
anchor.destroy();
anchors.splice(j, 1);
}
}
if (isPlayerControlling) {
// Calculate direction toward target
var deltaX = targetX - heart.x;
var deltaY = targetY - heart.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Move toward target if not already there
if (distance > 5) {
// Normalize direction and apply speed
movementDirection.x = deltaX / distance;
movementDirection.y = deltaY / distance;
heart.x += movementDirection.x * heartSpeed;
heart.y += movementDirection.y * heartSpeed;
}
} else {
// Auto movement - change direction periodically when not controlled
if (LK.ticks % 120 === 0) {
// Every 2 seconds at 60fps
movementDirection.x = (Math.random() - 0.5) * 2; // Random x direction between -1 and 1
movementDirection.y = (Math.random() - 0.5) * 2; // Random y direction between -1 and 1
}
// Apply automatic movement
heart.x += movementDirection.x * heartSpeed;
heart.y += movementDirection.y * heartSpeed;
// Bounce off walls by reversing direction
var heartRadius = 50;
if (heart.x - heartRadius <= boxX + 8 || heart.x + heartRadius >= boxX + boxWidth - 8) {
movementDirection.x *= -1; // Reverse horizontal direction
}
if (heart.y - heartRadius <= boxY + 8 || heart.y + heartRadius >= boxY + boxHeight - 8) {
movementDirection.y *= -1; // Reverse vertical direction
}
}
// Ensure heart stays within bounds each frame
constrainHeartPosition();
}; ===================================================================
--- original.js
+++ change.js
@@ -11,9 +11,10 @@
// Create anchor graphic
var anchorGraphics = self.attachAsset('anchor', {
anchorX: 0.5,
anchorY: 0.5,
- scaleX: 4,
+ scaleX: 13.33,
+ // 1600px / 120px = 13.33 to make anchor as long as box
scaleY: 4
});
self.isBlue = true; // true = blue (stop), false = orange (move)
self.damage = 2;
@@ -323,12 +324,12 @@
var anchor = new Anchor();
// Position anchor at left or right edge to travel across
var startFromLeft = Math.random() < 0.5;
if (startFromLeft) {
- anchor.x = boxX - 240; // Start from left side (accounting for huge size)
+ anchor.x = boxX - 800; // Start from left side (accounting for 1600px length)
anchor.movingRight = true;
} else {
- anchor.x = boxX + boxWidth + 240; // Start from right side
+ anchor.x = boxX + boxWidth + 800; // Start from right side
anchor.movingRight = false;
}
// Random Y position within the box
anchor.y = boxY + Math.random() * boxHeight;
@@ -426,9 +427,9 @@
anchors.splice(j, 1);
continue;
}
// Remove anchors that have moved off screen
- var anchorRadius = 240; // Half of scaled anchor size
+ var anchorRadius = 800; // Half of scaled anchor size (1600px / 2)
if (anchor.movingRight && anchor.x > boxX + boxWidth + anchorRadius || !anchor.movingRight && anchor.x < boxX - anchorRadius) {
anchor.destroy();
anchors.splice(j, 1);
}
Undertale Heart. In-Game asset. 2d. High contrast. No shadows
Undertale bone with black outline. In-Game asset. 2d. High contrast. No shadows
Undertale asgore spear. In-Game asset. 2d. High contrast. No shadows
Ivy. In-Game asset. 2d. High contrast. No shadows
Sans Undertale. In-Game asset. 2d. High contrast. No shadows
Asgore Undertale. In-Game asset. 2d. High contrast. No shadows
Flowey Undertale but with 6 souls (Orange,Green,Yellow,blue,Purple, Light Blue). In-Game asset. 2d. High contrast. No shadows
Flat staring gaster blaster Undertale. In-Game asset. 2d. High contrast. No shadows
Undertale heart but blue. In-Game asset. 2d. High contrast. No shadows
Green Heart Undertale. In-Game asset. 2d. High contrast. No shadows
Yellow heart Undertale. In-Game asset. 2d. High contrast. No shadows