Code edit (8 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: rotatedTriangle is not defined' in or related to this line: 'var v1 = rotatedTriangle.slice(0, 3);' Line Number: 244
Code edit (1 edits merged)
Please save this source code
User prompt
Make the triangle color darker when it's faces away from the camera.
Code edit (12 edits merged)
Please save this source code
User prompt
Put the colors of the rainbow in COLOR_ARRAY
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
properly calculate the momentum
Code edit (1 edits merged)
Please save this source code
User prompt
Add momentum to the rotate by the distance between the last frame rotation
Code edit (1 edits merged)
Please save this source code
User prompt
properly calculate the momentum
User prompt
the momentum is even faster
User prompt
the momentum is faster me dragging
User prompt
The momentum is too fast
Code edit (12 edits merged)
Please save this source code
User prompt
Add momentum to the rotate by the distance between the last frame coordinates
Code edit (3 edits merged)
Please save this source code
User prompt
Add momentum to the rotation
Code edit (1 edits merged)
Please save this source code
User prompt
The cube rotates on the wrong axis when I'm facing the sides
User prompt
The cube rotates on the wrong axis when I'm facing the sides
User prompt
The cube rotates the wrong way when I'm facing the sides, fix it
User prompt
Make the cube rotate up and down by dragging up and down
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0
});
/****
* Game Code
****/
// Game constants for the screen
var SCREEN_SIZE = 64;
var PIXEL_SIZE = 2048 / SCREEN_SIZE;
// Cache children array reference
var screen = game.children;
function clearScreen() {
var len = screen.length;
for (var i = 0; i < len; i++) {
screen[i].tint = 0;
}
}
function putPixel(x, y, color) {
if (x >= 0 && x < SCREEN_SIZE && y >= 0 && y < SCREEN_SIZE) {
screen[x + y * SCREEN_SIZE].tint = color;
}
}
// Line drawing function using Bresenham's line algorithm
function drawLine(x0, y0, x1, y1, color) {
var dx = x1 - x0;
var dy = y1 - y0;
var adx = dx < 0 ? -dx : dx;
var ady = dy < 0 ? -dy : dy;
var sx = dx < 0 ? -1 : 1;
var sy = dy < 0 ? -1 : 1;
var err = adx - ady;
var x = x0;
var y = y0;
while (true) {
putPixel(x, y, color);
if (x === x1 && y === y1) {
break;
}
var e2 = 2 * err;
if (e2 > -ady) {
err -= ady;
x += sx;
}
if (e2 < adx) {
err += adx;
y += sy;
}
}
}
function drawTriangle(triangle, color, wireframe) {
if (wireframe === undefined) {
wireframe = false;
}
// Extract triangle vertices
var x1 = triangle[0];
var y1 = triangle[1];
var x2 = triangle[2];
var y2 = triangle[3];
var x3 = triangle[4];
var y3 = triangle[5];
// Draw the three sides of the triangle only if wireframe is true
if (wireframe) {
drawLine(x1, y1, x2, y2, color); // Side 1-2
drawLine(x2, y2, x3, y3, color); // Side 2-3
drawLine(x3, y3, x1, y1, color); // Side 3-1
} else {
// Helper to interpolate x between two points at a given y
// Sort vertices by y (ascending) - reuse pre-allocated array
if (!drawTriangle.verts) {
drawTriangle.verts = [{
x: 0,
y: 0
}, {
x: 0,
y: 0
}, {
x: 0,
y: 0
}];
}
var verts = drawTriangle.verts;
verts[0].x = x1;
verts[0].y = y1;
verts[1].x = x2;
verts[1].y = y2;
verts[2].x = x3;
verts[2].y = y3;
var interpX = function interpX(y, x0, y0, x1, y1) {
if (y1 === y0) {
return x0;
}
return x0 + (x1 - x0) * (y - y0) / (y1 - y0);
}; // Fill bottom flat triangle (v0, v1, v2) if v1.y != v0.y
verts.sort(function (a, b) {
return a.y - b.y;
});
var v0 = verts[0];
var v1 = verts[1];
var v2 = verts[2];
if (v1.y !== v0.y) {
var yStart = Math.ceil(v0.y);
var yEnd = Math.ceil(v1.y);
for (var y = yStart; y < yEnd; y++) {
var xA = interpX(y, v0.x, v0.y, v2.x, v2.y);
var xB = interpX(y, v0.x, v0.y, v1.x, v1.y);
var xStart = xA < xB ? Math.ceil(xA) : Math.ceil(xB);
var xEnd = xA > xB ? Math.floor(xA) : Math.floor(xB);
for (var x = xStart; x <= xEnd; x++) {
putPixel(x, y, color);
}
}
}
// Fill top flat triangle (v1, v2, v0) if v2.y != v1.y
if (v2.y !== v1.y) {
var yStart = Math.ceil(v1.y);
var yEnd = Math.ceil(v2.y);
for (var y = yStart; y < yEnd; y++) {
var xA = interpX(y, v0.x, v0.y, v2.x, v2.y);
var xB = interpX(y, v1.x, v1.y, v2.x, v2.y);
var xStart = xA < xB ? Math.ceil(xA) : Math.ceil(xB);
var xEnd = xA > xB ? Math.floor(xA) : Math.floor(xB);
for (var x = xStart; x <= xEnd; x++) {
putPixel(x, y, color);
}
}
}
}
}
var colorIndex = 0;
var offset = 2732 / 2 - SCREEN_SIZE * PIXEL_SIZE / 2;
// Create the screen of pixels
for (var y = 0; y < SCREEN_SIZE; y++) {
for (var x = 0; x < SCREEN_SIZE; x++) {
// Get an instance of our pixel asset
var pixel = LK.getAsset('pixel', {
x: x * PIXEL_SIZE,
y: y * PIXEL_SIZE + offset,
tint: 0
});
game.addChild(pixel);
}
}
function translateTriangle(triangle, dx, dy, dz) {
// triangle: [x1, y1, z1, x2, y2, z2, x3, y3, z3]
// Translate each vertex by dx, dy, dz - reuse pre-allocated array
if (!translateTriangle.result) {
translateTriangle.result = [0, 0, 0, 0, 0, 0, 0, 0, 0];
}
var result = translateTriangle.result;
result[0] = triangle[0] + dx;
result[1] = triangle[1] + dy;
result[2] = triangle[2] + dz;
result[3] = triangle[3] + dx;
result[4] = triangle[4] + dy;
result[5] = triangle[5] + dz;
result[6] = triangle[6] + dx;
result[7] = triangle[7] + dy;
result[8] = triangle[8] + dz;
return result;
}
function rotateTriangle(triangle, angleX, angleY, angleZ) {
// triangle: [x1, y1, z1, x2, y2, z2, x3, y3, z3]
// angleX, angleY, angleZ in radians
// Reuse pre-allocated array for result
if (!rotateTriangle.result) {
rotateTriangle.result = [0, 0, 0, 0, 0, 0, 0, 0, 0];
}
var result = rotateTriangle.result;
// Precompute sines and cosines
var cosX = Math.cos(angleX),
sinX = Math.sin(angleX);
var cosY = Math.cos(angleY),
sinY = Math.sin(angleY);
var cosZ = Math.cos(angleZ),
sinZ = Math.sin(angleZ);
// Helper to rotate a single point
function rotate(x, y, z) {
// Rotate around Y axis (Yaw)
var x1 = x * cosY + z * sinY;
var z1 = -x * sinY + z * cosY;
// Rotate around X axis (Pitch)
var y2 = y * cosX - z1 * sinX;
var z2 = y * sinX + z1 * cosX;
// Rotate around Z axis (Roll)
var x3 = x1 * cosZ - y2 * sinZ;
var y3 = x1 * sinZ + y2 * cosZ;
return [x3, y3, z2];
}
// Rotate each vertex
var p1 = rotate(triangle[0], triangle[1], triangle[2]);
var p2 = rotate(triangle[3], triangle[4], triangle[5]);
var p3 = rotate(triangle[6], triangle[7], triangle[8]);
result[0] = p1[0];
result[1] = p1[1];
result[2] = p1[2];
result[3] = p2[0];
result[4] = p2[1];
result[5] = p2[2];
result[6] = p3[0];
result[7] = p3[1];
result[8] = p3[2];
return result;
}
function projectTriangle(triangle) {
// triangle: [x1, y1, z1, x2, y2, z2, x3, y3, z3]
// Perspective projection parameters
var fov = 80; // Focal length (distance from camera to projection plane)
var cx = SCREEN_SIZE / 2;
var cy = SCREEN_SIZE / 2;
function project(x, y, z) {
// Avoid division by zero
var zz = z === 0 ? 0.0001 : z;
return [Math.round(cx + (x - cx) * (fov / (fov + zz))), Math.round(cy + (y - cy) * (fov / (fov + zz)))];
}
// Reuse pre-allocated arrays for projection results
if (!projectTriangle.result) {
projectTriangle.result = [0, 0, 0, 0, 0, 0];
}
var result = projectTriangle.result;
var p1 = project(triangle[0], triangle[1], triangle[2]);
var p2 = project(triangle[3], triangle[4], triangle[5]);
var p3 = project(triangle[6], triangle[7], triangle[8]);
// Fill result array directly
result[0] = p1[0];
result[1] = p1[1];
result[2] = p2[0];
result[3] = p2[1];
result[4] = p3[0];
result[5] = p3[1];
return result;
}
function isBackfacing(projectedTriangle) {
// Check winding order using cross product of projected triangle
// projectedTriangle: [x1, y1, x2, y2, x3, y3]
var x1 = projectedTriangle[0];
var y1 = projectedTriangle[1];
var x2 = projectedTriangle[2];
var y2 = projectedTriangle[3];
var x3 = projectedTriangle[4];
var y3 = projectedTriangle[5];
// Calculate cross product to determine winding order
var crossProduct = (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
// If cross product is negative, triangle is clockwise (backfacing)
return crossProduct < 0;
}
//Start of the 3d renderer
var triangles = [[-16, -16, -16, 16, -16, -16, -16, 16, -16], [-16, 16, -16, 16, -16, -16, 16, 16, -16], [16, -16, -16, 16, -16, 16, 16, 16, -16], [16, 16, -16, 16, -16, 16, 16, 16, 16], [-16, -16, 16, -16, 16, 16, 16, -16, 16], [-16, 16, 16, 16, 16, 16, 16, -16, 16], [-16, -16, 16, -16, -16, -16, -16, 16, 16], [-16, 16, 16, -16, -16, -16, -16, 16, -16]];
// Center the cube by translating to the middle of the screen
var centerX = SCREEN_SIZE / 2;
var centerY = SCREEN_SIZE / 2;
var centerZ = 16; // Move slightly back for better perspective
// This is the part where the cube is drawn
// TODO: add dk water music
var angleX = 0;
var angleY = 0;
var angleZ = 0;
// Momentum variables for rotation
var momentumX = 0;
var momentumY = 0;
var lastDragX = null;
var lastDragY = null;
var lastMoveTime = null;
// Drag state for rotation
var dragStartX = null;
var dragStartAngleY = null;
var dragStartY = null;
var dragStartAngleX = null;
var isDragging = false;
// Touch/mouse down: start drag
game.down = function (x, y, obj) {
dragStartX = x;
dragStartAngleY = angleY;
dragStartY = y;
dragStartAngleX = angleX;
isDragging = true;
};
// Touch/mouse up: end drag
game.up = function (x, y, obj) {
if (isDragging && lastDragX !== null && lastDragY !== null && lastMoveTime !== null) {
// Calculate velocity based on last drag movement
var now = Date.now();
var dt = (now - lastMoveTime) / 1000; // seconds
if (dt < 0.2 && dt > 0) {
// Only if released soon after last move
// Calculate deltas since last move
var dx = lastDragX - dragStartX;
var dy = lastDragY - dragStartY;
// Calculate velocity (radians per second)
momentumY = -(dx / 2048 * (2 * Math.PI)) / dt;
momentumX = dy / 2732 * (2 * Math.PI) / dt;
}
}
isDragging = false;
lastDragX = null;
lastDragY = null;
lastMoveTime = null;
};
// Touch/mouse move: update angles if dragging
game.move = function (x, y, obj) {
if (isDragging) {
// Horizontal drag for Y-axis rotation
var dx = x - dragStartX;
angleY = dragStartAngleY - dx / 2048 * (2 * Math.PI);
// Vertical drag for X-axis rotation
var dy = y - dragStartY;
angleX = dragStartAngleX + dy / 2732 * (2 * Math.PI);
// Track last drag position and time for momentum
lastDragX = x;
lastDragY = y;
lastMoveTime = Date.now();
}
};
LK.setTimeout(function () {
game.update = function () {
// Apply rotation momentum if not dragging
if (!isDragging) {
angleX += momentumX;
angleY += momentumY;
// Decay momentum
momentumX *= 0.95;
momentumY *= 0.95;
// Clamp very small values to zero to prevent drift
if (Math.abs(momentumX) < 0.00001) momentumX = 0;
if (Math.abs(momentumY) < 0.00001) momentumY = 0;
}
clearScreen();
triangles.forEach(function (triangle, i) {
var rotatedTriangle = rotateTriangle(triangle, angleX, angleY, angleZ);
var centeredTriangle = translateTriangle(rotatedTriangle, centerX, centerY, centerZ);
var projectedTriangle = projectTriangle(centeredTriangle);
// Only draw triangle if it's not backfacing
if (!isBackfacing(projectedTriangle)) {
drawTriangle(projectedTriangle, 0xFFFFFF, true);
}
});
};
}, 2500); ===================================================================
--- original.js
+++ change.js
@@ -257,8 +257,14 @@
// TODO: add dk water music
var angleX = 0;
var angleY = 0;
var angleZ = 0;
+// Momentum variables for rotation
+var momentumX = 0;
+var momentumY = 0;
+var lastDragX = null;
+var lastDragY = null;
+var lastMoveTime = null;
// Drag state for rotation
var dragStartX = null;
var dragStartAngleY = null;
var dragStartY = null;
@@ -273,23 +279,55 @@
isDragging = true;
};
// Touch/mouse up: end drag
game.up = function (x, y, obj) {
+ if (isDragging && lastDragX !== null && lastDragY !== null && lastMoveTime !== null) {
+ // Calculate velocity based on last drag movement
+ var now = Date.now();
+ var dt = (now - lastMoveTime) / 1000; // seconds
+ if (dt < 0.2 && dt > 0) {
+ // Only if released soon after last move
+ // Calculate deltas since last move
+ var dx = lastDragX - dragStartX;
+ var dy = lastDragY - dragStartY;
+ // Calculate velocity (radians per second)
+ momentumY = -(dx / 2048 * (2 * Math.PI)) / dt;
+ momentumX = dy / 2732 * (2 * Math.PI) / dt;
+ }
+ }
isDragging = false;
+ lastDragX = null;
+ lastDragY = null;
+ lastMoveTime = null;
};
// Touch/mouse move: update angles if dragging
game.move = function (x, y, obj) {
if (isDragging) {
// Horizontal drag for Y-axis rotation
var dx = x - dragStartX;
- angleY = dragStartAngleY + dx / 2048 * (2 * Math.PI);
+ angleY = dragStartAngleY - dx / 2048 * (2 * Math.PI);
// Vertical drag for X-axis rotation
var dy = y - dragStartY;
- angleX = dragStartAngleX - dy / 2732 * (2 * Math.PI);
+ angleX = dragStartAngleX + dy / 2732 * (2 * Math.PI);
+ // Track last drag position and time for momentum
+ lastDragX = x;
+ lastDragY = y;
+ lastMoveTime = Date.now();
}
};
LK.setTimeout(function () {
game.update = function () {
+ // Apply rotation momentum if not dragging
+ if (!isDragging) {
+ angleX += momentumX;
+ angleY += momentumY;
+ // Decay momentum
+ momentumX *= 0.95;
+ momentumY *= 0.95;
+ // Clamp very small values to zero to prevent drift
+ if (Math.abs(momentumX) < 0.00001) momentumX = 0;
+ if (Math.abs(momentumY) < 0.00001) momentumY = 0;
+ }
clearScreen();
triangles.forEach(function (triangle, i) {
var rotatedTriangle = rotateTriangle(triangle, angleX, angleY, angleZ);
var centeredTriangle = translateTriangle(rotatedTriangle, centerX, centerY, centerZ);
@@ -299,6 +337,5 @@
drawTriangle(projectedTriangle, 0xFFFFFF, true);
}
});
};
-}, 1500);
-;
\ No newline at end of file
+}, 2500);
\ No newline at end of file