Добрый вечер. Не буду томить и сразу начну.
Половину своей жизни мечтаю о своей игре, а именно, собственной Guitar Hero, с блэкджеком и песнями. Простую, браузерную, в которую можно играть как на телефоне, так и на ПК.
В бородатые времена, было что-то подобное, называлось Flash Guitar Hero. Написанная на флэше, в которую можно было играть на сайте, либо скачать себе на ПК и играть без интернета.
Казалось, я уже дорос до того, что бы написать игру. Но, спойлер - нет, не дорос.
И я не программист, кстати.
Продумав механику игры, как она должна работать, я сел себя мучать.
Есть midi-файл, распарсив его, я получаю очень много информации:
Сами ноты:
[
{
"durationTicks": 1, //длинна ноты
"midi": 96, //струна, на которой находится нота
"time": 2.016804 //секунда, на которой звучит нота
}, {
"durationTicks": 1,
"midi": 97,
"time": 2.016804
},
...
]
BPM:
[{
"bpm": 119, //bpm, собственно
"ticks": 0 //тик (он потом конвертируется в секунду), на которой меняется bpm
},
{
"bpm": 99,
"ticks": 768
},
...
]
Ну а дальше, дело за малым, я решил выбрать JQuery, так как немного понимаю его.
var notesJSON = "notes.json";
var bpmJSON = "bpm.json";
$.getJSON(notesJSON, {format: "json"}).done(function(data) {
$.each(data, function(index,value) {
var TimeToPX = value['time']*762+50; //конвертирую секунды в пиксели
var height = parseInt(value['durationTicks'])+parseInt(109);
$('.notes').append('<div class="note"></div>');
var notesHeight = $('.notes .note:last-child').attr('data-px');
$('.notes').css({'height': parseInt(notesHeight) + parseInt(50)+'px'});
});
});
Поясняю:
var TimeToPX //конвертирую секунды в пиксели (шизик, да)
var height //делаю высоту у нот
$.getJSON(bpmJSON, {format: "json"}).done(function(data) {
$.each(data, function(index,value) {
var ppq = 192;
var bpm = value['bpm'];
var bpmppq = bpm * ppq / 60;
var ticks = value['ticks'];
var speed = (289400 / bpm) *100;
var bpmtime = ticks / bpmppq;
song.addEventListener('timeupdate', function () {
var songStart = parseFloat(song.currentTime);
if (songStart > bpmtime) {
var notesHeight = $('.notes .note:last-child').attr('data-px');
var translate = parseInt(notesHeight) + parseInt(50);
$('.notes').animate({bottom: '-'+translate+'px'}, speed, 'linear');
}
}, false);
});
});
Тут все понятно. Все переменные для той самой конвертации тиков в секунды.
Переменная speed "прокручивает" блок с нотами в низ с той скоростью, которую мы распарсили из bpm.json. И которая меняется когда надо.
Так а что в итоге? А то, что, как я понимаю, JQuery не подходит для этого, на андроиде жутко все тормозит, как будто я запустил ПК-ашный Киберпанк на Редми 6. Но вот на Айосе тянет все отлично.
Вероятно, подойдет чистый жаваскрипт, без создания вот этих всех блоков (на каждую ноту отдельный див создается), возможно, с канвасом, и рисованием нот, но в нем я вообще дуб-дубом. Еще никогда так близко я не был к реализации своей мечты.
Если есть энтузиасты, помогите, пожалуйста. Или за донат на пиво с чипсонами. Можете себе забрать игру в конечном счете и монетизировать, я не против.
А можем вообще вместе ее доделать.
Живой пример того, что я сделал - http://z33376pn.beget.tech/gh/ - играть можно только на телефоне. Нажав на play в левом верхнем углу. Но посмотреть, как движутся ноты, можно на любом устройстве.
Пример другой игры на JS без тормозов:
https://github.com/jyschwrtz/JS-Hero
А вот пример того, что хочется получить в идеале:
https://github.com/henryzt/Rhythm-Plus-Music-Game