这是我第一次使用canvas,并且我第一次使用Javascript来制作完整的游戏类型的东西,所以请原谅初学者的混乱!
我正试图制作一种圆形Flappy Bird类型的东西,你围绕一个圆圈旅行,以某种引力方式画入圆圈,点击让你起来。太高了,你死了,太低,你死了。但是,我在第一个障碍中摔倒......
我现在遇到的两个主要问题,从最小的问题开始,是.clearRect函数。我现在在球移动时模糊地清理球,但这有点不完美,如果距离太近则切入中间圈。如果我将整个窗口设置为每个框架都清晰,那么一切都会闪烁;有更好的方法吗?
第二个问题就是让球进入一个圆圈...我已经尝试了很多解决方案,而且我知道这很可能是我数学技能的巨大失败,但我可以'使它绕主圆圈运行。我可以让它移动,我让它从墙壁上反弹,这样我至少可以看到它在做什么,但它只是不会盘旋。如果我遇到同样的困难,我想我将在未来的某个时刻询问这个游戏的其他方面,但是,正如我所说,我正在努力学习!
在dx和dy变量中,' sun'代表我试图让行星绕轨道运行的圆圈的中点。变量的其余部分基于我在其他地方找到的一个答案,但我还没有设法让它工作。
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);
&#13;
答案 0 :(得分:2)
好的,所以
屏幕闪烁,因为您为makesun和draw设置了两个不同的间隔。 javascript做出零承诺,它不会在cals使用和绘制之间更新屏幕。我认为最好的解决方案是有效地清除整个矩形然后重新绘制太阳(图形很简单,所以你不会遇到性能问题)。
要为球设置动画,你想获得当前时间并决定你想要它的速度(以转/秒为单位)。正如其他人所建议的那样,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>
答案 1 :(得分:0)
使用requestAnimationFrame()而不是设置的间隔,之后你不应该闪烁,半圆的等式是y =±√(r ^ 2-x ^ 2) 使用变量来确定它应该是正数还是负数,并更改每个绘制的轨道运行对象的x变量以将其移动到圆圈中