我做了一个chip8仿真器,但是在绘制时遇到了一些检测碰撞的问题。 Chip8通过将各个像素异或到屏幕上并在像素关闭时设置标志来吸引屏幕。我的代码如下:

_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,则为ON;在像素为0时,像素为ON。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中查找实现。

最佳答案

我找到了这个网站:http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter,它详细解释了如何编写Chip-8解释器。从那以及CHIP-8上的Wikipedia文章,我认为您的例程应为:

_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,并仅在发生碰撞时进行设置。

09-25 18:47