Слияние кода завершено, страница обновится автоматически
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap5 实例</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="static/bootstrap.min.css" rel="stylesheet">
<script src="static/bootstrap.bundle.min.js"></script>
<script src="static/jquery.min.js"></script>
<script src="static/three.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
#three-container {
width: 100%;
height: 100%;
}
#toolbox {
position: absolute;
top: 10px;
left: 10px;
background-color: rgba(255, 255, 255, 0.1);
/* 半透明背景 */
padding: 10px;
border-radius: 5px;
z-index: 1000;
/* 确保覆盖在Three.js渲染内容之上 */
}
</style>
</head>
<body>
<div id="three-container"></div>
<div id="toolbox">
<div class="input-group mb-2">
<span id="show-time" class="btn btn-info" onclick="hc.show_tools()">0</span>
<span id="state-message" class="input-group-text"></span>
</div>
<div id="tools" style="display:none;">
<div class="input-group mb-1">
<button type="button" class="form-control btn btn-primary" onclick="hc.view(this)">前侧</button>
<button type="button" class="form-control btn btn-primary" onclick="hc.view(this)">后侧</button>
<button type="button" class="form-control btn btn-primary" onclick="hc.view(this)">左侧</button>
<button type="button" class="form-control btn btn-primary" onclick="hc.view(this)">右侧</button>
<button type="button" class="form-control btn btn-primary" onclick="hc.view(this)">俯视图</button>
<button type="button" class="form-control btn btn-primary" onclick="hc.view(this)">顺时针</button>
<button type="button" class="form-control btn btn-primary" onclick="hc.view(this)">逆时针</button>
</div>
<div class="input-group mb-1">
<span id="posColorList" class="badge bg-info" style="width: 35px;">0</span>
<button type="button" class="btn btn-primary" onclick="hc.step(this)">-</button>
<input class="form-control" type="range" id="myRange" onchange="hc.step(this)" value="0" min="0" max="0"
step="1">
<button type="button" class="btn btn-primary" onclick="hc.step(this)">+</button>
<button id="man-auto" type="button" class="btn btn-primary" onclick="hc.step(this)">》</button>
</div>
<textarea class="form-control" rows="3" id="sgftext" onchange="hc.getSGF(this)"></textarea>
</div>
</div>
<script>
var health_alert = false;
function health() {
const now = new Date();
const minutes = now.getMinutes();
if (minutes === 0 || minutes === 30) {
if (health_alert) {
alert("游戏健康忠告:请注意休息,合理安排游戏时间。");
health_alert = false;
}
} else {
health_alert = true;
}
}
class SimpleGo { //围棋基本类:下棋,提子
constructor() {
this.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"];
this.newWeiQi([], {}, []);
this.goString = { string: [], empty: [] };
}
go_handler(item = "B[qd]") {
var position = item.slice(2, 4);
if (this.posColor.hasOwnProperty(position)) {
return false;
} else {
this.posColor[position] = [item[0]];
}
var del_pos = [];
var near_pos = this.near_positions(position);
for (var npn in near_pos) {
if (this.posColor.hasOwnProperty(near_pos[npn])) {
if (this.posColor[near_pos[npn]][0] != this.posColor[position][0]) {
this.goString = { 'string': [], 'empty': [] };
this.go_string(near_pos[npn]);
if (this.goString['empty'].length == 0) {
for (var spn in this.goString['string']) {
del_pos.includes(this.goString['string'][spn]) || del_pos.push(this.goString['string'][spn]);
}
}
}
}
}
if (del_pos.length == 0) {
this.goString = { 'string': [], 'empty': [] };
this.go_string(position);
if (this.goString['empty'].length == 0) {
delete this.posColor[position];
return false;
}
} else {
for (var d_p in del_pos) {
delete this.posColor[del_pos[d_p]];
}
}
this.sgf.push(item);
this.posColor[position].push(this.sgf.length)
this.posColorList.push(JSON.parse(JSON.stringify(this.posColor)));
return true;
}
go_string(position) {
this.goString['string'].push(position);
var nPos = this.near_positions(position);
for (var np in nPos) {
if (this.posColor.hasOwnProperty(nPos[np])) {
if (!this.goString['string'].includes(nPos[np]) && this.posColor[nPos[np]][0] == this.posColor[position][0]) {
this.go_string(nPos[np]);
}
} else {
this.goString['empty'].includes(nPos[np]) || this.goString['empty'].push(nPos[np]);
}
}
}
near_positions(position) {
var near_pos = [];
var row = this.near(position[0]);
var col = this.near(position[1]);
for (var r in row) {
near_pos.push(row[r] + position[1]);
}
for (var c in col) {
near_pos.push(position[0] + col[c]);
}
return near_pos;
}
near(char) {
switch (char) {
case "a":
return ["b"];
case "s":
return ["r"];
case "b": case "c": case "d": case "e": case "f": case "g":
case "h": case "i": case "j": case "k": case "l": case "m":
case "n": case "o": case "p": case "q": case "r":
default:
var pos = this.positions.indexOf(char);
return [this.positions[pos - 1], this.positions[pos + 1]];
}
}
newWeiQi(sgf, posColor, posColorList) {
this.sgf = sgf;
this.posColor = posColor;
this.posColorList = posColorList;
}
}
class ThreeBase {
constructor(threeContainerId) {
this.scene = this.create_scene("LightBlue"); //场景
this.camera = this.create_camera([0, 0, 22]); //相机
this.renderer = this.create_renderer(); //渲染器
let threeContainer = document.getElementById(threeContainerId);
threeContainer.appendChild(this.renderer.domElement);
this.groupBase = new THREE.Group(); //场景用分组
this.scene.add(this.groupBase);
//this.animate_init();
}
create_scene(color) {
let scene = new THREE.Scene();
scene.background = new THREE.Color(color);
return scene;
}
create_camera(position = [10, 10, 10], origin = [0, 0, 0]) {
let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(position[0], position[1], position[2]);
camera.lookAt(new THREE.Vector3(origin[0], origin[1], origin[2]));
return camera;
}
create_renderer() {
let renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 可选:使用柔和阴影
renderer.setClearAlpha(0.5);
return renderer;
}
animate() { //动画
const currentTime = performance.now();
const elapsedTime = currentTime - this.startTime;
if (currentTime % 1000 < 100) {
if (this.is1000ms) { //每秒执行一次
health();
$("#show-time").text(Number($("#show-time").text()) + 1);
if ($("#state-message").text() != "" && this.is5s < 5) {
this.is5s++;
} else if ($("#state-message").text() != "") {
$("#state-message").text("");
this.is5s = 0;
}
if (this.autoRun) {
if (Number(document.getElementById("myRange").value) < this.weiQi.sgf.length - 2) {
document.getElementById("myRange").value = Number(document.getElementById("myRange").value) + 1;
document.getElementById("posColorList").textContent = document.getElementById("myRange").value;
this.show(this.weiQi.posColorList[Number(document.getElementById("myRange").value)]);
} else {
this.autoRun = false;
}
}
}
this.is1000ms = false;
} else {
this.is1000ms = true;
}
if (this.isRotation) { //相机顺时针或者逆时针旋转
let clockValue = 0
if (this.antiClockwise == 1) {
clockValue = -0.002;
} else if (this.antiClockwise == 2) {
clockValue = 0.002;
}
let radius, theta, phi, x, y, z;
[radius, theta, phi] = this.cartesianToSpherical(this.camera.position.x, this.camera.position.y, this.camera.position.z);
[x, y, z] = this.sphericalToCartesian(radius, theta, phi + clockValue);
this.camera.position.set(x, y, z);
this.camera.lookAt(new THREE.Vector3(0, 0, 0));
}
//this.groupWeiQi.children[0].material.needsUpdate = true;
this.renderer.render(this.scene, this.camera); //渲染器刷新
this.animationFrameId = requestAnimationFrame(this.animate.bind(this)); //按屏幕刷新频率执行动画
}
animate_init() { //初始化动画环境,并启动
this.startTime = null;
this.animationFrameId = null;
this.is1000ms = true;
this.animate_start();
}
animate_start() { //动画启动功能
if (this.animationFrameId == null) {
this.startTime = performance.now();
this.animate();
}
}
animate_stop() { //动画停止功能
if (this.animationFrameId !== null) {
cancelAnimationFrame(this.animationFrameId);
this.animationFrameId = null;
}
}
}
class ThreeHelper extends ThreeBase {
constructor(threeContainerId) {
super(threeContainerId);
this.groupHelper = new THREE.Group();
this.scene.add(this.groupHelper);
/* this.groupHelper.add(this.polar_grid_helper());
this.groupHelper.add(this.polar_grid_helper());
this.groupHelper.children[0].rotation.x = Math.PI / 2; */
this.groupHelper.add(this.ambient_light([0, 0, 0], "White", 5));
}
polar_grid_helper(position = [0, 0, 0], color = "Gray") {
/* 极坐标格辅助对象. 坐标格实际上是2维线数组. */
const radius = 10;
const sectors = 16;
const rings = 8;
const divisions = 64;
const helper = new THREE.PolarGridHelper(radius, sectors, rings, divisions);
helper.position.set(position[0], position[1], position[2]);
return helper;
}
ambient_light(position = [0, 0, 0], color = "White", intensity = 1) {
/* 创建一个环境光对象。 */
const light = new THREE.AmbientLight(color, intensity); // 柔和的白光
light.position.set(position[0], position[1], position[2]);
return light;
}
directional_light(position = [0, 0, 0], color = "White", intensity = 1) {
/* 平行光(DirectionalLight) */
const directionalLight = new THREE.DirectionalLight(color, intensity);
directionalLight.position.set(position[0], position[1], position[2]);
return directionalLight;
}
}
class ThreeMouse extends ThreeHelper {
constructor(threeContainerId) {
super(threeContainerId);
this.groupMouse = new THREE.Group();
this.scene.add(this.groupMouse);
this.setupClickListener(this.renderer.domElement, this); //渲染器canvas的监听事件
}
setupClickListener(element, someVariable) {
element.addEventListener('wheel', function (event) { //鼠标滚轮缩放画布
let delta = 0;
if (event.type === 'wheel') {
delta = -event.deltaY;
} else if (event.type === 'mousewheel') {
delta = event.wheelDelta;
}
let radius, theta, phi, x, y, z;
[radius, theta, phi] = someVariable.cartesianToSpherical(someVariable.camera.position.x, someVariable.camera.position.y, someVariable.camera.position.z);
[x, y, z] = someVariable.sphericalToCartesian(radius + delta / 100, theta, phi);
someVariable.camera.position.set(x, y, z);
someVariable.camera.lookAt(new THREE.Vector3(0, 0, 0));
});
element.addEventListener('mousedown', function (event) { //左键,右键按下初始化功能
if (event.button == 0) {
this.painting = true;
someVariable.left_listener(event.clientX, event.clientY);
} else if (event.button == 1) {
this.paintingM = true;
let x = someVariable.camera.position.x;
let y = someVariable.camera.position.y;
let z = someVariable.camera.position.z;
let [radius, theta, phi] = someVariable.cartesianToSpherical(x, z, y);
someVariable.basePosition = [event.clientX, event.clientY, radius, theta, phi];
}
});
element.addEventListener('mousemove', function (event) { //按下左键,右键移动事件
if (this.painting) {
console.log(event.button, event.clientX, event.clientY);
} else if (this.paintingM) {
someVariable.camera_rotate(event);
}
});
element.addEventListener('mouseup', function (event) { //鼠标左键,右键弹起事件
if (this.painting) {
this.painting = false;
} else if (this.paintingM) {
this.paintingM = false;
}
});
}
cartesianToSpherical(x, y, z) { //笛卡尔坐标转球面坐标
//r = sqrt(x^2 + y^2 + z^2), θ = arccos(z / r), φ = arctan2(y, x)
let radius, theta, phi;
radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
theta = Math.acos(z / radius);
phi = Math.atan2(y, x);
return [radius, theta, phi];
}
sphericalToCartesian(radius, theta, phi) { //球面坐标转笛卡尔坐标
//x=rsin(θ)cos(ϕ), y=rsin(θ)sin(ϕ), z=rcos(θ)
let x = radius * Math.sin(theta) * Math.cos(phi);
let y = radius * Math.sin(theta) * Math.sin(phi);
let z = radius * Math.cos(theta);
return [x, y, z];
}
camera_rotate(event) { //鼠标中键按住移动时,旋转相机坐标
const mouseX = event.clientX;
const mouseY = event.clientY;
var radius = this.basePosition[2];
var theta = this.minmax(mouseX - this.basePosition[0], -300, 300) / 300 * Math.PI / 2 + this.basePosition[3];
var phi = this.minmax(this.basePosition[1] - mouseY, -200, 200) / 200 * Math.PI / 2 + this.basePosition[4];
let [x, z, y] = this.sphericalToCartesian(radius, phi, theta);
this.camera.position.set(x, y, z);
this.camera.lookAt(new THREE.Vector3(0, 0, 0));
}
minmax(coordinate, min, max) {
return Math.min(max, Math.max(min, coordinate));
}
left_listener(clientX, clientY) { //左键监听事件,在继承中被覆盖
let mouse = new THREE.Vector2();
mouse.x = (clientX / window.innerWidth) * 2 - 1;
mouse.y = -(clientY / window.innerHeight) * 2 + 1;
let raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, this.camera);
let intersects = raycaster.intersectObjects(this.group1.children, true);
if (intersects.length > 0) {
let intersect = intersects[0];
console.log(intersect.point.x, intersect.point.y)
}
}
}
class ThreeGeometry extends ThreeMouse {
constructor(threeContainerId) {
super(threeContainerId);
this.canvasTexture = null;
//this.qipan = new CanvasQiPan();
this.groupGeometry = new THREE.Group();
this.scene.add(this.groupGeometry);
}
create_cube(position = [0, 0, 0], size = [1, 1, 1], color = "Gray") {
/* 立方缓冲几何体(BoxGeometry)
BoxGeometry 是四边形的原始几何类,它通常使用构造函数所提供的 “width”、“height”、“depth” 参数来创建立方体或者不规则四边形。 */
/* BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)
width — X 轴上面的宽度,默认值为 1。
height — Y 轴上面的高度,默认值为 1。
depth — Z 轴上面的深度,默认值为 1。
widthSegments — (可选)宽度的分段数,默认值是 1。
heightSegments — (可选)高度的分段数,默认值是 1。
depthSegments — (可选)深度的分段数,默认值是 1。 */
const geometry = new THREE.BoxGeometry(size[0], size[1], size[2]);
const material = new THREE.MeshStandardMaterial({ color: color });
const cube = new THREE.Mesh(geometry, material);
cube.position.set(position[0], position[1], position[2]);
return cube;
}
create_plane(position = [0, 0, 0], width = 1, height = 1, color = "Gray") {
/* 平面缓冲几何体(PlaneGeometry)
一个用于生成平面几何体的类。 */
/* width — 平面沿着 X 轴的宽度。默认值是 1。
height — 平面沿着 Y 轴的高度。默认值是 1。
widthSegments — (可选)平面的宽度分段数,默认值是 1。
heightSegments — (可选)平面的高度分段数,默认值是 1。 */
const geometry = new THREE.PlaneGeometry(width, height);
const material = new THREE.MeshStandardMaterial({ color: color, side: THREE.DoubleSide });
material.side = THREE.DoubleSide;
const plane = new THREE.Mesh(geometry, material);
plane.position.set(position[0], position[1], position[2]);
return plane;
}
create_torus(position = [0, 0, 0], radius = 1, tube = 0.5, color = "Gray") {
/* 圆环缓冲几何体(TorusGeometry)
一个用于生成圆环几何体的类。 */
/* radius - 环面的半径,从环面的中心到管道横截面的中心。默认值是1。
tube — 管道的半径,默认值为0.4。
radialSegments — 管道横截面的分段数,默认值为12。
tubularSegments — 管道的分段数,默认值为48。
arc — 圆环的圆心角(单位是弧度),默认值为Math.PI * 2。 */
const geometry = new THREE.TorusGeometry(radius, tube, 16, 100);
const material = new THREE.MeshBasicMaterial({ color: color });
const torus = new THREE.Mesh(geometry, material);
torus.position.set(position[0], position[1], position[2]);
return torus;
}
create_cylinder(position = [0, 0, 0], color = "Black", radiusTop = 0.2, radiusBottom = 0.5, height = 0.1) { // 创建圆柱体几何体和材质
var geometry = new THREE.CylinderGeometry(radiusTop, radiusBottom, height, 32); // 参数: 半径顶部, 半径底部, 高度, 径向分段数
var material = new THREE.MeshStandardMaterial({
color: color,
transparent: true,
opacity: 0.98,
});
var cylinder = new THREE.Mesh(geometry, material);
cylinder.position.set(position[0], position[1], position[2]);
cylinder.rotation.x = Math.PI / 2;
return cylinder;
}
create_sphere(position = [0, 0, 0], color = "Gray", radius = 1) {
/* 球缓冲几何体(SphereGeometry)
一个用于生成球体的类。 */
/* radius — 球体半径,默认为1。
widthSegments — 水平分段数(沿着经线分段),最小值为3,默认值为32。
heightSegments — 垂直分段数(沿着纬线分段),最小值为2,默认值为16。
phiStart — 指定水平(经线)起始角度,默认值为0。。
phiLength — 指定水平(经线)扫描角度的大小,默认值为 Math.PI * 2。
thetaStart — 指定垂直(纬线)起始角度,默认值为0。
thetaLength — 指定垂直(纬线)扫描角度大小,默认值为 Math.PI。
该几何体是通过扫描并计算围绕着Y轴(水平扫描)和X轴(垂直扫描)的顶点来创建的。
因此,不完整的球体(类似球形切片)可以通过为phiStart,
phiLength,thetaStart和thetaLength设置不同的值来创建,
以定义我们开始(或结束)计算这些顶点的起点(或终点) */
const geometry = new THREE.SphereGeometry(radius, 32, 16);
const material = new THREE.MeshLambertMaterial({ color: color, emissive: color });
const sphere = new THREE.Mesh(geometry, material);
sphere.position.set(position[0], position[1], position[2]);
return sphere;
}
}
class ThreeWeiQi extends ThreeGeometry { //创建棋盘,实现监听棋盘,下棋功能,显示棋盘内容
constructor(threeContainerId) {
super(threeContainerId)
this.weiQi = new SimpleGo();
this.positions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"];
this.groupQiPan = new THREE.Group();
this.scene.add(this.groupQiPan);
this.groupHuaXian = new THREE.Group();
this.scene.add(this.groupHuaXian);
this.groupHuaXian.add(this.create_cube([0, 0, -1], [0.2, 0.2, 0.1], "LightGreen"));
this.groupQi = new THREE.Group();
this.scene.add(this.groupQi);
this.groupSphere = new THREE.Group();
this.scene.add(this.groupSphere);
this.create_qipan();
this.current = "B"
this.currentDict = { "B": "Black", "W": "White", "Black": "B", "White": "W" };
}
left_listener(clientX, clientY) { //左键监听事件,棋盘下棋功能
let mouse = new THREE.Vector2();
mouse.x = (clientX / window.innerWidth) * 2 - 1;
mouse.y = -(clientY / window.innerHeight) * 2 + 1;
let raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, this.camera);
let intersects = raycaster.intersectObjects(this.groupQiPan.children, true);
if (intersects.length > 0) {
let intersect = intersects[0];
let position = this.coordinate_position(intersect.point.x + 10, 10 - intersect.point.y);
let sgf = this.current + "[" + position + "]";
if (this.weiQi.go_handler(sgf)) {
if (this.current == "B") {
this.current = "W";
} else {
this.current = "B";
}
let ww = this.weiQi.sgf.length - 1;
document.getElementById("myRange").max = ww;
document.getElementById("myRange").value = ww;
document.getElementById("posColorList").textContent = ww;
this.show(this.weiQi.posColor);
}
}
}
show(posColor) { //显示棋盘状态
let x, y, color = { "B": "Black", "W": "White", "Black": "B", "White": "W" };
while (this.groupQi.children.length > 0) {
this.groupQi.remove(this.groupQi.children[0]);
}
while (this.groupSphere.children.length > 0) {
this.groupSphere.remove(this.groupSphere.children[0]);
}
for (let position in posColor) {
[x, y] = this.position_coordinate(position);
let cylinder = this.create_cylinder([x, y, 0.05], color[posColor[position][0]]);
this.groupQi.add(cylinder);
let sphere = this.create_sphere([x * 2, y * 2, -5], color[posColor[position][0]]);
this.groupSphere.add(sphere);
}
let position = this.weiQi.sgf[Number(document.getElementById("myRange").value)].slice(2, 4);
let [lx, ly] = this.position_coordinate(position);
this.groupHuaXian.children[0].position.set(lx, ly, 0.1);
}
coordinate_position(x, y) { //棋盘three坐标转棋盘位置a~s
let row, col, grid = 1;
row = this.minmax(Math.floor((x - grid / 2) / grid), 0, 18);
col = this.minmax(Math.floor((y - grid / 2) / grid), 0, 18);
return this.positions[row] + this.positions[col];
}
position_coordinate(position) { //棋盘位置a~s转棋盘three坐标
let row, col, x, y, grid = 1;
row = this.positions.indexOf(position.slice(0, 1));
col = this.positions.indexOf(position.slice(1, 2));
x = Math.floor(row * grid);
y = Math.floor(col * grid);
return [x - 9, 9 - y];
}
create_qipan() { //创建棋盘
this.groupQiPan.add(this.create_cube([0, 0, -0.5 - 3e-3], [20, 20, 1], "Yellow")); //棋盘底座
for (let i = 0; i < 19; i++) { //棋盘19x19线条
this.groupHuaXian.add(this.create_plane([i - 9, 0, -1e-3], 0.1, 18, "Black"));
this.groupHuaXian.add(this.create_plane([0, i - 9, -1e-3], 18, 0.1, "Black"));
}
let xingwei = [-6, 0, 6]; //星位
xingwei.forEach((row) => {
xingwei.forEach((col) => {
this.groupHuaXian.add(this.create_torus([row, col, -0.03], 0.3, 0.05, "Black"));
});
});
this.groupHuaXian.add(this.create_cube([-9.6, 9.6, 0], [0.5, 0.5, 0.01], "LightGreen"));
//this.groupQiPan.add(this.create_face([0, 0, 0.1], [20, 20], "Black", 0));
}
}
class htmlClick extends ThreeWeiQi {
constructor(threeContainerId) {
super(threeContainerId);
this.animate_init();
this.animate_start();
this.combinedPattern = /[\u4e00-\u9fa5a-zA-Z0-9;\[\]\-: ]+/g;
}
view(tt) {
let radius, theta, phi, x, y, z;
radius = Math.sqrt(Math.pow(this.camera.position.x, 2) + Math.pow(this.camera.position.y, 2) + Math.pow(this.camera.position.z, 2));
this.camera.up.set(0, 0, 1);
this.antiClockwise = 0;
this.isRotation = false;
switch ($(tt).text()) {
case "前侧":
phi = Math.PI / 6;
theta = Math.PI * 1.5;
break;
case "后侧":
phi = Math.PI / 6;
theta = Math.PI * 0.5;
break;
case "左侧":
phi = Math.PI / 6;
theta = Math.PI;
break;
case "右侧":
phi = Math.PI / 6;
theta = 0;
break;
case "俯视图":
this.camera.up.set(0, 1, 0);
phi = 0;
theta = 0;
break;
case "逆时针":
this.antiClockwise = 1;
this.isRotation = true;
return;
case "顺时针":
this.antiClockwise = 2;
this.isRotation = true;
return;
default:
console.log($(tt).val());
return;
}
[x, y, z] = this.sphericalToCartesian(radius, phi, theta);
this.camera.position.set(x, y, z);
this.camera.lookAt(new THREE.Vector3(0, 0, 0));
}
step(tt) {
switch ($(tt).text()) {
case "-":
document.getElementById("myRange").value = Math.max(0, Number(document.getElementById("myRange").value) - 1);
break;
case "+":
document.getElementById("myRange").value = Math.min(sgo.sgf.length - 1, Number(document.getElementById("myRange").value) + 1);
break;
case "》":
if (this.weiQi.sgf.length == 0) {
this.weiQi.newWeiQi([], {}, []);
var results = sgftext.match(this.combinedPattern) || [];
var format_content = results.join('').split(";");
for (var index in format_content) {
var item = format_content[index];
if (item.length == 5 && this.weiQi.positions.includes(item[2]) && this.weiQi.positions.includes(item[3])) {
this.weiQi.go_handler(item);
}
}
document.getElementById("myRange").max = this.weiQi.sgf.length - 1;
}
document.getElementById("myRange").value = 0;
this.show(this.weiQi.posColorList[0]);
setTimeout("hc.autoRun = true", 1000);
//if (!this.autoRun) { this.autoRun = true; }
break;
default:
console.log(document.getElementById("myRange").value);
break;
}
document.getElementById("posColorList").textContent = document.getElementById("myRange").value;
}
show_tools() {
$("#tools").toggle();
$("#state-message").text("健康忠告:请注意休息,合理安排时间。");
}
getSGF(tt) {
this.weiQi.newWeiQi([], {}, []);
var results = $(tt).val().match(this.combinedPattern) || [];
var format_content = results.join('').split(";");
for (var index in format_content) {
var item = format_content[index];
if (item.length == 5 && this.weiQi.positions.includes(item[2]) && this.weiQi.positions.includes(item[3])) {
this.weiQi.go_handler(item);
}
}
let ww = this.weiQi.sgf.length - 1;
document.getElementById("myRange").max = ww;
document.getElementById("myRange").value = ww;
document.getElementById("posColorList").textContent = ww;
this.show(this.weiQi.posColor);
}
}
const hc = new htmlClick("three-container");
const sgftext = `(;CA[UTF-8]AP[YuanYu]GM[1]FF[4]
SZ[19]
GN[2018腾讯世界人工智能围棋大赛决赛第1局 30日10:00]
DT[2018-07-30]
PB[Golaxy]BR[9d]
PW[FineArt]WR[9d]
KM[7.5]HA[0]RU[Chinese]RE[W+R]TM[3600]TC[10]TT[60]
;B[qd];W[pp];B[dd];W[dp];B[qn];W[qo];B[pn];W[np];B[pj];W[od];B[lc]
;W[me];B[lq];W[qe];B[fq];W[cc];B[qq];W[rn];B[cd];W[dc];B[ed];W[ec]
;B[rm];W[or];B[ro];W[rp];B[qp];W[po];B[sn];W[rq];B[fc];W[fb];B[cn]
;W[er];B[bc];W[bb];B[eb];W[db];B[gb];W[pd];B[eo];W[co];B[bn];W[fp]
;B[ep];W[eq];B[do];W[cq];B[fr];W[iq];B[hp];W[gq];B[gp];W[fo];B[fn]
;W[go];B[hn];W[gr];B[gn];W[fs];B[ei];W[bd];B[be];W[ac];B[cf];W[ih]
;B[qc];W[rf];B[pf];W[qh];B[ob];W[nb];B[oc];W[pc];B[pb];W[rd];B[nd]
;W[qb];B[oe];W[rc];B[nc];W[if];B[hg];W[ig];B[je];W[gi];B[fg];W[hf]
;B[fj];W[lg];B[lf];W[mg];B[kg];W[kh];B[mf];W[ff];B[gg];W[fd];B[gc]
;W[hd];B[fe];W[gd];B[ic];W[gj];B[kf];W[bg];B[cg];W[kj];B[bo];W[gk]
;B[fk];W[id];B[jc];W[eh];B[fh];W[fi];B[ej];W[fl];B[el];W[gl];B[lo]
;W[ae];B[bh];W[em];B[dl];W[km];B[ho];W[qk];B[ol];W[bf];B[ce];W[gf]
;B[ef];W[qj];B[hq];W[hr];B[pi];W[qi];B[lk];W[kk];B[lh];W[li];B[mh]
;W[ng];B[oo];W[pq];B[og];W[nh];B[mi];W[oh];B[qr];W[rr];B[mj];W[ph]
;B[lm];W[kl];B[jh];W[ki];B[bq];W[hh];B[eg];W[ll];B[ml];W[no];B[ln]
;W[nk];B[mk];W[nm];B[nn];W[mm];B[nl];W[mn];B[om];W[mo];B[jq];W[rl]
;B[ql];W[pl];B[qm];W[ir];B[jn];W[pk];B[rk];W[on];B[pm];W[rj];B[sl]
;W[cr];B[jg];W[ji];B[hl];W[il];B[hm];W[jp];B[kp];W[kn];B[ko];W[ik]
;B[cp];W[jr];B[jo];W[hc];B[hb];W[ea];B[af];W[ag];B[fq];W[br];B[ar]
;W[lr];B[mr];W[kq];B[mq];W[ad];B[ah];W[af];B[fm];W[sp];B[nn];W[op]
;B[dq];W[dr];B[jm];W[jl];B[ls];W[on];B[kr];W[nf];B[ne];W[ok];B[hk]
;W[hj];B[pg];W[jd])`
window.addEventListener('resize', () => {
hc.camera.aspect = window.innerWidth / window.innerHeight;
hc.camera.updateProjectionMatrix();
hc.renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )