Kliknij na obrazek powyżej, by dodać obiekt.

Zabawny eksperyment z enginem fizyki w JavaScript


Eksperyment, który widzisz powyżej być może jest zupełnie bezcelowy, ale jest to interesujące piętnastominutowe ćwiczenie programistyczne owocujące czymś, co fajnie się ogląda przez piętnaście sekund.

Jeżeli nadal to czytasz, to widocznie uznałeś ten stosunek za akceptowalny, więc przeanalizujmy kod.

Użyjemy świetnego engine fizyki Matter.js.

Linie [1-20] to tylko standardowe odpalenie Matter.js.
[26-45] główna funkcja animacji, która obraca prostokąty [21-26] i przesuwa półkę do góry [28-32] lub w dół [33-36], jeżeli dotarła ona na szczyt .

[29-30] określ kierunek obrotu (zgodnie lub przeciwnie do obrotu zegara). Byłoby prościej napisać if (i < rectangles.length / 2), ale to nie zadziała, jeżeli zwiększysz liczbę wierszy obracających się prostokątów (spróbuj zmienić 4 na 6 w [65]).
[47-55] dodaj nowe koło lub kwadrat (50% prawodopodobieństwa) po każdym kliknięciu.
[57-91] stwórz świat:
[57-64] poziome półki
[65-74] obracające się prostokąty
[79-83] klocek, który pozwala obiektom ześlizgnąć się na półki
[84-86] wysoka pionowa ściana
[87-89] skośny klocek, który spycha obiekty z półki




<html>
<body>
<script src = 'matter.min.js'> </script
<script>
let Engine = Matter.Engine,
  Render = Matter.Render,
  World = Matter.World,
  Bodies = Matter.Bodies,
  Body = Matter.Body;
let engine = Engine.create();
let render = Render.create({
  elementdocument.body,
  engineengine,
  options: {
    wireframesfalse
  }
});
let world = engine.world;
Engine.run(engine);
Render.run(render);
 
const width = 50,
  height = 10,
  gap = 100;
 
function animate() {
  let direction;
  for (let i = 0i < rectangles.lengthi++) {
    if (Math.floor(i / 20) % 2direction = -1;
    else direction = 1;
    Body.rotate(rectangles[i], direction * .05)
  };
 
  for (let i = 0i < shelves.lengthi++) {
    Body.translate(shelves[i], {
      x0,
      y: -1
    });
    if (shelves[i].position.y < 0Body.translate(shelves[i], {
      x0,
      y600
    });
  }
  window.requestAnimationFrame(animate);
}
 
let canvas = document.getElementById('myCanvas');
canvas.onclick = function() {
  let object;
  if (Math.random() > .5)
    object = Bodies.circle(200020)
  else
    object = Bodies.rectangle(20003030);
  World.add(engine.worldobject);
}
 
const rectangles = [];
let shelves = [];
for (let i = 0i < 4i++) {
  rectangle = Bodies.rectangle(50i * 150widthheight, {
    isStatictrue
  });
  shelves.push(rectangle);
}
for (let rows = 2rows < 4rows++)
  for (let i = 2i < 12i++) {
    let rectangle = Bodies.rectangle(i * width + gap * (rows % 2), rows * gapwidthheight, {
      isStatictrue
    });
    let rectangle2 = Bodies.rectangle(i * width + gap * (rows % 2), rows * gapheightwidth, {
      isStatictrue
    });
    rectangles.push(rectangle, rectangle2);
  }
 
World.add(worldshelves);
World.add(engine.worldrectangles);
 
World.add(engine.world, [
  Bodies.rectangle(12552010010, {
    isStatictrue,
    angle: -Math.PI * 0.14
  }),
  Bodies.rectangle(2030010600, {
    isStatictrue
  }),
  Bodies.rectangle(6510010010, {
    isStatictrue,
    angle: -Math.PI * 0.14
  }),
]);
 
window.requestAnimationFrame(animate);
 
</script></body></html>



Inne samouczki:

Fraktale - 25 linii JavaScript


Złudzenie optyczne - 18 linii


Sinus scroll - 30 linii


Gra "Angry Chickens"


Rozbiajanie muru kulą - 14 linii Python/Blender 3d


Efekt domino - 10 linii Python/Blender 3d


English version of this page