gpt4 book ai didi

javascript - 如何使用javascript中的箭头键在 Canvas 上移动图像

转载 作者:行者123 更新时间:2023-11-30 12:00:36 26 4
gpt4 key购买 nike

我已经尝试了我在这里看到的几种不同的方式,但我无法完全让我的形象动起来。每当我尝试为箭头键按下调整代码时,它似乎只会让我的 Canvas 缩小并且我的玩家模型(太空人)消失。

这是我不断返回的“绘图板”,以及到目前为止的内容。

// Get the canvas and context
var canvas = document.getElementById("space");
var ctx = canvas.getContext("2d");
canvas.width = 1920;
canvas.height = 700;


// Create the image object
var spaceperson = new Image();

// Add onload event handler
spaceperson.onload = function () {
// Done loading, now we can use the image
ctx.drawImage(spaceperson, 280, 300);
};


// artwork by Harrison Marley (using make8bitart.com)
spaceperson.src = "http://i.imgur.com/Eh9Dpq2.png";`

我对 javascript 很陌生,我只是想弄清楚如何使用箭头键移动 specperson 图像。我试图为太空人创建一个类来访问他们的 x、y 值,但我似乎无法在不使用 .onload

的情况下绘制图像

最佳答案

这里有一个更完整的例子:

//just a utility
function image(url, callback){
var img = new Image();
if(typeof callback === "function"){
img.onload = function(){
//just to ensure that the callback is executed async
setTimeout(function(){ callback(img, url) }, 0)
}
}
img.src = url;
return img;
}

//a utility to keep a value constrained between a min and a max
function clamp(v, min, max){
return v > min? v < max? v: max: min;
}

//returns a function that can be called with a keyCode or one of the known aliases
//and returns true||false wether the button is down
var isKeyDown = (function(aliases){
for(var i=256, keyDown=Array(i); i--; )keyDown[i]=false;
var handler = function(e){
keyDown[e.keyCode] = e.type === "keydown";
e.preventDefault(); //scrolling; if you have to suppress it
};

addEventListener("keydown", handler, false);
addEventListener("keyup", handler, false);

return function(key){
return(true === keyDown[ key in aliases? aliases[ key ]: key ])
}
})({
//some aliases, to be extended
up: 38,
down: 40,
left: 37,
right: 39
});



// Get the canvas and context
var canvas = document.getElementById("space");
canvas.width = 1920;
canvas.height = 700;
var ctx = canvas.getContext("2d");

//the acutal image is just a little-part of what defines your figue
var spaceperson = {
image: image("//i.imgur.com/Eh9Dpq2.png", function(img){
spaceperson.width = img.naturalWidth;
spaceperson.height = img.naturalHeight;

//start the rendering by calling update
update();
}),

//position
x: 60, y: 310,
width: 0, height: 0,

speed: 200 // 200px/s
};

var lastCall = 0; //to calculate the (real) time between two update-calls
//the render-fucntion
function update(){
//taking account for (sometimes changing) framerates
var now = Date.now(), time = lastCall|0 && (now-lastCall)/1000;
lastCall = now;
requestAnimationFrame(update);

var sp = spaceperson,
speed = sp.speed;

//checking the pressed buttons and calculates the direction
//two opposite buttons cancel out each other, like left and right
var dx = (isKeyDown('right') - isKeyDown('left')) * time,
dy = (isKeyDown('down') - isKeyDown('up')) * time;

//fix the speed for diagonals
if(dx && dy) speed *= 0.7071067811865475; // * 1 / Math.sqrt(2)

if(dx) { //there is some movement on the x-axes
sp.x = clamp(
//calculate the new x-Position
//currentPos + direction * speed
sp.x + dx * sp.speed,

//restraining the result to the bounds of the map
0, canvas.width - sp.width
);
}

//same for y
if(dy) sp.y = clamp(sp.y + dy * sp.speed, 0, canvas.height - sp.height);

ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(sp.image, sp.x, sp.y);
}

编辑:

A quick question (I hope); if I was to later add other objects, would I check for collisions in update()?

这仍然只是一个非常基本的例子。 update() 函数的主要目的应该是充当主事件循环。触发必须按照事件发生的顺序在每一帧发生的所有事件。

var lastCall = 0;
function update(){
//I always want a next frame
requestAnimationFrame(update);

//handle timing
var now = Date.now(),
//time since the last call in seconds
//cause usually it's easier for us to think in
//tems like 50px/s than 0.05px/ms or 0.8333px/frame
time = lastCall|0 && (now-lastCall) / 1000;

lastCall = now;

movePlayer(time);
moveEnemies(time);
moveBullets(time);

collisionDetection();

render();
}

function render(){
ctx.clear(0, 0, canvas.width, canvas.height);
drawBackground(ctx);
for(var i=0; i<enemies.length; ++i)
enemies[i].render(ctx);
player.render(ctx);
}

并不是说您现在必须实现所有这些功能,而是让您了解一个可能的结构。不要害怕将大任务(功能)分解成子任务。
给每个敌人一个 move() 函数可能是有意义的,这样你就可以为每个敌人实现不同的移动模式,或者你说每个敌人的模式是(并且将是)完全相同的,最好参数化,然后你可以在循环中处理它。
渲染也是如此,正如我在代码的最后一部分中展示的那样。

关于javascript - 如何使用javascript中的箭头键在 Canvas 上移动图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36712648/

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