Обнаружение столкновений на эмуляторе chip8

Я сделал эмулятор chip8, но столкнулся с некоторыми проблемами при обнаружении столкновений при рисовании. Chip8 рисует на экране, делая XOR'ом отдельные пиксели на экране и устанавливая флаг, если пиксель выключен. Мой код выглядит следующим образом:

_DXYN: function(X, Y, N) {
    console.log("_DXYN");

    for (var i = 0; i < N; i++) {
        for (var j = 0; j < 8; j++) {
            var bitBefore = graphics[(i + cpu.registers.V[Y]) * 64 + j + cpu.registers.V[X]];
            var bitAfter = bitBefore ^ cpu.getBits(memory[cpu.registers.I + i])[j];
            graphics[(i + cpu.registers.V[Y]) * 64 + j + cpu.registers.V[X]] = bitAfter;

            if ((bitBefore != bitAfter) && bitBefore == 1)
                cpu.registers.V[0xF] = 0x1;
            else
                cpu.registers.V[0xF] = 0x0;
        }
    }
}

graphics является одномерным массивом целых, каждый из которых соответствует пикселю на экране. Пиксель включен, если его соответствующее целое число в массиве равно 1, а выключено - 0. cpu Объект содержит все методы, включая этот, а также регистры. X параметр кода операции для регистра, который содержит координату x спрайта для рисования, и Y параметр кода операции для регистра с координатой y I регистр - это место в памяти для чтения. cpu.getBits Функция выглядит следующим образом:

getBits: function(opcode) {
    var bits = [];
    for (var i = 0; i < 8; i++) {
        bits.push((opcode >> i) & 1)
    }
    return bits.reverse();
}

Полный код можно найти на github здесь: https://github.com/ichub/Chip8 Посмотрите в chip8cpu.js для реализации.

1 ответ

Решение

Я нашел этот веб-сайт: http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter который подробно объясняет, как написать интерпретатор Chip-8. Исходя из этого и статьи из Википедии на ЧИП-8, я думаю, что ваша рутина должна быть следующей:

_DXYN: function(X, Y, N) {
    console.log("_DXYN");

    cpu.registers.V[0xF] = 0x0;
    for (var i = 0; i < N; i++) { // rows of the sprite
        for (var j = 0; j < 8; j++) {
            var bitBefore = graphics[(i + cpu.registers.V[Y]) * 64 + j + 
                            cpu.registers.V[X]];
            var bitAfter = bitBefore ^ cpu.getBits(memory[cpu.registers.I + i])[j];
            graphics[(i + cpu.registers.V[Y]) * 64 + j + cpu.registers.V[X]] = bitAfter;

            if ((bitBefore != bitAfter) && bitBefore == 1)
                cpu.registers.V[0xF] = 0x1;
        }
    }
}

В вашей программе VF очищается на каждом пикселе, если нет столкновения, поэтому его значение зависит только от последнего нарисованного пикселя. Вы должны очистить VF перед началом рисования и устанавливать его только при столкновении.

Другие вопросы по тегам