🎮 Вы когда-нибудь видели Лос-Анджелес в 4 утра?

внешний интерфейс
🎮 Вы когда-нибудь видели Лос-Анджелес в 4 утра?

написать впереди

Я помню, как первый раз смотрел НБА летом 1999. Когда я набирал учеников в тур школьной команды, я жил в ветхой гостинице, и группа людей окружила черно-белый телевизор. время, и я не понимал, почему команда была в туре.Большие братья здесь прыгали вверх и вниз, наблюдая за игрой.Я помню тот день, когда «Буллз» играли против «Сиксерс», а Джордан играл против Айверсона.

В 2002 году Яо Мин был избран на драфте №1 в НБА и стал обращать внимание на НБА, Яо Мина и «Хьюстон Рокетс». На самом деле я начал смотреть "Рокетс", когда учился в старших классах.Знания Новака,22 победы подряд,заклинание плей-офф,память всего школьного периода,не экзамен,не школьный цветок,а спрятанный под грудой учебники Motorola, прямая трансляция текста NBA портала мобильных телефонов 3G и якорь A Xing "BOOOOOOOOM BABY!!!".

10 лет пролетели в мгновение ока, а у меня давно не было возможности посмотреть полноценную игру после работы, я не мог поверить в новость об уходе Кобе в кругу друзей на второй день лунного нового года Я читал новости в течение дня.

Чувствуется молодость, и эпоха подошла к концу.

Keep going

Из-за эпидемии я не могу выйти на улицу, и я случайно обратился к картине, которую нарисовал друг, когда Коби вышел на пенсию.


Популярный иллюстратор: Hibernating Bear Works(чердак:xiangxdx.lofter.com/,Вейбо:Weibo.com/U/217898786…)

Поэтому я хотел написать простую игру-стрелялку, чтобы отдать дань уважения, и нашел друга, чтобы нарисовать новую версию материала.

Это игра, в которую мы будем играть сегодня:


Принцип игры

Во-первых, давайте разберемся с принципами разработки физических игр.

Физическая игра состоит из 2 частей:


Для физических вычислений нам обычно нужно использовать некоторые готовые физические движки,Такие какBox2d,P2.js,matter.jsЖдать

Рендеринг графики может использовать собственный холст или более мощный движок 2D-рендеринга Pixi.js, CreateJS и т. д.

Физический движок обычно отвечает только за симуляцию расчетов физического движения, а не за рендеринг графики.

Таким образом, размер пакета уменьшается, и в то же время становится более гибким сочетание различных методов рендеринга для завершения разработки игры.

Просто используйте физический движок, вы ничего не увидите в интерфейсе

Физический движок на самом деле представляет собой нечто вроде широко используемой библиотеки расчета функций плавности Tween.js.

основная концепция

Мы выбираем комбинацию MatterJS + PixiJS для реализации этой игры

MatterJS:brm.io/matter-js/

Pixi.js:pixijs.io/

Использование двух библиотек относится к официальному примеру DEMO, который здесь подробно не рассматривается.

Поймите несколько основных концепций, чтобы начать разработку игр

Материя создастWorldОн используется для имитации физического мира. Объекты, добавляемые в мир, обладают такими физическими свойствами, как гравитация, трение и столкновение. Мы называем эти объектыRigidbody(Твердое тело), ​​в Материи твердое тело делится на два типа: динамическое твердое тело (Dynamic Body) и статическое твердое тело (Static body).

PIXI создастStageвещи, используемые для рендеринга графики, сущности находятся в DOMcanvasnode, а графику, добавленную на холст, мы называемSprite(текстура)

Физическая игра — это отображение физического движка (виртуальной среды) на движок рендеринга (визуальную среду).


Необходимо убедиться, что физический движок и движок рендеринга используют одну и ту же систему координат.Некоторые физические движки (например, P2) отличаются от системы координат Pixi, и сначала необходимо выполнить глобальное преобразование координат.

начать разработку

Инициализировать физическую среду и среду рендеринга

var Engine = Matter.Engine.create()
var world = Engine.world                 // 物理环境

var canvas = document.getElementById('canvas')
var App = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    transparent: true
})
var stage = App.stage                   // 渲染环境
canvas.appendChild(App.view)

App.ticker.add((delta) => {
    // update()                         // 启动刷新器
});

Как упоминалось ранее, физический движок обычно не отвечает за рендеринг графики, и Matter предоставляет простой рендерер для отладки, так что мы можем легко увидеть твердое тело, созданное физическим движком, в виде каркаса, когда движок рендеринга не подключен.

var Render = Matter.Render
var render = Render.create({
  element: document.getElementById('physic'),
  engine: Engine,
  options: {
    width: window.innerWidth,    height: window.innerHeight
  }
})

Создание круглого твердого тела

var body = Bodies.circle(x, y, radius, {
    restitution: 0.7,    // 弹性系数
    density:0.05,        // 密度
    firction: 1          // 摩擦力
})

добавить вWorldсередина

World.add(world, body)

Запускаем движок и рендерер

Matter.Engine.run(engine)
Matter.Render.run(render)

Здесь мы завершили инициализацию физического движка и движка рендеринга и добавили в физический мир первое круглое твердое тело.ДЕМО:код спрей.IO/национальное непостоянство/спрей/W…

Создание карт

Создайте текстуру баскетбола с помощью PIXI

var sprite = PIXI.Sprite.from('...ball.png');    
sprite.anchor.set(.5)                             // 改变锚点至中心位置,方便定位
stage.addChild(sprite)                            // 贴图添加到渲染环境

Жесткая синхронизация тела и текстуры

Синхронизируйте карту привязки с положением твердого тела, углом поворота в обновлении

function update () {
    sprite.position.x = body.position.x
    sprite.position.y = body.position.y    
    sprite.rotation   = body.angle
}

После завершения синхронизации тестовый каркас твердого тела можно удалить.

var body = Bodies.circle(x, y, radius, {
    ...
    render: { visible: false }   // 关闭线框渲染
})


ДЕМО:код спрей.IO/национальное непостоянство/спрей/G…

Создать корзину

Хотя наш материал имеет небольшую перспективу, мы достигаем 2D-перспективы, поэтому области столкновения корзины нужно всего лишь задать 2 статических твердых тела на поперечном сечении.

ДЕМО:код спрей.IO/национальное непостоянство/спрей/иметь…

Здесь обратите внимание на разборку кольца на 2 части, чтобы баскетбольный мяч мог пройти через середину кольца.


Добавьте сети

В Материи есть несколько предустановленных комплексов, смонтированных вCompositesВ, таких как softbody (мягкое тело), ​​car (автомобиль), bridge (мост) и т. д., мы используем softbody для имитации сетей.

// 参数说明参照 https://brm.io/matter-js/docs/classes/Composites.html
var nets =  Composites.softBody(800, 240, 8, 5, 0, 0, false, 3.2, { 
    firction: 1,
    frictionAir: 0.08,
    render: { visible: false },
    collisionFilter: { group: Body.nextGroup(true) }
}, {
    render: { lineWidth: 2, strokeStyle: "#fff" },
    stiffness: 1.4
})

ДЕМО:код спрей.IO/национальное непостоянство/спрей/день…

стрелять в баскетбол

Установите линейную и угловую скорость баскетбольного мяча.

// 操作刚体的方法挂载在Matter.Body类上
Body.setVelocity(body, { x: 1, y: -1 });     // 设置线速度
Body.setAngularVelocity(body, -0.1);         // 设置角速度,使球轻微后旋

ДЕМО:код спрей.В/О/национальная бр/спрей/нет...

На этом простая 2D-стрелялка DEMO завершена.

добавить персонажа

Затем мы используем скелетную систему анимационного программного обеспечения, чтобы сделать анимацию стрельбы в Кобе.

Конкретный процесс производства анимации здесь подробно описываться не будет, и это относительно шлак.

Затем экспортируйте диаграмму последовательности png

Перетащите его в TexturePack, чтобы синтезировать спрайт, выберите формат кадра PIXI для экспорта и получите спрайт и файл конфигурации JSON.

Спрайт загрузки PIXI

App.loader.add('.../kobe.json').load(function(){
    const frames = [];

    for (let i = 1; i <= 37; i++) {
        const val = i < 10 ? `0${i}` : i;
        frames.push(PIXI.Texture.from(`kobe00${val}.png`));
    }
    var Kobe = new PIXI.AnimatedSprite(frames);
    Kobe.animationSpeed = 0.4;
    Kobe.loop = false
})

пройти черезKobe.play()играть в анимацию

ключевой вопрос

Когда я писал это, я столкнулся с проблемой: в процессе от удержания мяча до броска в прыжке баскетбол представляет собой анимацию, которая следует за ладонью, а после броска представляет собой динамическое твердое тело, как две части соединяются ?

Решение, о котором я думал в начале, заключалось в том, что последовательность анимации не включает баскетбол, а только действие сбрасывания, создавая твердое тело баскетбола, чтобы следовать положению ладони в анимации стрельбы.Попробовав это, я обнаружил, что это сложно синхронизируются, а процесс удержания мяча не был простой линейной траекторией. Скорость воспроизведения анимации броска и скорость движения баскетбольного мяча, контролируемая Tween, также не поддаются контролю

Второе решение состоит в том, чтобы завершить первую половину броска в прыжке с мячом в последовательности анимации, оставить пустой кадр при броске баскетбольного мяча и создать идентичное твердое тело баскетбольного мяча в момент, когда баскетбольный мяч исчезает, чтобы реализовать связь между виртуальным и реальным



ключевой код

Kobe.onFrameChange = (e) => {
    // 动画帧回调,e为当前播放帧索引
    if (e === 4) {
        // 第5帧篮球消失瞬间,创建刚体
        var body = Bodies.circle(...)
        World.add(world, body)        
        Body.setVelocity(body, { x: 10, y: -10 });  // 创建瞬间将球投出
        ...
    } 
}

полная версия

Добавьте некоторые звуковые эффекты, субтитры, оценки и рекомендации, чтобы улучшить детали взаимодействия.

Адрес полной версии:guowc.github.io/mamba/

наконец

Heros comes and go, but legends are forever.