为什么精灵角色更新位置会导致拖尾?
Why is sprite character update position causing a trail?
当点击输入以重新渲染和移动精灵时,这会导致精灵在屏幕上排序 trail/smear。
我试过 clearRect()
但这似乎没有任何区别。我也以此为灵感 https://github.com/jlongster/canvas-game-bootstrap 但我不太明白 canvas 是如何被覆盖的
我正在使用与 https://github.com/jlongster/canvas-game-bootstrap 非常相似的渲染实体方法,但这仍然不是玩球。
ctx.save();
ctx.translate( entity.settings.pos[ 0 ], entity.settings.pos[ 1 ] );
entity.settings.sprite.render( ctx );
ctx.restore();
这是我的index.js
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
var playerSpeed = 200;
resources.load([
"images/rsprites_iddle/trump_iddle.png",
"images/rsprites_run/trump_run.png"
]);
function init() {
loop();
}
resources.onReady( init );
var previousCoords = {
x: 0,
y: 0,
};
window.previousCoords = previousCoords;
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
width = window.innerWidth,
height = window.innerHeight,
keys = [],
friction = 0.8,
gravity = 0.4,
boxes = [],
powerup = [];
var playerCharacter = new Player({
direction: 'forward',
pos: [0, 0],
sprite: new Sprite( "images/rsprites_iddle/trump_iddle.png", [0, 0], [ 256, 256 ], 14, [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], 'horizontal' ),
x: width / 2,
y: height - 256,
width: 256,
height: 256,
speed: 3,
velX: 0,
velY: 0,
jumping: false,
grounded: true,
});
window.playerCharacter = playerCharacter;
canvas.width = width;
canvas.height = height;
function update( dt ) {
handleInput(dt);
updateEntities( dt )
draw();
}
function draw(){
renderEntity( playerCharacter );
}
// draw();
var lastTime = 0;
function loop(timestamp) {
var now = Date.now();
var dt = (now - lastTime) / 1000.0;
var progress = timestamp - lastRender;
update(dt);
lastRender = timestamp;
lastTime = now;
window.requestAnimationFrame(loop);
}
document.body.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
function renderEntity( entity ) {
ctx.save();
ctx.clearRect( previousCoords.x, previousCoords.y, playerCharacter.settings.width, playerCharacter.settings.height );
ctx.translate( entity.settings.pos[ 0 ], entity.settings.pos[ 1 ] );
entity.settings.sprite.render( ctx );
ctx.restore();
}
function updateEntities( dt ) {
playerCharacter.settings.sprite.update( dt );
}
function handleInput( dt ) {
if( input.isDown( 'LEFT' ) || input.isDown( 'a' ) ) {
playerCharacter.settings.pos[0] += playerSpeed * dt;
playerCharacter.settings.direction = "LEFT";
}
if( input.isDown( 'RIGHT' ) || input.isDown( 'd' ) ) {
playerCharacter.settings.pos[0] -= playerSpeed * dt;
playerCharacter.settings.direction = "RIGHT";
}
previousCoords.x = playerCharacter.settings.pos[0];
previousCoords.y = playerCharacter.settings.pos[1];
}
var lastRender = 0;
})();
sprite.js
(function() {
function Sprite( url, pos, size, speed, frames, dir, once ) {
this.pos = pos;
this.size = size;
this.speed = typeof speed === 'number' ? speed : 0;
this.frames = frames;
this._index = 0;
this.url = url;
this.dir = dir || 'horizontal';
this.once = once;
}
Sprite.prototype = {
update: function( dt ) {
this._index += this.speed * dt;
},
render: function( ctx ) {
var frame;
if( this.speed > 0 ) {
var max = this.frames.length;
var idx = Math.floor( this._index );
frame = this.frames[ idx % max ];
if( this.once && idx >= max ) {
this.done = true;
return;
}
}
else {
frame = 0;
}
var x = this.pos[0];
var y = this.pos[1];
if( this.dir == 'vertical' ) {
y += frame * this.size[1];
}
else {
x += frame * this.size[0];
}
if( playerCharacter.settings.direction !== "forward" ) {
if( playerCharacter.settings.direction == "LEFT" ) {
x = this.size[0];
}
else if( playerCharacter.settings.direction == "RIGHT" ) {
x = this.size[0] * 2;
}
else {
x = 0;
}
}
ctx.drawImage( resources.get( this.url ), 256, y, this.size[0], this.size[1], window.innerWidth / 2 - ( this.size[ 0 ] / 2 ), window.innerHeight - this.size[0], this.size[0], this.size[1] );
}
};
window.Sprite = Sprite;
})();
我希望 sprite 更新位置并重新绘制到 canvas,那里没有工件或以前的 sprite。
Canvas 是一个像素缓冲区,您需要清除它并在每一帧重新绘制动画内容。在主渲染循环开始时使用 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
正如blindman67的评论所指出的
当点击输入以重新渲染和移动精灵时,这会导致精灵在屏幕上排序 trail/smear。
我试过 clearRect()
但这似乎没有任何区别。我也以此为灵感 https://github.com/jlongster/canvas-game-bootstrap 但我不太明白 canvas 是如何被覆盖的
我正在使用与 https://github.com/jlongster/canvas-game-bootstrap 非常相似的渲染实体方法,但这仍然不是玩球。
ctx.save();
ctx.translate( entity.settings.pos[ 0 ], entity.settings.pos[ 1 ] );
entity.settings.sprite.render( ctx );
ctx.restore();
这是我的index.js
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
var playerSpeed = 200;
resources.load([
"images/rsprites_iddle/trump_iddle.png",
"images/rsprites_run/trump_run.png"
]);
function init() {
loop();
}
resources.onReady( init );
var previousCoords = {
x: 0,
y: 0,
};
window.previousCoords = previousCoords;
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
width = window.innerWidth,
height = window.innerHeight,
keys = [],
friction = 0.8,
gravity = 0.4,
boxes = [],
powerup = [];
var playerCharacter = new Player({
direction: 'forward',
pos: [0, 0],
sprite: new Sprite( "images/rsprites_iddle/trump_iddle.png", [0, 0], [ 256, 256 ], 14, [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], 'horizontal' ),
x: width / 2,
y: height - 256,
width: 256,
height: 256,
speed: 3,
velX: 0,
velY: 0,
jumping: false,
grounded: true,
});
window.playerCharacter = playerCharacter;
canvas.width = width;
canvas.height = height;
function update( dt ) {
handleInput(dt);
updateEntities( dt )
draw();
}
function draw(){
renderEntity( playerCharacter );
}
// draw();
var lastTime = 0;
function loop(timestamp) {
var now = Date.now();
var dt = (now - lastTime) / 1000.0;
var progress = timestamp - lastRender;
update(dt);
lastRender = timestamp;
lastTime = now;
window.requestAnimationFrame(loop);
}
document.body.addEventListener("keydown", function(e) {
keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function(e) {
keys[e.keyCode] = false;
});
function renderEntity( entity ) {
ctx.save();
ctx.clearRect( previousCoords.x, previousCoords.y, playerCharacter.settings.width, playerCharacter.settings.height );
ctx.translate( entity.settings.pos[ 0 ], entity.settings.pos[ 1 ] );
entity.settings.sprite.render( ctx );
ctx.restore();
}
function updateEntities( dt ) {
playerCharacter.settings.sprite.update( dt );
}
function handleInput( dt ) {
if( input.isDown( 'LEFT' ) || input.isDown( 'a' ) ) {
playerCharacter.settings.pos[0] += playerSpeed * dt;
playerCharacter.settings.direction = "LEFT";
}
if( input.isDown( 'RIGHT' ) || input.isDown( 'd' ) ) {
playerCharacter.settings.pos[0] -= playerSpeed * dt;
playerCharacter.settings.direction = "RIGHT";
}
previousCoords.x = playerCharacter.settings.pos[0];
previousCoords.y = playerCharacter.settings.pos[1];
}
var lastRender = 0;
})();
sprite.js
(function() {
function Sprite( url, pos, size, speed, frames, dir, once ) {
this.pos = pos;
this.size = size;
this.speed = typeof speed === 'number' ? speed : 0;
this.frames = frames;
this._index = 0;
this.url = url;
this.dir = dir || 'horizontal';
this.once = once;
}
Sprite.prototype = {
update: function( dt ) {
this._index += this.speed * dt;
},
render: function( ctx ) {
var frame;
if( this.speed > 0 ) {
var max = this.frames.length;
var idx = Math.floor( this._index );
frame = this.frames[ idx % max ];
if( this.once && idx >= max ) {
this.done = true;
return;
}
}
else {
frame = 0;
}
var x = this.pos[0];
var y = this.pos[1];
if( this.dir == 'vertical' ) {
y += frame * this.size[1];
}
else {
x += frame * this.size[0];
}
if( playerCharacter.settings.direction !== "forward" ) {
if( playerCharacter.settings.direction == "LEFT" ) {
x = this.size[0];
}
else if( playerCharacter.settings.direction == "RIGHT" ) {
x = this.size[0] * 2;
}
else {
x = 0;
}
}
ctx.drawImage( resources.get( this.url ), 256, y, this.size[0], this.size[1], window.innerWidth / 2 - ( this.size[ 0 ] / 2 ), window.innerHeight - this.size[0], this.size[0], this.size[1] );
}
};
window.Sprite = Sprite;
})();
我希望 sprite 更新位置并重新绘制到 canvas,那里没有工件或以前的 sprite。
Canvas 是一个像素缓冲区,您需要清除它并在每一帧重新绘制动画内容。在主渲染循环开始时使用 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
正如blindman67的评论所指出的