引言:学js有一段时间了,也写了一些小游戏,今天突然想起小时候玩的游戏机上的像素赛车就想用刚学的js基础写一下,像素赛车玩过的都知道很简单的一款游戏,其实最底下的赛车是不动的,动的只是随机从上往下的那些赛车,所以给人一种视觉上的效果说是底下的赛车一直在动

主要思路:先创建底下固定的赛车并且给绑定键盘事件使其能够自由移动,接下来创建移动的赛车,给它两个定时器,一个控制创建的速度,一个控制移动的速度,创建好之后就判断是否撞车撞了就GameOver就OK了,并且按下键盘上键的时候加速。这就是这个游戏的主要思路

具体实现:
首先布局这一块儿不多说主要说一下js部分(后面有源码)

1.游戏开始时点击开始游戏按钮让开始界面隐藏进入游戏界面,并且调用创建移动赛车的计时器,在调用计时器之前先调用一次创建的函数(因为计时器会在规定的秒数后才开始执行,游戏开始时让它先创建一个之后再开始调用计时器创建)

//游戏开始
var timeraaaa=2300;/*赛车创建的时间*/
startbtn.onclick = function() {
        createCar();
        Timer1=setInterval("createCar()", timeraaaa);
        gamestart.style.display = 'none';
    }

2.创建赛车并且使赛车移动,创建赛车时让赛车随机出现,随机出现需要一个随机函数,随机函数随机出赛车(赛车时绝对定位的)需要的left(提前写好赛车的位置并放到数组中位置)值,在创建时调用就可以了,赛车自己移动就需要用到一个定时器,没隔相应的时间改变其top值就可以了。并且在创建的函数中就开始记录分数并且判断游戏结束的情况。

//赛车出现的位置
var saicheArr = ['0px','150px', '300px'];

//随机函数取出赛车的位置
function rand() {
    return Math.floor(Math.random() * 3);/*将随机数返回*/
}
var speedTemp = 1;/*赛车移动的距离*/
//创建赛车
function createCar() {
    var cars = document.createElement('div');/*创建一个div*/
    cars.className = 'cars';/*调用css中写好的样式*/
    //赛车的形状用表格将它画出来
    cars.innerHTML = "<table> <tr><td></td><td class='tdds'></td><td></td></tr> <tr><td class='tdds'></td><td></td><td class='tdds'></td></tr> <tr><td></td><td class='tdds'></td><td></td></tr> <tr><td class='tdds'></td><td></td><td class='tdds'></td></tr></table>"
    //赛车的left值通过随机函数在数组中取出来
    cars.style.left = saicheArr[rand()];
    //将赛车的top值给为-200的目的是让它在游戏界面的上方开始创建
    cars.style.top = '-200px';
    wrap.appendChild(cars);
        //赛车移动
    cars.speed = -200;
    //赛车自己移动的方法  每5毫秒调用一次
    cars.Timer = setInterval(function() {
        cars.speed += speedTemp;
        cars.style.top = cars.speed + 'px';/*每次移动一个像素*/
        //当赛车出画布就将其删除掉
        if(cars.offsetTop > 800) {
            clearInterval(cars.Timer);/*清除其移动的函数*/
            wrap.removeChild(cars);/*在界面上删除赛车*/
            score += 1;
            fs.innerHTML = score;/*页面中的分数值加1*/
        }

        //判断游戏结束的情况
        if(car.offsetTop <= (cars.offsetTop + 200) && car.offsetLeft == cars.offsetLeft) {
            gameover();/*调用游戏结束的函数*/
        }
    }, 5)

}

3.通过键盘的上左右键来分别控制赛车的加速及移动,通过键码来判断相应的操作。这里需要注意按上键的时候不只是汽车移动速度变快还要让创建的速度也加快,并且上键按下不松是可以一直调用的,所以需要一个开关去控制让其只调用一次,按下的时候改赛车移动的距离,并且改创建的时间,键盘抬起的时候恢复到刚开始的状态。

var timeraaaa=2300;/*赛车创建的时间*/
var Timer1=null;/*赛车移动的计时器*/
var flag=true;/*键盘按下的开关*/
//键盘按下的事件
document.onkeydown = function() {
    var event = event|| window.event;
    var left = car.offsetLeft
    switch(event.keyCode) {
    //左键的情况
        case 37:
        //判断如果移除边界就让它的left变为0,没有出去的话每次向左移动150(赛车的宽度)个像素
            if(left == 0) {
                car.style.left = '0px';
            } else {

                car.style.left = left - 150 + 'px';
            }
            break;
            //右键的情况
        case 39:
        //判断如果移除边界就让它的left变为游戏界面的宽度,没有出去的话每次向右移动150(赛车的宽度)个像素
            if(left == 300) {
                car.style.left = '300px';
            } else {
                car.style.left = left + 150 + 'px';
            }
            break;
            //上键的情况
        case 38:
        //改变其移动的偏移量
            speedTemp = 3;
            //判断如果开关打开时
            if(flag) {
                clearInterval(Timer1);/*先清除赛车创建的计时器*/
                timeraaaa=850;/*然后改时间*/
                Timer1=setInterval("createCar()", timeraaaa);/*再次调用*/
                flag=false;/*将开关关闭只执行一次*/
            }           
            break;
    }
}

//松开键盘的事件
document.onkeyup = function() {
        var ev = event || window.event;
        //松开上键的时候
        if(ev.keyCode == 38) {
            speedTemp = 1;//移动的速度改为原来的状态
            clearInterval(Timer1);/*先清除赛车创建的计时器*/
            timeraaaa=2300;/*然后改时间*/
            Timer1=setInterval("createCar()", timeraaaa);/*再次调用*/
            flag=true;/*将开关打开*/
        }
    }

4.游戏结束时清除所有计时器并且将游戏结束的页面显示出来

//游戏结束
function gameover() {
    sc.innerHTML += score;/*显示分数*/
    gameOver.style.display = 'block';/*将游戏结束界面显示出来*/
    clearTimer();/*清除所有计时器*/
    //历史积分
    var historyScore = localStorage.getItem('his');
    if(historyScore == null || historyScore < score) {
    //本地缓存
        localStorage.setItem('his', score);
        historyScore = score;
    }
    his.innerHTML = historyScore;/*显示历史积分*/
}
//清除所有计时器
function clearTimer() {
    var timer = setInterval(function() {}, 30);
    for(var i = 0; i < timer; i++) {
        clearInterval(i);
    }
}

5.游戏结束界面再来一发按钮就是重新开始,重新开始嫌麻烦没做就直接刷新了页面,若大家有兴趣可以完善一下。

//重新开始
overbtn.onclick = function() {
        history.go('0');/*刷新页面*/
    }
    //键盘事件

到这里这个游戏就写完了,下面是HTML,CSS以及js的源码,注释没上面这么详细,若有不懂得可以留言24之内回复

1.HTML源码

<!DOCTYPE html>
<html>

    <head>
        <title></title>
        <meta charset="utf-8">
        <link rel="stylesheet" type="text/css" href="css/index.css" />
    </head>

    <body>
        <div class="wrap">
            <div class="fenshu">得分:
                <div class="fs">0</div>
            </div>
            <!--游戏开始界面-->
            <div class="gameStart">
                <div class="mes">经典赛车</div>
                <div class="stratbtn">
                    开始游戏
                </div>
            </div>
            <!--自己的车-->
            <div class="car">

            </div>
            <!--游戏结束界面-->
            <div class="gameOver">
                <div class="message">游戏结束</div>
                <div class="overbtn">再来一发</div>
                <div class="score">得 分:
                    <div class="sc"></div>
                </div>
                <div class="hisscore">历史最高:
                    <div class="his"></div>
                </div>
            </div>
        </div>
    </body>
    <script src="js/index.js" type="text/javascript" charset="utf-8"></script>

</html>

2.CSS源码

/*整个游戏环境的样式*/

            .wrap {
                width: 450px;
                height: 800px;
                border: 1px solid black;
                position: relative;
                margin: auto;
                overflow: hidden;
            }
            /*最底下赛车的样式*/

            .car {
                position: absolute;
                bottom: 0px;
                left: 150px;
            }
            /*创建的赛车样式*/

            .cars {
                position: absolute;
            }
            /*合并表格的边线*/

            table {
                border-collapse: collapse;
            }

            td {
                width: 48px;
                height: 48px;
            }
            /*底下赛车的样式*/

            .tdd {
                background: black;
            }
            /*创建并移动的赛车的样式*/

            .tdds {
                background: gray;
            }
            /*游戏开始界面的样式*/

            .gameStart {
                width: 450px;
                height: 800px;
                position: relative;
                text-align: center;
                background: rgba(0, 0, 0, 0.9);
                /*display: none;*/
            }
            /*开始界面文字的样式*/

            .mes {
                line-height: 500px;
                font-size: 5em;
                color: white;
            }
            /*开始按钮的样式*/

            .stratbtn {
                width: 180px;
                height: 50px;
                line-height: 50px;
                font-size: 1.6em;
                color: white;
                border: 1px solid black;
                position: absolute;
                top: 450px;
                left: 135px;
                cursor: pointer;
            }
            /*游戏结束页面的样式*/

            .gameOver {
                width: 450px;
                height: 800px;
                position: relative;
                text-align: center;
                background: rgba(0, 0, 0, 0.9);
                display: none;
                z-index: 999;
            }
            /*游戏结束页面文字的样式*/

            .message {
                line-height: 500px;
                font-size: 5em;
                color: white;
            }
            /*游戏结束按钮样式*/

            .overbtn {
                width: 180px;
                height: 50px;
                line-height: 50px;
                font-size: 1.6em;
                color: white;
                border: 1px solid black;
                position: absolute;
                top: 510px;
                left: 135px;
                cursor: pointer;
            }
            /*游戏结束页面的分数*/

            .score {
                width: 180px;
                height: 50px;
                font-size: 1.6em;
                color: white;
                border: 1px solid black;
                line-height: 50px;
                position: absolute;
                top: 350px;
                left: 135px;
                display: inline-block;
            }

            .sc {
                width: 80px;
                height: 48px;
                display: inline-block;
                vertical-align: top;
            }
            /*游戏结束页面的历史分数*/

            .hisscore {
                width: 180px;
                height: 50px;
                font-size: 1.6em;
                color: white;
                border: 1px solid black;
                line-height: 50px;
                position: absolute;
                top: 430px;
                left: 135px;
                display: inline-block;
            }

            .his {
                width: 43px;
                height: 48px;
                display: inline-block;
                vertical-align: top;
            }
            /*游戏界面的分数*/

            .fenshu {
                width: 450px;
                height: 50px;
                position: absolute;
                line-height: 50px;
                font-size: 1.8em;
                display: inline-block;
            }

            .fs {
                display: inline-block;
                color: red;
            }

3.JS源码

//获取所有用到的标签
var wrap = document.querySelector(".wrap");
var car = document.querySelector(".car");
var gamestart = document.querySelector(".gameStart")
var gameOver = document.querySelector(".gameOver")
var startbtn = document.querySelector(".stratbtn")
var overbtn = document.querySelector(".overbtn")
var sc = document.querySelector(".sc")
var his = document.querySelector(".his")
var fs = document.querySelector(".fs")
    //赛车用表格画
car.innerHTML = "<table> <tr><td></td><td class='tdd'></td><td></td></tr> <tr><td class='tdd'></td><td></td><td class='tdd'></td></tr> <tr><td></td><td class='tdd'></td><td></td></tr> <tr><td class='tdd'></td><td></td><td class='tdd'></td></tr></table>"
    //赛车出现的位置
var saicheArr = ['0px',
    '150px',
    '300px'
];
var speedTemp = 1; /*赛车移动的距离*/
var score = 0; /*分数*/
var timeraaaa = 2300; /*赛车创建的时间*/
var Timer1 = null; /*赛车移动的计时器*/
var flag = true; /*键盘按下的开关*/

//随机函数取赛车的位置
function rand() {
    return Math.floor(Math.random() * 3);
}

//      随机创建赛车
function createCar() {
    //  console.log(timer);
    var cars = document.createElement('div');
    cars.className = 'cars';
    cars.innerHTML = "<table> <tr><td></td><td class='tdds'></td><td></td></tr> <tr><td class='tdds'></td><td></td><td class='tdds'></td></tr> <tr><td></td><td class='tdds'></td><td></td></tr> <tr><td class='tdds'></td><td></td><td class='tdds'></td></tr></table>"

    cars.style.left = saicheArr[rand()];
    cars.style.top = '-200px';
    wrap.appendChild(cars);
    //赛车移动
    cars.speed = -200;
    cars.Timer = setInterval(function() {
        cars.speed += speedTemp;
        cars.style.top = cars.speed + 'px';
        if(cars.offsetTop > 800) {
            clearInterval(cars.Timer);
            wrap.removeChild(cars);
            score += 1;
            fs.innerHTML = score;
        }

        //判断游戏结束的情况
        if(car.offsetTop <= (cars.offsetTop + 200) && car.offsetLeft == cars.offsetLeft) {
            console.log('撞上了')
            gameover();
        }
    }, 5)

}
//游戏开始
startbtn.onclick = function() {
        createCar();
        Timer1 = setInterval("createCar()", timeraaaa);
        gamestart.style.display = 'none';
    }
    //重新开始
overbtn.onclick = function() {
        history.go('0');
    }
    //键盘事件
document.onkeydown = function() {
        var event = event || window.event;
        var left = car.offsetLeft
        switch(event.keyCode) {
            case 37:
                if(left == 0) {
                    car.style.left = '0px';
                } else {

                    car.style.left = left - 150 + 'px';
                }
                break;
            case 39:
                if(left == 300) {
                    car.style.left = '300px';
                } else {
                    car.style.left = left + 150 + 'px';
                }
                break;
            case 38:
                speedTemp = 3;
                if(flag) {
                    clearInterval(Timer1);
                    timeraaaa = 850;
                    Timer1 = setInterval("createCar()", timeraaaa);
                    flag = false;
                }
                console.log(timeraaaa);

                break;
        }
    }
    //松开键盘的事件
document.onkeyup = function() {
        var ev = event || window.event;
        if(ev.keyCode == 38) {
            speedTemp = 1;
            clearInterval(Timer1);
            timeraaaa = 2300;
            Timer1 = setInterval("createCar()", timeraaaa);
            flag = true;
        }
    }
    //游戏结束
function gameover() {
    sc.innerHTML += score;
    gameOver.style.display = 'block';
    clearTimer();
    //历史积分
    var historyScore = localStorage.getItem('his');
    if(historyScore == null || historyScore < score) {
        localStorage.setItem('his', score);
        historyScore = score;
    }
    his.innerHTML = historyScore;
}
//清除所有计时器
function clearTimer() {
    var timer = setInterval(function() {}, 30);
    for(var i = 0; i < timer; i++) {
        clearInterval(i);
    }
}

经本人测试没发现什么bug,若有人发现了bug请及时告知以及时修改,(还有就是不怎么美观,望见谅哈!!!)