Вот такая луна получилась у меня после 20 минут рисования в Inkscape. Конечно невесть что, но для начала сойдёт. Эта луна будет у меня летать в компании таких же.
Phaser
меня заинтересовал, продолжаю его изучать. На этот раз я хотел сделать несколько сталкивающихся шариков, движение которых никогда не затухает. Делать просто шары с отладочной графикой неитересно, да и смотреть на это никто не будет, а так вроде и картинка получилась.
Итак, чего я хотел:
- игровой мир, в котором летают шарики;
- движение никогда не должно останавливаться;
- по клику - ставить на паузу.
Вот и все нехитрые требования.
Сделать шарики несложно, достаточно просто создать объект и установить тип для body:
moon.body.setCircle(radius);
Самым сложным оказалось организовать вечное движение. Дело в том, что при столкновении скорость движения затухает, а мне этого хотелось избежать. Поначалу я искал возможность выставить минимальную скорость у объекта или какой-нибудь постоянный импульс, но не нашёл. Потом хотел в update
корректировать скорость, т.е. вычислять направление, а потом вычислять новый вектор скорости. Но с этим тоже не задалось, картинка всё время дёргалась. В конце концов нужного мне поведения добился, установив упругость в 1, т.е. при столкновениях с грацицами и между лунами, не происходит потеря энергии, это меня устроило:
var moonMaterial = game.physics.p2.createMaterial('moonMaterial'); var worldMaterial = game.physics.p2.createMaterial('worldMaterial'); var moon2worldCcontactMaterial = game.physics.p2.createContactMaterial( moonMaterial, worldMaterial, { restitution: 1.0 }); var moon2moonContactMaterial = game.physics.p2.createContactMaterial( moonMaterial, moonMaterial, { restitution: 1.0 }); game.physics.p2.setWorldMaterial(worldMaterial);
Ну а выставлять на паузу по клику и вовсе просто:
game.paused = !game.paused;
Вот что получилось в итоге:
Исходник bouncingmoons.js:
(function() { var onPreload = function() { game.load.image('moon', 'moon.png'); }; var onCreate = function() { game.stage.backgroundColor = '#373e48'; game.physics.startSystem(Phaser.Physics.P2JS); game.physics.p2.gravity.y = 0; game.physics.p2.friction = 0; game.physics.p2.applyDamping = false; var moonMaterial = game.physics.p2.createMaterial('moonMaterial'); var worldMaterial = game.physics.p2.createMaterial('worldMaterial'); var moon2worldCcontactMaterial = game.physics.p2.createContactMaterial( moonMaterial, worldMaterial, { restitution: 1.0 }); var moon2moonContactMaterial = game.physics.p2.createContactMaterial( moonMaterial, moonMaterial, { restitution: 1.0 }); game.physics.p2.setWorldMaterial(worldMaterial); var maxMoonsNumber = 5; var maxVelocity = 400; var moons = game.add.group(); for(var i = 0; i < maxMoonsNumber; i++) { var moon = moons.create(50 + 110 * i, 100, 'moon'); game.physics.p2.enable(moon); var scale = 0.3 + 0.05 * i; moon.scale = {x: scale, y: scale}; moon.body.setCircle(60 * scale); moon.damping = 0; moon.angularDamping = 0; moon.body.velocity.x = Math.floor(Math.random() * maxVelocity + 1); moon.body.velocity.y = Math.floor(Math.random() * maxVelocity + 1); moon.body.setMaterial(moonMaterial); } game.input.onDown.add(onClick, this); }; var onClick = function() { game.paused = !game.paused; }; var WIDTH = $(window).width(); var HEIGHT = $(window).height(); var game = new Phaser.Game( WIDTH, HEIGHT, Phaser.CANVAS, '', {preload: onPreload, create: onCreate}); })();
index.html:
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>moons</title> <style type="text/css" media="all"> * { margin: 0; padding: 0; } </style> </head> <body> <script src="jquery.min.js" type="text/javascript" charset="utf-8"></script> <script src="phaser.min.js" type="text/javascript" charset="utf-8"></script> <script src="bouncingmoons.js" type="text/javascript" charset="utf-8"></script> </body> </html>