diff --git a/src/levels/1.ts b/src/levels/1.ts index fbe6f4c..9a67c83 100644 --- a/src/levels/1.ts +++ b/src/levels/1.ts @@ -21,9 +21,7 @@ add([text('Uncomment the exit')]) ` export const script = ` -/** - * Single-line comments start with 2 forward slashes // - */ +// Single-line comments start with 2 forward slashes // console.log('This is commented out') console.log('This is not commented out') diff --git a/src/levels/10.ts b/src/levels/10.ts index de48a6a..bf6c269 100644 --- a/src/levels/10.ts +++ b/src/levels/10.ts @@ -6,81 +6,45 @@ import { } from '../templates' export const level = 10 -export const title = 'forEach' +export const title = 'For Loop' + +const password = Array.from(Array(42).keys()) + .map(() => 'answer') + .join('') export const prescript = ` ${loadPlayer()} ${loadExit()} -loadSprite('spike', 'sprites/spike.png') +loadSprite('key', 'sprites/key.png') -const player = add([ - sprite('player'), - pos(40, 80), - area(), - body(), - anchor('center'), - 'player', -]) +const player = add([sprite('player'), pos(100, 100), area(), 'player']) -add([sprite('exit'), pos(500, 500), area(), 'exit']) +add([sprite('key'), pos(center()), area(), 'key', { password: '${password}' }]) ${registerPlayerKeys()} ${registerWinCondition(level)} -const map = [ - ' ', - ' ', - '^^^^^ ^^^', - ' ', - '^ ^^^^ ', - '^ ^^^', - ' ^ ', - '^^^^ ^^^ ', -] - -const SPIKES_COUNT = map.join('').split(' ').join('').length -const TILE_SIZE = 64 - -map.forEach((row, rowIndex) => { - row.split('').forEach((column, columnIndex) => { - if (column === '^') { - add([ - sprite('spike'), - area(), - pos(TILE_SIZE * columnIndex, TILE_SIZE * rowIndex), - opacity(0), - 'spike', - ]) - } - }) -}) - -onCollide('player', 'spike', (player, spike) => { - spike.opacity = 1 - player.destroy() - addKaboom(player.pos) -}) - -onUpdate(() => { - const { x, y } = player.pos - - if (x < 0 || y < 0 || x > width() || y > height()) { - player.moveTo(40, 80) - } - - if (get('spike').length < SPIKES_COUNT) { - throw new Error('There must be ' + SPIKES_COUNT + ' spikes!') +onCollide('key', 'player', (key) => { + if (key.password === '${password}') { + key.destroy() + add([sprite('exit'), pos(500, 500), area(), 'exit']) + } else { + debug.log('Incorrect password') } }) -add([text('Invisible spikes')]) +add([text('Repeat the password')]) ` export const script = ` /** - * forEach() is an iterative method + * For loops repeat a block of code */ -const spikes = get('spike') -spikes[0].opacity = 0 +const key = get('key')[0] + +// password = 'answer' repeated 42 times +let password = 'answer' + 'answer' + +key.password = password ` diff --git a/src/levels/11.ts b/src/levels/11.ts index ef2f106..d6e62a3 100644 --- a/src/levels/11.ts +++ b/src/levels/11.ts @@ -6,17 +6,16 @@ import { } from '../templates' export const level = 11 -export const title = 'Loops' +export const title = 'forEach' export const prescript = ` ${loadPlayer()} ${loadExit()} -loadSprite('enemy', 'sprites/ghosty.png') -loadSprite('wall', 'sprites/steel.png') +loadSprite('spike', 'sprites/spike.png') const player = add([ sprite('player'), - pos(40, 60), + pos(40, 80), area(), body(), anchor('center'), @@ -28,66 +27,60 @@ add([sprite('exit'), pos(500, 500), area(), 'exit']) ${registerPlayerKeys()} ${registerWinCondition(level)} -const ENEMY_SPEED = 500 - -let cancelEnemyUpdate; - -function addEnemy() { - const enemy = add([ - sprite('enemy'), - pos(center()), - area(), - body(), - 'enemy', - ]) - - cancelEnemyUpdate = enemy.onUpdate(() => { - if (player) { - const dir = player.pos.sub(enemy.pos).unit() - enemy.move(dir.scale(ENEMY_SPEED)) +const map = [ + ' ', + ' ', + '^^^^^ ^^^', + ' ', + '^ ^^^^ ', + '^ ^^^', + ' ^ ', + '^^^^ ^^^ ', +] + +const SPIKES_COUNT = map.join('').split(' ').join('').length +const TILE_SIZE = 64 + +map.forEach((row, rowIndex) => { + row.split('').forEach((column, columnIndex) => { + if (column === '^') { + add([ + sprite('spike'), + area(), + pos(TILE_SIZE * columnIndex, TILE_SIZE * rowIndex), + opacity(0), + 'spike', + ]) } - }).cancel - - return enemy -} - -addEnemy() + }) +}) -onCollide('player', 'enemy', (player, enemy) => { - if (typeof cancelEnemyUpdate === 'function') { - cancelEnemyUpdate() - } +onCollide('player', 'spike', (player, spike) => { + spike.opacity = 1 player.destroy() addKaboom(player.pos) }) -onDestroy('enemy', () => { - addEnemy() +onUpdate(() => { + const { x, y } = player.pos + + if (x < 0 || y < 0 || x > width() || y > height()) { + player.moveTo(40, 80) + } + + if (get('spike').length < SPIKES_COUNT) { + throw new Error('There must be ' + SPIKES_COUNT + ' spikes!') + } }) -add([text('Protect yourself')]) +add([text('Invisible spikes')]) ` export const script = ` /** - * Can you build a fortress to protect yourself? + * forEach() is an iterative method */ -const wall = { - width: 64, - height: 64, -} - -add([ - sprite('wall'), - pos(wall.width * 6, wall.height * 6), - area(), - body({ isStatic: true }), -]) -` - -export const postscript = ` - if (get('enemy').length) { - get('enemy')[0].moveTo(center()) - } +const spikes = get('spike') +spikes[0].opacity = 0 ` diff --git a/src/levels/12.ts b/src/levels/12.ts index 672616d..0154cf0 100644 --- a/src/levels/12.ts +++ b/src/levels/12.ts @@ -6,30 +6,88 @@ import { } from '../templates' export const level = 12 -export const title = 'setTimeout' +export const title = 'Loops' export const prescript = ` ${loadPlayer()} ${loadExit()} +loadSprite('enemy', 'sprites/ghosty.png') +loadSprite('wall', 'sprites/steel.png') -const player = add([sprite('player'), pos(50, 50), area(), 'player']) +const player = add([ + sprite('player'), + pos(40, 60), + area(), + body(), + anchor('center'), + 'player', +]) + +add([sprite('exit'), pos(500, 500), area(), 'exit']) ${registerPlayerKeys()} ${registerWinCondition(level)} -add([text('Wait for the exit')]) +const ENEMY_SPEED = 500 + +let cancelEnemyUpdate; + +function addEnemy() { + const enemy = add([ + sprite('enemy'), + pos(center()), + area(), + body(), + 'enemy', + ]) + + cancelEnemyUpdate = enemy.onUpdate(() => { + if (player) { + const dir = player.pos.sub(enemy.pos).unit() + enemy.move(dir.scale(ENEMY_SPEED)) + } + }).cancel + + return enemy +} + +addEnemy() + +onCollide('player', 'enemy', (player, enemy) => { + if (typeof cancelEnemyUpdate === 'function') { + cancelEnemyUpdate() + } + player.destroy() + addKaboom(player.pos) +}) + +onDestroy('enemy', () => { + addEnemy() +}) + +add([text('Protect yourself')]) ` export const script = ` /** - * setTimeout() executes a function once the timer expires + * Can you build a fortress to protect yourself? */ -const MILLISECOND = 1 -const SECOND = MILLISECOND * 1000 -const MINUTE = SECOND * 60 +const wall = { + width: 64, + height: 64, +} + +add([ + sprite('wall'), + pos(wall.width * 6, wall.height * 6), + area(), + body({ isStatic: true }), +]) +` -setTimeout(() => { - add([sprite('exit'), pos(center()), area(), 'exit']) -}, 5 * MINUTE) +export const postscript = ` + if (get('enemy').length) { + get('enemy')[0].moveTo(center()) + } ` diff --git a/src/levels/13.ts b/src/levels/13.ts index 436a502..9f3aaf0 100644 --- a/src/levels/13.ts +++ b/src/levels/13.ts @@ -6,46 +6,30 @@ import { } from '../templates' export const level = 13 -export const title = 'setInterval' +export const title = 'setTimeout' export const prescript = ` ${loadPlayer()} ${loadExit()} -const player = add([sprite('player'), pos(50, 80), area(), anchor('center'), 'player']) - -const exit = add([ - sprite('exit'), - pos(center()), - area(), - anchor('center'), - 'exit', -]) +const player = add([sprite('player'), pos(50, 50), area(), 'player']) +${registerPlayerKeys()} ${registerWinCondition(level)} -add([text('Exit in a loop')]) +add([text('Wait for the exit')]) ` export const script = ` /** - * setInterval() calls a function at specified intervals + * setTimeout() executes a function once the timer expires */ const MILLISECOND = 1 const SECOND = MILLISECOND * 1000 +const MINUTE = SECOND * 60 -const exit = get('exit')[0] - -setInterval(() => { - exit.moveTo( - randi(width()), - randi(height()), - ) -}, SECOND) -` - -export const postscript = ` -const player = get('player')[0] -${registerPlayerKeys(50)} +setTimeout(() => { + add([sprite('exit'), pos(center()), area(), 'exit']) +}, 5 * MINUTE) ` diff --git a/src/levels/14.ts b/src/levels/14.ts index 9cbba53..734fbe4 100644 --- a/src/levels/14.ts +++ b/src/levels/14.ts @@ -6,62 +6,46 @@ import { } from '../templates' export const level = 14 -export const title = 'Timer' +export const title = 'setInterval' export const prescript = ` ${loadPlayer()} ${loadExit()} -loadSprite('key', 'sprites/key.png') -const player = add([sprite('player'), pos(center()), area(), 'player']) +const player = add([sprite('player'), pos(50, 80), area(), anchor('center'), 'player']) -let keys = 420 +const exit = add([ + sprite('exit'), + pos(center()), + area(), + anchor('center'), + 'exit', +]) -const getMessage = () => - 'Collect ' + keys + ' more key' + (keys !== 1 ? 's' : '') - -const message = add([text(getMessage())]) - -function addKey() { - add([ - sprite('key'), - pos(randi(width()), randi(height())), - area(), - anchor('center'), - 'key', - ]) -} - -addKey() - -${registerPlayerKeys()} ${registerWinCondition(level)} -onCollide('key', 'player', (key) => { - keys-- - key.destroy() - message.text = getMessage() - - if (keys) { - addKey() - } else { - add([sprite('exit'), pos(center()), area(), 'exit']) - } -}) - -onAdd('exit', () => { - if (keys) { - destroyAll('exit') - } -}) +add([text('Exit in a loop')]) ` export const script = ` /** - * Can we speed this up? + * setInterval() calls a function at specified intervals */ +const MILLISECOND = 1 +const SECOND = MILLISECOND * 1000 + +const exit = get('exit')[0] + +setInterval(() => { + exit.moveTo( + randi(width()), + randi(height()), + ) +}, SECOND) +` + +export const postscript = ` const player = get('player')[0] -const key = get('key')[0] -// player.moveTo(key.pos) +${registerPlayerKeys(50)} ` diff --git a/src/levels/15.ts b/src/levels/15.ts index 33c2be8..b2519ee 100644 --- a/src/levels/15.ts +++ b/src/levels/15.ts @@ -6,43 +6,62 @@ import { } from '../templates' export const level = 15 -export const title = 'JSON.stringify' - -const password = JSON.stringify({ level, year: new Date().getFullYear() }) +export const title = 'Timer' export const prescript = ` ${loadPlayer()} ${loadExit()} loadSprite('key', 'sprites/key.png') -const player = add([sprite('player'), pos(100, 100), area(), 'player']) +const player = add([sprite('player'), pos(center()), area(), 'player']) + +let keys = 420 + +const getMessage = () => + 'Collect ' + keys + ' more key' + (keys !== 1 ? 's' : '') + +const message = add([text(getMessage())]) + +function addKey() { + add([ + sprite('key'), + pos(randi(width()), randi(height())), + area(), + anchor('center'), + 'key', + ]) +} -add([sprite('key'), pos(center()), area(), 'key', { password: '${password}' }]) +addKey() ${registerPlayerKeys()} ${registerWinCondition(level)} onCollide('key', 'player', (key) => { - if (key.password === '${password}') { - key.destroy() - add([sprite('exit'), pos(500, 500), area(), 'exit']) + keys-- + key.destroy() + message.text = getMessage() + + if (keys) { + addKey() } else { - debug.log('Incorrect password') + add([sprite('exit'), pos(center()), area(), 'exit']) } }) -add([text('Got the password?')]) +onAdd('exit', () => { + if (keys) { + destroyAll('exit') + } +}) ` export const script = ` /** - * JSON.stringify() is a method that converts data into a string + * Can we speed this up? */ +const player = get('player')[0] const key = get('key')[0] - -// password = JSON string of object containing 'level' and 'year' -let password - -key.password = password +// player.moveTo(key.pos) ` diff --git a/src/levels/16.ts b/src/levels/16.ts new file mode 100644 index 0000000..9401694 --- /dev/null +++ b/src/levels/16.ts @@ -0,0 +1,48 @@ +import { + loadExit, + loadPlayer, + registerPlayerKeys, + registerWinCondition, +} from '../templates' + +export const level = 16 +export const title = 'JSON.stringify' + +const password = JSON.stringify({ level, year: new Date().getFullYear() }) + +export const prescript = ` +${loadPlayer()} +${loadExit()} +loadSprite('key', 'sprites/key.png') + +const player = add([sprite('player'), pos(100, 100), area(), 'player']) + +add([sprite('key'), pos(center()), area(), 'key', { password: '${password}' }]) + +${registerPlayerKeys()} +${registerWinCondition(level)} + +onCollide('key', 'player', (key) => { + if (key.password === '${password}') { + key.destroy() + add([sprite('exit'), pos(500, 500), area(), 'exit']) + } else { + debug.log('Incorrect password') + } +}) + +add([text('Got the password?')]) +` + +export const script = ` +/** + * JSON.stringify() is a method that converts data into a string + */ + +const key = get('key')[0] + +// password = JSON string of object containing 'level' and 'year' +let password + +key.password = password +` diff --git a/src/levels/2.ts b/src/levels/2.ts index 2c2a989..98514f4 100644 --- a/src/levels/2.ts +++ b/src/levels/2.ts @@ -6,27 +6,38 @@ import { } from '../templates' export const level = 2 -export const title = 'Strings' +export const title = 'Multi-line comments' export const prescript = ` ${loadPlayer()} ${loadExit()} -const player = add([sprite('player'), pos(center()), area(), 'player']) +add([sprite('exit'), pos(center()), area(), 'exit']) -${registerPlayerKeys()} ${registerWinCondition(level)} + +add([text('Uncomment the player')]) ` export const script = ` -/** - * Strings are text inside single or double quotes - */ +// Multi-line comments start with /* and end with */ + +/* console.log('This is commented out') */ +console.log('This is not commented out') +/* add([ - // fix the error below - sprite('exite'), + sprite('player'), + pos(50, 50), area(), - "exit", + 'player', ]) +*/ +` + +export const postscript = ` +const player = get('player')[0] +if (player) { +${registerPlayerKeys()} +} ` diff --git a/src/levels/3.ts b/src/levels/3.ts index 98ec752..a6411f0 100644 --- a/src/levels/3.ts +++ b/src/levels/3.ts @@ -6,29 +6,27 @@ import { } from '../templates' export const level = 3 -export const title = 'Numbers' +export const title = 'Strings' export const prescript = ` ${loadPlayer()} ${loadExit()} -const player = add([sprite('player'), pos(500, 500), area(), 'player']) +const player = add([sprite('player'), pos(center()), area(), 'player']) ${registerPlayerKeys()} ${registerWinCondition(level)} - -add([text('Exit is not in view?')]) ` export const script = ` /** - * Numbers represent floating-point numbers like 42 or -13.37 + * Strings are text inside single or double quotes */ add([ - sprite('exit'), + // fix the error below + sprite('exite'), area(), - 'exit', - pos(-9999, -9999), + "exit", ]) ` diff --git a/src/levels/4.ts b/src/levels/4.ts index 27defe7..eb1220c 100644 --- a/src/levels/4.ts +++ b/src/levels/4.ts @@ -6,30 +6,29 @@ import { } from '../templates' export const level = 4 -export const title = 'Booleans' +export const title = 'Numbers' export const prescript = ` ${loadPlayer()} ${loadExit()} -const player = add([sprite('player'), pos(center()), area(), 'player']) +const player = add([sprite('player'), pos(500, 500), area(), 'player']) ${registerPlayerKeys()} ${registerWinCondition(level)} -add([text('Exit is not truthy')]) +add([text('Exit is not in view?')]) ` export const script = ` /** - * Booleans can either be true or false + * Numbers represent floating-point numbers like 42 or -13.37 */ -if (false) { - add([ - sprite('exit'), - area(), - 'exit', - ]) -} +add([ + sprite('exit'), + area(), + 'exit', + pos(-9999, -9999), +]) ` diff --git a/src/levels/5.ts b/src/levels/5.ts index bda942d..61c57bb 100644 --- a/src/levels/5.ts +++ b/src/levels/5.ts @@ -6,56 +6,30 @@ import { } from '../templates' export const level = 5 -export const title = 'Arrays' +export const title = 'Booleans' export const prescript = ` ${loadPlayer()} -loadSprite('wall', 'sprites/steel.png') ${loadExit()} -const player = add([sprite('player'), pos(center()), area(), body(), 'player']) -add([sprite('exit'), pos(500, 500), area(), 'exit']) +const player = add([sprite('player'), pos(center()), area(), 'player']) ${registerPlayerKeys()} ${registerWinCondition(level)} -add([text('Trapped in arrays')]) - -onUpdate(() => { - if (!get('map')[0]?.map?.length) { - throw new Error('Map must be valid') - } -}) +add([text('Exit is not truthy')]) ` export const script = ` /** - * Arrays are an ordered list of data + * Booleans can either be true or false */ -const map = [ - '#######', - '# #', - '# #', - '# #', - '# #', - '#######', -] - -add(['map', { map }]) -` - -export const postscript = ` -addLevel(get('map')[0].map, { - tileWidth: 64, - tileHeight: 64, - pos: vec2(64, 64), - tiles: { - '#': () => [ - sprite('wall'), - area(), - body({ isStatic: true }), - ], - } -}) +if (false) { + add([ + sprite('exit'), + area(), + 'exit', + ]) +} ` diff --git a/src/levels/6.ts b/src/levels/6.ts index e72f471..a4c1f13 100644 --- a/src/levels/6.ts +++ b/src/levels/6.ts @@ -1,35 +1,61 @@ -import { loadExit, loadPlayer, registerWinCondition } from '../templates' +import { + loadExit, + loadPlayer, + registerPlayerKeys, + registerWinCondition, +} from '../templates' export const level = 6 -export const title = 'Objects' +export const title = 'Arrays' export const prescript = ` ${loadPlayer()} +loadSprite('wall', 'sprites/steel.png') ${loadExit()} -const player = add([sprite('player'), pos(0, 36), area(), body(), 'player']) -add([sprite('exit'), pos(516, 516), area(), 'exit']) - -onKeyPress(() => { - debug.log('Keypress disabled!') -}) +const player = add([sprite('player'), pos(center()), area(), body(), 'player']) +add([sprite('exit'), pos(500, 500), area(), 'exit']) +${registerPlayerKeys()} ${registerWinCondition(level)} -add([text('Reposition me')]) +add([text('Trapped in arrays')]) + +onUpdate(() => { + if (!get('map')[0]?.map?.length) { + throw new Error('Map must be valid') + } +}) ` export const script = ` /** - * Objects are a collection of properties or key-value pairs + * Arrays are an ordered list of data */ -const coordinates = { - x: 0, - y: 36, -} +const map = [ + '#######', + '# #', + '# #', + '# #', + '# #', + '#######', +] -const player = get('player')[0] -player.pos.x = coordinates.x -player.pos.y = coordinates.y +add(['map', { map }]) +` + +export const postscript = ` +addLevel(get('map')[0].map, { + tileWidth: 64, + tileHeight: 64, + pos: vec2(64, 64), + tiles: { + '#': () => [ + sprite('wall'), + area(), + body({ isStatic: true }), + ], + } +}) ` diff --git a/src/levels/7.ts b/src/levels/7.ts index 171e8ee..657c716 100644 --- a/src/levels/7.ts +++ b/src/levels/7.ts @@ -1,14 +1,14 @@ import { loadExit, loadPlayer, registerWinCondition } from '../templates' export const level = 7 -export const title = 'Functions' +export const title = 'Objects' export const prescript = ` ${loadPlayer()} ${loadExit()} -add([sprite('player'), pos(0, 36), area(), 'player']) -add([sprite('exit'), pos(center().x, 500), area(), 'exit']) +const player = add([sprite('player'), pos(0, 36), area(), body(), 'player']) +add([sprite('exit'), pos(516, 516), area(), 'exit']) onKeyPress(() => { debug.log('Keypress disabled!') @@ -16,24 +16,20 @@ onKeyPress(() => { ${registerWinCondition(level)} -add([text('Move me')]) +add([text('Reposition me')]) ` export const script = ` /** - * Functions are blocks of code designed to perform a task + * Objects are a collection of properties or key-value pairs */ -const player = get('player')[0] -player.move(0, 0) - -function movePlayer() { - // how can we move the player? +const coordinates = { + x: 0, + y: 36, } -player.onUpdate(() => movePlayer()) -` - -export const postscript = ` -get('player')[0].moveTo(0, 36) +const player = get('player')[0] +player.pos.x = coordinates.x +player.pos.y = coordinates.y ` diff --git a/src/levels/8.ts b/src/levels/8.ts index 6a4a274..692d69c 100644 --- a/src/levels/8.ts +++ b/src/levels/8.ts @@ -1,48 +1,39 @@ -import { - loadExit, - loadPlayer, - registerPlayerKeys, - registerWinCondition, -} from '../templates' +import { loadExit, loadPlayer, registerWinCondition } from '../templates' export const level = 8 -export const title = 'Variables' - -const password = (new Date().getFullYear() + level) * 31337 +export const title = 'Functions' export const prescript = ` ${loadPlayer()} ${loadExit()} -loadSprite('key', 'sprites/key.png') - -const player = add([sprite('player'), pos(100, 100), area(), 'player']) -add([sprite('key'), pos(center()), area(), 'key', { password: ${password} }]) -${registerPlayerKeys()} -${registerWinCondition(level)} +add([sprite('player'), pos(0, 36), area(), 'player']) +add([sprite('exit'), pos(center().x, 500), area(), 'exit']) -onCollide('key', 'player', (key) => { - if (key.password === ${password}) { - key.destroy() - add([sprite('exit'), pos(500, 500), area(), 'exit']) - } else { - debug.log('Incorrect password') - } +onKeyPress(() => { + debug.log('Keypress disabled!') }) -add([text('Update password & go to key')]) +${registerWinCondition(level)} + +add([text('Move me')]) ` export const script = ` /** - * Variables store data - * 'const' cannot be reassigned, whereas 'let' can be reassigned + * Functions are blocks of code designed to perform a task */ -const key = get('key')[0] +const player = get('player')[0] +player.move(0, 0) + +function movePlayer() { + // how can we move the player? +} -// password = (current_year + current_level_number) * 31337 -let password +player.onUpdate(() => movePlayer()) +` -key.password = password +export const postscript = ` +get('player')[0].moveTo(0, 36) ` diff --git a/src/levels/9.ts b/src/levels/9.ts index 5d6c3b3..bc3ebd5 100644 --- a/src/levels/9.ts +++ b/src/levels/9.ts @@ -6,11 +6,9 @@ import { } from '../templates' export const level = 9 -export const title = 'For Loop' +export const title = 'Variables' -const password = Array.from(Array(42).keys()) - .map(() => 'answer') - .join('') +const password = (new Date().getFullYear() + level) * 31337 export const prescript = ` ${loadPlayer()} @@ -18,14 +16,13 @@ ${loadExit()} loadSprite('key', 'sprites/key.png') const player = add([sprite('player'), pos(100, 100), area(), 'player']) - -add([sprite('key'), pos(center()), area(), 'key', { password: '${password}' }]) +add([sprite('key'), pos(center()), area(), 'key', { password: ${password} }]) ${registerPlayerKeys()} ${registerWinCondition(level)} onCollide('key', 'player', (key) => { - if (key.password === '${password}') { + if (key.password === ${password}) { key.destroy() add([sprite('exit'), pos(500, 500), area(), 'exit']) } else { @@ -33,18 +30,19 @@ onCollide('key', 'player', (key) => { } }) -add([text('Repeat the password')]) +add([text('Update password & go to key')]) ` export const script = ` /** - * For loops repeat a block of code + * Variables store data + * 'const' cannot be reassigned, whereas 'let' can be reassigned */ const key = get('key')[0] -// password = 'answer' repeated 42 times -let password = 'answer' + 'answer' +// password = (current_year + current_level_number) * 31337 +let password key.password = password `