作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Node 服务器上托管 NES 模拟器 ( JSNES )。我知道您可以使用 unpkg 将 JSNES 嵌入网页中,但我希望它在服务器上运行,因为我希望多个客户端共享相同的状态。我编写复制代码在服务器上运行模拟器(有效)并将帧缓冲区发送到客户端作为对 GET 请求的响应(也有效),最后在 Canvas 。我可以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>
游戏.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();
服务器.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,
...
}
最佳答案
当您在服务器端的 Uint8ClampedArray
实例上调用 JSON.stringify()
时,它将被序列化为 JS 对象,即使人们希望它是数组。
const data = new Uint8ClampedArray(3);
data.set([1,2,3]);
const json = JSON.stringify(data);
JSON
{
"0":1,
"1":2,
"2":3
}
当您在客户端使用 JSON.parse()
反序列化它时,您会获得 JS 对象并尝试将其传递给 ImageData.data.set()
。
ImageData.data
是 Uint8ClampedArray它期望将一个数组传递给它的 set()
方法,但是当您传递一个对象时,它会默默地忽略它。
你可以
使用 Array.from 将帧缓冲区转换为服务器端的数组然后序列化它:
const data = new Uint8ClampedArray(3);
data.set([1,2,3]);
const dataArray = Array.from(data);
const json = JSON.stringify(dataArray);
// response.send(json);
JSON
[1,2,3]
或者在客户端将反序列化对象转换为数组
const dataArray = Object.values(response);
image.data.set(dataArray);
关于javascript - 使用 `CanvasRenderingContext2D.putImageData()` 时出现白屏,即使数据似乎包含图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61109608/
我是一名优秀的程序员,十分优秀!