/**** * Classes ****/ var Cube = Container.expand(function (size) { var self = Container.call(this); size = size || 100; self.faces = []; self.rotationX = 0; self.rotationY = 0; self.rotationZ = 0; var vertices = [{ x: -size / 2, y: -size / 2, z: -size / 2 }, { x: size / 2, y: -size / 2, z: -size / 2 }, { x: size / 2, y: size / 2, z: -size / 2 }, { x: -size / 2, y: size / 2, z: -size / 2 }, { x: -size / 2, y: -size / 2, z: size / 2 }, { x: size / 2, y: -size / 2, z: size / 2 }, { x: size / 2, y: size / 2, z: size / 2 }, { x: -size / 2, y: size / 2, z: size / 2 }]; var faces = [[0, 1, 2, 3], // Front [4, 5, 6, 7], // Back [0, 1, 5, 4], // Top [2, 3, 7, 6], // Bottom [0, 3, 7, 4], // Left [1, 2, 6, 5] // Right ]; faces.forEach(function (faceIndices) { var facePoints = faceIndices.map(function (index) { return vertices[index]; }); var face = new SimpleFace({ points: facePoints, tint: 0xFFFFFF }); face.originalPoints = facePoints.map(function (p) { return { x: p.x, y: p.y, z: p.z }; }); self.addChild(face); self.faces.push(face); }); self.rotate3D = function (angleX, angleY, angleZ) { self.rotationX += angleX; self.rotationY += angleY; self.rotationZ += angleZ; var cosX = Math.cos(self.rotationX), sinX = Math.sin(self.rotationX); var cosY = Math.cos(self.rotationY), sinY = Math.sin(self.rotationY); var cosZ = Math.cos(self.rotationZ), sinZ = Math.sin(self.rotationZ); self.faces.forEach(function (face) { var transformedPoints = face.originalPoints.map(function (point) { var x = point.x, y = point.y, z = point.z; // Apply rotation around X-axis var newY = cosX * y - sinX * z; var newZ = sinX * y + cosX * z; // Apply rotation around Y-axis var newX = cosY * x + sinY * newZ; newZ = cosY * newZ - sinY * x; // Apply rotation around Z-axis x = cosZ * newX - sinZ * newY; y = sinZ * newX + cosZ * newY; return { x: x, y: y, z: newZ }; }); // Store transformed points face.transformedPoints = transformedPoints; face.points = transformedPoints; // Ensure points are updated here! }); }; }); var SimpleFace = Container.expand(function (options) { var self = Container.call(this); options = options || {}; self.points = options.points || [{ x: -50, y: -50 }, { x: 50, y: -50 }, { x: 50, y: 50 }, { x: -50, y: 50 }]; self.tint = options.tint || 0xFFFFFF; self.fillDensity = 300; self.lines = []; for (var i = 0; i < self.points.length; i++) { var start = self.points[i]; var end = self.points[(i + 1) % self.points.length]; var line = drawLine(start.x, start.y, end.x, end.y, self.tint); self.addChild(line); self.lines.push(line); } self.fillLines = []; for (var i = 1; i <= self.fillDensity; i++) { var ratio = i / (self.fillDensity + 1); var fillStart = interpolate(self.points[0], self.points[1], ratio); var fillEnd = interpolate(self.points[3], self.points[2], ratio); var tint = calculateShadowTint(fillStart); var fillLine = drawLine(fillStart.x, fillStart.y, fillEnd.x, fillEnd.y, tint); self.addChild(fillLine); self.fillLines.push(fillLine); } function calculateShadowTint(point) { var normal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { x: 0, y: 0, z: 1 }; var dx = light.x - point.x; var dy = light.y - point.y; var dz = light.z - point.z; var distance = Math.sqrt(dx * dx + dy * dy + dz * dz); // Normalize intensity (closer = brighter) var intensity = Math.max(0, 1 - distance / 6000); // Calculate light direction var lightDir = { x: dx / distance, y: dy / distance, z: dz / distance }; // Ensure `normal` exists if (!normal) { normal = { x: 0, y: 0, z: 1 }; // Default normal } // Calculate dot product for directional shading var dot = Math.max(0.2, lightDir.x * normal.x + lightDir.y * normal.y + lightDir.z * normal.z); dot = Math.max(0, dot); // Ensure it's non-negative (shadows only) // Combine distance and angle effects var finalIntensity = Math.pow(intensity * dot, 1.2); // Convert intensity to grayscale color var brightness = Math.floor(finalIntensity * 255); return brightness << 16 | brightness << 8 | brightness; } function interpolate(p1, p2, t) { return { x: p1.x + (p2.x - p1.x) * t, y: p1.y + (p2.y - p1.y) * t, z: p1.z + (p2.z - p1.z) * t // Added Z interpolation }; } self.updateFace = function (transformedPoints) { if (!transformedPoints || transformedPoints.length < 4) { return; } // Prevents errors self.lines.forEach(function (line, i) { var start = transformedPoints[i]; var end = transformedPoints[(i + 1) % transformedPoints.length]; line.x = start.x; line.y = start.y; var distance = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2)); line.width = distance; var angle = Math.atan2(end.y - start.y, end.x - start.x); line.rotation = angle; }); // Recalculate normal vector for shading direction var edge1 = { x: transformedPoints[1].x - transformedPoints[0].x, y: transformedPoints[1].y - transformedPoints[0].y, z: transformedPoints[1].z - transformedPoints[0].z }; var edge2 = { x: transformedPoints[3].x - transformedPoints[0].x, y: transformedPoints[3].y - transformedPoints[0].y, z: transformedPoints[3].z - transformedPoints[0].z }; var normal = { x: edge1.y * edge2.z - edge1.z * edge2.y, y: edge1.z * edge2.x - edge1.x * edge2.z, z: edge1.x * edge2.y - edge1.y * edge2.x }; // Normalize the normal vector var normLength = Math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z); if (normLength !== 0) { normal.x /= normLength; normal.y /= normLength; normal.z /= normLength; } else { normal = { x: 0, y: 0, z: 1 }; // Default normal if zero-length } // Update each fill line dynamically var start = transformedPoints[0]; var end = transformedPoints[3]; self.fillLines.forEach(function (fillLine, i) { var ratio = (i + 1) / (self.fillDensity + 1); var fillStart = interpolate(start, transformedPoints[1], ratio); var fillEnd = interpolate(end, transformedPoints[2], ratio); var tint = calculateShadowTint(fillStart, normal); fillLine.tint = tint; fillLine.x = fillStart.x; fillLine.y = fillStart.y; var distance = Math.sqrt(Math.pow(fillEnd.x - fillStart.x, 2) + Math.pow(fillEnd.y - fillStart.y, 2)); fillLine.width = distance; var angle = Math.atan2(fillEnd.y - fillStart.y, fillEnd.x - fillStart.x); fillLine.rotation = angle; }); }; function interpolate(p1, p2, t) { return { x: p1.x + (p2.x - p1.x) * t, y: p1.y + (p2.y - p1.y) * t, z: p1.z + (p2.z - p1.z) * t // Added Z interpolation }; } }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x24aae2 }); /**** * Game Code ****/ var light = { x: game.width / 2 + 100, y: game.height / 2 - 300, z: 800 }; /**** * Dynamic Shadows ****/ function calculateShadowTint(point) { var normal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { x: 0, y: 0, z: 1 }; var dx = light.x - point.x; var dy = light.y - point.y; var dz = light.z - point.z; var distance = Math.sqrt(dx * dx + dy * dy + dz * dz); // Normalize intensity (closer = brighter) var intensity = Math.max(0, 1 - distance / 500); // Calculate light direction var lightDir = { x: dx / distance, y: dy / distance, z: dz / distance }; // Ensure `normal` exists if (!normal) { normal = { x: 0, y: 0, z: 1 }; // Default normal } // Calculate dot product for directional shading var dot = lightDir.x * normal.x + lightDir.y * normal.y + lightDir.z * normal.z; dot = Math.max(0, dot); // Ensure it's non-negative (shadows only) // Combine distance and angle effects var finalIntensity = intensity * dot; // Convert intensity to grayscale color var brightness = Math.floor(finalIntensity * 255); return brightness << 16 | brightness << 8 | brightness; } /**** * Utility Functions ****/ function drawLine(x1, y1, x2, y2, tint) { var line = LK.getAsset('line', { anchorX: 0, anchorY: 0, x: x1, y: y1, tint: tint }); var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); line.width = distance; var angle = Math.atan2(y2 - y1, x2 - x1); line.rotation = angle; return line; } /**** * Game Variables ****/ var cube; var rotationSpeedX = 0.01; var rotationSpeedY = 0.01; function gameInitialize() { cube = new Cube(1000); cube.x = game.width / 2; cube.y = game.height / 2; game.addChild(cube); } game.update = function () { // Apply rotation first cube.rotate3D(rotationSpeedX, rotationSpeedY, 0); // Update each face dynamically after transformation cube.faces.forEach(function (face) { face.points = face.transformedPoints; // Make sure it updates with the rotated values face.updateFace(face.transformedPoints); }); }; gameInitialize(); // Define JSON object if not already defined var JSON = JSON || { parse: function parse(s) { return eval('(' + s + ')'); }, stringify: function stringify(o) { var r = []; if (typeof o == "string") { return '"' + o.replace(/"/g, '\\"') + '"'; } if (typeof o == "number" || typeof o == "boolean") { return o.toString(); } if (o instanceof Array) { for (var i = 0; i < o.length; i++) { r.push(JSON.stringify(o[i])); } return '[' + r.join(',') + ']'; } for (var k in o) { r.push('"' + k + '":' + JSON.stringify(o[k])); } return '{' + r.join(',') + '}'; } };
===================================================================
--- original.js
+++ change.js
@@ -257,9 +257,9 @@
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0x000050
+ backgroundColor: 0x24aae2
});
/****
* Game Code