#javascript #canvas
#javascript #холст
Вопрос:
Я создаю игру на javascript, и анимированный спрайт мигает, когда он движется, я думаю, это связано со скоростью анимации, потому что мне также нужно ее замедлить. вот мой код для обновления анимации
var playerani = setInterval(function(){
if(animate == true){
if(aniframe == maxframes){
aniframe = 1
}else{
aniframe = 1;
}
}
if(controller.left == true){
animate = true;
window.aniimgY = 576;
}else if(controller.up == true){
animate = true;
window.aniimgY = 512;
}else if(controller.down == true){
animate = true;
window.aniimgY = 640;
}else if(controller.right == true){
animate = true;
window.aniimgY = 704;
}else{
animate = false;
aniframe = 0;
}
},10)
Вот таблица спрайтов
Вы можете протестировать игру здесь
Комментарии:
1. Ну, нет никакого способа протестировать ваш код. Но на первый взгляд я бы сказал, что вы должны использовать
requestAnimationFrame
вместоsetInterval
того, чтобы вызывать свой цикл, посколькуrequestAnimationFrame
пытается поддерживать частоту обновления на уровне 60 кадров в секунду.2. Кажется, это лучший способ анимации игрока, но он все равно мигает, когда он движется
3. Как я уже сказал, нет способа протестировать ваш код. Попробуйте создать фрагмент в редакторе вопросов с помощью
<>
кнопки на панели инструментов и сделать свой код работоспособным. Или создайте jsfiddle, codepen или другой ресурс, в котором мы можем запускать ваш код.4. Вы можете протестировать его на ryangrube.com/projects/tilegame
5. Это выглядит как отключение из-за одной ошибки. У вас есть только 9 кадров, 8, если вы не учитываете первый незанятый кадр, но ваш maxframe увеличивается до 10, что приведет к тому, что изображение не будет отображаться для одного или двух кадров в зависимости от того, как вычисляются смещения atlas. Если ваш максимальный кадр установлен на 8, это должно это исправить, но, как сказал @EmielZuurbier, мы не можем точно сказать, что происходит без кода.
Ответ №1:
Как предложил @HanYolo, установите var maxframes = 8;
:
var aniframe = 0;
var maxframes = 8;
var animate = false;
window.aniimg = document.getElementById("aniimg1")
var timer = null;
var aniTimer = null;
var levelnum = 0;
var img = document.getElementById("img")
var img2 = document.getElementById("img2")
var c = document.getElementById("c");
var ctx = c.getContext('2d')
var props = document.getElementById("props");
var prps = c.getContext('2d')
var tilesize = 32;
var tiles = 10;
player = {
size: 10,
x: 150,
y: 150,
v: 2,
}
controller = {
up: false,
right: false,
left: false,
down: false,
keyParse: function(key) {
switch (key) {
//keydowns
case 38:
this.up = true;
break;
case 37:
this.left = true;
break;
case 39:
this.right = true;
break;
case 40:
this.down = true;
break;
}
},
keyStop: function(key) {
switch (key) {
//keydowns
case 38:
this.up = false;
break;
case 37:
this.left = false;
break;
case 39:
this.right = false;
break;
case 40:
this.down = false;
break;
}
}
}
function drawlvl() {
for (y = 0; y < lvl[levelnum].length; y ) {
for (x = 0; x < lvl[levelnum][y].length; x ) {
switch (lvl[levelnum][y][x]) {
case 0:
//nw grass
var imgvar = img
var sx = 32;
var sy = 192;
break;
case 1:
//w dirt
var imgvar = img
var sx = 224;
var sy = 160;
break;
case 2:
//nw top dirt
var imgvar = img
var sx = 128;
var sy = 96;
break;
case 3:
//nw bottom dirt
var imgvar = img2
var sx = 95;
var sy = 320;
break;
case 4:
//lvl up dirt
var imgvar = img
var sx = 224;
var sy = 160;
break;
case 5:
//lvl down dirt
var imgvar = img
var sx = 224;
var sy = 160;
break;
case 6:
//w water
var imgvar = img
var sx = 0;
var sy = 416;
break;
case 7:
//w water side left
var imgvar = img
var sx = 0;
var sy = 288;
break;
case 8:
//w water side right
var imgvar = img2
var sx = 223;
var sy = 128;
break;
}
ctx.drawImage(imgvar, sx, sy, 32, 32, x * tilesize, y * tilesize, tilesize, tilesize)
}
}
}
walkable_blocks = [1, 6, 7, 8]
walkable_props = [0, 8, 9, 10, 11, 12]
lvlup_blocks = [4]
lvldown_blocks = [5]
function gameLoop() {
if (controller.up == true) {
player.newY = player.y - player.v
} else if (controller.left == true) {
player.newX = player.x - player.v
} else if (controller.right == true) {
player.newX = player.x player.v
} else if (controller.down == true) {
player.newY = player.y player.v
} else {
player.newY = player.y;
player.newX = player.x;
}
function playerani() {
if (animate == true) {
if (aniframe == maxframes) {
aniframe = 1
} else {
aniframe = 1;
}
}
if (window.aniimgY == null) {
window.aniimgY = 640;
}
if (controller.left == true) {
animate = true;
window.aniimgY = 576;
} else if (controller.up == true) {
animate = true;
window.aniimgY = 512;
} else if (controller.down == true) {
animate = true;
window.aniimgY = 640;
} else if (controller.right == true) {
animate = true;
window.aniimgY = 704;
} else {
animate = false;
aniframe = 0;
}
}
player.col = Math.floor((player.newX 5) / tilesize)
player.row = Math.floor((player.newY 5) / tilesize)
tileval = lvl[levelnum][player.row][player.col]
propval = propsArr[levelnum][player.row][player.col]
ctx.fillStyle = "black"
if (walkable_blocks.includes(tileval) amp;amp; walkable_props.includes(propval)) {
player.y = player.newY;
player.x = player.newX;
if (player.x <= 0) {
player.x = 0
}
if (player.y <= 0) {
player.y = 0
}
if (player.x player.size >= c.width) {
player.x = c.width - player.size;
}
if (player.y player.size >= c.height) {
player.y = c.height - player.size;
}
} else if (lvlup_blocks.includes(tileval)) {
document.getElementById("body").style.ainmation = "fadeInAnimation";
document.getElementById('body').style.animationPlayState = "running";
if (timer == null) {
timer = setTimeout(function() {
levelnum ;
player.x = 280;
player.y = 150;
timer = null;
}, 2500)
if (aniTimer == null) {
aniTimer = setTimeout(function() {
document.getElementById("body").style.animationPlayState = "paused";
clearTimeout(aniTimer)
aniTimer = null;
}, 5000)
}
} else {
}
} else if (lvldown_blocks.includes(tileval)) {
document.getElementById("body").style.ainmation = "fadeInAnimation";
document.getElementById('body').style.animationPlayState = "running";
if (timer == null) {
timer = setTimeout(function() {
levelnum--;
player.x = 33;
player.y = 150;
timer = null;
}, 2500)
}
if (aniTimer == null) {
aniTimer = setTimeout(function() {
document.getElementById("body").style.animationPlayState = "paused";
clearTimeout(aniTimer);
aniTimer = null;
}, 5000)
}
} else {
player.y = player.y;
player.x = player.x;
if (player.x <= 0) {
player.x = 0
}
if (player.y <= 0) {
player.y = 0
}
if (player.x player.size >= c.width) {
player.x = c.width - player.size;
}
if (player.y player.size >= c.height) {
player.y = c.height - player.size;
}
}
ctx.fillRect(0, 0, c.width, c.height)
drawlvl()
drawprops()
drawEnemy()
playerani()
ctx.drawImage(window.aniimg, 64 * (Math.floor(aniframe)), window.aniimgY, 64, 64, player.x - 16, player.y - 16, 48, 48)
}
var gameintertval = setInterval(function() {
gameLoop()
}, 10)
document.addEventListener('keydown', function(event) {
controller.keyParse(event.keyCode)
})
document.addEventListener('keyup', function(event) {
controller.keyStop(event.keyCode)
})
body {
zoom: 100%;
animation: fadeInAnimation ease 5s;
animation-play-state: paused;
animation-iteration-count: infinite;
}
@keyframes fadeInAnimation {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
canvas{
position: absolute;
}
#props{
z-index: 1000;
}
#c{
z-index: -1000;
}
<html>
<head>
<title>TileGame</title>
<base href="http://ryangrube.com/projects/tilegame/">
</head>
<body id="body">
<img id="img" style="display: none;" src="TileSet_V1.png">
<img id="img2" style="display: none;" src="TileSet_V2.png">
<img id="img3" style="display: none;" src="TileSet_V3.png">
<img id="aniimg1" style="display: none;" src="no_dagger.png">
<img id="aniimg2" style="display: none;" src="dagger.png">
<canvas id="c" width="320" height="320" style="background-color: black;border:3px solid black;"></canvas>
<canvas id="props" width="320" height="320" style="border:3px solid black;"></canvas>
<script src="map.js"></script>
<script src="props.js"></script>
<script src="drawprops.js"></script>
<script src="enemy.js"></script>
<script src="drawenemy.js"></script>
</body>
</html>