Javascript 无法通过的边界(画布游戏)

Javascript 无法通过的边界(画布游戏),javascript,css,html,canvas,Javascript,Css,Html,Canvas,我必须为学校做一个游戏:) 我是Javascript(和英语)的初学者,我有一个关于画布的问题 我在我的画布上做了一艘宇宙飞船,我可以用我的箭头键绕着它飞行。问题是我的宇宙飞船能从我画布的边缘飞过去。。但事实并非如此 我希望你们中的一个人能帮我做这件事!:) 这是我的密码 window.onload = init; var ctx; var x = 750; var y = 400; var up = false; var right = false; var left = false; var

我必须为学校做一个游戏:)

我是Javascript(和英语)的初学者,我有一个关于画布的问题

我在我的画布上做了一艘宇宙飞船,我可以用我的箭头键绕着它飞行。问题是我的宇宙飞船能从我画布的边缘飞过去。。但事实并非如此

我希望你们中的一个人能帮我做这件事!:)

这是我的密码

window.onload = init;
var ctx;
var x = 750;
var y = 400;
var up = false;
var right = false;
var left = false;
var gravity = -1.1;
var horizontalSpeed = 0.1;
function init() {
    document.onkeydown = handleKeyDown;
    document.onkeyup = handleKeyUp;
    var canvas = document.querySelector("canvas");
    ctx = canvas.getContext("2d");
    animate();

}

function animate() {
    moveShip();
    drawScene();
    requestAnimationFrame(animate);
}
function drawScene(){
    ctx.clearRect(0,0,1600,800);
    drawSpaceship();
}
function moveShip() {
    if (left) {
        horizontalSpeed -= 0.1;
    }else if (right){
        horizontalSpeed += 0.1;
    }
    if (up) {
        gravity -=0.4;
    }
    gravity += 0.12;
    y += gravity;
    x += horizontalSpeed;
}
function drawSpaceship () {
    ctx.save();
    ctx.translate(x, y);
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(0, -40);
    ctx.lineTo(30,-80);
    ctx.lineTo(60,-40);
    ctx.lineTo(60,0);
    ctx.lineTo(80,30);
    ctx.lineTo(80,90);
    ctx.lineTo(60,50);
    ctx.lineTo(0,50);
    ctx.lineTo(-20,90);
    ctx.lineTo(-20,30);
    ctx.lineTo(0,0);
    ctx.strokeStyle = 'white';
    ctx.stroke();
    ctx.closePath();
    ctx.restore();
}
function handleKeyDown (evt) {
    evt = evt || window.event;
    switch (evt.keyCode) {
        case 37:
            left = true;
            break;
        case 38:
            up = true;
            break;
        case 39:
            right = true;
            break;
    }
}
function handleKeyUp(evt) {
    evt = evt || window.event;
    switch (evt.keyCode) {
        case 37:
            left = false;
            break;
        case 38:
            up = false;
            break;
        case 39:
            right = false;
            break;
    }
}

您需要一个称为“夹紧”的概念。

夹紧是将值限制在指定范围内

您希望将船的水平位置钳制为不小于0且不大于画布宽度

您希望将船的垂直位置钳制为不小于0且不大于画布高度

这是将值钳制在最小值和最大值之间的代码

clampedValue = Math.min(Math.max(currentValue, min), max);
要将任何[x,y]保持在画布中,可以像这样夹紧x,y:

clampedX = Math.min(Math.max(x, 0), canvasWidth);
clampedY = Math.min(Math.max(y, 0), canvasHeight);
y += gravity;
x += horizontalSpeed;
x=Math.min(Math.max(x,0+20),width-80);
y=Math.min(Math.max(y,0+80),height-90);
现在你的飞船比一个[x,y]点大。因此,为了将整艘船保持在画布内,您可以像这样夹紧[x,y]:

clampedX = Math.min(Math.max(x, 0), canvasWidth);
clampedY = Math.min(Math.max(y, 0), canvasHeight);
y += gravity;
x += horizontalSpeed;
x=Math.min(Math.max(x,0+20),width-80);
y=Math.min(Math.max(y,0+80),height-90);
而且,即使你的船在地面上,你也会让重力增加。在这一点上,重力效应变为零,因为船舶完全由地面反重力支撑。因此,当船舶在地面上时,您需要将重力设置为零:

if(y==height-90){gravity=0;}
以下是经过重构的代码,以使您的产品始终处于最佳状态:

var x=200;
变量y=100;
var-up=false;
var-right=false;
var left=false;
var重力=-1.1;
var水平速度=0.1;
var canvas=document.querySelector(“canvas”);
var width=canvas.width;
var height=canvas.height;
var ctx=canvas.getContext(“2d”);
init();
函数init(){
document.onkeydown=handleKeyDown;
document.onkeyup=handleKeyUp;
制作动画();
}
函数animate(){
移动船舶();
drawScene();
请求动画帧(动画);
}
函数drawsecene(){
ctx.clearRect(0,01600800);
太空船();
}
函数moveShip(){
如果(左){
水平速度-=0.1;
}否则,如果(右){
水平速度+=0.1;
}
如果(向上){
重力-=0.4;
}
重力+=0.12;
y+=重力;
x+=水平速度;
x=数学最小值(数学最大值(x,0+20),宽度-80);
y=数学最小值(数学最大值(y,0+80),高度-90);
如果(y==height-90){gravity=0;}
}
太空船的功能(){
ctx.save();
ctx.translate(x,y);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(0,-40);
ctx.lineTo(30,-80);
ctx.lineTo(60,-40);
ctx.lineTo(60,0);
ctx.lineTo(80,30);
ctx.lineTo(80,90);
ctx.lineTo(60,50);
ctx.lineTo(0,50);
ctx.lineTo(-20,90);
ctx.lineTo(-20,30);
ctx.lineTo(0,0);
ctx.strokeStyle='蓝色';
ctx.stroke();
ctx.closePath();
ctx.restore();
}
功能handleKeyDown(evt){
evt=evt | | window.event;
开关(evt.keyCode){
案例37:
左=真;
打破
案例38:
向上=真;
打破
案例39:
右=真;
打破
}
}
功能handleKeyUp(evt){
evt=evt | | window.event;
开关(evt.keyCode){
案例37:
左=假;
打破
案例38:
向上=错误;
打破
案例39:
右=假;
打破
}
}
body{背景色:象牙;}
#画布{边框:1px纯红;边距:0自动;}
按住箭头键移动船舶。

如果你想找到一本教程,这个过程叫做“碰撞检测”。当你的游戏有很多墙的时候,这是一个复杂的过程——当你试图阻止他们离开游戏区域时,会有更简单的版本。谢谢,我要试试那个版本。它并没有真正帮到我:(哦,伙计,我不知道你是谁,但你真的帮了我!只剩下一个问题。控制台告诉我“画布为空”。很高兴我能提供帮助。关于canvas未定义的问题,您可以将var canvas从init函数中拉出来,并将其与其他起始变量放在一起--请参阅我的修订代码。祝您的项目好运!抱歉,但它仍然不断地说“TypeError:canvas为null”好的,将您的代码与我的答案中的工作代码进行比较。请确保您已将
var canvas
与其他起始变量一起向上拉,并确保您已使用
var width
var height
与起始变量一起创建:-)如果我看起来很愚蠢,请原谅,但是复制了所有的工作脚本并用我的脚本替换它。但仍然不起作用。是否可能是因为它必须对window.onload=init();?我以前用过这个密码