krouzek:arcade_volleyball

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)

1) Správně napojit ovládání druhého hráče.

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.

2) Klávesa nahoru výskok, ne let

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

3) Vytvořit strop nebo zvětšit stěny

Protože by míč mohl vyletět pryč :)

4) Zlepšit fyziku

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

5) Detekce kolize


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>
  • krouzek/arcade_volleyball.txt
  • Poslední úprava: 2023/11/15 20:54
  • autor: 127.0.0.1