Cíl: s použitím knihovny matter.js vytvoříme 2d hru, ve které si dva hráči pinkají s míčkem. Inspirací je prastará DOSová hra Arcade Volleyball (video).
* výchozí zdrojový kód (zip je nutné rozbalit)
Proměnné stisknutoVlevoB
, stisknutoVpravoB
, stisknutoNahoruB
jsou už vytvořené a reagují na stisknutí kláves. To znamená, že se jejich hodnota změní z false
na true
ve chvíli kdy je klávesa stisknuta a změní se opačně, když je klávesa uvolněna.
Postup je tedy zkopírovat to, jak je řešena reakce na tyto proměnné hráče A (úplně na konci kódu) a adaptovat aby se to týkalo hráče B.
Pokud se nemám od čeho odrazit, neměl bych vyskočit. Jedno z možných řešení je v reakci na stisknutoNahoruA
použít funcki applyForce
s vyšší hodnotou, ale podmínit tím, že jsme na zemi - tedy že naše y souřadnice je >499
Protože by míč mohl vyletět pryč :)
Experimentujeme s hodnotami restitution
(odrazivost, mezi 0 a 1) a density
(hustota → hmotnost)
var ball = Bodies.circle(400, 0, 40, { render: { fillStyle: '#999999' } }); Composite.add(engine.world, [ball]); Matter.Body.setDensity(ball, 0.0005) ball.restitution = 0.5
Kód s 1-4:
<!DOCTYPE html> <html lang="cs"> <head> <meta charset="utf-8" /> <title>Hra</title> <style> </style> <script src="matter.js"></script> </head> <body> <script> /* <![CDATA[ */ // z https://github.com/liabru/matter-js/wiki/Getting-started // (modifikovano) // module aliases var Engine = Matter.Engine, Render = Matter.Render, Runner = Matter.Runner, Bodies = Matter.Bodies, Composite = Matter.Composite; // create an engine var engine = Engine.create(); // create a renderer var render = Render.create({ element: document.body, engine: engine, options: { background: '#ffffff', wireframes: false } }); // Dva hraci var playerA = Bodies.circle(200, 530, 80, { render: { fillStyle: '#ff0000' } }); var playerB = Bodies.circle(600, 530, 80, { render: { fillStyle: '#009900' } }); Composite.add(engine.world, [playerA, playerB]); // Zeme var ground = Bodies.rectangle(400, 610, 810, 60, { isStatic: true }); Composite.add(engine.world, [ground]); // Strop var ceil = Bodies.rectangle(400, 0, 810, 20, { isStatic: true }); Composite.add(engine.world, [ceil]); // Zdi vlevo a vpravo var wallA = Bodies.rectangle(0, 310, 10, 610, { isStatic: true }); var wallB = Bodies.rectangle(800, 310, 10, 610, { isStatic: true }); Composite.add(engine.world, [wallA, wallB]); // Sit var net = Bodies.rectangle(400, 460, 10, 300, { isStatic: true }); Composite.add(engine.world, [net]); var ball = Bodies.circle(400, 0, 40, { render: { fillStyle: '#999999' } }); Matter.Body.setDensity(ball, 0.0005) ball.restitution = 0.5 Composite.add(engine.world, [ball]); // run the renderer Render.run(render); // create runner var runner = Runner.create(); // run the engine Runner.run(runner, engine); /* Klavesy */ stisknutoVlevoA = false stisknutoVpravoA = false stisknutoNahoruA = false stisknutoVlevoB = false stisknutoVpravoB = false stisknutoNahoruB = false document.onkeydown = function (event) { if (event.keyCode == 65) { // A stisknutoVlevoA = true } else if (event.keyCode == 87) { // W stisknutoNahoruA = true } else if (event.keyCode == 68) { // D stisknutoVpravoA = true } else if (event.keyCode == 37) { // sipka vlevo stisknutoVlevoB = true } else if (event.keyCode == 39) { // sipka vpravo stisknutoVpravoB = true } else if (event.keyCode == 38) { // sipka nahoru stisknutoNahoruB = true } } document.onkeyup = function (event) { if (event.keyCode == 65) { // A stisknutoVlevoA = false } else if (event.keyCode == 87) { // W stisknutoNahoruA = false } else if (event.keyCode == 68) { // D stisknutoVpravoA = false } else if (event.keyCode == 37) { // sipka vlevo stisknutoVlevoB = false } else if (event.keyCode == 39) { // sipka vpravo stisknutoVpravoB = false } else if (event.keyCode == 38) { // sipka nahoru stisknutoNahoruB = false } } setInterval(function () { if (stisknutoVlevoA) { Matter.Body.applyForce(playerA, playerA.position, { x: -0.1, y: 0 }) } if (stisknutoVpravoA) { Matter.Body.applyForce(playerA, playerA.position, { x: 0.1, y: 0 }) } if (stisknutoNahoruA) { if(playerA.position.y > 499){ Matter.Body.applyForce(playerA, playerA.position, { x: 0, y: -0.9 }) } } if (stisknutoVlevoB) { Matter.Body.applyForce(playerB, playerB.position, { x: -0.1, y: 0 }) } if (stisknutoVpravoB) { Matter.Body.applyForce(playerB, playerB.position, { x: 0.1, y: 0 }) } if (stisknutoNahoruB) { if(playerB.position.y > 499){ Matter.Body.applyForce(playerB, playerB.position, { x: 0, y: -0.9 }) } } }, 30) /* ]]> */ </script> </body> </html>