User prompt
create a new Face class equivalent to the SimpleFace but with a customizable number of points (min=2; max =10)
Code edit (2 edits merged)
Please save this source code
User prompt
Create a new Sphere class equivalent to the Cube class
Code edit (1 edits merged)
Please save this source code
Initial prompt
Copy 3d Cube Demo
/****
* Classes
****/
/***********************************************************************************/
/********************************** CUBE CLASS ************************************/
/***********************************************************************************/
var Cube = Container.expand(function () {
var self = Container.call(this);
self.z = 0;
self.baseSize = 100;
// Initialize cube faces using SimpleFace class
self.frontFace = new SimpleFace({
w: self.baseSize,
h: self.baseSize,
d: self.baseSize,
dx: 0,
dy: 0,
dz: 1,
rx: 0,
ry: 0,
rz: 0,
ti: 0xFFFFFF
});
self.backFace = new SimpleFace({
w: self.baseSize,
h: self.baseSize,
d: self.baseSize,
dx: 0,
dy: 0,
dz: -1,
rx: Math.PI,
ry: 0,
rz: 0,
ti: 0xFFFFFF
});
self.leftFace = new SimpleFace({
w: self.baseSize,
h: self.baseSize,
d: self.baseSize,
dx: -1,
dy: 0,
dz: 0,
rx: 0,
ry: Math.PI / 2,
rz: 0,
ti: 0xFFFFFF
});
self.rightFace = new SimpleFace({
w: self.baseSize,
h: self.baseSize,
d: self.baseSize,
dx: 1,
dy: 0,
dz: 0,
rx: 0,
ry: -Math.PI * 0.5,
rz: 0,
ti: 0xFFFFFF
});
self.topFace = new SimpleFace({
w: self.baseSize,
h: self.baseSize,
d: self.baseSize,
dx: 0,
dy: -1,
dz: 0,
rx: -Math.PI / 2,
ry: 0,
rz: 0,
ti: 0xFFFFFF
});
self.bottomFace = new SimpleFace({
w: self.baseSize,
h: self.baseSize,
d: self.baseSize,
dx: 0,
dy: 1,
dz: 0,
rx: Math.PI / 2,
ry: 0,
rz: 0,
ti: 0xFFFFFF
});
self.faces = [self.frontFace, self.backFace, self.leftFace, self.rightFace, self.topFace, self.bottomFace];
self.faces.forEach(function (face) {
self.addChild(face);
});
self.speedX = 5;
self.speedY = 5;
self.speedZ = 5;
// Rotate cube around its axes
self.rotate3D = function (angleX, angleY, angleZ) {
log("cube rotate3D ");
self.rotation = angleZ;
var zScaleFactor = 1 + self.z / 500;
self.faces.forEach(function (face) {
face.rotate3D(angleX, angleY, angleZ, zScaleFactor);
});
};
});
/***********************************************************************************/
/********************************** SHAPE CLASS ************************************/
/***********************************************************************************/
var Shape = Container.expand(function (coordinates, tint) {
var self = Container.call(this);
self.polygon = drawPolygon(coordinates, tint); // Function to create a polygon from a list of coordinates
self.tint = tint;
self.attachLines = function () {
// Iterate through each line in the polygon and attach it to the shape
self.polygon.forEach(function (line) {
self.addChild(line);
});
};
self.attachLines();
self.updateCoordinates = function (newCoordinates) {
log("Shape updateCoordinates ", newCoordinates);
// Ensure newCoordinates is an array and has the same length as the current polygon
if (!Array.isArray(newCoordinates) || newCoordinates.length !== self.polygon.length) {
error("Invalid newCoordinates length");
return;
}
// Update each line in the polygon with new coordinates
self.polygon = updatePolygon(self.polygon, newCoordinates);
};
});
/***********************************************************************************/
/******************************* SIMPLE FACE CLASS *********************************/
/***********************************************************************************/
var SimpleFace = Container.expand(function (options) {
var self = Container.call(this);
log("SimpleFAce init options =", options);
self.baseSize = 100;
options = options || {};
self.w = options.w || self.baseSize;
self.h = options.h || self.baseSize;
self.d = options.d || self.baseSize, self.dx = options.dx || 0;
self.dy = options.dy || 0;
self.dz = options.dz || 0;
self.rx = options.rx || 0;
self.ry = options.ry || 0;
self.rz = options.rz || 0;
self.tint = options.ti || 0xFFFFFF;
// Define faceCoordinates property
self.baseFaceCoordinates = [{
x: -self.w + self.dx * self.w,
y: -self.h + self.dy * self.h,
z: self.dz * self.d
},
// Top-left
{
x: self.w + self.dx * self.w,
y: -self.h + self.dy * self.h,
z: self.dz * self.d
},
// Top-right
{
x: self.w + self.dx * self.w,
y: self.h + self.dy * self.h,
z: self.dz * self.d
},
// Bottom-right
{
x: -self.w + self.dx * self.w,
y: self.h + self.dy * self.h,
z: self.dz * self.d
} // Bottom-left
];
log("SimpleFAce ready to init ...", self.baseFaceCoordinates, "DX=" + self.dx);
self.baseFaceCoordinates.forEach(function (point) {
// Update z of each face point coordinates depending on dz and rx, ry
point.z += self.dz * Math.cos(self.rx) * Math.cos(self.ry);
});
// Create a square face using the Shape class
self.face = new Shape(self.baseFaceCoordinates, self.tint);
// Attach the face to the SimpleFace container
self.addChild(self.face);
// Rotate in 3d : X = roasting chicken / Y = whirling dervish / Z = wheel of Fortune
self.rotate3D = function (angleX, angleY, angleZ, scale) {
scale = scale || 1;
log("SimpleFace rotate3D old coord=", self.faceCoordinates, Date.now());
self.faceCoordinates = self.baseFaceCoordinates.map(function (coord) {
return {
x: coord.x,
y: coord.y,
z: coord.z
};
});
// Apply rotation around X-axis
// Adjust initial rotation parameters before applying new rotations
self.faceCoordinates = self.faceCoordinates.map(function (coord) {
// Apply initial rotation around Z-axis
var xZ = coord.x * Math.cos(self.rz) - coord.y * Math.sin(self.rz);
var yZ = coord.x * Math.sin(self.rz) + coord.y * Math.cos(self.rz);
// Apply initial rotation around Y-axis
var xY = xZ * Math.cos(self.ry) + coord.z * Math.sin(self.ry);
var zY = coord.z * Math.cos(self.ry) - xZ * Math.sin(self.ry);
// Apply initial rotation around X-axis
var yX = yZ * Math.cos(self.rx) - zY * Math.sin(self.rx);
var zX = yZ * Math.sin(self.rx) + zY * Math.cos(self.rx);
return {
x: xY,
y: yX,
z: zX
};
});
// Apply new rotations
// Calculate center of the face
var centerX = self.faceCoordinates.reduce(function (acc, coord) {
return acc + coord.x;
}, 0) / self.faceCoordinates.length;
var centerY = self.faceCoordinates.reduce(function (acc, coord) {
return acc + coord.y;
}, 0) / self.faceCoordinates.length;
var centerZ = self.faceCoordinates.reduce(function (acc, coord) {
return acc + coord.z;
}, 0) / self.faceCoordinates.length;
self.faceCoordinates = self.faceCoordinates.map(function (coord) {
// Translate coordinates to rotate around the center including dy and dz adjustment
var translatedY = (coord.y + self.dy * self.h - centerY) * Math.cos(angleX) - (coord.z + self.dz * self.d - centerZ) * Math.sin(angleX);
var translatedZ = (coord.y + self.dy * self.h - centerY) * Math.sin(angleX) + (coord.z + self.dz * self.d - centerZ) * Math.cos(angleX);
return {
x: coord.x + self.dx * self.w - centerX,
// Keep X unchanged but translate to rotate around center
y: translatedY + centerY,
z: translatedZ + centerZ
};
});
self.faceCoordinates = self.faceCoordinates.map(function (coord) {
var translatedX = (coord.z - centerZ) * Math.sin(angleY) + (coord.x - centerX) * Math.cos(angleY);
var translatedZ = (coord.z - centerZ) * Math.cos(angleY) - (coord.x - centerX) * Math.sin(angleY);
return {
x: translatedX + centerX,
y: coord.y,
// Keep Y unchanged
z: translatedZ + centerZ
};
});
self.faceCoordinates = self.faceCoordinates.map(function (coord) {
return {
x: coord.x * scale,
y: coord.y * scale,
z: coord.z * scale
};
});
log("SimpleFace rotate3D new coord=", self.faceCoordinates, Date.now());
self.face.updateCoordinates(self.faceCoordinates);
};
// initialize face in 3D space
self.rotate3D(0, 0, 0, 1);
log("SimpleFace end init coord=", self.baseFaceCoordinates, Date.now());
});
/****
* Initialize Game
****/
// Utility function to draw a polygon using drawLine
var game = new LK.Game({
backgroundColor: 0x000050 // Initialize game with a black background
});
/****
* Game Code
****/
var fpsText;
var lastTick;
var frameCount;
var debugText;
/***********************************************************************************/
/******************************* UTILITY FUNCTIONS *********************************/
/***********************************************************************************/
function drawPolygon(coordinates, tint) {
log("drawPolygon ", coordinates);
var lines = [];
for (var i = 0; i < coordinates.length; i++) {
var startPoint = coordinates[i];
var endPoint = coordinates[(i + 1) % coordinates.length]; // Loop back to the first point
var line = drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, tint);
lines.push(line);
}
return lines;
}
function updatePolygon(lines, newCoordinates, scale) {
log("updatePolygon ", lines, scale);
// Ensure lines and newCoordinates have the same length
if (lines.length !== newCoordinates.length) {
error("updatePolygon error: lines and newCoordinates length mismatch");
return lines;
}
// Update each line with new coordinates
for (var i = 0; i < lines.length; i++) {
var startPoint = newCoordinates[i];
var endPoint = newCoordinates[(i + 1) % newCoordinates.length]; // Loop back to the first point for the last line
updateLine(lines[i], startPoint.x, startPoint.y, endPoint.x, endPoint.y, scale);
}
return lines;
}
// Utility function to draw lines between two points
function drawLine(x1, y1, x2, y2, tint) {
log("drawLine ", x1, y1);
var line = LK.getAsset('line', {
anchorX: 0.0,
anchorY: 0.0,
x: x1,
y: y1,
tint: tint
});
line.startX = x1;
line.startY = y1;
line.endX = x2;
line.endY = y2;
// Calculate the distance between the two points
var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
// Set the width of the line to the distance between the points
line.width = distance;
// Calculate the angle between the two points
var angle = Math.atan2(y2 - y1, x2 - x1);
// Correct angle calculation for all quadrants
line.rotation = angle;
return line;
}
// Utility function to draw lines between two points
function updateLine(line, newX1, newY1, newX2, newY2, scale) {
log("updateLine ", line);
scale = scale === undefined ? 1 : scale;
// Calculate midpoint of the original line
var midX = (newX1 + newX2) / 2;
var midY = (newY1 + newY2) / 2;
// Adjust start and end points based on scale
newX1 = midX + (newX1 - midX) * scale;
newY1 = midY + (newY1 - midY) * scale;
newX2 = midX + (newX2 - midX) * scale;
newY2 = midY + (newY2 - midY) * scale;
// Update line start and end coordinates after scaling
line.x = newX1;
line.y = newY1;
line.startX = newX1;
line.startY = newY1;
line.endX = newX2;
line.endY = newY2;
// Recalculate the distance between the new scaled points
var distance = Math.sqrt(Math.pow(newX2 - newX1, 2) + Math.pow(newY2 - newY1, 2));
// Update the width of the line to the new distance
line.width = distance;
// Recalculate the angle between the new points
var angle = Math.atan2(newY2 - newY1, newX2 - newX1);
// Update the rotation of the line to the new angle
line.rotation = angle;
return line;
}
function log() {
if (isDebug) {
console.log(arguments);
}
}
/***********************************************************************************/
/******************************* GAME VARIABLES*********************************/
/***********************************************************************************/
var cube;
var simpleFace;
var simpleFace2;
var simpleFace3;
var rotationSpeedX = 0;
var rotationSpeedY = 0;
var rotationSpeedZ = 0;
var isDebug = false;
var fullLog = [];
/***********************************************************************************/
/***************************** GAME INITIALIZATION *********************************/
/***********************************************************************************/
function gameInitialize() {
cube = new Cube();
cube.x = 2048 * 0.25; // Center horizontally
cube.y = 2732 / 2; // Center vertically
cube.z = 0;
game.addChild(cube);
if (isDebug) {
var debugMarker = LK.getAsset('debugMarker', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 * 0.5,
y: 2732 / 2
});
game.addChild(debugMarker);
fpsText = new Text2('FPS: 0', {
size: 50,
fill: "#ffffff"
});
// Position FPS text at the bottom-right corner
fpsText.anchor.set(1, 1); // Anchor to the bottom-right
LK.gui.bottomRight.addChild(fpsText);
// Update FPS display every second
lastTick = Date.now();
frameCount = 0;
// Debug text to display cube information
debugText = new Text2('Debug Info', {
size: 50,
fill: "#ffffff"
});
debugText.anchor.set(0.5, 0); // Anchor to the bottom-right
LK.gui.top.addChild(debugText);
}
}
/***********************************************************************************/
/******************************** MAIN GAME LOOP ***********************************/
/***********************************************************************************/
game.update = function () {
if (isDebug) {
debugText.setText("X: " + Math.round(cube.x) + ", Y: " + Math.round(cube.y) + ", Z: " + Math.round(cube.z) + ", R: " + cube.rotation.toFixed(2));
// FPS
var now = Date.now();
frameCount++;
if (now - lastTick >= 1000) {
// Update every second
fpsText.setText('FPS: ' + frameCount);
frameCount = 0;
lastTick = now;
}
}
};
gameInitialize(); // Initialize the game ===================================================================
--- original.js
+++ change.js
@@ -403,31 +403,8 @@
/***********************************************************************************/
/******************************** MAIN GAME LOOP ***********************************/
/***********************************************************************************/
game.update = function () {
- // Rotate simpleFace in 3D on each game update
- rotationSpeedX += 1 * Math.PI * 0.125 * 0.02;
- rotationSpeedY += 1 * Math.PI * 0.125 * 0.02;
- rotationSpeedZ += 1 * Math.PI * 0.125 * 0.02;
- // Update cube position with movement speed
- cube.x += cube.speedX;
- cube.y += cube.speedY;
- cube.z += cube.speedZ;
- // Check for cube bouncing on horizontal borders
- if (cube.x <= 100 || cube.x >= 2048 - 100) {
- cube.speedX *= -1; // Reverse horizontal direction
- }
- // Check for cube bouncing on Z dimension boundaries
- if (cube.z <= -250 || cube.z >= 1000) {
- // Assuming -500 and 500 as Z dimension boundaries
- cube.speedZ *= -1; // Reverse Z dimension direction
- }
- // Check for cube bouncing on vertical borders
- if (cube.y <= 100 || cube.y >= 2732 - 100) {
- cube.speedY *= -1; // Reverse vertical direction
- }
- // Rotating the cube
- cube.rotate3D(rotationSpeedX, rotationSpeedY, rotationSpeedZ);
if (isDebug) {
debugText.setText("X: " + Math.round(cube.x) + ", Y: " + Math.round(cube.y) + ", Z: " + Math.round(cube.z) + ", R: " + cube.rotation.toFixed(2));
// FPS
var now = Date.now();
remove background
remove background
Futuristic speaker in the shape of a white orb. Face view
white video camera icon
landscape of a furturistic world by night
a white music note
white sparkles emiting from the center. back background
clean red-violet beam from above
button in the shape of a protorealistic holographic futuristc Rectangle . Front view.
above the clouds by a bright night, no visible moon Photorealistic
White Clef de sol
A 20 nodes straight metalic lock chain. High definition. In-Game asset. 2d. High contrast. No shadows
a closed metalic padlock. No visible key hole.
white menu icon
in white