Cette fois je vais vous montrer comment utiliser JS pour écrire un simulateur. Quelles sont les précautions pour écrire un simulateur en JS Voici un cas pratique, jetons un oeil.
0x00 Introduction à CHIP8
Nous pouvons apprendre du wiki CHIP8 que CHIP8 est un langage de programmation interprété. Sa première utilisation remonte au milieu des années 1970. Le programme CHIP8 s'exécute dans la machine virtuelle CHIP8 et son émergence a simplifié la programmation des jeux vidéo (par rapport à cette époque). Les jeux électroniques implémentés avec CHIP8 incluent Bee, Tetris, Pac-Man, etc. Vous pouvez en savoir plus sur le wiki de CHIP8.
0x01 Créer un objet CHIP8
Nous supposons que CHIP8 est composé d'un processeur, d'un clavier, d'un écran et d'un haut-parleur, où le CPU est le cœur de CHIP8, alors le code devrait être comme ceci :
<!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 Écriture d'un écran d'affichage simple
Selon le Wiki CHIP8, on peut apprendre que la résolution d'affichage du CHIP8 est de 64X32 pixels et est monochrome. Si un pixel vaut 1, le pixel correspondant sera affiché à l'écran, et s'il vaut 0, il ne sera pas affiché. Cependant, lorsqu'un certain pixel passe de la présence à l'absence, l'indicateur de retenue est défini sur 1, ce qui peut être utilisé pour la détection de collision.
Ensuite, le code devrait ressembler à ceci :
function Screen() { this.rows = 32;//32行 this.columns = 64;//64列 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]; } };
Après avoir écrit le module d'affichage, nous écrivons l'écran d'affichage pour tester le module d'affichage (voir le test d'écran en ligne) :
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 Écrivez l'orateur
Vous devez vous référer aux API Web ici :
API https://developer.mozilla.org/en-US/docs/Web/API/AudioContext API https://developer.mozilla.org/en-US/docs/Web/API/OscillatorNode
Exemple https://mdn.github.io/violent-theremin/
Exemple https://codepen.io/ gregh/pen/LxJEaj
Le haut-parleur est également très simple :
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; } } };
Après avoir écrit le haut-parleur, on peut tester le haut-parleur (voir le test du locuteur en ligne) :
<!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>
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web PHP chinois !
Lecture connexe :
Explication détaillée des modèles de chaînes dans ES6
Explication détaillée de la portée et de la déclaration des variables dans ES6
Comment utiliser les outils plug-in pour convertir le code ES6 en ES5
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!