视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
怎样用JS编写模拟器
2020-11-27 20:01:24 责编:小采
文档

这次给大家带来怎样用JS编写模拟器,用JS编写模拟器的注意事项有哪些,下面就是实战案例,一起来看一下。

0x00 CHIP8简介

我们根据CHIP8的Wiki可以了解到CHIP8是一种解释性的编程语言。最初被应用是在1970年代中期。CHIP8的程序运行在CHIP8虚拟机中,它的出现让电子游戏编程变得简单些了(相对于那个年代来说)。用CHIP8实现的电子游戏有,比如小蜜蜂,俄罗斯方块,吃豆人等。更多可以前往CHIP8的Wiki了解。

0x01 创建CHIP8对象

我们假设CHIP8是由处理器、键盘、显示屏与扬声器组成,其中CPU是CHIP8核心,那么代码应该像这样的:

<!DOCTYPE html><html><head> 
 <title>创建Chip8对象</title></head><body> 
 <script>
 (function () { function CPU() {/*...*/ }; function Screen() {/*...*/ }; function Keyboard() {/*...*/ }; function Speaker(){/*...*/ }; window.CHIP8 = function () { var c8 = new CPU();
 c8.screen = new Screen();
 c8.speaker = new Speaker();
 c8.input = new Keyboard(); return c8;
 };
 })(); </script></body></html>

0x02 编写简单的显示屏

根据CHIP8的Wiki可以了解到,CHIP8显示分辨率是X32的像素,并且是单色的。某像素点为1则屏幕上显示相应像素点,为0则不显示。但某个像素点由有到无则进位标识被设置为1,可以用来进行冲撞检测。
那么代码应该像这样:

function Screen() { this.rows = 32;//32行
 this.columns = ;//列
 this.resolution = this.rows * this.columns;//分辨率
 this.bitMap = new Array(this.resolution);//像素点阵
 this.clear = function () { this.bitMap = new Array(this.resolution);
 } this.render = function () { };//显示渲染
 this.setPixel = function (x, y) {//在屏幕坐标(x,y)进行计算与显示
 // 显示溢出处理
 if (x > this.columns - 1) while (x > this.columns - 1) x -= this.columns; if (x < 0) while (x < 0) x += this.columns; if (y > this.rows - 1) while (y > this.rows - 1) y -= this.rows; if (y < 0) while (y < 0) y += this.rows; //获取点阵索引
 var location = x + (y * this.columns); //反向显示,假设二值颜色黑白分别用1、0代表,那么值为1那么就将值设置成0,同理0的话变成1
 this.bitMap[location] = this.bitMap[location] ^ 1; return !this.bitMap[location];
 }
};

编写好显示模块我们编写显示屏来测试显示模块(在线查看屏幕测试):

var chip8 = CHIP8();
chip8.screen.render = function () {//自定义实现显示渲染
 var boxs = document.getElementById("boxs");
 boxs.innerHTML = ""; for (var i of this.bitMap) { var d = document.createElement("span");
 d.style = "width: 5px;height: 5px;float: left;";
 d.style.backgroundColor = i ? "#000" : "#fff";
 boxs.appendChild(d);
 }
};/** 测试 **/chip8.screen.setPixel(2, 2);//设置x,y坐标像素chip8.screen.render();
chip8.screen.setPixel(2, 2);//设置x,y坐标像素

0x03 编写扬声器

这里需要参考 Web APIs:

API https://developer.mozilla.org/en-US/docs/Web/API/AudioContext
API https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode

示例 https://mdn.github.io/violent-theremin/

示例 https://codepen.io/gregh/pen/LxJEaj

扬声器也十分简单:

function Speaker() { var contextClass = (window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext)
 , context
 , oscillator
 , gain; 
 if (contextClass) {
 context = new contextClass();
 gain = context.createGain();
 gain.connect(context.destination);
 } 
 //播放声音
 this.play = function (frequency) { //API https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode
 //示例 https://mdn.github.io/violent-theremin/
 if (context && !oscillator) {
 oscillator = context.createOscillator();
 oscillator.frequency.value = frequency || 440;//声音频率 
 oscillator.type = oscillator.TRIANGLE;//波形这里用的是三角波 查看示例:https://codepen.io/gregh/pen/LxJEaj
 oscillator.connect(gain);
 oscillator.start(0);
 }
 } 
 //停止播放
 this.clear = this.stop = function () { if (oscillator) {
 oscillator.stop(0);
 oscillator.disconnect(0);
 oscillator = null;
 }
 }
};

编写好扬声器我们可以对扬声器进行测试(在线查看扬声器测试):

<!DOCTYPE html><html><head> 
 <title>编写扬声器</title></head><body>
 频率: <input type="range" id="frequency" value="440" min="100" max="1000">
 <label id="showfv">(440)</label>
 <button id="play_btn">播放</button>
 <script>
 (function () { function CPU() {/*...*/ }; function Screen() {/*...*/ };//略...
 function Keyboard() {/*...*/ }; function Speaker() {/*...*/};//略...
 window.CHIP8 = function () { var c8 = new CPU();
 c8.screen = new Screen();
 c8.speaker = new Speaker();
 c8.input = new Keyboard(); return c8;
 };
 })(); var chip8 = CHIP8(); //=======
 var f = document.getElementById("frequency"); var isPlay = false; var play_btn = document.getElementById("play_btn");
 f.onchange = function () { var v = Number(this.value); document.getElementById("showfv").innerHTML = "(" + v + ")"; if (isPlay) {
 chip8.speaker.stop();
 chip8.speaker.play(v);
 }
 };
 play_btn.onclick = function () {
 isPlay = !isPlay; this.innerHTML = isPlay ? '停止' : '播放'; if (!isPlay) chip8.speaker.stop(); else chip8.speaker.play(f.value);
 }; </script></body></html>

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

相关阅读:

ES6的字符串模板详解

ES6的变量的作用域与声明详解

怎样利用插件工具将ES6的代码转化成ES5

下载本文
显示全文
专题