gpt4 book ai didi

javascript - 使用 Canvas 在 Javascript 中做一个圆圈旅行

转载 作者:行者123 更新时间:2023-11-29 11:01:44 25 4
gpt4 key购买 nike

我是第一次用canvass,也是第一次用javascript做一个游戏类的东西,初学者的困惑还请见谅!

我正在尝试制作一种圆形的 Flappy Bird 类型的东西,你绕着一个圆圈移动,以一种类似重力的方式被吸引到圆圈中,点击让你升起。太高会死,太低也会死。然而,我在第一个障碍上就倒下了……

我现在遇到的两个主要问题是 .clearRect 函数,从最小的开始。我目前让它在球移动时模糊地在球后方清理,但这有点不完美,如果它离得太近就会切入中间的圆圈。如果我将整个窗口设置为清除每一帧,一切都会可怕地闪烁;有更好的方法吗?

第二个问题就是让球转一圈……我已经尝试了很多解决方案,我知道这很可能是我数学技能的一个巨大失败,但我做不到它完全围绕主圆运行。我可以让它移动,我已经让它从墙上弹开,这样我至少可以看到它在做什么,但它只是没有盘旋。我想如果我遇到同样的困难,我会在未来的某个时候询问这款游戏的其他方面,但是,正如我所说,我正在努力学习!

在 dx 和 dy 变量中,“太阳”代表我试图让行星围绕其运行的圆的中点。变量的其余部分基于我在其他地方找到的一个答案,但我也没有设法让它发挥作用。

var canvas = document.createElement("canvas"),
context = canvas.getContext("2d"),
sun = 300,
sunRadius = sun / 2,
x = sun +110,
y = sun -110,

angle = 0,
distance = 10,
dx = sun + sunRadius * Math.cos(angle*Math.PI/180),
dy = sun + sunRadius * Math.sin(angle*Math.PI/180),

planetRadius = 10;



document.body.appendChild(canvas);
canvas.width = canvas.height = sun * 2;

function makeSun() {
context.beginPath();
context.strokeStyle = "yellow";
context.arc(sun, sun, 60, 0, 2 * Math.PI);
context.fillStyle = "yellow";
context.fill();
context.closePath();
}

function makePlanet() {
context.beginPath();
context.arc(x, y, planetRadius, 0, Math.PI * 2);
context.fillStyle = "green";
context.fill();
context.strokeStyle = "green";
context.stroke();
}

function draw() {
context.clearRect(x + -20, y - 15, 40, 40);
makePlanet();


if (x + dx > canvas.width - planetRadius || x + dx < planetRadius) {
dx = -dx;
}
if (y + dy > canvas.height - planetRadius || y + dy < planetRadius) {
dy = -dy;
}

x += dx;
y += dy;
}


setInterval(makeSun, 10);
setInterval(draw, 10);

最佳答案

好吧

首先:

屏幕闪烁是因为您正在为 makesun 和 draw 设置两个不同的间隔。 javascript 零 promise 它不会在调用 makesun 和绘制之间更新屏幕。我认为最好的解决方案是有效地清除整个矩形然后重新绘制你的太阳(图形足够简单所以你不会有性能问题)。

第二个:

要为球制作动画,您需要获取当前时间并确定您希望它移动多快(以旋转/秒为单位)。正如其他人所建议的那样,requestAnimationFrame 比 setInterval 更好,因为它传递给您一个时间戳。

例子

我已经调整了您的代码,使地球旋转。我还为太阳添加了运动,所以你会看到行星实际上是相对于它的。看看吧,有不懂的地方请教。

const canvas = document.createElement("canvas"),
context = canvas.getContext("2d"),
checkbox = document.getElementById("moveSunBx"),
sun = 300,
sunRadius = sun / 2,
controllables = {
movesun : false,
rotationspeed : 1/2 // half a turn every second (timestamps are in milliseconds)
},

distancePtoS = 110,//distance from planet to sun
planetRadius = 10;

var planetAngle = 0.0,// Starting angles
sunAngle = 0.0,
lastTimestamp;


var gui = new dat.GUI();
gui.add(controllables, 'movesun').name("move sun");
gui.add(controllables, 'rotationspeed', -6, 6).name("planet speed");// in turns per second

function makeSun(x, y) {
context.beginPath();
context.strokeStyle = "yellow";
context.arc(x, y, 60, 0, 2 * Math.PI);
context.fillStyle = "yellow";
context.fill();
context.closePath();
}

function makePlanet(x, y) {
context.beginPath();
context.arc(x, y, planetRadius, 0, Math.PI * 2);
context.fillStyle = "green";
context.fill();
context.strokeStyle = "green";
context.stroke();
}

function draw(timestamp) {
requestAnimationFrame(draw);//immediately ask for next frame

if(!lastTimestamp){
lastTimestamp = timestamp;
return;
}


var speed = Math.PI * 2.0 * controllables.rotationspeed / 1000, // convert speed from turns per second to radian per millisec
timestep = timestamp - lastTimestamp;

lastTimestamp = timestamp;//we save the stamp

planetAngle += timestep * speed;//we update the angle depending on the currentspeed and the timestep

//angle = angle % Math.PI / 2;// this is for better comprehension, Math.cos and sin do the clamping for us
debugger;
//let's make the sun move!!!
if(controllables.movesun){
sunAngle += timestep * speed;
}
var sunx = sunRadius + Math.cos(sunAngle /2) * distancePtoS;// <- sin of 2 angle gives a beautiful infinity
var suny = sunRadius + Math.sin(sunAngle) * distancePtoS / 2;


//x and y don't need to be kept, I made them local to draw()
var planetx = sunx + Math.cos(planetAngle) * distancePtoS;
var planety = suny + Math.sin(planetAngle) * distancePtoS;

context.clearRect(0, 0, canvas.width, canvas.height);
makeSun(sunx, suny);
makePlanet(planetx, planety);
}

document.body.appendChild(canvas);
canvas.width = canvas.height = sun * 2;

draw();//we start the cycle
<script src="//cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>

关于javascript - 使用 Canvas 在 Javascript 中做一个圆圈旅行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45838912/

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