gpt4 book ai didi

Javascript 对象在碰撞时粘在 div 对象上

转载 作者:行者123 更新时间:2023-12-01 15:17:02 24 4
gpt4 key购买 nike

我正在尝试制作一个小游戏,用户可以单击页面上的某个位置,圆圈将跟随指针的位置,然后用户可以从那里拖动鼠标使圆圈像弹弓一样移动。我希望圆圈能够从墙上反弹。

然而,似乎在圆与墙壁碰撞时,圆似乎“粘”在墙上而不是立即弹回。我认为这可能是由于舍入误差导致圆圈改变方向太快?顶墙的碰撞还没有实现,因为我认为我没有正确声明顶墙 div 对象。

let windowHeight = window.innerHeight;
let windowWidth = window.innerWidth;
//console.log(`Window height: ${windowHeight}, Window width: ${windowWidth}`);

var $ = document.querySelector.bind(document);
var $on = document.addEventListener.bind(document);

var mouseX, mouseY;
$on('mousedown', function (e){
mouseX = e.clientX || e.pageX;
mouseY = e.clientY || e.pageY;

initialX = mouseX;
initialY = mouseY;
//console.log('mousedown');
});

$on('mouseup', function (e){
//var d = Math.hypot(e.clientX - mouseX, e.clientY - mouseY);
var movebyX = (Math.abs(e.clientX - mouseX));
var movebyY = (Math.abs(e.clientY - mouseY));
// Move puck in opposite direction
if (e.clientX > mouseX){
mouseX -= movebyX;
}
else if(e.clientX < mouseX){
mouseX += movebyX;
}

if (e.clientY > mouseY){
mouseY -= movebyY;
}
else if(e.clientY < mouseY){
mouseY += movebyY;
}

//console.log('mouseup');
});


var circle = $('#circle');


var top = $('#top');
var bottom = $('#bottom');
var left = $('#left');
var right = $('#right');
var top = $('#top');


var x = void 0,
y = void 0,
dx = void 0;
dy = void 0;
v0x = void 0;
v0y = void 0;
accelScalar = 0.3;
key = -1;
velocityScalar = 0.05;
teleport = 0.1;
isCollide = false;
swap = false;
initialX = void 0;
initialY = void 0;

var followMouse = function followMouse(){
key = requestAnimationFrame(followMouse);
//tester();
if(!x || !y){
x = mouseX;
y = mouseY;
}
else {
makeMove(findVelocity().dx,findVelocity().dy);
}

};

function tester() {
console.log(top.getBoundingClientRect());
}



function findVelocity(){
v0x = (mouseX - x) * velocityScalar
v0y = (mouseY - y) * velocityScalar
return {
dx: v0x * accelScalar,
dy: v0y * accelScalar,
};
}


function makeMove(vx,vy){
//console.log(`x: ${x}, mouseX: ${mouseX}, vx: ${vx}`);

// teleport, avoid asymptote
if(Math.abs(vx) + Math.abs(vy) < teleport) {
x = mouseX;
y = mouseY;
vx = 0;
vy = 0;
}

// update position if collision

if (x-41 < (left.getBoundingClientRect().x)){
vx = -vx
vy = -vy
}
if (x+41 > (right.getBoundingClientRect().x)){
vx = -vx
vy = -vy
}
if (y+41 > (bottom.getBoundingClientRect().y)){
vx = -vx
vy = -vy
}
x += vx;
y += vy;
// show circle position
circle.style.left = (x-20) + 'px';
circle.style.top = (y-20) + 'px';
}

followMouse();
html, body {
margin: 0;
height: 100%;
background: #161616;


}

.wrap {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
overflow: hidden;
}

@keyframes animation {
0% {
transform: scale(0.9)
}
25% {
transform: scale(1.1)
}
50% {
transform: scale(0.9)
}
75% {
transform: scale(1.1)
}
100% {
transform: scale(0.9)
}
}

#circle {

width: 50px;
height: 50px;
background: none;
border: 5px solid aqua;
border-radius: 50%;
position: absolute;
left: 50%;
top: 50%;
margin: -10px 0 0 -10px;
pointer-events: none;
/*animation: animation 5s infinite

*/
}

#top, #bottom, #left, #right {
background: #a5ebff;
position: fixed;
}
#left, #right {
top: 0; bottom: 0;
width: 10px;
}
#left { left: 0; }
#right { right: 0; }

#top, #bottom {
left: 0; right: 0;
height: 10px;
}
#top { top: 0; }
#bottom { bottom: 0; }
<!DOCTYPE html>
<html>
<head>
<title> Test Project </title>
<link rel = "stylesheet" href = "main.css">

</head>

<body>
<div class = "wrap">
<div id = "circle"></div>
</div>

<div id="left"></div>
<div id="right"></div>
<div id="top"></div>
<div id="bottom"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type = "text/javascript" src = "./main.js"> </script>
</body>
</html>

最佳答案

两个问题:

  • top是顶层框架的保留变量。与尝试访问 ID 为 top 的元素发生冲突, (你应该避免依赖,使用 getElementById 代替)
  • 仅仅反转速度是行不通的,因为您正在使用最后一次鼠标单击的位置计算每帧的速度(这是您的缓动位置的工作方式,即当它接近 mouseX/Y 时通过衰减速度来工作)。
    完成这项工作的最简单方法是使用鼠标在边框外单击之间的距离在边框内设置一个新的鼠标单击位置,偏移距离。 (基本上与使用边框作为轴来反转位置具有相同的效果。在这种情况下,它还会在它反转的轴上增加一半的圆宽度。使用硬编码数字,但如果想要作为从实际计算的改进尺寸也可以。)


  • let windowHeight = window.innerHeight;
    let windowWidth = window.innerWidth;
    //console.log(`Window height: ${windowHeight}, Window width: ${windowWidth}`);

    var $ = document.querySelector.bind(document);
    var $on = document.addEventListener.bind(document);

    var mouseX, mouseY;
    $on('mousedown', function (e){
    mouseX = e.clientX || e.pageX;
    mouseY = e.clientY || e.pageY;

    initialX = mouseX;
    initialY = mouseY;
    //console.log('mousedown');
    });

    $on('mouseup', function (e){
    //var d = Math.hypot(e.clientX - mouseX, e.clientY - mouseY);
    var movebyX = (Math.abs(e.clientX - mouseX));
    var movebyY = (Math.abs(e.clientY - mouseY));
    // Move puck in opposite direction
    if (e.clientX > mouseX){
    mouseX -= movebyX;
    }
    else if(e.clientX < mouseX){
    mouseX += movebyX;
    }

    if (e.clientY > mouseY){
    mouseY -= movebyY;
    }
    else if(e.clientY < mouseY){
    mouseY += movebyY;
    }

    //console.log('mouseup');
    });


    var circle = $('#circle');


    var top = $('#top');
    var bottom = $('#bottom');
    var left = $('#left');
    var right = $('#right');
    var top = $('#top');


    var x = void 0,
    y = void 0,
    dx = void 0;
    dy = void 0;
    v0x = void 0;
    v0y = void 0;
    accelScalar = 0.3;
    key = -1;
    velocityScalar = 0.05;
    teleport = 0.1;
    isCollide = false;
    swap = false;
    initialX = void 0;
    initialY = void 0;

    var followMouse = function followMouse(){
    key = requestAnimationFrame(followMouse);
    //tester();
    if(!x || !y){
    x = mouseX;
    y = mouseY;
    }
    else {
    makeMove(findVelocity().dx,findVelocity().dy);
    }

    };

    function tester() {
    console.log(top.getBoundingClientRect());
    }



    function findVelocity(){
    v0x = (mouseX - x) * velocityScalar
    v0y = (mouseY - y) * velocityScalar
    return {
    dx: v0x * accelScalar,
    dy: v0y * accelScalar,
    };
    }


    function makeMove(vx,vy){
    //console.log(`x: ${x}, mouseX: ${mouseX}, vx: ${vx}`);

    // teleport, avoid asymptote
    if(Math.abs(vx) + Math.abs(vy) < teleport) {
    x = mouseX;
    y = mouseY;
    vx = 0;
    vy = 0;
    }

    // update position if collision

    if (x-41 < (left.getBoundingClientRect().x)){
    mouseX = Math.abs(mouseX - x) + 41
    }
    if (x+31 > (right.getBoundingClientRect().x)){
    mouseX = right.getBoundingClientRect().x - Math.abs(mouseX - x) - 31
    }
    var top = document.getElementById('top')
    if (y-41 < (top.getBoundingClientRect().y)){
    mouseY = Math.abs(mouseY - y) + 41
    }
    if (y+31 > (bottom.getBoundingClientRect().y)){
    mouseY = bottom.getBoundingClientRect().y - Math.abs(mouseY - y) - 31
    }
    x += vx;
    y += vy;
    // show circle position
    circle.style.left = (x-20) + 'px';
    circle.style.top = (y-20) + 'px';
    }

    followMouse();
    html, body {
    margin: 0;
    height: 100%;
    background: #161616;


    }

    .wrap {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    overflow: hidden;
    }

    @keyframes animation {
    0% {
    transform: scale(0.9)
    }
    25% {
    transform: scale(1.1)
    }
    50% {
    transform: scale(0.9)
    }
    75% {
    transform: scale(1.1)
    }
    100% {
    transform: scale(0.9)
    }
    }

    #circle {

    width: 50px;
    height: 50px;
    background: none;
    border: 5px solid aqua;
    border-radius: 50%;
    position: absolute;
    left: 50%;
    top: 50%;
    margin: -10px 0 0 -10px;
    pointer-events: none;
    /*animation: animation 5s infinite

    */
    }

    #top, #bottom, #left, #right {
    background: #a5ebff;
    position: fixed;
    }
    #left, #right {
    top: 0; bottom: 0;
    width: 10px;
    }
    #left { left: 0; }
    #right { right: 0; }

    #top, #bottom {
    left: 0; right: 0;
    height: 10px;
    }
    #top { top: 0; }
    #bottom { bottom: 0; }
    <!DOCTYPE html>
    <html>
    <head>
    <title> Test Project </title>
    <link rel = "stylesheet" href = "main.css">

    </head>

    <body>
    <div class = "wrap">
    <div id = "circle"></div>
    </div>

    <div id="left"></div>
    <div id="right"></div>
    <div id="top"></div>
    <div id="bottom"></div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script type = "text/javascript" src = "./main.js"> </script>
    </body>
    </html>

    关于Javascript 对象在碰撞时粘在 div 对象上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62312161/

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