Я пытаюсь разместить эмулятор NES ( JSNES ) на сервере Node. Я знаю, что вы можете встроить JSNES в веб-страницу с помощью команды unpkg, но я хочу, чтобы она работала на сервере, потому что я хочу, чтобы несколько клиентов имели одно и то же состояние. Я написал скопировал код для запуска эмулятора на сервере (который работал) и отправки буферов кадров клиенту в ответ на запросы GET (что также работало) и, наконец, для отображения этого буфера кадров на холсте , Я могу console.log
данные изображения, и они выглядят правильно (под «выглядит правильно» я имею в виду, что они содержат в основном черные пиксели с несколькими элементами в середине изображения), но все, что я получаю, это белый экран. Кто-нибудь может определить, что я делаю неправильно?
index. html:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Example</title>
</head>
<body>
<div style="">
<canvas id="canvas" width="256" height="240" style="border: 1px solid black;"/>
</div>
<script type="text/javascript" src="game.js"></script>
</body>
</html>
game. js
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var image = context.getImageData(0, 0, 256, 240);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(this.responseText);
console.log(response);
console.log(Object.keys(response).length);
image.data.set(response);
context.putImageData(image, 0, 0);
}
};
xhttp.open("GET", "data", true);
xhttp.send();
server. js
const fs = require('fs');
var express = require('express');
var jsnes = require('jsnes');
var path = require('path');
var app = express();
var SCREEN_WIDTH = 256;
var SCREEN_HEIGHT = 240;
var FRAMEBUFFER_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT;
var buffer = new ArrayBuffer(FRAMEBUFFER_SIZE);
var framebuffer_u8 = new Uint8ClampedArray(buffer);
var framebuffer_u32 = new Uint32Array(buffer);
var nes = new jsnes.NES({
onFrame: function(framebuffer_24) {
for (var i = 0; i < FRAMEBUFFER_SIZE; i++) framebuffer_u32[i] = 0xFF000000 | framebuffer_24[i];
},
});
var romData = fs.readFileSync('InterglacticTransmissing.nes', {
encoding: 'binary'
});
nes.loadROM(romData);
app.get('/', function(request, response) {
response.sendFile(path.join(__dirname, 'index.html'));
console.log('/');
});
app.get('/game.js', function(request, response) {
response.sendFile(path.join(__dirname, 'game.js'));
console.log('/game');
});
app.get('/data', function(request, response) {
response.setHeader('Content-Type', 'application/json');
response.send(JSON.stringify(framebuffer_u8));
console.log('/data');
});
setInterval(function() {
nes.frame();
}, 1000 / 60);
app.listen(3000);
Вывод (я удалил много данных, потому что они вызывали проблемы с веб-страницей):
{
"0": 0,
"1": 0,
"2": 0,
"3": 255,
"4": 0,
"5": 0,
"6": 0,
"7": 255,
"8": 0,
"9": 0,
"10": 0,
"11": 255,
"12": 0,
"13": 0,
"14": 0,
"15": 255,
"16": 0,
"17": 0,
"18": 0,
"19": 255,
"20": 0,
"21": 0,
"22": 0,
"23": 255,
"24": 0,
"25": 0,
"26": 0,
"27": 255,
"28": 0,
"29": 0,
"30": 0,
"31": 255,
"32": 0,
"33": 0,
"34": 0,
"35": 255,
"36": 0,
"37": 0,
"38": 0,
"39": 255,
"40": 0,
"41": 0,
"42": 0,
"43": 255,
"44": 0,
"45": 0,
"46": 0,
"47": 255,
"48": 0,
"49": 0,
"50": 0,
"51": 255,
"52": 0,
"53": 0,
"54": 0,
"55": 255,
"56": 0,
"57": 0,
"58": 0,
"59": 255,
"60": 0,
"61": 0,
"62": 0,
"63": 255,
"64": 0,
"65": 0,
"66": 0,
"67": 255,
"68": 0,
"69": 0,
"70": 0,
"71": 255,
"72": 0,
"73": 0,
"74": 0,
"75": 255,
"76": 0,
"77": 0,
"78": 0,
"79": 255,
"80": 0,
"81": 0,
"82": 0,
"83": 255,
"84": 0,
"85": 0,
"86": 0,
"87": 255,
"88": 0,
"89": 0,
"90": 0,
"91": 255,
"92": 0,
"93": 0,
"94": 0,
"95": 255,
"96": 0,
"97": 0,
"98": 0,
"99": 255,
"100": 0,
"101": 0,
"102": 0,
"103": 255,
"104": 0,
"105": 0,
"106": 0,
"107": 255,
"108": 0,
"109": 0,
"110": 0,
"111": 255,
"112": 0,
"113": 0,
"114": 0,
"115": 255,
"116": 0,
"117": 0,
"118": 0,
"119": 255,
"120": 0,
"121": 0,
"122": 0,
"123": 255,
"124": 0,
"125": 0,
"126": 0,
"127": 255,
"128": 0,
"129": 0,
"130": 0,
"131": 255,
"132": 0,
"133": 0,
"134": 0,
"135": 255,
"136": 0,
"137": 0,
"138": 0,
"139": 255,
"140": 0,
"141": 0,
"142": 0,
"143": 255,
"144": 0,
"145": 0,
"146": 0,
"147": 255,
"148": 0,
"149": 0,
"150": 0,
"151": 255,
"152": 0,
"153": 0,
"154": 0,
"155": 255,
"156": 0,
"157": 0,
"158": 0,
"159": 255,
"160": 0,
"161": 0,
"162": 0,
"163": 255,
"164": 0,
"165": 0,
"166": 0,
"167": 255,
"168": 0,
"169": 0,
"170": 0,
"171": 255,
"172": 0,
"173": 0,
"174": 0,
"175": 255,
"176": 0,
"177": 0,
"178": 0,
"179": 255,
"180": 0,
"181": 0,
"182": 0,
"183": 255,
"184": 0,
"185": 0,
"186": 0,
"187": 255,
"188": 0,
"189": 0,
"190": 0,
"191": 255,
"192": 0,
"193": 0,
"194": 0,
"195": 255,
"196": 0,
"197": 0,
"198": 0,
"199": 255,
"200": 0,
"201": 0,
"202": 0,
"203": 255,
"204": 0,
"205": 0,
"206": 0,
"207": 255,
"208": 0,
"209": 0,
"210": 0,
"211": 255,
"212": 0,
"213": 0,
"214": 0,
"215": 255,
"216": 0,
"217": 0,
"218": 0,
"219": 255,
"220": 0,
"221": 0,
"222": 0,
"223": 255,
"224": 0,
"225": 0,
"226": 0,
"227": 255,
...
"17670": 0,
"17671": 255,
"17672": 0,
"17673": 0,
"17674": 0,
"17675": 255,
"17676": 0,
"17677": 0,
"17678": 0,
"17679": 255,
"17680": 0,
"17681": 0,
"17682": 0,
"17683": 255,
"17684": 0,
"17685": 0,
"17686": 0,
"17687": 255,
"17688": 0,
"17689": 0,
"17690": 0,
"17691": 255,
"17692": 0,
"17693": 0,
"17694": 0,
"17695": 255,
"17696": 0,
"17697": 0,
"17698": 0,
"17699": 255,
"17700": 0,
"17701": 0,
"17702": 0,
"17703": 255,
"17704": 64,
"17705": 24,
"17706": 0,
"17707": 255,
"17708": 64,
"17709": 24,
"17710": 0,
"17711": 255,
"17712": 177,
"17713": 84,
"17714": 0,
"17715": 255,
"17716": 64,
"17717": 24,
"17718": 0,
"17719": 255,
"17720": 247,
"17721": 180,
"17722": 0,
"17723": 255,
"17724": 177,
"17725": 84,
"17726": 0,
"17727": 255,
"17728": 177,
"17729": 84,
"17730": 0,
"17731": 255,
"17732": 247,
"17733": 180,
"17734": 0,
"17735": 255,
"17736": 247,
"17737": 180,
"17738": 0,
...
}