Javascript 使用canvas和requestAnimationFrame设置图像数组动画时的位置问题
我正在做一个射击游戏和动画七个敌人的形象。 你可以看到彼此之间的距离非常好,只有10px。但是动画完成后,最左侧的敌人图像变得更远,比10px高Javascript 使用canvas和requestAnimationFrame设置图像数组动画时的位置问题,javascript,html5-canvas,requestanimationframe,Javascript,Html5 Canvas,Requestanimationframe,我正在做一个射击游戏和动画七个敌人的形象。 你可以看到彼此之间的距离非常好,只有10px。但是动画完成后,最左侧的敌人图像变得更远,比10px高 <canvas id="canvas" width="700" height="600" style="border: 1px solid #333" ></canvas> <script> let canvas = docume
<canvas
id="canvas"
width="700"
height="600"
style="border: 1px solid #333"
></canvas>
<script>
let canvas = document.querySelector("canvas");
let c = canvas.getContext("2d");
c.fillRect(30, 470, 640, 100);
let enemys = [];
let limitObj = {
enemyLimitDown: 470,
enemyLimitLeft: 30,
enemyLimitRight: 670,
enemyLimitTop: 30
};
class Enemy {
constructor(x) {
(this.x = x),
(this.y = 30),
(this.width = 50),
(this.height = 50),
(this.xstep = 2),
(this.ystep = 50),
(this.direction = "right"),
enemys.push(this);
}
draw(enemys) {
for (let i = 0; i < num; i++) {
c.drawImage(
imageEnemy,
enemys[i].x,
enemys[i].y,
enemys[i].width,
enemys[i].height
);
}
}
clear() {
c.clearRect(0, 0, canvas.width, canvas.height - 130);
}
update(enemys) {
for (let i = num-1; i >=0; i--) {
if (enemys[i].direction == "right") {
enemys[i].x += enemys[i].xstep;
let max = 0;
max = findMax();
if (max == limitObj.enemyLimitRight - enemys[i].width) {
for (let i = num - 1; i >= 0; i--) {
enemys[i].y += this.ystep;
enemys[i].direction = "left";
}
}
} else {
enemys[i].x -= enemys[i].xstep;
let min = findMin();
if (min == limitObj.enemyLimitLeft) {
for (let i = num - 1; i >= 0; i--) {
enemys[i].y += this.ystep;
enemys[i].direction = "right";
}
}
}
}
}
animate(enemys) {
this.update(enemys);
this.clear();
this.draw(enemys);
let canRequest = requestAnimationFrame(() => {
this.animate(enemys);
});
for (let i = 0; i < num; i++) {
if (enemys[i].y + this.height >= limitObj.enemyLimitDown) {
cancelAnimationFrame(canRequest);
}
}
}
}
function findMax() {
let max = 0;
for (let i = 0; i < num; i++) {
if (max <= enemys[i].x) {
max = enemys[i].x;
}
}
return max;
}
function findMin() {
let min = canvas.width + 1;
for (let i = 0; i < num; i++) {
if (min >= enemys[i].x) {
min = enemys[i].x;
}
}
return min;
}
// initialize enemy picture
let imageEnemy = new Image();
imageEnemy.src = "https://raw.githubusercontent.com/AbdullA-Ababakre/BlogImage/master/enemy.png";
function initEnemy(x) {
imageEnemy.addEventListener("load", () => {
c.drawImage(imageEnemy, x, 30, 50, 50);
});
}
let enemyStart = 10;
let enemyWidth = 50;
let num = 7;
for (let i = 0; i < num; i++) {
enemys[i] = new Enemy(enemyStart + i * enemyWidth + i * 10);
initEnemy(enemyStart + i * enemyWidth + i * 10);
}
enemys[0].animate(enemys);
</script>
我尝试了很多方法,发现问题出在更新方法上
对于(设i=0;i=0;i--),最左侧的敌人图像变得更远,距离大于10px
<canvas
id="canvas"
width="700"
height="600"
style="border: 1px solid #333"
></canvas>
<script>
let canvas = document.querySelector("canvas");
let c = canvas.getContext("2d");
c.fillRect(30, 470, 640, 100);
let enemys = [];
let limitObj = {
enemyLimitDown: 470,
enemyLimitLeft: 30,
enemyLimitRight: 670,
enemyLimitTop: 30
};
class Enemy {
constructor(x) {
(this.x = x),
(this.y = 30),
(this.width = 50),
(this.height = 50),
(this.xstep = 2),
(this.ystep = 50),
(this.direction = "right"),
enemys.push(this);
}
draw(enemys) {
for (let i = 0; i < num; i++) {
c.drawImage(
imageEnemy,
enemys[i].x,
enemys[i].y,
enemys[i].width,
enemys[i].height
);
}
}
clear() {
c.clearRect(0, 0, canvas.width, canvas.height - 130);
}
update(enemys) {
for (let i = num-1; i >=0; i--) {
if (enemys[i].direction == "right") {
enemys[i].x += enemys[i].xstep;
let max = 0;
max = findMax();
if (max == limitObj.enemyLimitRight - enemys[i].width) {
for (let i = num - 1; i >= 0; i--) {
enemys[i].y += this.ystep;
enemys[i].direction = "left";
}
}
} else {
enemys[i].x -= enemys[i].xstep;
let min = findMin();
if (min == limitObj.enemyLimitLeft) {
for (let i = num - 1; i >= 0; i--) {
enemys[i].y += this.ystep;
enemys[i].direction = "right";
}
}
}
}
}
animate(enemys) {
this.update(enemys);
this.clear();
this.draw(enemys);
let canRequest = requestAnimationFrame(() => {
this.animate(enemys);
});
for (let i = 0; i < num; i++) {
if (enemys[i].y + this.height >= limitObj.enemyLimitDown) {
cancelAnimationFrame(canRequest);
}
}
}
}
function findMax() {
let max = 0;
for (let i = 0; i < num; i++) {
if (max <= enemys[i].x) {
max = enemys[i].x;
}
}
return max;
}
function findMin() {
let min = canvas.width + 1;
for (let i = 0; i < num; i++) {
if (min >= enemys[i].x) {
min = enemys[i].x;
}
}
return min;
}
// initialize enemy picture
let imageEnemy = new Image();
imageEnemy.src = "https://raw.githubusercontent.com/AbdullA-Ababakre/BlogImage/master/enemy.png";
function initEnemy(x) {
imageEnemy.addEventListener("load", () => {
c.drawImage(imageEnemy, x, 30, 50, 50);
});
}
let enemyStart = 10;
let enemyWidth = 50;
let num = 7;
for (let i = 0; i < num; i++) {
enemys[i] = new Enemy(enemyStart + i * enemyWidth + i * 10);
initEnemy(enemyStart + i * enemyWidth + i * 10);
}
enemys[0].animate(enemys);
</script>
让canvas=document.querySelector(“canvas”);
设c=canvas.getContext(“2d”);
c、 fillRect(30470640100);
让敌人=[];
设limitObj={
enemyLimitDown:470,
enemyLimitLeft:30,
enemyLimitRight:670,
enemyLimitTop:30
};
阶级敌人{
构造器(x){
(这个.x=x),
(此.y=30),
(此宽度=50),
(该高度=50),
(this.xstep=2),
(this.ystep=50),
(this.direction=“right”),
敌人推(这个);
}
抽签(敌人){
for(设i=0;i=0;i--){
如果(敌人[i]。方向==“右”){
enemys[i].x+=enemys[i].xstep;
设max=0;
max=findMax();
if(max==limitObj.enemyLimitRight-enemys[i].width){
对于(设i=num-1;i>=0;i--){
敌人[i].y+=this.ystep;
敌人[i].direction=“left”;
}
}
}否则{
敌人[i].x-=敌人[i].xstep;
设min=findMin();
if(min==limitObj.enemyLimitLeft){
对于(设i=num-1;i>=0;i--){
敌人[i].y+=this.ystep;
敌人[i].direction=“right”;
}
}
}
}
}
制作动画(敌人){
更新(敌人);
这个.clear();
这个。画(敌人);
让canRequest=requestAnimationFrame(()=>{
使(敌人)活跃起来;
});
for(设i=0;i=limitObj.enemyLimitDown){
取消动画帧(canRequest);
}
}
}
}
函数findMax(){
设max=0;
for(设i=0;i{
c、 drawImage(图像敌人,x,30,50,50);
});
}
让敌人开始=10;
灌肠宽度=50;
设num=7;
for(设i=0;i
错误的结果,最后一个图像离得很远。
欢迎来到Slack
我已经看过你的代码了,我想让你知道问题并不是很明显
最终,我相信我已经为您找到了问题的根源,并且只做了一点小小的调整就解决了它
[...]
let max = 0;
max = findMax();
if (max == limitObj.enemyLimitRight - enemys[i].width) {
for (let j = num - 1; j >= 0; j--) {
enemys[j].y += this.ystep;
enemys[j].direction = "left";
}
} else {
enemys[i].x += enemys[i].xstep;
}
} else {
let min = findMin();
if (min == limitObj.enemyLimitLeft) {
for (let j = num - 1; j >= 0; j--) {
enemys[j].y += this.ystep;
enemys[j].direction = "right";
}
} else {
enemys[i].x -= enemys[i].xstep;
}
[...]
注意我是如何移动你的enemys[I].x-=enemys[I].xstep代码>和敌人[i].x+=敌人[i].xstep代码>行进入限额检查的else条件
我相信你的问题是你一直在增加敌人[I].x
,即使是在你达到x限制并打算只增加y的回合中,每次迭代都会导致x的略微增加,但只针对最后一个敌人<代码>敌人[6]
希望能有所帮助。非常感谢您的回答,它很有效。之后,我得出结论,当我们需要检查和移动时,我们应该首先进行检查,这是我在这个错误中坚持了整整3天之后的编码经验总结。@Abdullaabababakre现在不要停止,你仍然需要构建游戏的其余部分:-Dhello Graham P health,我很麻烦。对不起。你能回答我关于这个项目的新问题吗。