const PLAYER_SPEED = 640; const JUMP_FORCE = 1200; const NUM_PLATFORMS = 5; function genCoin(avoid = 0) { const plats = k.get("platform"); let idx = k.randi(0, plats.length); if (avoid != null) { idx = k.choose([...plats.keys()].filter((i) => i !== avoid)); } const plat = plats[idx]; k.add([ k.pos(), k.anchor("center"), k.sprite("coin"), k.area(), k.follow(plat, k.vec2(0, -60)), "coin", { idx: idx }, ]); } function makeGameObjects(k) { k.loadSprite( "bean", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAA1CAYAAADyMeOEAAAAAXNSR0IArs4c6QAAAn5JREFUaIHdm7txAkEMhnUMBUAFEEPmcUgHhHRBQXThkA4IGTKIoQLoAEcw60PS6XkP/zNO7Nt/95O099hdV5Co2WTx9LS/PS5V1FhKhZt6QTlFBSHEJBOUkicAbugugEtZ4M3QUtjVbq32Pmz3quu14GpoCawFlJM0CFJ4FXQTcDQspqYASMDF0BxwG7B1UfBh0H0DLoXBN4E3QlPAXcOW0oKPOLMhAFPiqpOMxtCANXMczfTQgAF0Y/uIghWYe5R4gkX5Up6S+S2CxjrQvjVRPpS0/i9vNbQE2ALb5BnlLwVn797l4A7bfQgwNSju917fut7Q3C0+CpbzjAwoVkklH5lp6fy73s8h11jacX/nxj8C0H8TX+/n94+mjbYP63VU1bw40Uy3/TyuD9JaGVKxNzJK8+kS5tOluk3bopI39iz3SEEsAZJkm/LlKnU2WTxFmc4o9yZPSzVJfAGQ8qYaRYLXvaK8MR/sd6o5vdqt3QPMCqqm/djbgeSlQjog7jUywv8lE7SnQ42n9gtLKjd0prLeF0zP6aHrAzrj46Jv+veZxpI4vj0uVcQmXFsV4p3nt8elQjOtBWhzSkT0NQLI2/HvWlSAyDk99Bsat06W9pz++foO89qcjmFeAEWmPSXet00A12qop8SjsxOpP9BYtrue29rgSRb7w15OsBL3ZHtzOqLtI6bSB3R0tqnBR11fSrpPjd68PLuWmdNBux1E3ZxT9qejwa07pmpoAP9Zk+zNPq4P7hFsPnMiHRQ3sCxf90EbgG4OzHHighh6jgwg92ikRBEH5wCSjknW1bfzoekHYrPV6ingl7qEt34kDepkP0DMgkfqiklf/4fjF/Soc3nSQqqQAAAAAElFTkSuQmCC" ); k.loadSprite( "coin", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAiCAYAAACuoaIwAAAAAXNSR0IArs4c6QAAAO9JREFUSIntl0EOAiEMRQt6ABfujXHnBTyQ5/JAXmB2xszexVzA6AqDTPspFDUx/NWEAo/fYZjiCGiz2j9QPNU4DQ7FxWApSANlGy0gBJw1tABJwGUOdLkes5PuticV/EWWHGlgCBq782hwCUhSbMKlDVaQlNJxGhx0ViO0SNYZGrA434iI6H5YQyjn0Jds9QBKnzlxC56lscWmkNT8nXVYh3XYn8LYs1HTKSg+fHMHMSefK784YA3oI/8zIjk7LExbwJTKE+UrWavC/GIaa92hcW+OrIWPqZQLE2hcavp8tfz+7cWiBbToymQBos/oCUxkZzDzTje1AAAAAElFTkSuQmCC" ); k.loadSprite( "grass", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAdlJREFUeJztmy1yQjEURvM6XUAFmgpcPQ6LYifsoCtgB+wEVYurx1VQXcEOWnWZEEKa3CTvuy+5Rz3aSbjfmfwy8wZj8fry9ms64Hw5DfR8feglPEESBmP6C0+cL6dh6DU88ez+YbXfIOoYjeP2cPP5CVSHGFQAugA0KgBdABoVgC4Azd05QBLunh2Ce34RKSAluK9NigxRU+C4PbDC+/qJxXsXGPs4XCJ0CDuP+13By1BtEbHBd+tl8P/vH59R/az2mzQB1Kg0McH/C+0jVoRN0nU4V0at4C4pIti/B6TIGCu4S4yIOwG79ZI1lLjUCO4SyuMVENOwBGOEd3EzBQ9CVGBpEYjgj4g6CboFc4RICm3DOgqjwizmM2OMMV/fP8X6FHUUDkHh3edcJiOgFpMRYA/7klNA5HX4ESWDE5MZAbVQAdyGi/ms6GqMgiWg1paEQKcAp1GtLQkBexucenBCpwC6ADQqAF0AGhWALgCNCkAXgL5TQAVIuFPARwAaqAAJdwr4T2LoO0WzUyB2cW1SQMri2qSAFJoUkLK4whfBWsQurk2OgBRUQIlO0Of5HLIFSDjP56BTILcDCef5HIpsg1MMTnT/4qS+OksfepNw8/I00YsE+/X5P+6znC4h3qbLAAAAAElFTkSuQmCC" ); k.loadSprite( "spike", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAVCAYAAAD2KuiaAAAAAXNSR0IArs4c6QAAASxJREFUWIXtlr0RgzAMheVMwAb07JciE6RgP3o2YANSKecY/cuXO0JelfPFn56fsKCAUeMw7fh73ZZi3fctXlSmwrVZVMZ0b15GalHKLMprWmJFeBzTw7l5C2rFe/zXyuOYnlpiUlaQlrjHkKV7vXwBCE8AVeR5v1vqqhxkUTzpcFLXPbVrua+AxzQXYs2w8qTDcGFq+wCYACLdb/d4GFIIWte1MDkvqMMdsRp/zDMJXLelRALkeJwkHsXi5sHHote41bR1dlh4GRYVwnshOvQ0097BKfF6sNoQUt8BALKpyFuD4/RitY0u1CIW9ahNO2O4ZmUPLs0qACaAaFEs1qtbvSRdhdDEPqO4ENIz4Mwah2k/BPCL3Qfgz0VegSvp0lcA4B8A/x1wBa3bUl6DELTjnD/LxgAAAABJRU5ErkJggg==" ); k.loadSound( "coin", "data:image/png;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4Ljc2LjEwMAAAAAAAAAAAAAAA//tAwAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAAGAAAFmwBFRUVFRUVFRUVFRUVFRUVFampqampqampqampqampqamqQkJCQkJCQkJCQkJCQkJCQtbW1tbW1tbW1tbW1tbW1tbXa2tra2tra2tra2tra2tra2v////////////////////8AAAAATGF2YzU4LjEzAAAAAAAAAAAAAAAAJAKAAAAAAAAABZsJ0z/tAAAAAAD/+1DEAAAIxHNYVPKAAZ2dLrcw0AAgFUQ9DznNM0zrZ1wTgI+DnAzg5wkYuZ1s78UIQhCEJziYfAMAwOLtQjf/UTDgcDgY/lAQBCGPwQOf8Hwf0/6wf/8Tv/4IMpIOTbAAA7bbXORplFRJ/v1+k0gxL8iOE+jOgdDTsbabgTR6rZb5N0c4Ul5/lvqGcLySLLEON6WNIazJFJNRkJe+pMiN1DhManoEmYovyRX84p+yz7oq+fDbqjelvWMf0Mxfi/9+voV5UxAkVEEVbaJbFGPo//tSxAaAC+Dxb/z2gBF6n2588zXSQhtJyXUfLikRJQii5M/XbhOascTUgzyYkcJ0fvJb3r92XOCWBIh5KHwdpdUkibol/0dJxSSSnX6tXUvSH4eKSSnZtP+1lHHzv8u63+nd/1O/63l0MFVlRWeytKC1FKQuZCj1YWJTKQrlAdT1Q/nMJivJrna0oifllmLpq6f+tLNw2zBNQ8gXjc4bJOYl2pJReRqF0TRGxWbO//fkQsQNnGs8pdv1mvMm5z/O1f7qP99CnLcABkUQzAEyUvX/+1LEBYALVR9V7CSuwN8JY9wxDOBpBSoggEDHiytwICZga9Hcjtyy+9rjQymwTRWXc/1LrHQAjsvxI7P/+Ih4DaGVv+vEQ62v//mFkeVv/9Q6K6l//1QPCzQVd/xF/vgr/K1A0BYmKQ3RllYKGBggwMIBiHqGBDgIIcSwUMCcvJlDAgcNPkTrwELiv+K/7M9/qu//60M2///6QkK1TEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/7UsQaA8AAAaQAAAAgAAA0gAAABFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//tSxHgDwAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/+1LEoYPAAAGkAAAAIAAANIAAAARVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==" ); const score = k.add([k.text("0", 24), k.pos(24, 24), { value: 0 }]); const bean = k.add([ k.sprite("bean"), k.area(), k.anchor("center"), k.pos(0, 0), k.body({ jumpForce: JUMP_FORCE }), k.doubleJump(), k.rotate(0), ]); for (let i = 1; i < NUM_PLATFORMS; i++) { k.add([ k.sprite("grass"), k.area(), k.pos(k.rand(0, k.width()), (i * k.height()) / NUM_PLATFORMS), k.body({ isStatic: true }), k.anchor("center"), "platform", { speed: k.rand(120, 320), dir: k.choose([-1, 1]), }, ]); } for (let i = 0; i < k.width() / 64; i++) { k.add([ k.pos(i * 64, k.height()), k.sprite("spike"), k.area(), k.anchor("bot"), k.scale(), "danger", ]); } return { score, bean }; } function sceneGame(k) { const { score, bean } = makeGameObjects(k); bean.pos = k.get("platform")[0].pos.sub(0, 64); genCoin(); bean.onCollide("coin", (c) => { k.destroy(c); k.play("coin"); score.value += 1; score.text = score.value; genCoin(c.idx); }); // обработка падения k.onUpdate("platform", (p) => { p.move(p.dir * p.speed, 0); // инверт дирекшена на стенах }); k.onKeyPress("space", () => { bean.doubleJump(); }); function move(x) { bean.move(x, 0); // обработка выхода за границы } k.onKeyDown("left", () => { move(-PLAYER_SPEED); }); k.onKeyDown("right", () => { move(PLAYER_SPEED); }); } function sceneLose(k) { // добавить текст поражения // добавить рестарт } const k = kaplay({ background: [141, 183, 255], global: false, }); k.setGravity(4000); k.scene("game", () => sceneGame(k)); k.scene("lose", () => sceneLose(k)); k.go("game");