gpt4 book ai didi

凸形上的 JavaScript 墙碰撞,卡在 Angular 落

转载 作者:行者123 更新时间:2023-12-01 16:10:20 26 4
gpt4 key购买 nike

这是另一个问题的后续:How do I handle player collision with corners of a wall

its answer 中给出的代码的启发,我试着写一些新的代码。

基本上,在原版中,墙壁滑动在墙壁内侧效果很好,但我想让它也适用于外侧,所以我根据他的技术制作了一个新的基本代码引擎:

var aD =[]
var r
function start() {
r = new CanvasRenderer(can),
my = new scene();
window.my = my
eventHandler();
my.add(new mesh({
verts: [
0, 0,
100, 15,
115, 60,
50, 100,
20, 75,2,8
],
position: {
x: 100,
y:100
},
scale: {

x:4,y:5
},
color:"orange",
onupdate(me) {
// me.position.x++
}
}));
var g = false
my.add(new mesh({
primitive:"rect",
name: "player",
scale: {
x: 50,
y:50
},
position: {
x: 311,
y:75
},
origin: {
x:0.5,
y:0.5
},
onupdate(me) {
var upKey = keys[38],
downKey = keys[40],
rightKey = keys[39],
leftKey = keys[37],
drx = 0,
dx = 0,
speed = 5,
turningSpeed = 3

drx = leftKey ? -1 : rightKey ? 1 : 0
forward = upKey ? 1 : downKey ? -1 : 0

me.rotation.x += (
(drx * Math.PI / 180 * turningSpeed )
)
me.rotation.y = 1;

var xDir = Math.cos(me.rotation.x)
var yDir = Math.sin(me.rotation.x)

me.position.x += xDir * forward * speed
me.position.y += yDir * forward * speed

for(var i = 0; i < my.objects.length; i++) {
let cur = my.objects[i];
if(cur.name !== me.name) {
cur.lineSegments.forEach(l => {
var col = checkCollision(
me.position.x,
me.position.y,
me.scale.x/2,
l
)

if(col) {

me.position.y=col.y
me.position.x = col.x
}
});
}
}




}

}));

let i = setInterval(() => render(r, my), 16);
r.on("resize", () => render(r, my));

}

function checkCollision(x1, y1, rad,l) {
var dist = distance2(
l.start[0],
l.start[1],

l.end[0],
l.end[1]
),
vec1 = [
x1 - l.start[0],
y1 - l.start[1]
],

vec2 = [
l.end[0] - l.start[0],
l.end[1] - l.start[1]
],

percentOfWall = (
Math.max(
0,
Math.min(
1,
dot(
vec1[0],
vec1[1],

vec2[0],
vec2[1]
) / dist
)
)
),
projection = [
l.start[0] + percentOfWall * vec2[0],
l.start[1] + percentOfWall * vec2[1],
],
acDist = Math.sqrt(distance2(
x1, y1,
projection[0], projection[1]
))
aD.push( () => {
r.ctx.beginPath()
r.ctx.fillStyle="green"
r.ctx.arc(projection[0], projection[1], 5, 0, Math.PI*2);
r.ctx.fill()
r.ctx.closePath();
})


if(acDist < rad) {
var mag = Math.sqrt(dist),
delt = [
l.end[0] - l.start[0],
l.end[1] - l.start[1]
],
normal = [
delt[0] / mag,
delt[1] / mag
]

return {

x: projection[0] +

rad * (normal[1] ),

y:projection[1] +
rad* (-normal[0] ),
projection,
normal
}
}


}


function dot(x1, y1, x2, y2) {
return (
x1 * x2 + y1 * y2
)
}

function distance2(x1, y1, x2, y2) {
let dx = (x1 - x2), dy = (y1 - y2);
return (
dx * dx + dy * dy
);
}

function render(r,s) {
//r.ctx.clearRect(0,0,r.ctx.canvas.width,r.ctx.canvas.height)
s.update();
r.render(s)
aD.forEach(x=>x());
aD = []
}

onload = start;

function eventHandler() {
window.keys = {};
addEventListener("keyup" , e=> {
keys[e.keyCode] = false;

});

addEventListener("keydown" , e=> {
keys[e.keyCode] = true;
});
}

function CanvasRenderer(dom) {
if(!dom) dom = document.createElement("canvas");

var events = {}, self = this;
function rsz() {
dom.width = dom.clientWidth;
dom.height = dom.clientHeight;
self.dispatchEvent("resize");
}

window.addEventListener("resize", rsz);

let ctx = dom.getContext("2d");

function render(scene) {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
for(let i = 0; i < scene.objects.length; i++) {
let o = scene.objects[i],
verts = o.realVerts;


ctx.beginPath();
ctx.moveTo(
verts[0] ,

verts[1]
);
verts.forEach((v, i, ar) => {
let y = i;



ctx.lineTo(
v[0] ,

v[1]
);

});
ctx.lineTo(
verts[0],
verts[1]
);
ctx.fillStyle = o.color || "blue";
ctx.lineWidth = 1;
ctx.fill()
ctx.stroke();
ctx.closePath();
}
}

Object.defineProperties(this, {
domElement: {
get: () => dom
},
ctx: {
get: () => ctx
},
render: {
get: () => render
},
on: {
get: () => (nm, cb) => {
if(!events[nm]) {
events[nm] = [];
}
events[nm].push(data => {
if(typeof cb == "function") {
cb(data);
}
});
}
},
dispatchEvent: {
get: () => (name, data) => {
if(events[name]) {
events[name].forEach(x => {
x(data);
});
}
}
}
});

rsz();

}

function scene() {
let objects = [];
Object.defineProperties(this, {
add: {
get: () => obj => {
objects.push(obj);
}
},
objects: {
get: () => objects
},
update: {
get: () => () => {
objects.forEach(x => {
if(typeof x.update == "function") {
x.update();
}
});

}
}
});
}

function mesh(data={}) {
let verts = [],
self = this,
holder = {
position:{},
scale: {

},
rotation: {},
origin:{}
},
actual = {

},
position = {},
scale = {},
rotation = {},
origin = {},
color,
name,
primitive,
eventNames = "update",
events = {},
drawPrimitive = {
circle(ctx) {
ctx.beginPath();
ctx.arc(
self.position.x,
self.position.y,
5,
0,
360 * Math.PI / 180
);
ctx.closePath();
},
rect(ctx) {
ctx.strokeRect(
self.position.x,
self.position.y,
30, 30
);
}
},
width = 1,
height = 1,
primitiveToVerts = {
rect: () => [
0, 0,
width , 0,
width, height,
0, height
]
},
realVerts = verts,
lineSegments = [],
o = this;

function updateRealVerts() {

let actualVerts = [],
originedVerts = [],
adjustedVerts = [],
rotatedVerts = [],
stepSize = o.step || 2,
curVerts = [];

o.verts.forEach((v, i) => {
curVerts.push(v);
if(
(i - 1) % stepSize === 0 &&
i !== 0
) {
actualVerts.push(curVerts);
curVerts = [];
}
});
actualVerts = actualVerts.filter(x => x.length == stepSize);

originedVerts = actualVerts.map(v => [
v[0] - o.origin.x,
v[1] - o.origin.y,
v[2] - o.origin.z
]);

rotatedVerts = originedVerts.map(v =>
[

v[0] * Math.cos(o.rotation.x) -
v[1] * Math.sin(o.rotation.x),

v[0] * Math.sin(o.rotation.x) +
v[1] *Math.cos(o.rotation.x),
v[2]
]
);

adjustedVerts = rotatedVerts.map(v =>
[
v[0] *
o.scale.x +
o.position.x,

v[1] *
o.scale.y +
o.position.y,

v[2] *
o.scale.z +
o.position.z,
]
);

realVerts = adjustedVerts;
updateLineSegments();
}

function updateLineSegments() {
let lines = [];
for(let i = 0, a = realVerts; i < a.length;i++) {
let start = [], end = []
if(i < a.length - 1) {
start = a[i];
end = a[i + 1];
} else {
start = a[i];
end = a[0];
}

lines.push({
start, end
})
}
lineSegments = lines;
}
Object.defineProperties(position, {
x: {
get: () => holder.position.x || 0,
set: v => holder.position.x = v
},
y: {
get: () => holder.position.y || 0,
set: v => holder.position.y = v
},
z: {
get: () => holder.position.z || 0,
set: v => holder.position.z = v
}
});

Object.defineProperties(scale, {
x: {
get: () => holder.scale.x || 1,
set: v => holder.scale.x = v
},
y: {
get: () => holder.scale.y || 1,
set: v => holder.scale.y = v
},
z: {
get: () => holder.scale.z || 1,
set: v => holder.scale.z = v
}
});

Object.defineProperties(rotation, {
x: {
get: () => holder.rotation.x || 0,
set: v => holder.rotation.x = v
},
y: {
get: () => holder.rotation.y || 0,
set: v => holder.rotation.y = v
},
z: {
get: () => holder.rotation.z || 0,
set: v => holder.rotation.z = v
}
});

Object.defineProperties(origin, {
x: {
get: () => holder.origin.x || 0,
set: v => holder.origin.x = v
},
y: {
get: () => holder.origin.y || 0,
set: v => holder.origin.y = v
},
z: {
get: () => holder.origin.z || 0,
set: v => holder.origin.z = v
}
});


Object.defineProperties(this, {
verts: {
get: ()=>verts,
set(v) {
verts = v
}
},
name: {
get: ()=>name,
set(v) {
name = v
}
},
primitive: {
get: ()=>primitive,
set(v) {
primitive = v;
let newVerts = primitiveToVerts[v];
if(newVerts) {
this.verts = newVerts();
}
}
},
width: {
get: ()=>width,
set(v) {
width = v
}
},
height: {
get: ()=>height,
set(v) {
height = v
}
},
position: {
get: () => position,
set: v => {
position.x = v.x || 0;
position.y = v.y || 0;
position.z = v.z || 0;
}
},
scale: {
get: () => scale,
set: v => {
scale.x = v.x || v.x === 0 ? v.x : 1;
scale.y = v.y || v.y === 0 ? v.y : 1;
scale.z = v.z || v.z === 0 ? v.z : 1;
}
},
rotation: {
get: () => rotation,
set: v => {
rotation.x = v.x || 0;
rotation.y = v.y || 0;
rotation.z = v.z || 0;
}
},
origin: {
get: () => origin,
set: v => {
origin.x = v.x || 0;
origin.y = v.y || 0;
origin.z = v.z || 0;
}
},
color: {
get: () => color,
set: v => {
color = v;
}
},
realVerts: {
get: () => realVerts
},
lineSegments: {
get: () => lineSegments
},
update: {
get: () => () => {
if(events["update"]) {
events.update.forEach(x => {
updateRealVerts();
x(this);
});
}
}
},
on: {
get: () => (nm, fnc) => {
if(!events[nm]) events[nm] = [];
events[nm].push(stuff => {
if(typeof fnc == "function") {
fnc(stuff);
}
});
}
}
});

eventNames.split(" ").forEach(x => {
var name = "on" + x;
if(!this.hasOwnProperty(name)) {
Object.defineProperty(this, name, {
get: () => events[name],
set(v) {
events[x] = [
data => {
typeof v == "function" && v(data)
}
];
}
});
}
});

for(let k in data) {
this[k] = data[k]
}

updateRealVerts();

}
canvas{
width:100%;
height:100%;
position:absolute;
top:0;
left:0px
}

.wow{
float:right;
z-index:1298737198
}
<meta charset="utf-8">
<button onclick="start()" class=wow>ok</button>
<canvas id=can>

</canvas>


有关碰撞检测实现调用(以及那里的函数的返回值),请参见第 71 行。

问题是,正如您希望看到的(只需全屏显示并使用箭头键移动,尝试与 Angular 落处的橙色网格碰撞)它可以很好地滑动,但是当它到达 Angular 落时,它会卡在它们上面。

任何想法如何解决这个问题 - 不使用任何类型的外部库等(只有代码片段中可用的内容)?

最佳答案

我会说只是检查您是否不在 Angular 落 - 当 percentOfWall 时丢弃案例要么正好是 0或者正好 1
编辑 :为了解决评论中提到的问题,我必须解释为什么你的实现卡住了。它计算了所有墙壁的穿透力,并通过该穿透量减少了位置变化。 Angular 落里,物体一下子撞到了两边,被两边都排斥了,一下子停止了移动。

正如您正确地注意到的那样,在 Angular 落里,您的方块进入障碍物内一帧,然后在随后的帧上被推出。

然而,替代解决方案更复杂且更难调试,但这里有几个选项的草图:

  • 限制碰撞以一次只从一面墙排斥,并尽早退出您的 forEach环形。这是一个简单的解决方案,适用于这个特定示例,但不适用于一般情况,例如在拐 Angular 处,当您需要与 2 堵墙发生碰撞以防止您朝两个方向前进时。
  • 在每个 Angular 落添加一个小圆圈并与其碰撞以避免进入。法线是沿着圆心和接触点之间的线。这会平滑拐 Angular 处的法线不连续性,并且始终存在一条法线,物体沿着该法线被排斥,从一个部分到另一部分不断变化。

  • 将“推”指向障碍物的每个部分(这就是您要问的)的外面并不会阻止在拐 Angular 处停止(这正是您关心的点),两面墙都会与您的物体发生碰撞并且“外面”将在相反的方向。所以它会像以前一样卡住,原因完全相同 - 法线不会连续。

    我希望有帮助

    var aD =[]
    var r
    function start() {
    r = new CanvasRenderer(can),
    my = new scene();
    window.my = my
    eventHandler();
    my.add(new mesh({
    verts: [
    0, 0,
    100, 15,
    115, 60,
    50, 100,
    20, 75,2,8
    ],
    position: {
    x: 100,
    y:100
    },
    scale: {

    x:4,y:5
    },
    color:"orange",
    onupdate(me) {
    // me.position.x++
    }
    }));
    var g = false
    my.add(new mesh({
    primitive:"rect",
    name: "player",
    scale: {
    x: 50,
    y:50
    },
    position: {
    x: 311,
    y:75
    },
    origin: {
    x:0.5,
    y:0.5
    },
    onupdate(me) {
    var upKey = keys[38],
    downKey = keys[40],
    rightKey = keys[39],
    leftKey = keys[37],
    drx = 0,
    dx = 0,
    speed = 5,
    turningSpeed = 3

    drx = leftKey ? -1 : rightKey ? 1 : 0
    forward = upKey ? 1 : downKey ? -1 : 0

    me.rotation.x += (
    (drx * Math.PI / 180 * turningSpeed )
    )
    me.rotation.y = 1;

    var xDir = Math.cos(me.rotation.x)
    var yDir = Math.sin(me.rotation.x)

    me.position.x += xDir * forward * speed
    me.position.y += yDir * forward * speed

    for(var i = 0; i < my.objects.length; i++) {
    let cur = my.objects[i];
    if(cur.name !== me.name) {
    cur.lineSegments.forEach(l => {
    var col = checkCollision(
    me.position.x,
    me.position.y,
    me.scale.x/2,
    l
    )

    if(col) {
    me.position.y=col.y
    me.position.x = col.x
    }
    });
    }
    }




    }

    }));

    let i = setInterval(() => render(r, my), 16);
    r.on("resize", () => render(r, my));

    }

    function checkCollision(x1, y1, rad,l) {
    var dist = distance2(
    l.start[0],
    l.start[1],

    l.end[0],
    l.end[1]
    ),
    vec1 = [
    x1 - l.start[0],
    y1 - l.start[1]
    ],

    vec2 = [
    l.end[0] - l.start[0],
    l.end[1] - l.start[1]
    ],

    percentOfWall = (
    Math.max(
    0,
    Math.min(
    1,
    dot(
    vec1[0],
    vec1[1],

    vec2[0],
    vec2[1]
    ) / dist
    )
    )
    ),
    projection = [
    l.start[0] + percentOfWall * vec2[0],
    l.start[1] + percentOfWall * vec2[1],
    ],
    acDist = Math.sqrt(distance2(
    x1, y1,
    projection[0], projection[1]
    ))
    aD.push( () => {
    r.ctx.beginPath()
    r.ctx.fillStyle="green"
    r.ctx.arc(projection[0], projection[1], 5, 0, Math.PI*2);
    r.ctx.fill()
    r.ctx.closePath();
    })


    if(acDist < rad && percentOfWall > 0 && percentOfWall < 1) {
    var mag = Math.sqrt(dist),
    delt = [
    l.end[0] - l.start[0],
    l.end[1] - l.start[1]
    ],
    normal = [
    delt[0] / mag,
    delt[1] / mag
    ]

    return {

    x: projection[0] +

    rad * (normal[1] ),

    y:projection[1] +
    rad* (-normal[0] ),
    projection,
    normal
    }
    }


    }


    function dot(x1, y1, x2, y2) {
    return (
    x1 * x2 + y1 * y2
    )
    }

    function distance2(x1, y1, x2, y2) {
    let dx = (x1 - x2), dy = (y1 - y2);
    return (
    dx * dx + dy * dy
    );
    }

    function render(r,s) {
    //r.ctx.clearRect(0,0,r.ctx.canvas.width,r.ctx.canvas.height)
    s.update();
    r.render(s)
    aD.forEach(x=>x());
    aD = []
    }

    onload = start;

    function eventHandler() {
    window.keys = {};
    addEventListener("keyup" , e=> {
    keys[e.keyCode] = false;

    });

    addEventListener("keydown" , e=> {
    keys[e.keyCode] = true;
    });
    }

    function CanvasRenderer(dom) {
    if(!dom) dom = document.createElement("canvas");

    var events = {}, self = this;
    function rsz() {
    dom.width = dom.clientWidth;
    dom.height = dom.clientHeight;
    self.dispatchEvent("resize");
    }

    window.addEventListener("resize", rsz);

    let ctx = dom.getContext("2d");

    function render(scene) {
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
    for(let i = 0; i < scene.objects.length; i++) {
    let o = scene.objects[i],
    verts = o.realVerts;


    ctx.beginPath();
    ctx.moveTo(
    verts[0] ,

    verts[1]
    );
    verts.forEach((v, i, ar) => {
    let y = i;



    ctx.lineTo(
    v[0] ,

    v[1]
    );

    });
    ctx.lineTo(
    verts[0],
    verts[1]
    );
    ctx.fillStyle = o.color || "blue";
    ctx.lineWidth = 1;
    ctx.fill()
    ctx.stroke();
    ctx.closePath();
    }
    }

    Object.defineProperties(this, {
    domElement: {
    get: () => dom
    },
    ctx: {
    get: () => ctx
    },
    render: {
    get: () => render
    },
    on: {
    get: () => (nm, cb) => {
    if(!events[nm]) {
    events[nm] = [];
    }
    events[nm].push(data => {
    if(typeof cb == "function") {
    cb(data);
    }
    });
    }
    },
    dispatchEvent: {
    get: () => (name, data) => {
    if(events[name]) {
    events[name].forEach(x => {
    x(data);
    });
    }
    }
    }
    });

    rsz();

    }

    function scene() {
    let objects = [];
    Object.defineProperties(this, {
    add: {
    get: () => obj => {
    objects.push(obj);
    }
    },
    objects: {
    get: () => objects
    },
    update: {
    get: () => () => {
    objects.forEach(x => {
    if(typeof x.update == "function") {
    x.update();
    }
    });

    }
    }
    });
    }

    function mesh(data={}) {
    let verts = [],
    self = this,
    holder = {
    position:{},
    scale: {

    },
    rotation: {},
    origin:{}
    },
    actual = {

    },
    position = {},
    scale = {},
    rotation = {},
    origin = {},
    color,
    name,
    primitive,
    eventNames = "update",
    events = {},
    drawPrimitive = {
    circle(ctx) {
    ctx.beginPath();
    ctx.arc(
    self.position.x,
    self.position.y,
    5,
    0,
    360 * Math.PI / 180
    );
    ctx.closePath();
    },
    rect(ctx) {
    ctx.strokeRect(
    self.position.x,
    self.position.y,
    30, 30
    );
    }
    },
    width = 1,
    height = 1,
    primitiveToVerts = {
    rect: () => [
    0, 0,
    width , 0,
    width, height,
    0, height
    ]
    },
    realVerts = verts,
    lineSegments = [],
    o = this;

    function updateRealVerts() {

    let actualVerts = [],
    originedVerts = [],
    adjustedVerts = [],
    rotatedVerts = [],
    stepSize = o.step || 2,
    curVerts = [];

    o.verts.forEach((v, i) => {
    curVerts.push(v);
    if(
    (i - 1) % stepSize === 0 &&
    i !== 0
    ) {
    actualVerts.push(curVerts);
    curVerts = [];
    }
    });
    actualVerts = actualVerts.filter(x => x.length == stepSize);

    originedVerts = actualVerts.map(v => [
    v[0] - o.origin.x,
    v[1] - o.origin.y,
    v[2] - o.origin.z
    ]);

    rotatedVerts = originedVerts.map(v =>
    [

    v[0] * Math.cos(o.rotation.x) -
    v[1] * Math.sin(o.rotation.x),

    v[0] * Math.sin(o.rotation.x) +
    v[1] *Math.cos(o.rotation.x),
    v[2]
    ]
    );

    adjustedVerts = rotatedVerts.map(v =>
    [
    v[0] *
    o.scale.x +
    o.position.x,

    v[1] *
    o.scale.y +
    o.position.y,

    v[2] *
    o.scale.z +
    o.position.z,
    ]
    );

    realVerts = adjustedVerts;
    updateLineSegments();
    }

    function updateLineSegments() {
    let lines = [];
    for(let i = 0, a = realVerts; i < a.length;i++) {
    let start = [], end = []
    if(i < a.length - 1) {
    start = a[i];
    end = a[i + 1];
    } else {
    start = a[i];
    end = a[0];
    }

    lines.push({
    start, end
    })
    }
    lineSegments = lines;
    }
    Object.defineProperties(position, {
    x: {
    get: () => holder.position.x || 0,
    set: v => holder.position.x = v
    },
    y: {
    get: () => holder.position.y || 0,
    set: v => holder.position.y = v
    },
    z: {
    get: () => holder.position.z || 0,
    set: v => holder.position.z = v
    }
    });

    Object.defineProperties(scale, {
    x: {
    get: () => holder.scale.x || 1,
    set: v => holder.scale.x = v
    },
    y: {
    get: () => holder.scale.y || 1,
    set: v => holder.scale.y = v
    },
    z: {
    get: () => holder.scale.z || 1,
    set: v => holder.scale.z = v
    }
    });

    Object.defineProperties(rotation, {
    x: {
    get: () => holder.rotation.x || 0,
    set: v => holder.rotation.x = v
    },
    y: {
    get: () => holder.rotation.y || 0,
    set: v => holder.rotation.y = v
    },
    z: {
    get: () => holder.rotation.z || 0,
    set: v => holder.rotation.z = v
    }
    });

    Object.defineProperties(origin, {
    x: {
    get: () => holder.origin.x || 0,
    set: v => holder.origin.x = v
    },
    y: {
    get: () => holder.origin.y || 0,
    set: v => holder.origin.y = v
    },
    z: {
    get: () => holder.origin.z || 0,
    set: v => holder.origin.z = v
    }
    });


    Object.defineProperties(this, {
    verts: {
    get: ()=>verts,
    set(v) {
    verts = v
    }
    },
    name: {
    get: ()=>name,
    set(v) {
    name = v
    }
    },
    primitive: {
    get: ()=>primitive,
    set(v) {
    primitive = v;
    let newVerts = primitiveToVerts[v];
    if(newVerts) {
    this.verts = newVerts();
    }
    }
    },
    width: {
    get: ()=>width,
    set(v) {
    width = v
    }
    },
    height: {
    get: ()=>height,
    set(v) {
    height = v
    }
    },
    position: {
    get: () => position,
    set: v => {
    position.x = v.x || 0;
    position.y = v.y || 0;
    position.z = v.z || 0;
    }
    },
    scale: {
    get: () => scale,
    set: v => {
    scale.x = v.x || v.x === 0 ? v.x : 1;
    scale.y = v.y || v.y === 0 ? v.y : 1;
    scale.z = v.z || v.z === 0 ? v.z : 1;
    }
    },
    rotation: {
    get: () => rotation,
    set: v => {
    rotation.x = v.x || 0;
    rotation.y = v.y || 0;
    rotation.z = v.z || 0;
    }
    },
    origin: {
    get: () => origin,
    set: v => {
    origin.x = v.x || 0;
    origin.y = v.y || 0;
    origin.z = v.z || 0;
    }
    },
    color: {
    get: () => color,
    set: v => {
    color = v;
    }
    },
    realVerts: {
    get: () => realVerts
    },
    lineSegments: {
    get: () => lineSegments
    },
    update: {
    get: () => () => {
    if(events["update"]) {
    events.update.forEach(x => {
    updateRealVerts();
    x(this);
    });
    }
    }
    },
    on: {
    get: () => (nm, fnc) => {
    if(!events[nm]) events[nm] = [];
    events[nm].push(stuff => {
    if(typeof fnc == "function") {
    fnc(stuff);
    }
    });
    }
    }
    });

    eventNames.split(" ").forEach(x => {
    var name = "on" + x;
    if(!this.hasOwnProperty(name)) {
    Object.defineProperty(this, name, {
    get: () => events[name],
    set(v) {
    events[x] = [
    data => {
    typeof v == "function" && v(data)
    }
    ];
    }
    });
    }
    });

    for(let k in data) {
    this[k] = data[k]
    }

    updateRealVerts();

    }
    canvas{
    width:100%;
    height:100%;
    position:absolute;
    top:0;
    left:0px
    }

    .wow{
    float:right;
    z-index:1298737198
    }
    <meta charset="utf-8">
    <button onclick="start()" class=wow>ok</button>
    <canvas id=can>

    </canvas>

    关于凸形上的 JavaScript 墙碰撞,卡在 Angular 落,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61518457/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com