Home >Web Front-end >JS Tutorial >How to write simulator with JS

How to write simulator with JS

php中世界最好的语言
php中世界最好的语言Original
2018-03-10 15:29:153945browse

This time I will show you how to write a simulator with JS, and what are the precautions for writing a simulator with JS. The following is a practical case, let's take a look.

0x00 Introduction to CHIP8

We can learn from the CHIP8 Wiki that CHIP8 is an interpretive

programming language. It was first used in the mid-1970s. The CHIP8 program runs in the CHIP8 virtual machine, and its emergence has made video game programming simpler (compared to that era). Electronic games implemented with CHIP8 include Bee, Tetris, Pac-Man, etc. You can go to CHIP8’s Wiki to learn more.

0x01 Create CHIP8 object

We assume that CHIP8 is composed of processor, keyboard, display screen and speaker, where CPU is the core of CHIP8, then the code should be like this:

<!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 Writing a simple display screen

According to the CHIP8 Wiki, we can learn that the CHIP8 display resolution is 64X32 pixels and is monochrome. If a pixel is 1, the corresponding pixel will be displayed on the screen, and if it is 0, it will not be displayed. However, when a certain pixel changes from presence to absence, the carry flag is set to 1, which can be used for collision detection.

Then the code should look like this:

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];
    }
};

After writing the display module, we write the display screen to test the display module (view the screen test online):

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 Write the speaker

You need to refer to Web APIs here:

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

Example https://mdn.github.io/violent-theremin/

Example https://codepen.io/gregh/pen/LxJEaj

The speaker is also very 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;
        }
    }
};

After writing the speaker, we can test the speaker (view the speaker test online):

<!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 ? &#39;停止&#39; : &#39;播放&#39;;            if (!isPlay) chip8.speaker.stop();            else chip8.speaker.play(f.value);
        };    </script></body></html>

I believe you have mastered the method after reading the case in this article , for more exciting content, please pay attention to other related articles on the php Chinese website!


Related reading:

Detailed explanation of string templates in ES6

Detailed explanation of scope and declaration of variables in ES6

How to use plug-in tools to convert ES6 code into ES5

The above is the detailed content of How to write simulator with JS. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn