如何使Kaboom.js精灵动画重复



我正在使用Kaboom.js制作一些游戏,虽然移动玩家很容易,但我已经在制作精灵表动画方面陷入了一段时间的困境。正如你在这里的代码中看到的那样,我已经处理好了,使用setInterval,并篡改了值来制作我的特定7步动画(Open Game Art中的恐龙动画,我使用Codeshack图像到精灵生成器将其制作成精灵表,但我忍不住想一定有更好的方法?

kaboom({
global: true,
width: 320,
height: 240,
scale: 2,
debug: true,
clearColor: [0, 0, 1, 1],
});
loadRoot("img/");
loadSprite("dino", "spritesheet.png", {
sliceX: 8,
sliceY: 1,
anims: {
idle: { from: 1, to: 1 },
run: { from: 1, to: 7 },
},
});
const player = add([
sprite("dino", {
animSpeed: 2,
frame: 1,
}),
pos(width() * 0.5, height() * 0.5),
origin("center"),
scale(1),
]);

let myInterval;
function animateR() {
myInterval = setInterval(() => {
player.play("run");
player.move(1000, 0);
}, 100);
}
function animateL() {
myInterval = setInterval(() => {
player.play("run");
player.move(-1000, 0);
}, 100);
}
keyPress("right", () => {
player.scale.x = 1;
animateR();
});
keyPress("left", () => {
player.scale.x = -1;
animateL();
});
keyDown("x", () => {
player.move(0, -10);
});
keyRelease("left", () => {
clearInterval(myInterval);
});
keyRelease("right", () => {
clearInterval(myInterval);
});

还有一种方法集成了JSON和Aseplite创建的文件格式。该方法在他们的马里奥教程中的Replit文档中进行了概述。以下是链接:使用Kaboom 构建马里奥

本教程包含图片,还包含其他与精灵相关的信息。如果你发现你想为精灵表生成JSON文件,那么Aseprite可以在GitHub上获得。以下是它的工作原理:

  1. 将您的精灵表导入Aseplite。这在网格中具有相同大小图元的图纸上效果最佳。我使用.png格式
  2. 将循环和标记添加到文件信息中
  3. 将精灵表导出为JSON文件。一定要将类型从";散列";至";数组";在下拉列表中。否则,Kaboom.js将抛出一个错误
  4. 将您的精灵表和JSON文件添加到您的项目中。如果循环和标记正确地添加到Aseplite项目中,JSON文件将包含在Kaboom.js中使用动画所需的信息

教程中使用的马里奥角色数据提供了一个很好的示例。当您打开包含在"的资产包中的.ase文件时;Mario";,你可以在时间线上看到标签。(您可能需要在设置中打开时间线。(

//License: MIT, free software, Mgr. Jan Hrubos, kaboom.js example
// Init with some options (check out #KaboomOpt for full options list)
kaboom({
width: 800,
height: 600,
font: "sinko",
global:true,
background: [ 0, 0, 255, ],
canvas: document.querySelector("#mycanvas"),
debug:true
})

scene("begin",()=>{
function addButton(txt, p, f) {
const btn = add([
text(txt,{size:48}),
pos(p),
area(),
scale(1),
origin("center"),
])

btn.onClick(f)

btn.onUpdate(() => {
if (btn.isHovering()) {
const t = time() * 10
btn.color = rgb(
wave(0, 255, t),
wave(0, 255, t + 2),
wave(0, 255, t + 4),
)
btn.scale = vec2(1.2)
} else {
btn.scale = vec2(1)
btn.color = rgb()
}
})

}

addButton("Start CD Man", vec2(width()/2, height()/2), () => go("level1"))
onKeyPress("space", () => go("level1"))
})
go("begin")
loadSprite("bck", "./assets/images/bck.png")
loadSprite("ghost", "./assets/images/ghost.png")
loadSprite("diamond", "./assets/images/diamond.png")
loadSprite("star", "./assets/images/star.png")
loadSprite("wall", "./assets/images/wall.png")
loadSprite('pacman', './assets/images/pacmanMap.png', {
sliceX: 8,
sliceY: 1,
anims: {
runRight: { from: 0, to: 1 },
runLeft: { from: 2, to: 3 },
runDown: { from: 4, to: 5 },
runUp: { from: 6, to: 7 }
}
})
loadSound("shoot", "./assets/sounds/shoot.mp3")
loadSound("kling", "./assets/sounds/kling.mp3")

scene("level1",()=>{

const score = add([
text("Score: 0", {
size: 28, // 48 pixels tall
width: 320, // it'll wrap to next line when width exceeds this value
font: "sink", // there're 4 built-in fonts: "apl386", "apl386o", "sink", and "sinko"
},),
pos(10, 5),
{ value: 0 },
])

const SPEED=80
const bck2 = add([
sprite("bck"),
origin("center"),
pos(width()/2,height()/2),
z(-100),       
])
const map = [[
// Design the level layout with symbols
"====================",
"=        =         =",
"=        =   ****  =",
"=        =   ****  =",
"=        =====     =",
"=                  =",
"=    ********      =",
"=========          =",
"=       =          =",
"=  ***  =          =",
"=  ***  =    ****  =",
"=  ***  =    ****  =",
"=  ***  =    ****  =",
"=       =    ****  =",
"=    ====          =",
"=                  =",
"=          =========",
"=          *****   =",
"=          *****   =",
"====================",
]]
const levelCfg={
// The size of each grid
width: 40,
height: 30,
"=": () => [
sprite("wall"),
area(),     
scale(0.5),
solid(),
z(-90),
"wall",
],
"*": () => [
sprite("star"),
area(),     
scale(1),
solid(),
"star",
],
}
const level1 = addLevel(map[0],levelCfg)

const player = add([
sprite('pacman', {
animSpeed: 1,
frame: 0
}),
origin("center"),
pos(100,100),
z(-90),
body(),
gravity(0),
area(),
"player"       
])
const ghost1 = add([
sprite('ghost'),
origin("center"),
pos(400,400),
z(-90),
body(),
gravity(0),
area(),
"enemy"       
])

dir=1
loop(0.1,()=>{
ghost1.move(0,dir*SPEED*10)
})
ghost1.onCollide("wall",()=>{
dir=-dir
})
ghost1.onCollide("star",()=>{
dir=-dir
})
player.onCollide("star", (star) => {
destroy(star)
score.value += 1
score.text = "Score:" + score.value
play("kling")
if (score.value==54){
go("begin")
}
})

let myInterval;
const intervalTime=300
function animateR() {
clearInterval(myInterval)
myInterval = setInterval(() => {
player.play("runRight");
}, intervalTime);
}
function animateL() {
clearInterval(myInterval)
myInterval = setInterval(() => {
player.play("runLeft");
}, intervalTime);
}
function animateD() {
clearInterval(myInterval)
myInterval = setInterval(() => {
player.play("runDown");
}, intervalTime);
}
function animateU() {
clearInterval(myInterval)
myInterval = setInterval(() => {
player.play("runUp");
}, intervalTime);
}
onKeyPress("right", () => {
animateR()
})
onKeyPress("left", () => {
animateL()
})
onKeyPress("down", () => {
animateD()
})
onKeyPress("up", () => {
animateU()
})
let Risdown=false
let Lisdown=false
let Uisdown=false
let Disdown=false
onKeyDown("right",()=>{
Risdown=true
if (Lisdown==false && Uisdown==false && Disdown==false){
player.move(SPEED, 0)
}
})
onKeyDown("left", () => {
Lisdown=true
if (Risdown==false && Uisdown==false && Disdown==false){
player.move(-SPEED, 0)  
}
})
onKeyDown("down", () => {
Disdown=true
if (Lisdown==false && Risdown==false && Uisdown==false){
player.move(0, SPEED)
}
})
onKeyDown("up", () => {
Uisdown=true
if (Lisdown==false && Risdown==false && Disdown==false){
player.move(0, -SPEED)
} 
})
onKeyRelease("right",()=>{
Risdown=false
})
onKeyRelease("left",()=>{
Lisdown=false
})
onKeyRelease("up",()=>{
Uisdown=false
})
onKeyRelease("down",()=>{
Disdown=false
})
onKeyDown("space", () => {
clearInterval(myInterval)
})

onKeyPress("f", (c) => {
fullscreen(!isFullscreen())
})


player.onCollide("enemy",(enemy)=>{
destroy(enemy)
shake(20)
play("shoot")
})
})

最新更新