change speed, add keynames
This commit is contained in:
parent
5278954aec
commit
8d37f85def
192
app.js
192
app.js
@ -1,3 +1,24 @@
|
|||||||
|
const MAX_LEVEL = 3
|
||||||
|
const DRAW_PERIOD = 0.04 // s
|
||||||
|
const UPDATE_PERIOD = 0.01 // s
|
||||||
|
const FLOOR = 400 // px
|
||||||
|
const FIRST_NOTE = 48 // C2
|
||||||
|
const LAST_NOTE = 73 // C4
|
||||||
|
const FREQUENCIES = [
|
||||||
|
// C C♯ / D♭ D D♯ / E♭ E F F♯ / G♭ G G♯ / A♭ A A♯ / B♭ B
|
||||||
|
16.35, 17.32, 18.35, 19.45, 20.6, 21.83, 23.12, 24.5, 25.96, 27.5, 29.14, 30.87,
|
||||||
|
32.7, 34.65, 36.71, 38.89, 41.2, 43.65, 46.25, 49, 51.91, 55, 58.27, 61.74,
|
||||||
|
65.41, 69.3, 73.42, 77.78, 82.41, 87.31, 92.5, 98, 103.83, 110, 116.54, 123.47,
|
||||||
|
130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185, 196, 207.65, 220, 233.08, 246.94,
|
||||||
|
261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392, 415.3, 440, 466.16, 493.88,
|
||||||
|
523.25, 554.37, 587.33, 622.25, 659.26, 698.46, 739.99, 783.99, 830.61, 880, 932.33, 987.77,
|
||||||
|
1046.5, 1108.73, 1174.66, 1244.51, 1318.51, 1396.91, 1479.98, 1567.98, 1661.22, 1760, 1864.66, 1975.53,
|
||||||
|
2093, 2217.46, 2349.32, 2489.02, 2637.02, 2793.83, 2959.96, 3135.96, 3322.44, 3520, 3729.31, 3951.07,
|
||||||
|
4186.01, 4434.92, 4698.64, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93, 6644.88, 7040, 7458.62, 7902.13,
|
||||||
|
]
|
||||||
|
const NOTE_NAMES = ["C", "C♯", "D", "D♯", "E", "F", "F♯", "G", "G♯", "A", "A♯", "B"]
|
||||||
|
|
||||||
|
|
||||||
Array.prototype.remove = function(item) {
|
Array.prototype.remove = function(item) {
|
||||||
let index = this.indexOf(item)
|
let index = this.indexOf(item)
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
@ -89,16 +110,18 @@ class Sprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Canon extends Sprite {
|
class Cannon extends Sprite {
|
||||||
constructor(canvasCtx, note) {
|
constructor(canvasCtx, note) {
|
||||||
let sharp = [1, 3, 6, 8, 10].includes(note % 12)
|
let sharp = [1, 3, 6, 8, 10].includes(note % 12)
|
||||||
super(canvasCtx, "canon.png", 34 * (note - FIRST_NOTE) + 66, sharp? 446:450, 11, 26, 4)
|
super(canvasCtx, "cannon.png", 34 * (note - FIRST_NOTE) + 66, sharp? 422:426, 11, 26, 4)
|
||||||
this.note = note
|
this.note = note
|
||||||
|
this.key = keyMap[note - FIRST_NOTE].toUpperCase()
|
||||||
this.impactHeight = 9
|
this.impactHeight = 9
|
||||||
this.impactY = 0
|
this.impactY = 0
|
||||||
this.sy = sharp? 0 : this.sHeight
|
this.sy = sharp? 0 : this.sHeight
|
||||||
this.shooting = false
|
this.shooting = false
|
||||||
this.df = 1
|
this.df = 1
|
||||||
|
this.pipeSprite = new Sprite(canvasCtx, "pipe.png", this.x-1, this.y+36, 16, 18)
|
||||||
}
|
}
|
||||||
|
|
||||||
draw() {
|
draw() {
|
||||||
@ -109,6 +132,11 @@ class Canon extends Sprite {
|
|||||||
} else {
|
} else {
|
||||||
if (this.frame > 0) this.frame--
|
if (this.frame > 0) this.frame--
|
||||||
}
|
}
|
||||||
|
this.pipeSprite.draw()
|
||||||
|
this.canvasCtx.fillStyle = "#d3d6cf"
|
||||||
|
this.canvasCtx.fillText(this.key, this.pipeSprite.x+2, this.pipeSprite.y+10)
|
||||||
|
this.canvasCtx.fillStyle = "#222327"
|
||||||
|
this.canvasCtx.fillText(this.key, this.pipeSprite.x, this.pipeSprite.y+8)
|
||||||
super.draw()
|
super.draw()
|
||||||
if (this.frame) {
|
if (this.frame) {
|
||||||
this.canvasCtx.drawImage(this.sprite, this.sWidth*(this.frame), 0, this.sWidth, 1, this.dx, this.impactY, 22, this.dy - this.impactY)
|
this.canvasCtx.drawImage(this.sprite, this.sWidth*(this.frame), 0, this.sWidth, 1, this.dx, this.impactY, 22, this.dy - this.impactY)
|
||||||
@ -202,23 +230,6 @@ class Whole extends Note {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const MAX_LEVEL = 2
|
|
||||||
const UPDATE_PERIOD = 10 //ms
|
|
||||||
const FIRST_NOTE = 48
|
|
||||||
const LAST_NOTE = 73
|
|
||||||
const FREQUENCIES = [
|
|
||||||
// C C♯ / D♭ D D♯ / E♭ E F F♯ / G♭ G G♯ / A♭ A A♯ / B♭ B
|
|
||||||
16.35, 17.32, 18.35, 19.45, 20.6, 21.83, 23.12, 24.5, 25.96, 27.5, 29.14, 30.87,
|
|
||||||
32.7, 34.65, 36.71, 38.89, 41.2, 43.65, 46.25, 49, 51.91, 55, 58.27, 61.74,
|
|
||||||
65.41, 69.3, 73.42, 77.78, 82.41, 87.31, 92.5, 98, 103.83, 110, 116.54, 123.47,
|
|
||||||
130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185, 196, 207.65, 220, 233.08, 246.94,
|
|
||||||
261.63, 277.18, 293.66, 311.13, 329.63, 349.23, 369.99, 392, 415.3, 440, 466.16, 493.88,
|
|
||||||
523.25, 554.37, 587.33, 622.25, 659.26, 698.46, 739.99, 783.99, 830.61, 880, 932.33, 987.77,
|
|
||||||
1046.5, 1108.73, 1174.66, 1244.51, 1318.51, 1396.91, 1479.98, 1567.98, 1661.22, 1760, 1864.66, 1975.53,
|
|
||||||
2093, 2217.46, 2349.32, 2489.02, 2637.02, 2793.83, 2959.96, 3135.96, 3322.44, 3520, 3729.31, 3951.07,
|
|
||||||
4186.01, 4434.92, 4698.64, 4978.03, 5274.04, 5587.65, 5919.91, 6271.93, 6644.88, 7040, 7458.62, 7902.13,
|
|
||||||
]
|
|
||||||
|
|
||||||
let keyMap = keyMapInput.value
|
let keyMap = keyMapInput.value
|
||||||
let playing = false
|
let playing = false
|
||||||
|
|
||||||
@ -228,27 +239,19 @@ canvasCtx.webkitImageSmoothingEnabled = false
|
|||||||
canvasCtx.msImageSmoothingEnabled = false
|
canvasCtx.msImageSmoothingEnabled = false
|
||||||
canvasCtx.imageSmoothingEnabled = false
|
canvasCtx.imageSmoothingEnabled = false
|
||||||
|
|
||||||
let consoleSprite = new Sprite(canvasCtx, "console.png", canvas.width/2, 554, 480, 86)
|
canvasCtx.font = '12px "Press Start 2P"'
|
||||||
let syntheSprite = new Sprite(canvasCtx, "synthe.png", canvas.width/2, 540, 110, 80)
|
canvasCtx.textAlign = "center"
|
||||||
let canonSprites = []
|
|
||||||
for (let note=FIRST_NOTE; note<LAST_NOTE; note++) canonSprites[note] = new Canon(canvasCtx, note)
|
let consoleSprite = new Sprite(canvasCtx, "console.png", canvas.width/2, 554, 482, 86)
|
||||||
|
let syntheSprite = new Sprite(canvasCtx, "synthe.png", canvas.width/2, 546, 110, 80)
|
||||||
|
let cannonSprites = []
|
||||||
|
for (let note=FIRST_NOTE; note<LAST_NOTE; note++) cannonSprites[note] = new Cannon(canvasCtx, note)
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
startDialog.showModal()
|
startDialog.showModal()
|
||||||
window.setInterval(draw, 60)
|
//window.setInterval(draw, 60)
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
|
||||||
canvasCtx.clearRect(0, 0, canvas.width, canvas.height)
|
|
||||||
|
|
||||||
consoleSprite.draw()
|
|
||||||
canonSprites.forEach(canonSprite => canonSprite.draw())
|
|
||||||
noteSprites.forEach(noteSprite => noteSprite.draw())
|
|
||||||
syntheSprite.draw()
|
|
||||||
explosionSprites.forEach(explosionSprite => explosionSprite.draw())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let audioCtx
|
let audioCtx
|
||||||
let volume
|
let volume
|
||||||
let wave
|
let wave
|
||||||
@ -282,19 +285,32 @@ function init() {
|
|||||||
|
|
||||||
onpartialinput()
|
onpartialinput()
|
||||||
|
|
||||||
|
Tone.Transport.scheduleRepeat(draw, DRAW_PERIOD)
|
||||||
|
Tone.Transport.scheduleRepeat(update, UPDATE_PERIOD)
|
||||||
|
|
||||||
showSettings()
|
showSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
startDialog.onclose = init
|
startDialog.onclose = init
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
canvasCtx.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
|
||||||
|
consoleSprite.draw()
|
||||||
|
cannonSprites.forEach(cannonSprite => cannonSprite.draw())
|
||||||
|
noteSprites.forEach(noteSprite => noteSprite.draw())
|
||||||
|
syntheSprite.draw()
|
||||||
|
explosionSprites.forEach(explosionSprite => explosionSprite.draw())
|
||||||
|
}
|
||||||
|
|
||||||
function showSettings() {
|
function showSettings() {
|
||||||
pause()
|
pause()
|
||||||
settingsDialog.showModal()
|
settingsDialog.showModal()
|
||||||
}
|
}
|
||||||
|
window.onblur = showSettings
|
||||||
|
|
||||||
function pause() {
|
function pause() {
|
||||||
Tone.Transport.pause()
|
Tone.Transport.pause()
|
||||||
window.clearInterval(updateTaskId)
|
//window.clearInterval(updateTaskId)
|
||||||
playing = false
|
playing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,24 +318,14 @@ settingsButton.onclick = showSettings
|
|||||||
|
|
||||||
keyMapInput.onchange = function(event) {
|
keyMapInput.onchange = function(event) {
|
||||||
keyMap = keyMapInput.value
|
keyMap = keyMapInput.value
|
||||||
}
|
if (midiKeyboard) {
|
||||||
|
cannonSprites.forEach((cannonSprite, index) => {
|
||||||
volRange.oninput = function(event) {
|
cannonSprite.key = NOTE_NAMES[index % NOTE_NAMES.length]
|
||||||
volume.gain.linearRampToValueAtTime(volRange.value, audioCtx.currentTime)
|
})
|
||||||
}
|
} else {
|
||||||
|
cannonSprites.forEach((cannonSprite, index) => {
|
||||||
modRange.oninput = function(event) {
|
cannonSprite.key = keyMap[index - FIRST_NOTE].toUpperCase()
|
||||||
depth.gain.value = modRange.value
|
})
|
||||||
}
|
|
||||||
|
|
||||||
function onpartialinput() {
|
|
||||||
wave = audioCtx.createPeriodicWave(
|
|
||||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
||||||
[0].concat(Array.from(document.querySelectorAll(".partial")).map(range => range.value)),
|
|
||||||
{disableNormalization: false,}
|
|
||||||
)
|
|
||||||
for (const note in oscillators) {
|
|
||||||
oscillators[note].setPeriodicWave(wave)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,22 +352,44 @@ midiSelect.onfocus = function() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var midiKeyboard = ""
|
||||||
midiSelect.oninput = () => {
|
midiSelect.oninput = () => {
|
||||||
for (const id in midiIputs) midiIputs[id].onmidimessage = null
|
for (const id in midiIputs) midiIputs[id].onmidimessage = null
|
||||||
if (midiSelect.value) {
|
midiKeyboard = midiSelect.value
|
||||||
midiIputs[midiSelect.value].onmidimessage = onMIDIMessage
|
if (midiKeyboard) {
|
||||||
|
midiIputs[midiKeyboard].onmidimessage = onMIDIMessage
|
||||||
|
}
|
||||||
|
keyMapInput.onchange()
|
||||||
|
}
|
||||||
|
|
||||||
|
volRange.oninput = function(event) {
|
||||||
|
volume.gain.linearRampToValueAtTime(volRange.value, audioCtx.currentTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
modRange.oninput = function(event) {
|
||||||
|
depth.gain.value = modRange.value
|
||||||
|
}
|
||||||
|
|
||||||
|
function onpartialinput() {
|
||||||
|
wave = audioCtx.createPeriodicWave(
|
||||||
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
[0].concat(Array.from(document.querySelectorAll(".partial")).map(range => range.value)),
|
||||||
|
{disableNormalization: false,}
|
||||||
|
)
|
||||||
|
for (const note in oscillators) {
|
||||||
|
oscillators[note].setPeriodicWave(wave)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMIDIMessage(event) {
|
function onMIDIMessage(event) {
|
||||||
let [code, note, velocity] = event.data
|
let [code, note, velocity] = event.data
|
||||||
|
|
||||||
if (144 <= code && code <= 159 && canonSprites[note]) {
|
if (144 <= code && code <= 159 && cannonSprites[note]) {
|
||||||
//playNote(note, velocity / 128)
|
//playNote(note, velocity / 128)
|
||||||
canonSprites[note].shooting = true
|
cannonSprites[note].shooting = true
|
||||||
} else if (128 <= code && code <= 143 && canonSprites[note]) {
|
} else if (128 <= code && code <= 143 && cannonSprites[note]) {
|
||||||
//stopNote(note)
|
//stopNote(note)
|
||||||
canonSprites[note].shooting = false
|
cannonSprites[note].shooting = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,21 +405,23 @@ function newGame() {
|
|||||||
let midiSong
|
let midiSong
|
||||||
let noteSprites = []
|
let noteSprites = []
|
||||||
let explosionSprites = []
|
let explosionSprites = []
|
||||||
|
let speed
|
||||||
async function nextLevel() {
|
async function nextLevel() {
|
||||||
level++
|
level++
|
||||||
midiSong = await Midi.fromUrl(`midi/${level}.mid`)
|
midiSong = await Midi.fromUrl(`midi/${level}.mid`)
|
||||||
levelTitle.innerText = `Niveau ${level}`
|
levelTitle.innerText = `Niveau ${level}`
|
||||||
songNameTitle.innerText = midiSong.name
|
songNameTitle.innerText = midiSong.name
|
||||||
|
speed = 0.04 * FLOOR / midiSong.header.tempos[0].bpm
|
||||||
noteSprites = []
|
noteSprites = []
|
||||||
midiSong.tracks.forEach(track => {
|
midiSong.tracks.forEach(track => {
|
||||||
//console.log(track.name)
|
//console.log(track.name)
|
||||||
track.notes.filter(note => FIRST_NOTE <= note.midi && note.midi <= LAST_NOTE).forEach(note => {
|
track.notes.filter(note => FIRST_NOTE <= note.midi && note.midi <= LAST_NOTE).forEach(note => {
|
||||||
let noteSprite
|
let noteSprite
|
||||||
let durationInQuarter = note.durationTicks / midiSong.header.ppq
|
let durationInQuarter = note.durationTicks / midiSong.header.ppq
|
||||||
if (durationInQuarter <= 0.25) noteSprite = new Sixteenth(canvasCtx, note.midi, 1000*note.duration)
|
if (durationInQuarter <= 0.25) noteSprite = new Sixteenth(canvasCtx, note.midi, note.duration)
|
||||||
else if (durationInQuarter <= 0.5) noteSprite = new Eighth(canvasCtx, note.midi, 1000*note.duration)
|
else if (durationInQuarter <= 0.5) noteSprite = new Eighth(canvasCtx, note.midi, note.duration)
|
||||||
else if (durationInQuarter <= 1) noteSprite = new Quarter(canvasCtx, note.midi, 1000*note.duration)
|
else if (durationInQuarter <= 1) noteSprite = new Quarter(canvasCtx, note.midi, note.duration)
|
||||||
else noteSprite = new Whole(canvasCtx, note.midi, 1000*note.duration)
|
else noteSprite = new Whole(canvasCtx, note.midi, note.duration)
|
||||||
Tone.Transport.scheduleOnce(time => noteSprites.push(noteSprite), note.time)
|
Tone.Transport.scheduleOnce(time => noteSprites.push(noteSprite), note.time)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -406,43 +436,42 @@ let updateTaskId
|
|||||||
function resume() {
|
function resume() {
|
||||||
playing = true
|
playing = true
|
||||||
Tone.Transport.start()
|
Tone.Transport.start()
|
||||||
updateTaskId = window.setInterval(update, UPDATE_PERIOD)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
noteSprites.forEach(noteSprite => {
|
noteSprites.forEach(noteSprite => {
|
||||||
noteSprite.y += 0.5
|
noteSprite.y += speed
|
||||||
})
|
})
|
||||||
noteSprites.filter(noteSprite => noteSprite.y >= 420).forEach(noteSprite => {
|
noteSprites.filter(noteSprite => noteSprite.y >= FLOOR).forEach(noteSprite => {
|
||||||
stopNote(noteSprite.note)
|
stopNote(noteSprite.note)
|
||||||
let explosionSprite = noteSprite.explose()
|
let explosionSprite = noteSprite.explose()
|
||||||
explosionSprites.push(explosionSprite)
|
explosionSprites.push(explosionSprite)
|
||||||
explosionSprite.play().then(() => explosionSprites.remove(explosionSprite))
|
explosionSprite.play().then(() => explosionSprites.remove(explosionSprite))
|
||||||
})
|
})
|
||||||
noteSprites = noteSprites.filter(note => note.y < 420)
|
noteSprites = noteSprites.filter(note => note.y < FLOOR)
|
||||||
|
|
||||||
canonSprites.forEach(canonSprite => {
|
cannonSprites.forEach(cannonSprite => {
|
||||||
let noteSprite = noteSprites.find(noteSprite => noteSprite.note == canonSprite.note)
|
let noteSprite = noteSprites.find(noteSprite => noteSprite.note == cannonSprite.note)
|
||||||
if (noteSprite) {
|
if (noteSprite) {
|
||||||
noteSprite.shot = canonSprite.shooting
|
noteSprite.shot = cannonSprite.shooting
|
||||||
if (noteSprite.shot) {
|
if (noteSprite.shot) {
|
||||||
noteSprite.duration -= UPDATE_PERIOD
|
noteSprite.duration -= UPDATE_PERIOD
|
||||||
if (noteSprite.duration > 0) {
|
if (noteSprite.duration > 0) {
|
||||||
playNote(canonSprite.note)
|
playNote(cannonSprite.note)
|
||||||
canonSprite.impactY = noteSprite.y
|
cannonSprite.impactY = noteSprite.y
|
||||||
} else {
|
} else {
|
||||||
stopNote(canonSprite.note)
|
stopNote(cannonSprite.note)
|
||||||
let explosionSprite = noteSprite.explose()
|
let explosionSprite = noteSprite.explose()
|
||||||
explosionSprites.push(explosionSprite)
|
explosionSprites.push(explosionSprite)
|
||||||
explosionSprite.play().then(() => explosionSprites.remove(explosionSprite))
|
explosionSprite.play().then(() => explosionSprites.remove(explosionSprite))
|
||||||
noteSprites.remove(noteSprite)
|
noteSprites.remove(noteSprite)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stopNote(canonSprite.note)
|
stopNote(cannonSprite.note)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stopNote(canonSprite.note)
|
stopNote(cannonSprite.note)
|
||||||
canonSprite.impactY = 0
|
cannonSprite.impactY = 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -471,6 +500,8 @@ function stopNote(note) {
|
|||||||
|
|
||||||
velocity = oscillators[note].velocity.gain.value
|
velocity = oscillators[note].velocity.gain.value
|
||||||
oscillators[note].velocity.gain.setValueCurveAtTime([velocity, velocity/10, velocity/20, 0], audioCtx.currentTime + 0.1, 0.5)
|
oscillators[note].velocity.gain.setValueCurveAtTime([velocity, velocity/10, velocity/20, 0], audioCtx.currentTime + 0.1, 0.5)
|
||||||
|
oscillators[note].stop(audioCtx.currentTime + 0.6)
|
||||||
|
|
||||||
delete(oscillators[note])
|
delete(oscillators[note])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,13 +526,14 @@ function playNoise(noiseDuration, startGain=0.5, bandHz=1000) {
|
|||||||
gain.gain.setValueCurveAtTime([startGain, startGain/5, 0], audioCtx.currentTime, noiseDuration)
|
gain.gain.setValueCurveAtTime([startGain, startGain/5, 0], audioCtx.currentTime, noiseDuration)
|
||||||
noise.connect(bandpass).connect(gain).connect(audioCtx.destination)
|
noise.connect(bandpass).connect(gain).connect(audioCtx.destination)
|
||||||
noise.start()
|
noise.start()
|
||||||
|
noise.stop(audioCtx.currentTime + noiseDuration)
|
||||||
}
|
}
|
||||||
|
|
||||||
document.onkeydown = function(event) {
|
document.onkeydown = function(event) {
|
||||||
if (playing && keyMap.includes(event.key)) {
|
if (playing && keyMap.includes(event.key)) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
let note = FIRST_NOTE + keyMap.indexOf(event.key)
|
let note = FIRST_NOTE + keyMap.indexOf(event.key)
|
||||||
canonSprites[note].shooting = true
|
cannonSprites[note].shooting = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,6 +541,6 @@ document.onkeyup = function(event) {
|
|||||||
if (playing && keyMap.includes(event.key)) {
|
if (playing && keyMap.includes(event.key)) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
let note = FIRST_NOTE + keyMap.indexOf(event.key)
|
let note = FIRST_NOTE + keyMap.indexOf(event.key)
|
||||||
canonSprites[note].shooting = false
|
cannonSprites[note].shooting = false
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
img/cannon.png
Normal file
BIN
img/cannon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
img/canon.png
BIN
img/canon.png
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 20 KiB |
BIN
img/pipe.png
Normal file
BIN
img/pipe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
midi/1.mid
BIN
midi/1.mid
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user