人工智能实战:ClaudeAI辅助程序开发测试

以倒水小游戏为例

参考游戏

开发过程

小明:

how do i create a color sort game prototype like 'water sort puzzle' with babylon and javascript?

(备注:一般从创建游戏原型开始,最好能给出游戏类型、参考游戏和目标引擎,比如问题里的color sort game、water sort puzzle和babylon。如果目标引擎如果支持多种语言,应指定想要使用的语言,比如问题里的Javascript。而且开发者应具备目标引擎的基础知识,知道如何将AI给出的代码应用到引擎的工程中)

Claude:

Here's a basic prototype for a color sort game in Babylon.js:

js

// Create scene

var scene = new BABYLON.Scene(engine);

// Create camera

var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene);

// Create light

var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);

// Create boxes

var boxes = [];

var boxSize = 1;

var boxGap = 0.5;

for (var i = 0; i < 10; i++) {

for (var j = 0; j < 10; j++) {

var box = BABYLON.MeshBuilder.CreateBox("box", {size: boxSize}, scene);

box.position.x = i * (boxSize + boxGap);

box.position.z = j * (boxSize + boxGap);

box.material = new BABYLON.StandardMaterial("boxMaterial", scene);

box.material.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random());

boxes.push(box);

}

}

// On pointer down

scene.onPointerDown = function(evt) {

var pickResult = scene.pick(evt.position.x, evt.position.y);

if (pickResult.hit && pickResult.pickedMesh.name === "box") {

var selectedBox = pickResult.pickedMesh;

// Find closest matching color

var closestBox;

var minDistance = Number.MAX_VALUE;

for (var i = 0; i < boxes.length; i++) {

if (boxes[i] != selectedBox) {

var distance = BABYLON.Vector3.Distance(selectedBox.material.diffuseColor, boxes[i].material.diffuseColor);

if (distance < minDistance) {

closestBox = boxes[i];

minDistance = distance;

}

}

}

// Swap positions

var pos1 = selectedBox.position.clone();

var pos2 = closestBox.position.clone();

selectedBox.position = pos2;

closestBox.position = pos1;

}

};

// Game loop

scene.registerBeforeRender(function() {

// Check if all boxes are sorted

var sorted = true;

for (var i = 0; i < boxes.length - 1; i++) {

if (BABYLON.Vector3.Distance(boxes[i].position, boxes[i+1].position) != boxSize + boxGap) {

sorted = false;

break;

}

}

if (sorted) {

console.log("Sorted! Game over.");

scene.onPointerDown = null; // Disable interaction

}

});

This creates a grid of colored boxes, and on pointer down, it finds the closest matching color and swaps the two boxes. It checks in the game loop if all boxes are sorted, and if so, ends the game.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

good, i want a orthographic camera, how can i do?

(备注:我们是想做一个2D游戏,所以需要的是正交相机,正交相机是一个开发者需要知道的基础知识)

Claude:

To use an orthographic camera instead of a perspective camera, you can do:

js

// Create orthographic camera

var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 10, 0), scene);

camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

camera.orthoLeft = -10;

camera.orthoRight = 10;

camera.orthoBottom = -10;

camera.orthoTop = 10;

This will create an orthographic camera with viewport bounds from -10 to 10 on the x and z axes.You'll also want to remove the ArcRotateCamera controls, since those are for perspective cameras. So your full camera setup would be:

js

// Create orthographic camera

var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 10, 0), scene);

camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

camera.orthoLeft = -10;

camera.orthoRight = 10;

camera.orthoBottom = -10;

camera.orthoTop = 10;

// Disable default controls

scene.detachControl();

// Attach custom controls

scene.onPointerDown = function(evt) {

// ...

}

This will give you an orthographic view and use your custom pointer down controls instead of the default ArcRotateCamera controls.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

按照AI给出的正交相机代码渲染了一个立方体,发现立方体被“压扁了”

小明:

the ratio of the object rendered by orthographic camera is wrong, how do i get the right ratio?

(备注:按照AI给出的代码渲染出来的物体变形,需要给相机设置正确的纵横比,纵横比是开发者需要知道的基础知识。但AI给出的解决变形的方案依然是错的,正确的解决方案请参考下面的对话代码)

Claude:

Good catch! Orthographic cameras render objects uniformly scaled, so without adjusting the scale, objects will appear distorted.
To fix this, you need to:

1. Set the camera's aspect ratio to match your canvas
2. Scale the objects by 1/aspect ratioSo your full camera setup would be:

js

// Get canvas size

var canvas = scene.getEngine().getRenderingCanvas();

var width = canvas.width;

var height = canvas.height;

// Create orthographic camera

var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 10, 0), scene);

camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

camera.orthoLeft = -10;

camera.orthoRight = 10;

camera.orthoBottom = -10;

camera.orthoTop = 10;

camera.aspectRatio = width / height;

// Scale objects

for (var i = 0; i < boxes.length; i++) {

boxes[i].scaling.x = 1 / camera.aspectRatio;

}

// Disable default controls

scene.detachControl();

// Attach custom controls

scene.onPointerDown = function(evt) {

// ...

}

Setting the camera's aspectRatio will ensure it has a proper field of view.
Scaling the objects by 1/aspectRatio will counteract the uniform scaling and make the objects appear normal.With these two changes, your orthographic view should render objects with the proper aspect ratio.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

i can't fix with your solution, this is my solution:
var ratio = window.innerHeight/window.innerWidth;
camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
camera.orthoLeft = -10;
camera.orthoRight = 10;
camera.orthoTop = 10 * ratio;
camera.orthoBottom = -10 * ratio;

(备注:如果AI给出的代码错误,给它正确的方法能提高AI准确度)

Claude:

You're absolutely right, setting the orthographic viewport based on the window aspect ratio is a better solution!
Your code:

js

var ratio = window.innerHeight/window.innerWidth;

camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

camera.orthoLeft = -10;

camera.orthoRight = 10;

camera.orthoTop = 10 * ratio;

camera.orthoBottom = -10 * ratio;

Is a perfect way to get the right aspect ratio with an orthographic camera. My previous solution with setting the camera aspect ratio and scaling objects would not actually fix the aspect ratio distortion.Your method is the correct way to setup an orthographic camera with the proper viewport. Nicely done!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

the ratio is wrong again when i resize the browser window, how can i fix this?

Claude:

Good catch, you'll need to handle window resizes to update the orthographic camera viewport. You can do so with:

js

// On window resize

window.addEventListener("resize", function() {

// Get new ratio and update camera

var ratio = window.innerHeight / window.innerWidth;

camera.orthoTop = 10 * ratio;

camera.orthoBottom = -10 * ratio;

});

So your full code would be:

js

// Create orthographic camera

var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 10, 0), scene);

camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

camera.orthoLeft = -10;

camera.orthoRight = 10;

// Get initial ratio and set viewport

var ratio = window.innerHeight / window.innerWidth;

camera.orthoTop = 10 * ratio;

camera.orthoBottom = -10 * ratio;

// On window resize update viewport

window.addEventListener("resize", function() {

var ratio = window.innerHeight / window.innerWidth;

camera.orthoTop = 10 * ratio;

camera.orthoBottom = -10 * ratio;

});

// Disable default controls

scene.detachControl();

// Attach custom controls

scene.onPointerDown = function(evt) {

// ...

}

This will ensure your orthographic viewport is updated on resize to always match the window aspect ratio.

小明:

good job!

(备注:AI上一个问题给出的解决方案非常好,给它一个正向反馈,也许对它提高准确度有帮助)

Claude:

Thank you, I'm glad I could help explain orthographic cameras in Babylon.js!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

i want to use cylinders to represent bottles and water rather than boxes, how do i implement?

(备注:AI能知道我用cylinder是为了更像瓶子,这一点儿还是体现了它的智能性)

Claude:

Great idea! Using cylinders instead of boxes will look much more realistic for bottles.
To implement this, you can:

1.Create cylinder meshes instead of box meshes

2.Set the cylinder height based on the amount of "water" it will hold

3.Raise and lower the water level (cylinder height) when bottles are filled/emptied

For example:

js

// Bottle height

var bottleHeight = 5;

// Create bottles

var bottles = [];

for (var i = 0; i < 10; i++) {

// Create cylinder mesh

var bottle = BABYLON.MeshBuilder.CreateCylinder("bottle", {

height: bottleHeight,

diameterTop: 1,

diameterBottom: 1

}, scene);

// Position bottle

bottle.position.x = i * 2;

// Create cylinder to hold water

var water = BABYLON.MeshBuilder.CreateCylinder("water", {

height: 3, // Start at 60% full

diameterTop: 1,

diameterBottom: 1

}, scene);

// Position water cylinder inside bottle cylinder

water.position.y = 2;

// Set materials

bottle.material = new BABYLON.StandardMaterial("bottleMaterial", scene);

water.material = new BABYLON.StandardMaterial("waterMaterial", scene);

// Add to bottles array

bottles.push({

bottle: bottle,

water: water

});

}

// On pointer down

scene.onPointerDown = function(evt) {

// Get bottle

var pickResult = scene.pick(evt.position.x, evt.position.y);

if (pickResult.hit && pickResult.pickedMesh.name === "water") {

var selectedBottle = pickResult.pickedMesh.parent;

// Get bottle info from bottles array

var bottleInfo = bottles.find(b => b.water == selectedBottle);

// Raise or lower the water level

if (bottleInfo.water.position.y > 1.5) { // If over half full

bottleInfo.water.position.y -= 0.5;

} else {

bottleInfo.water.position.y += 0.5;

}

}

}

This will create bottles full of "water", and on click will either raise or lower the water level in the selected bottle. Let me know if you have any other questions!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

I want 2 to 4 different colors of water in each bottle

(备注:上一个问题给出的答案每个瓶子里只有一种颜色的水,明显是把要做颜色排序这个上下文给忘了,所以需要再明确问一下)

Claude:

To have multiple colors of water in each bottle, you can:

1.Create multiple cylinder meshes for the water, one for each color
2.Position the water cylinders at the same y position inside the bottle
3.Set a different material color for each water cylinderFor example:

js

// Bottle height

var bottleHeight = 5;

// Create bottles

var bottles = [];

for (var i = 0; i < 10; i++) {

// Create bottle cylinder

var bottle = BABYLON.MeshBuilder.CreateCylinder("bottle", { /* ... */ }, scene);

// Position bottle

bottle.position.x = i * 2;

// Create 2-4 water cylinders of different colors

var numColors = 2 + Math.floor(Math.random() * 3);

for (var j = 0; j < numColors; j++) {

// Create water cylinder

var water = BABYLON.MeshBuilder.CreateCylinder("water", { /* ... */ }, scene);

// Position at same y in bottle

water.position.y = 2;

// Set material color

water.material = new BABYLON.StandardMaterial("waterMaterial", scene);

water.material.diffuseColor = new BABYLON.Color3(Math.random(),

Math.random(),

Math.random());

// Add to bottle

bottle.addChild(water);

}

// Add bottle to bottles array

bottles.push(bottle);

}

// On pointer down

scene.onPointerDown = function(evt) {

// Get bottle

var pickResult = scene.pick(evt.position.x, evt.position.y);

if (pickResult.hit && pickResult.pickedMesh.name.startsWith("water")) {

var selectedWater = pickResult.pickedMesh;

var selectedBottle = selectedWater.parent;

// Get bottle info

var bottleInfo = bottles.find(b => b == selectedBottle);

// Raise or lower just the selected water cylinder

selectedWater.position.y += 0.5; // Raise

// Or

selectedWater.position.y -= 0.5; // Lower

}

}

This will create bottles with 2 to 4 cylinders of different colored "water" at the same level. On click, it will raise or lower just the selected water cylinder.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

对AI代码稍作修改之后的渲染结果

小明:

I want the water to be layered like a cocktail, so i think water should be at the same x position

(备注:上一个问题给出的代码没有做水平分层,再详细问一下,到这一步基本能把想要的瓶子给渲染出来了,但还是对代码做一些小的修改,比如要创建空瓶子、要在固定的4个颜色之间随机而不是完全随机、每个瓶子里所有的水不能是一种颜色)

Claude:

You're right, to have the water appear layered like a cocktail, the water cylinders should be at the same x position inside the bottle.
To implement this, you can:

1.Create the water cylinders at the same x position

2.Increment the y position for each new water cylinderFor example:

js

// Bottle height

var bottleHeight = 5;

// Create bottles

var bottles = [];

for (var i = 0; i < 10; i++) {

// Create bottle cylinder

var bottle = BABYLON.MeshBuilder.CreateCylinder("bottle", { /* ... */ }, scene);

// Position bottle

bottle.position.x = i * 2;

// Create 2-4 water cylinders of different colors

var numColors = 2 + Math.floor(Math.random() * 3);

var yPosition = 2; // Start at y=2

for (var j = 0; j < numColors; j++) {

// Create water cylinder at same x position

var water = BABYLON.MeshBuilder.CreateCylinder("water", {

height: 1,

diameterTop: 1,

diameterBottom: 1

}, scene);

water.position = bottle.position.clone(); // Same x as bottle

water.position.y = yPosition; // Increment y

// Set material color

water.material = new BABYLON.StandardMaterial("waterMaterial", scene);

water.material.diffuseColor = new BABYLON.Color3(Math.random(),

Math.random(),

Math.random());

// Add to bottle

bottle.addChild(water);

// Increment yPosition for next cylinder

yPosition += 1;

}

// Add bottle to bottles array

bottles.push(bottle);

}

// ...

// On pointer down

scene.onPointerDown = function(evt) {

// ...

// Raise or lower just the selected water cylinder

selectedWater.position.y += 0.5; // Raise

// Or

selectedWater.position.y -= 0.5; // Lower

}

This will create the water cylinders at the same x position inside the bottle, incrementing the y position, to appear layered.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

how can i get the children of bottle?

(备注:在如何获得瓶子里所有水的问题上,AI回答的有点儿傻,直接getChildren()就可以了,非要给我用遍历的方法。一开始以为是没告诉它是要获取拾取的瓶子的所有水,结果告诉它了也不行)

Claude:

You can get the children of a mesh (the bottle) using:

js

var bottleChildren = bottle.getChildren();

This will return an array of all the direct children of the bottle mesh.
So in your code, you could do:

js

// Create bottles

var bottles = [];

for (var i = 0; i < 10; i++) {

// Create bottle cylinder

var bottle = BABYLON.MeshBuilder.CreateCylinder("bottle", { /* ... */ }, scene);

// Position bottle

bottle.position.x = i * 2;

// Create water cylinders

// ...

// Add bottle to bottles array

bottles.push({

bottle: bottle,

waterCylinders: bottle.getChildren() // Store water cylinders

});

}

// On pointer down

scene.onPointerDown = function(evt) {

// Get selected bottle

var pickResult = scene.pick(evt.position.x, evt.position.y);

var selectedBottle = pickResult.pickedMesh;

// Get bottle info

var bottleInfo = bottles.find(b => b.bottle == selectedBottle);

// Get the water cylinders for this bottle

var waterCylinders = bottleInfo.waterCylinders;

// Raise or lower selected water cylinder

// ...

}

Now in your pointer down logic, you have access to waterCylinders which contains all the water cylinders for the selected bottle.
So you can raise/lower the selected water cylinder, remove cylinders, add new ones, etc.

小明:

how can i get the children of picked bottle?

Claude:

When a bottle is picked (selected), you can get its children (water cylinders) by:

  1. Storing the bottle mesh and its children in the bottles array
  2. When the bottle is picked, finding it in the bottles array to get the childrenFor example:

js

// Create bottles

var bottles = [];

for (var i = 0; i < 10; i++) {

// Create bottle

var bottle = BABYLON.MeshBuilder.CreateCylinder("bottle", { /* ... */ }, scene);

// Create water cylinders

var waterCylinders = [];

for (var j = 0; j < 3; j++) {

var water = BABYLON.MeshBuilder.CreateCylinder("water", { /* ... */ }, scene);

bottle.addChild(water);

waterCylinders.push(water);

}

// Store bottle and children in array

bottles.push({

bottle: bottle,

waterCylinders: waterCylinders

});

}

// On pointer down

scene.onPointerDown = function(evt) {

// Get picked bottle

var pickResult = scene.pick(evt.position.x, evt.position.y);

var selectedBottle = pickResult.pickedMesh;

// Find in bottles array to get children

var bottleInfo = bottles.find(b => b.bottle == selectedBottle);

var waterCylinders = bottleInfo.waterCylinders;

// Use waterCylinders ...

}

This will:- Store each bottle and its water cylinder children in the bottles array
- On pointer down, get the picked bottle mesh
- Find that bottle in the bottles array to get its .waterCylinders property
- Now you have access to the water cylinders for the selected bottle

小明:

i think your solution is complex, this is my simple solution:
scene.onPointerDown = (evt, pickInfo) => {
if (pickInfo.hit) {

(备注:不过给AI一些简单的示例代码,AI就能给出合理的方法了,我不知道它是真懂还是假懂,感觉是很厉害)

Claude:

You're right, accessing the picked mesh's .getChildren() directly is a simpler solution than storing all the parent-child relationships in an array.
Your solution would be:

js

// On pointer down

scene.onPointerDown = (evt, pickInfo) => {

if (pickInfo.hit) {

var selectedBottle = pickInfo.pickedMesh;

var waterCylinders = selectedBottle.getChildren();

// Use waterCylinders ...

}

}

This simply gets the .getChildren() of the picked bottle mesh, which will return its water cylinders.
So a full example would be:

js

// Create bottles

var bottles = [];

for (var i = 0; i < 10; i++) {

// Create bottle

var bottle = BABYLON.MeshBuilder.CreateCylinder("bottle", { /* ... */ }, scene);

// Create water cylinders

for (var j = 0; j < 3; j++) {

var water = BABYLON.MeshBuilder.CreateCylinder("water", { /* ... */ }, scene);

bottle.addChild(water);

}

bottles.push(bottle);

}

// On pointer down

scene.onPointerDown = (evt, pickInfo) => {

if (pickInfo.hit) {

var selectedBottle = pickInfo.pickedMesh;

var waterCylinders = selectedBottle.getChildren();

// Change water cylinder materials

for (var i = 0; i < waterCylinders.length; i++) {

waterCylinders[i].material.diffuseColor = BABYLON.Color3.Red();

}

}

}

This is indeed a simpler solution - nicely optimized! Directly accessing .getChildren() removes the need to track parent-child relationships separately.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

How do I check if the color of the water is the same?

(备注:开始写判断逻辑,主要是颜色相同判断,给的代码不太靠谱,能用的就是颜色的equals方法)

Claude:

You can check if two materials (and thus, two meshes) have the same color by comparing their diffuseColor properties.
For example:

js

// Get materials of two water cylinders

var water1Mat = water1.material;

var water2Mat = water2.material;

// Check if diffuseColors are equal

if (water1Mat.diffuseColor.equals(water2Mat.diffuseColor)) {

// Colors are the same!

} else {

// Colors are different

}

So in your code, you could do:

js

// On pointer down

scene.onPointerDown = function(evt) {

// Get selected bottle

var pickResult = scene.pick(evt.position.x, evt.position.y);

var selectedBottle = pickResult.pickedMesh;

// Get bottle info

var bottleInfo = bottles.find(b => b.bottle == selectedBottle);

// Check if selected color matches any other water cylinders

var selectedColor;

for (var i = 0; i < bottleInfo.waterCylinders.length; i++) {

var water = bottleInfo.waterCylinders[i];

if (water == pickResult.pickedMesh) {

selectedColor = water.material.diffuseColor;

} else if (selectedColor.equals(water.material.diffuseColor)) {

// Found a match!

console.log("Found matching color!");

}

}

}

This will loop through all the water cylinders in the selected bottle, check if any match the selected color, and log a message if a match is found.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

小明:

how do i set one water of one bottle as child of another?

(备注:开始写移动逻辑,主要是重设父物体并更新位置,感觉AI在对空间问题的处理上还比较差)

Claude:

o set a single water cylinder from one bottle as a child of another bottle, you can:

  1. Get the source bottle and water cylinder to reparent
  2. Get the target bottle to reparent to
  3. Remove the water cylinder from the source bottle
  4. Add the water cylinder as a child of the target bottleFor example:

js

// Bottle and water cylinder vars

var sourceBottle;

var targetBottle;

var waterToReparent;

// On reparent button click

function reparentWater() {

// Get source info

sourceBottle = bottles.find(b => /* ... */);

waterToReparent = sourceBottle.getChildren().find(w => /* ... */);

// Get target bottle

targetBottle = bottles.find(b => /* ... */);

// Remove from source parent

sourceBottle.removeChild(waterToReparent);

// Add to target parent

targetBottle.addChild(waterToReparent);

}

// ...

// On click, reparent water

reparentButton.onclick = reparentWater;

This will:- Get the source bottle and specific water cylinder to reparent
- Get the target bottle
- Remove the water cylinder from the source bottle
- Add the water cylinder as a child of the target bottleSo that single water cylinder will now appear inside the target bottle, having been reparented.
The .removeChild() and .addChild() methods are key to reparenting a mesh to a new parent.

一个基本可玩的版本

小明:

after i set one water as a child of another bottle, its position is still in the previous bottle, how do i set its position correct?

(备注:经过自己较多修改,做完这步之后,有了一个基本可以玩的版本,但随机算法有瑕疵,会出现瓶子填不满的情况)

Claude:

Good catch! When you reparent a mesh to a new parent, its local position remains the same. So you'll need to update its position to be relative to the new parent.
To fix the position of the reparented water cylinder, you can:

1. Get the new parent bottle's world matrix
2. Convert the water cylinder's local position to world space using its previous parent's world matrix
3. Transform the world position into the new parent's local space
4. Set the water cylinder's local position to the new local positionFor example:

js

// Bottle and water cylinder vars

var sourceBottle;

var targetBottle;

var waterToReparent;

// On reparent button click

function reparentWater() {

// ...

// Get new parent world matrix

var targetWorld = targetBottle.getWorldMatrix();

// Get water local and world positions

var waterLocal = waterToReparent.position;

var sourceWorld = sourceBottle.getWorldMatrix();

var waterWorld = BABYLON.Vector3.TransformCoordinates(waterLocal, sourceWorld);

// Transform to new local position

var newLocal = BABYLON.Vector3.TransformCoordinates(waterWorld,

targetWorld.invert());

// Set new local position

waterToReparent.position = newLocal;

}

// ...

This will:- Get the target bottle's world matrix
- Transform the water cylinder's local position to world space using the source bottle
- Invert the target bottle's world matrix to get its local space
- Transform the water world position into the target bottle's local space
- Set the water cylinder's local position to the new local positionSo after reparenting, the water cylinder will appear in the correct position relative to its new parent.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

解决完算法瑕疵的可玩版本

小明:

how to shuffle an array in javascript?

(备注:为解决之前随机算法的瑕疵,让AI给出一个洗牌算法,当然自己得先知道需要洗牌算法,否则不太好给AI描述清楚算法的瑕疵。解决完算法瑕疵就有了一个可玩版本,剩下的就是倒水效果等完善工作)

Claude:

You can shuffle an array in JavaScript using the .shuffle() method from lodash, or by implementing the Fisher-Yates shuffle algorithm.Using lodash:

js

let array = [1, 2, 3, 4, 5];

_.shuffle(array);

// array is now [3, 5, 1, 4, 2]

Implementing the Fisher-Yates shuffle:

js

let array = [1, 2, 3, 4, 5];

function shuffle(array) {

let m = array.length, t, i;

// While there remain elements to shuffle

while (m) {

// Pick a remaining element

i = Math.floor(Math.random() * m--);

// And swap it with the current element

[array[m], array[i]] = [array[i], array[m]];

}

return array;

}

shuffle(array);

// array is now [3, 5, 1, 4, 2]

The Fisher-Yates shuffle works by randomly swapping elements in the array until all elements have been swapped. This gives a properly randomized shuffle.
So either by using lodash's .shuffle() convenience method, or implementing the Fisher-Yates algorithm yourself, you can shuffle an array in JavaScript.

欢迎加入我们!

感兴趣的同学可以投递简历至:CYouEngine@cyou-inc.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搜狐畅游引擎部

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值