@code-dot-org/dance-party
Advanced tools
Comparing version 0.0.17 to 0.0.18
@@ -11,7 +11,7 @@ module.exports = { | ||
everySeconds(1, "measures", function () { | ||
everySeconds(2, "measures", function () { | ||
changeMoveLR(lead_dancer, 3, -1); | ||
}); | ||
everySeconds(2, "measures", function () { | ||
everySeconds(4, "measures", function () { | ||
changeMoveLR(lead_dancer, 1, -1); | ||
@@ -27,7 +27,7 @@ }); | ||
everySeconds(2, "measures", function () { | ||
everySeconds(4, "measures", function () { | ||
changeMoveLR(lead_dancer, 1, -1); | ||
}); | ||
everySeconds(1, "measures", function () { | ||
everySeconds(2, "measures", function () { | ||
changeMoveLR(lead_dancer, 3, -1); | ||
@@ -38,3 +38,3 @@ }); | ||
validationCode: ` | ||
if (nativeAPI.getTime("measures") === 2) { | ||
if (nativeAPI.getTime("measures") === 4) { | ||
let cats = nativeAPI.getGroupByName_('CAT'); | ||
@@ -47,7 +47,7 @@ for(let i = 0; i < cats.length; i++){ | ||
} | ||
if (nativeAPI.getTime("measures") === 3) { | ||
if (nativeAPI.getTime("measures") > 7 && nativeAPI.getTime("measures") < 8) { | ||
let cats = nativeAPI.getGroupByName_('CAT'); | ||
for(let i = 0; i < cats.length; i++){ | ||
if(cats[i].current_move !== 3){ | ||
nativeAPI.fail("Cat sprite not dancing 3."); | ||
nativeAPI.fail("Cat sprite not dancing 3."); | ||
} | ||
@@ -57,3 +57,3 @@ } | ||
if (nativeAPI.getTime("measures") > 7) { | ||
if (nativeAPI.getTime("measures") > 8) { | ||
nativeAPI.pass(); | ||
@@ -72,7 +72,7 @@ } | ||
everySeconds(2, "seconds", function () { | ||
everySeconds(3, "seconds", function () { | ||
changeMoveLR(lead_dancer, 3, -1); | ||
}); | ||
everySeconds(5, "seconds", function () { | ||
everySeconds(6, "seconds", function () { | ||
changeMoveLR(lead_dancer, 1, -1); | ||
@@ -88,7 +88,7 @@ }); | ||
everySeconds(5, "seconds", function () { | ||
everySeconds(6, "seconds", function () { | ||
changeMoveLR(lead_dancer, 1, -1); | ||
}); | ||
everySeconds(2, "seconds", function () { | ||
everySeconds(3, "seconds", function () { | ||
changeMoveLR(lead_dancer, 3, -1); | ||
@@ -99,3 +99,3 @@ }); | ||
validationCode: ` | ||
if (nativeAPI.getTime("seconds") === 5) { | ||
if (nativeAPI.getTime("seconds") > 7 && nativeAPI.getTime("seconds") < 9) { | ||
let cats = nativeAPI.getGroupByName_('CAT'); | ||
@@ -108,3 +108,3 @@ for(let i = 0; i < cats.length; i++){ | ||
} | ||
if (nativeAPI.getTime("seconds") === 2) { | ||
if (nativeAPI.getTime("seconds") > 4 && nativeAPI.getTime("seconds") < 6) { | ||
let cats = nativeAPI.getGroupByName_('CAT'); | ||
@@ -118,3 +118,3 @@ for(let i = 0; i < cats.length; i++){ | ||
if (nativeAPI.getTime("seconds") > 7) { | ||
if (nativeAPI.getTime("seconds") > 9) { | ||
nativeAPI.pass(); | ||
@@ -158,3 +158,3 @@ } | ||
validationCode: ` | ||
if (nativeAPI.getTime("measures") === 2) { | ||
if (nativeAPI.getTime("measures") >= 3 && nativeAPI.getTime("measures") < 4) { | ||
let cats = nativeAPI.getGroupByName_('CAT'); | ||
@@ -167,3 +167,3 @@ for(let i = 0; i < cats.length; i++){ | ||
} | ||
if (nativeAPI.getTime("measures") === 4) { | ||
if (nativeAPI.getTime("measures") >= 5 && nativeAPI.getTime("measures") < 6) { | ||
let cats = nativeAPI.getGroupByName_('CAT'); | ||
@@ -177,3 +177,3 @@ for(let i = 0; i < cats.length; i++){ | ||
if (nativeAPI.getTime("measures") > 5) { | ||
if (nativeAPI.getTime("measures") > 6) { | ||
nativeAPI.pass(); | ||
@@ -180,0 +180,0 @@ } |
{ | ||
"name": "@code-dot-org/dance-party", | ||
"version": "0.0.17", | ||
"version": "0.0.18", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "dist/main.js", |
@@ -20,1 +20,6 @@ [](https://travis-ci.org/code-dot-org/dance-party/builds) | ||
This will set up a symlink in apps/node_modules to point at your local changes. Run `npm run build` in dance-party, and then the apps build should pick the changes up next time it builds. | ||
To debug unit tests in the Chrome debugger: | ||
`node --inspect --debug-brk ./node_modules/.bin/tape ./test/unit/*.js` | ||
Open [chrome://inspect](chrome://inspect) in Chrome browser (requires Chrome 55+) | ||
Tap on `inspect` link under "Remote Target" |
@@ -6,5 +6,13 @@ module.exports = class Effects { | ||
function randomNumber(min, max) { | ||
return Math.floor(p5.random(min, max)); | ||
return Math.round(p5.random(min, max)); | ||
} | ||
function colorFromHue(h, s=100, l=80, a=alpha) { | ||
return p5.color("hsla(" + Math.floor(h % 360) + ", " + s + "%, " + l + "%," + a + ")"); | ||
} | ||
function randomColor(s=100, l=80, a=alpha) { | ||
return colorFromHue(randomNumber(0, 359), s, l, a); | ||
} | ||
this.none = { | ||
@@ -17,9 +25,35 @@ draw: function ({backgroundColor}) { | ||
this.rainbow = { | ||
color: p5.color('hsla(0, 100%, 80%, ' + alpha + ')'), | ||
lengths: [0, 0, 0, 0, 0, 0, 0], | ||
current: 0, | ||
update: function () { | ||
this.lengths[this.lengths.length - (1 + this.current)] = 1; | ||
this.current = (this.current + 1) % this.lengths.length; | ||
}, | ||
draw: function ({isPeak, bpm}) { | ||
if (isPeak) { | ||
this.update(); | ||
} | ||
p5.push(); | ||
p5.colorMode(p5.HSL); | ||
this.color = | ||
p5.color(this.color._getHue() + 10, 100, 80, alpha); | ||
p5.background(colorFromHue(180, 50, 90)); | ||
p5.noFill(); | ||
p5.strokeWeight(50); | ||
let d, i; | ||
for (i = 0; i < 7; i++) { | ||
p5.stroke(colorFromHue(i * 51.5, 100, 95)); | ||
d = 150 + i * 100; | ||
p5.arc(0, 400, d, d, -90, 0); | ||
if (this.lengths[i] > 0) { | ||
p5.stroke(colorFromHue(i * 60, 100, 80, 1 - this.lengths[i] / 90)); | ||
p5.arc(0, 400, d, d, -90, -90 + this.lengths[i]); | ||
this.lengths[i] = (this.lengths[i] + bpm / 50) % 90; | ||
} | ||
} | ||
p5.pop(); | ||
} | ||
}; | ||
this.color_cycle = { | ||
color: colorFromHue(0), | ||
update: function () { | ||
this.color = colorFromHue(this.color._getHue() + 10); | ||
}, | ||
@@ -45,10 +79,10 @@ draw: function ({isPeak}) { | ||
for (let i = 0; i < this.colors.length; i++) { | ||
this.colors[i] = p5.color("hsl(" + randomNumber(0, 359) + ", 100%, 80%)"); | ||
this.colors[i] = randomColor(); | ||
} | ||
}, | ||
update: function () { | ||
const numChanges = randomNumber(this.minColorChangesPerUpdate, this.maxColorChangesPerUpdate + 1); | ||
const numChanges = randomNumber(this.minColorChangesPerUpdate, this.maxColorChangesPerUpdate); | ||
for (let i = 0; i < numChanges; i++) { | ||
const loc = randomNumber(0, this.colors.length + 1); | ||
this.colors[loc] = p5.color("hsl(" + randomNumber(0, 359) + ", 100%, 80%)"); | ||
const loc = randomNumber(0, this.colors.length); | ||
this.colors[loc] = randomColor(); | ||
} | ||
@@ -88,3 +122,2 @@ }, | ||
p5.push(); | ||
p5.colorMode(p5.HSB); | ||
p5.rectMode(p5.CENTER); | ||
@@ -96,3 +129,3 @@ p5.translate(200, 200); | ||
for (let i = 5; i > -1; i--) { | ||
p5.stroke((this.hue + i * 10) % 360, 100, 75, alpha); | ||
p5.stroke(colorFromHue((this.hue + i * 10) % 360)); | ||
p5.rect(0, 0, i * 100 + 50, i * 100 + 50); | ||
@@ -161,2 +194,38 @@ } | ||
this.text = { | ||
texts: [], | ||
maxTexts: 100, | ||
update: function (text, hue, size) { | ||
this.texts.push({ | ||
x: randomNumber(25, 375), | ||
y: randomNumber(25, 375), | ||
text: text, | ||
color: colorFromHue(hue), | ||
size: size | ||
}); | ||
if (this.texts.length > this.maxTexts) { | ||
this.texts.shift(); | ||
} | ||
}, | ||
draw: function ({isPeak, centroid, artist, title}) { | ||
if (isPeak) { | ||
let text; | ||
if (randomNumber(0, 1) === 0) { | ||
text = artist; | ||
} else { | ||
text = title; | ||
} | ||
this.update(text, centroid, randomNumber(14, 48)); | ||
} | ||
p5.push(); | ||
p5.textAlign(p5.CENTER, p5.CENTER); | ||
this.texts.forEach(function (t) { | ||
p5.textSize(t.size); | ||
p5.fill(t.color); | ||
p5.text(t.text, t.x, t.y); | ||
}); | ||
p5.pop(); | ||
} | ||
}; | ||
this.raining_tacos = { | ||
@@ -207,3 +276,3 @@ tacos: [], | ||
y: randomNumber(0,400), | ||
color: p5.color("hsl(" + randomNumber(0, 359) + ", 100%, 80%)"), | ||
color: randomColor(), | ||
width: r, | ||
@@ -262,3 +331,3 @@ height: r, | ||
p5.rotate(Math.PI / 180 * this.angle); | ||
p5.tint(p5.color("hsl(" + this.color + ", 100%, 60%)")); | ||
p5.tint(colorFromHue(this.color, 100, 60)); | ||
p5.image(this.swirl,0,0,600,600); | ||
@@ -287,3 +356,3 @@ p5.pop(); | ||
} | ||
p5.background(p5.color("hsl(" + this.color + ", 100%, 10%)")); | ||
p5.background(colorFromHue(this.color, 100, 10)); | ||
p5.push(); | ||
@@ -295,3 +364,3 @@ p5.imageMode("center"); | ||
p5.rotate(Math.PI / 180 * this.angle); | ||
p5.tint(p5.color("hsl(" + this.color + ", 100%, 60%)")); | ||
p5.tint(colorFromHue(this.color, 100, 60)); | ||
p5.image(this.swirl,0,0,600,600); | ||
@@ -343,3 +412,43 @@ p5.pop(); | ||
}; | ||
this.color_lights = { | ||
lights: [], | ||
newLight: function (x, arc, offset) { | ||
return { | ||
x: x, | ||
arc: arc, | ||
offset: offset, | ||
shift: randomNumber(0, 359), | ||
color: randomColor(100, 50, 0.25), | ||
}; | ||
}, | ||
init: function () { | ||
this.lights.push(this.newLight(75, 25, -10)); | ||
this.lights.push(this.newLight(100, 15, -15)); | ||
this.lights.push(this.newLight(300, 15, 15)); | ||
this.lights.push(this.newLight(325, 25, 10)); | ||
}, | ||
update: function () { | ||
this.lights.forEach(function (light) { | ||
light.color = randomColor(100, 50, 0.25); | ||
}); | ||
}, | ||
draw: function ({isPeak, centroid}) { | ||
if (this.lights.length<1) { | ||
this.init(); | ||
} | ||
if (isPeak) { | ||
this.update(); | ||
} | ||
p5.noStroke(); | ||
this.lights.forEach(function (light) { | ||
p5.push(); | ||
p5.fill(light.color); | ||
p5.translate(light.x, -50); | ||
p5.rotate((Math.sin((p5.frameCount / 100) + light.shift + centroid / 2000) * light.arc) + light.offset); | ||
p5.triangle(0, 0, -75, 600, 75, 600); | ||
p5.pop(); | ||
}); | ||
} | ||
}; | ||
} | ||
}; |
@@ -27,2 +27,3 @@ /* eslint-disable no-unused-vars, curly, eqeqeq, babel/semi, semi, no-undef */ | ||
// NOTE: min and max are inclusive | ||
function randomInt(min, max) { | ||
@@ -81,3 +82,3 @@ return Math.floor(Math.random() * (max - min + 1)) + min; | ||
this.world.MOVE_NAMES = moveNames || [ | ||
{name: "Rest", mirror: true}, | ||
{name: "Rest", mirror: true, rest: true}, | ||
{name: "ClapHigh", mirror: true}, | ||
@@ -94,8 +95,8 @@ {name: "Clown", mirror: false}, | ||
{name: "Thriller", mirror: true}, | ||
{name: "XArmsSide", mirror: false}, | ||
{name: "XArmsUp", mirror: false}, | ||
{name: "XJump", mirror: false}, | ||
{name: "XClapSide", mirror: false}, | ||
{name: "XHeadHips", mirror: false}, | ||
{name: "XHighKick", mirror: false}, | ||
{name: "XArmsSide", mirror: false, shortBurst: true}, | ||
{name: "XArmsUp", mirror: false, shortBurst: true}, | ||
{name: "XJump", mirror: false, shortBurst: true}, | ||
{name: "XClapSide", mirror: false, shortBurst: true}, | ||
{name: "XHeadHips", mirror: false, shortBurst: true}, | ||
{name: "XHighKick", mirror: false, shortBurst: true}, | ||
]; | ||
@@ -107,2 +108,10 @@ | ||
// Sort after spriteConfig function has executed to ensure that | ||
// rest moves are at the beginning and shortBurst moves are all at the end | ||
this.world.MOVE_NAMES = this.world.MOVE_NAMES.sort((move1, move2) => ( | ||
move1.rest * -2 * move2.rest * 2 + move2.shortBurst * -1 + move1.shortBurst * 1 | ||
)); | ||
this.world.restMoveCount = this.world.MOVE_NAMES.filter(move => move.rest).length; | ||
this.world.fullLengthMoveCount = this.world.MOVE_NAMES.filter(move => !move.shortBurst).length; | ||
this.songStartTime_ = 0; | ||
@@ -303,3 +312,5 @@ | ||
if (sprite.looping_frame % FRAMES === 0) { | ||
if (ANIMATIONS[sprite.style][sprite.current_move].mirror) sprite.mirroring *= -1; | ||
if (ANIMATIONS[sprite.style][sprite.current_move].mirror) { | ||
sprite.mirroring *= -1; | ||
} | ||
if (sprite.animation.looping) { | ||
@@ -354,17 +365,37 @@ sprite.mirrorX(sprite.mirroring); | ||
changeMoveLR(sprite, move, dir) { | ||
if (!this.spriteExists_(sprite)) return; | ||
if (move === "next") { | ||
move = 1 + (sprite.current_move % (ANIMATIONS[sprite.style].length - 1)); | ||
} else if (move === "prev") { | ||
//Javascript doesn't handle negative modulos as expected, so manually resetting the loop | ||
move = sprite.current_move - 1; | ||
if (move <= 0) { | ||
move = ANIMATIONS[sprite.style].length - 1; | ||
if (!this.spriteExists_(sprite)) { | ||
return; | ||
} | ||
// Number of valid full length moves | ||
const { fullLengthMoveCount, restMoveCount } = this.world; | ||
const firstNonRestingMoveIndex = restMoveCount; | ||
// The "rest" moves are assumed to always be at the beginning | ||
const nonRestingFullLengthMoveCount = fullLengthMoveCount - restMoveCount; | ||
if (typeof move === 'number') { | ||
if (move < 0 || move >= fullLengthMoveCount) { | ||
throw "Not moving to a valid full length move index!"; | ||
} | ||
} else if (move === "rand") { | ||
// Make sure random switches to a new move | ||
move = sprite.current_move; | ||
while (move === sprite.current_move) { | ||
move = randomInt(0, ANIMATIONS[sprite.style].length - 1); | ||
} else { | ||
if (nonRestingFullLengthMoveCount <= 1) { | ||
throw "next/prev/rand requires that we have 2 or more non-resting full length moves"; | ||
} | ||
if (move === "next") { | ||
move = sprite.current_move + 1; | ||
if (move >= fullLengthMoveCount) { | ||
move = firstNonRestingMoveIndex; | ||
} | ||
} else if (move === "prev") { | ||
move = sprite.current_move - 1; | ||
if (move < firstNonRestingMoveIndex) { | ||
move = fullLengthMoveCount - 1; | ||
} | ||
} else if (move === "rand") { | ||
// Make sure random switches to a new move | ||
move = sprite.current_move; | ||
while (move === sprite.current_move) { | ||
move = randomInt(firstNonRestingMoveIndex, fullLengthMoveCount - 1); | ||
} | ||
} else { | ||
throw `Unexpected move value: ${move}`; | ||
} | ||
} | ||
@@ -374,3 +405,5 @@ sprite.mirroring = dir; | ||
sprite.changeAnimation("anim" + move); | ||
if (sprite.animation.looping) sprite.looping_frame = 0; | ||
if (sprite.animation.looping) { | ||
sprite.looping_frame = 0; | ||
} | ||
sprite.animation.looping = true; | ||
@@ -381,3 +414,5 @@ sprite.current_move = move; | ||
doMoveLR(sprite, move, dir) { | ||
if (!this.spriteExists_(sprite)) return; | ||
if (!this.spriteExists_(sprite)) { | ||
return; | ||
} | ||
if (move === "next") { | ||
@@ -393,6 +428,11 @@ move = (sprite.current_move + 1) % ANIMATIONS[sprite.style].length; | ||
} | ||
if (move < 0 || move >= this.world.MOVE_NAMES.length) { | ||
throw `Invalid move index: ${move}`; | ||
} | ||
sprite.mirrorX(dir); | ||
sprite.changeAnimation("anim" + move); | ||
sprite.animation.looping = false; | ||
sprite.animation.changeFrame(FRAMES / 2); | ||
// For non-shortBurst, we jump to the middle of the animation | ||
const frameNum = this.world.MOVE_NAMES[move].shortBurst ? 0 : (FRAMES / 2); | ||
sprite.animation.changeFrame(frameNum); | ||
} | ||
@@ -922,2 +962,4 @@ | ||
bpm: this.songMetadata_ && this.songMetadata_.bpm, | ||
artist: this.songMetadata_.artist, | ||
title: this.songMetadata_.title, | ||
}; | ||
@@ -924,0 +966,0 @@ |
@@ -41,8 +41,15 @@ const DanceParty = require('../../src/p5.dance'); | ||
// Mock 4 cat and moose animation poses. | ||
for(let i = 0; i < 10; i++) { | ||
const moveCount = 10; | ||
for(let i = 0; i < moveCount; i++) { | ||
api.setAnimationSpriteSheet("CAT", i, {}, () => {}); | ||
api.setAnimationSpriteSheet("MOOSE", i, {}, () => {}); | ||
api.setAnimationSpriteSheet("ROBOT", i, {}, () => {}); | ||
api.world.MOVE_NAMES.push({ | ||
name: `move${i}` | ||
}); | ||
} | ||
api.world.fullLengthMoveCount = moveCount; | ||
api.world.restMoveCount = 1; | ||
api.addCues(getCueList()); | ||
@@ -49,0 +56,0 @@ api.onHandleEvents = currentFrameEvents => runUserEvents(currentFrameEvents); |
@@ -13,2 +13,8 @@ const helpers = require('../helpers/createDanceAPI'); | ||
nativeAPI.setAnimationSpriteSheet("BEAR", 1, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES = [ | ||
{ name: `move1` }, | ||
{ name: `move2` }, | ||
]; | ||
nativeAPI.world.fullLengthMoveCount = nativeAPI.world.MOVE_NAMES.length; | ||
nativeAPI.world.restMoveCount = 1; | ||
@@ -66,2 +72,8 @@ const catSprite = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); | ||
nativeAPI.setAnimationSpriteSheet("BEAR", 1, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES = [ | ||
{ name: `move1` }, | ||
{ name: `move2` }, | ||
]; | ||
nativeAPI.world.fullLengthMoveCount = nativeAPI.world.MOVE_NAMES.length; | ||
nativeAPI.world.restMoveCount = 1; | ||
@@ -68,0 +80,0 @@ const catSpriteAlpha = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); |
@@ -11,5 +11,11 @@ const test = require('tape'); | ||
// Mock 4 cat animation poses | ||
for(let i = 0; i < 4; i++) { | ||
const moveCount = 4; | ||
for(let i = 0; i < moveCount; i++) { | ||
nativeAPI.setAnimationSpriteSheet("CAT", i, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES.push({ | ||
name: `move${i}` | ||
}) | ||
} | ||
nativeAPI.world.fullLengthMoveCount = moveCount; | ||
nativeAPI.world.restMoveCount = 1; | ||
@@ -38,5 +44,11 @@ const sprite = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); | ||
// Mock 3 cat animation poses | ||
for(let i = 0; i < 3; i++) { | ||
const moveCount = 3; | ||
for(let i = 0; i < moveCount; i++) { | ||
nativeAPI.setAnimationSpriteSheet("CAT", i, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES.push({ | ||
name: `move${i}` | ||
}) | ||
} | ||
nativeAPI.world.fullLengthMoveCount = moveCount; | ||
nativeAPI.world.restMoveCount = 1; | ||
@@ -70,5 +82,11 @@ const sprite = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); | ||
// Mock 3 cat animation poses | ||
for(let i = 0; i < 3; i++) { | ||
const moveCount = 3; | ||
for(let i = 0; i < moveCount; i++) { | ||
nativeAPI.setAnimationSpriteSheet("CAT", i, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES.push({ | ||
name: `move${i}` | ||
}) | ||
} | ||
nativeAPI.world.fullLengthMoveCount = moveCount; | ||
nativeAPI.world.restMoveCount = 1; | ||
@@ -87,2 +105,223 @@ const sprite = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); | ||
test('Sprite dance changes with next/prev/rand avoids rest dance', async t => { | ||
const subTest = async testCode => { | ||
const nativeAPI = await helpers.createDanceAPI(); | ||
nativeAPI.play({ | ||
bpm: 120, | ||
}); | ||
// Mock 3 cat animation poses | ||
const moveCount = 3; | ||
for(let i = 0; i < moveCount; i++) { | ||
nativeAPI.setAnimationSpriteSheet("CAT", i, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES.push({ | ||
name: `move${i}`, | ||
rest: i == 0, | ||
}) | ||
} | ||
nativeAPI.world.fullLengthMoveCount = moveCount; | ||
nativeAPI.world.restMoveCount = 1; | ||
const sprite = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); | ||
testCode({ nativeAPI, sprite }); | ||
nativeAPI.reset(); | ||
} | ||
// Verify Next behavior: | ||
await subTest(({ nativeAPI, sprite }) => { | ||
// Initial value | ||
t.equal(sprite.current_move, 0); | ||
nativeAPI.changeMoveLR(sprite, 'next', 1); | ||
// Index 1 | ||
t.equal(sprite.current_move, 1); | ||
nativeAPI.changeMoveLR(sprite, 'next', 1); | ||
// Index 2 | ||
t.equal(sprite.current_move, 2); | ||
nativeAPI.changeMoveLR(sprite, 'next', 1); | ||
// Loops back to index 1 (skipping 0, which is the rest dance) | ||
t.equal(sprite.current_move, 1); | ||
}); | ||
// Verify Prev behavior: | ||
await subTest(({ nativeAPI, sprite }) => { | ||
// Initial value | ||
t.equal(sprite.current_move, 0); | ||
nativeAPI.changeMoveLR(sprite, 'prev', 1); | ||
// Index 2 | ||
t.equal(sprite.current_move, 2); | ||
nativeAPI.changeMoveLR(sprite, 'prev', 1); | ||
// Index 1 | ||
t.equal(sprite.current_move, 1); | ||
nativeAPI.changeMoveLR(sprite, 'prev', 1); | ||
// Loops back to index 2 (skipping 0, which is the rest dance) | ||
t.equal(sprite.current_move, 2); | ||
}); | ||
// Verify Rand behavior: | ||
await subTest(({ nativeAPI, sprite }) => { | ||
// Initial value | ||
t.equal(sprite.current_move, 0); | ||
nativeAPI.changeMoveLR(sprite, 1, 1); | ||
// Index 1 | ||
t.equal(sprite.current_move, 1); | ||
nativeAPI.changeMoveLR(sprite, 'rand', 1); | ||
// Must be Index 2 (must be different and not 0, which is the rest dance) | ||
t.equal(sprite.current_move, 2); | ||
nativeAPI.changeMoveLR(sprite, 'rand', 1); | ||
// Must be Index 1 (must be different and not 0, which is the rest dance) | ||
t.equal(sprite.current_move, 1); | ||
}); | ||
t.end(); | ||
}); | ||
test('Sprite dance changes will throw with invalid parameters', async t => { | ||
const subTest = async ({ moveCount = 3, testCode }) => { | ||
const nativeAPI = await helpers.createDanceAPI(); | ||
nativeAPI.play({ | ||
bpm: 120, | ||
}); | ||
// Mock cat animation poses | ||
for(let i = 0; i < moveCount; i++) { | ||
nativeAPI.setAnimationSpriteSheet("CAT", i, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES.push({ | ||
name: `move${i}`, | ||
rest: i == 0, | ||
}) | ||
} | ||
nativeAPI.world.fullLengthMoveCount = moveCount; | ||
nativeAPI.world.restMoveCount = 1; | ||
const sprite = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); | ||
testCode({ nativeAPI, sprite }); | ||
nativeAPI.reset(); | ||
} | ||
// Verify invalid string parameter behavior: | ||
await subTest({ testCode: ({ nativeAPI, sprite }) => { | ||
let error = null; | ||
try { | ||
// Passing 'some_string' should fail | ||
nativeAPI.changeMoveLR(sprite, 'some_string', 1); | ||
} catch (e) { | ||
error = e; | ||
} | ||
t.notEqual(error, null, "invalid string parameter"); | ||
}}); | ||
// Verify invalid move index behavior for changeMoveLR(): | ||
await subTest({ testCode: ({ nativeAPI, sprite }) => { | ||
let error = null; | ||
try { | ||
// Passing 3 should fail (index is too large) | ||
nativeAPI.changeMoveLR(sprite, 3, 1); | ||
} catch (e) { | ||
error = e; | ||
} | ||
t.notEqual(error, null, "invalid move index for changeMoveLR"); | ||
}}); | ||
// Verify invalid rand move because we don't have any different, non-resting moves: | ||
await subTest({ moveCount: 2, testCode: ({ nativeAPI, sprite }) => { | ||
let error = null; | ||
try { | ||
// Passing 'rand' should fail | ||
nativeAPI.changeMoveLR(sprite, 'rand', 1); | ||
} catch (e) { | ||
error = e; | ||
} | ||
t.notEqual(error, null, "invalid rand move"); | ||
}}); | ||
// Verify invalid move index behavior for doMoveLR(): | ||
await subTest({ testCode: ({ nativeAPI, sprite }) => { | ||
let error = null; | ||
try { | ||
// Passing 3 should fail (index is too large) | ||
nativeAPI.doMoveLR(sprite, 3, 1); | ||
} catch (e) { | ||
error = e; | ||
} | ||
t.notEqual(error, null, "invalid move index for doMoveLR"); | ||
}}); | ||
t.end(); | ||
}); | ||
test('Sprite dance changes will allow short burst moves for doMoveLR but not changeMoveLR', async t => { | ||
const subTest = async ({ moveCount = 3, shortMoveCount = 1, testCode }) => { | ||
const nativeAPI = await helpers.createDanceAPI(); | ||
nativeAPI.play({ | ||
bpm: 120, | ||
}); | ||
// Mock cat animation poses | ||
for(let i = 0; i < moveCount; i++) { | ||
nativeAPI.setAnimationSpriteSheet("CAT", i, {}, () => {}); | ||
nativeAPI.world.MOVE_NAMES.push({ | ||
name: `move${i}`, | ||
rest: i == 0, | ||
shortBurst: i >= (moveCount - shortMoveCount), | ||
}) | ||
} | ||
nativeAPI.world.fullLengthMoveCount = moveCount - shortMoveCount; | ||
nativeAPI.world.restMoveCount = 1; | ||
const sprite = nativeAPI.makeNewDanceSprite("CAT", null, {x: 200, y: 200}); | ||
testCode({ nativeAPI, sprite }); | ||
nativeAPI.reset(); | ||
} | ||
// Verify we can call doMoveLR() with a rest, full length, and short burst move: | ||
await subTest({ testCode: ({ nativeAPI, sprite }) => { | ||
// Full length move: | ||
nativeAPI.doMoveLR(sprite, 1, 1); | ||
t.equal(sprite.getAnimationLabel(), 'anim1'); | ||
// Rest move: | ||
nativeAPI.doMoveLR(sprite, 0, 1); | ||
t.equal(sprite.getAnimationLabel(), 'anim0'); | ||
// Short burst move: | ||
nativeAPI.doMoveLR(sprite, 2, 1); | ||
t.equal(sprite.getAnimationLabel(), 'anim2'); | ||
}}); | ||
// Verify we can call changeMoveLR() with a rest or a full length, but not a short burst move: | ||
await subTest({ testCode: ({ nativeAPI, sprite }) => { | ||
// Full length move: | ||
nativeAPI.changeMoveLR(sprite, 1, 1); | ||
t.equal(sprite.getAnimationLabel(), 'anim1'); | ||
t.equal(sprite.current_move, 1); | ||
// Rest move: | ||
nativeAPI.changeMoveLR(sprite, 0, 1); | ||
t.equal(sprite.getAnimationLabel(), 'anim0'); | ||
t.equal(sprite.current_move, 0); | ||
// Short burst move: | ||
let error = null; | ||
try { | ||
nativeAPI.changeMoveLR(sprite, 2, 1); | ||
} catch (e) { | ||
error = e; | ||
} | ||
t.notEqual(error, null, "short burst move should fail with changeMoveLR"); | ||
t.equal(sprite.getAnimationLabel(), 'anim0'); | ||
t.equal(sprite.current_move, 0); | ||
}}); | ||
t.end(); | ||
}); | ||
test('getCurrentDance returns current move value for initialized sprite and undefined for uninitialized sprite', async t => { | ||
@@ -89,0 +328,0 @@ const nativeAPI = await helpers.createDanceAPI(); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
4087943
41
107385
25
13