html+js 实现 推箱子 贪吃蛇和简单的飞机大战

2022-07-29,,,,

推箱子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #app{

        }
        *{
            margin: 0;
            padding: 0;
        }
        #app span{
            width: 20px;
            height: 20px;
            display: inline-block;
        }
        .person{
          background:    red;
        }
        .kong{
            background: white;
        }
        .shitu{
            background: #8c8c8c;
        }
        .yellow{
            background: yellow;
        }
        .xiaozi{
            background: burlywood;
        }
        #context{
            position: absolute;
            right: 10%;
            top: 25%;
            font-size: 50px;
            color: #00FF00;
        }
    </style>
</head>
<body onkeydown="doKeyDown(event)">
<div id="app"></div>
<canvas id="canvas"></canvas>
<div id="context"></div>
</body>
<script>
    window.onload=function(){
        // let can = document.getElementById("canvas");
        // cxt=can.getContext("2d");
        load(levels[cuindex],true);
        //3 5  j  35 1
        //  let image = new Image();
        //  image.src="3.png";
        //  image.οnlοad=function (){
        //      cxt.drawImage(image,0,35,100,100);
        //  }

    }
    let x,y,flag=0,xian;//记录上一个值
    let maxcount,cucount=0;//最多的 值
    let cuindex=0;//当前关卡
    let conll;//克隆对象
    let map = new Map();
    let map2 = new Map();//食物 2,3
    map.set(0,"<span class=\"kong\"></span>");
    map.set(1,"<span class=\"shitu\"></span>");
    map.set(2,"<span class=\"yellow\"></span>");
    map.set(3,"<span class=\"xiaozi\"></span>");
    map.set(4,"<span class=\"person\"></span>");
    function dian(x,y,key) {
        let arr;
        switch (key) {
            case 37://左键头 0
                arr=[x,y-1];
                break;
            case 38://上键头 1
                arr=[x-1,y];
                break;
            case 39://右箭头 2
                arr=[x,y+1];
                break;
            case 40://下箭头 3
                arr=[x+1,y];
                break;
        }
        return arr;
    }
    function doKeyDown(event){
        if(event.keyCode%37<4){
        xian=event.keyCode;
        let dian1 = dian(x,y,xian);
       move(dian1[0],dian1[1]);

        }
    }
    function move(cx,cy) {
        //判断下一步的值是什么
       switch (levels[cuindex][cx][cy]) {
        case 0:
        case 2:
            //离开判断 是否上一个是我 现在的 位置是否是食物
            //x y
            flag=levels[cuindex][cx][cy];
            levels[cuindex][cx][cy]=4;
            if(map2.get(x+","+y))
                levels[cuindex][x][y]=2;
            else{
                if(flag!==2){
                    levels[cuindex][x][y]=flag;
                }else{
                    levels[cuindex][x][y]=0;
                }
            }
            x=cx;
            y=cy;
            load(levels[cuindex]);
            break;
            case 3 : //是箱子
                let a = dian(cx,cy,xian);
                switch (levels[cuindex][a[0]][a[1]]) {
                    case 0:
                    case 2:
                        //flag=levels[0][cx][cy]
                        if(levels[cuindex][a[0]][a[1]]===2){
                            cucount++;
                        }
                        //判断之前的是否为 箱子
                        if(map2.get(cx+","+cy)){
                            cucount--;
                        }
                        levels[cuindex][a[0]][a[1]]=3;
                        levels[cuindex][cx][cy]=4;
                        levels[cuindex][x][y]=flag;
                        x=cx;
                        y=cy;
                        load(levels[cuindex]);
                        break;
                }
                break;
       }
        if(cucount===maxcount){
            //替换
            levels[cuindex]=conll;
            load(levels[++cuindex],true);
        }
        else
            info();
    }
    function info() {
        document.getElementById("context").innerText="当前关卡"+cuindex+"完成了的"+cucount+"还有"+(maxcount-cucount);

    }
    function load(arr,flag){
        let byId = document.getElementById("app");
        byId.innerHTML="";
        if(flag) {//第一次 的参数设定
            conll=[arr.length];
            maxcount=0;
            cucount=0;
            map2.clear();
            info();
        }
       for (let i=0;i<arr.length;i++){
           byId.innerHTML+="<div>"
           for (let j=0;j<arr[i].length;j++){
               byId.innerHTML+=map.get(arr[i][j]);
               if(flag) {
                   if(!conll[i])
                   conll[i]=[];
                   conll[i][j]=arr[i][j];
               if(arr[i][j]===4){
                   x=i;
                   y=j;
               }
               if(arr[i][j]===2){
                   map2.set(i+","+j,true);
                       maxcount++;
                   }
               }
           }
           byId.innerHTML+="</div>"
       }
    }
    //地图
    let levels=[];
    levels[0]=[
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0],
        [0,0,0,0,1,1,1,3,0,3,2,1,0,0,0,0],
        [0,0,0,0,1,2,0,3,4,1,1,1,0,0,0,0],
        [0,0,0,0,1,1,1,1,3,1,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
    levels[1]=[
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,4,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,3,3,1,0,1,1,1,0,0,0],
        [0,0,0,0,1,0,3,0,1,0,1,2,1,0,0,0],
        [0,0,0,0,1,1,1,0,1,1,1,2,1,0,0,0],
        [0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0],
        [0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0],
        [0,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0],
        [0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];


    levels[2]=[
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0],
        [0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,0],
        [0,0,0,1,1,3,1,1,1,0,0,0,1,0,0,0],
        [0,0,0,1,0,4,0,3,0,0,3,0,1,0,0,0],
        [0,0,0,1,0,2,2,1,0,3,0,1,1,0,0,0],
        [0,0,0,1,1,2,2,1,0,0,0,1,0,0,0,0],
        [0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
    levels[3]=[
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,4,3,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,1,1,3,0,1,1,0,0,0,0,0,0],
        [0,0,0,0,1,1,0,3,0,1,0,0,0,0,0,0],
        [0,0,0,0,1,2,3,0,0,1,0,0,0,0,0,0],
        [0,0,0,0,1,2,2,5,2,1,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];

</script>
</html>

贪吃蛇

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #contie span{
            width: 20px;
            height: 20px;
            display: inline-block;
        }
        .person{
            background:    red;
        }
        .kong{
            background: #bce8f1;
        }
        .shitu{
            background: #8c8c8c;
        }
        .yellow{
            background: yellow;
        }
        .xiaozi{
            background: burlywood;
        }
        #context{
            position: absolute;
            right: 10%;
            top: 25%;
            font-size: 50px;
            color: #00FF00;
        }

    </style>
</head>
<body onkeydown="doKeyDown(event)">
<div id="contie">

</div>
</body>
<script>
    // 0 空白 1 为食物 2 为 蛇
    let arr=[];
    let max=9;
    let xiaosize=2;//小蛇长度
    let point=[{x:1,y:1},{x:1,y:2}];//小蛇点数 1.2 -->>>  1.1
    let eat={x:5,y:5};//食物位置
    let dom;//操作对象
    let postion=39;//方向
    let map = new Map();
    map.set(0,"<span class=\"kong\"></span>");
    map.set(1,"<span class=\"shitu\"></span>");
    map.set(2,"<span class=\"yellow\"></span>");
    initial();
    function initial() {
        dom=document.getElementById("contie");
        //初始化数据
        for (let i=0;i<max;i++){
            arr[i]=[];
            for (let j=0;j<max;j++)
                arr[i][j]=0;
        }
        for (let i=0;i<point.length;i++){
            arr[point[i].x][point[i].y]=2;
        }
        arr[eat.x][eat.y]=1;
        playgame();
    }
    function xuanyan() {
        dom.innerHTML="";
        for (let i=0;i<max;i++){
            for (let j=0;j<max;j++){
              dom.innerHTML+=map.get(arr[i][j]);
            }
            dom.innerHTML+="<br>";
        }
    }
    function playgame() {
        xuanyan();
        dom.hello=setInterval(function () {
            //清空上一次的坐标
                    arr[point[0].x][point[0].y]=0;
                //移动 根据方向 移动 只需要改变头和尾巴
            for (let i=0;i<point.length;i++){
                //交换 0<1<2
                // 1<2<3
                if(i+1<point.length){
                    point[i].x=point[i+1].x;
                    point[i].y=point[i+1].y;
                }else{
                    switch (postion) {
                        case 37:
                            point[xiaosize-1].y--;
                            break;
                        case 38:
                            point[xiaosize-1].x--;
                            break;
                        case 39:
                            point[xiaosize-1].y++;
                            break;
                        case 40:
                            point[xiaosize-1].x++;
                            break;
                    }
                    //监测是否碰撞到边缘
                    if(point[xiaosize-1].x<0||point[xiaosize-1].x>=max||point[xiaosize-1].y<0||point[xiaosize-1].y>=max){
                        clearInterval(dom.hello);
                        return   alert("撞墙了");
                    }
                    if(f(point[xiaosize-1].x,point[xiaosize-1].y,xiaosize-1)){
                        clearInterval(dom.hello);
                        return   alert("吃到自己了");
                    }

                }
            }
            //吃到eat ;
            if(arr[point[xiaosize-1].x][point[xiaosize-1].y]===1){
                point.push({x:0,y:0});
                //后移一位
                for (let i=xiaosize-1;i>=0;i--){
                 point[i+1].x=point[i].x;
                point[i+1].y=point[i].y;
                }
                xiaosize++;//添加长度
                //添加尾巴
              if(point[1].x===point[2].x){
                  point[0].x=point[1].x;
                  point[0].y= point[1].y<point[2].y?point[1].y-1:point[1].y+1;
              }else{
                  point[0].y=point[1].y;
                  point[0].x= point[1].x<point[2].x?point[1].x-1:point[1].x+1;
              }
              //重新生成食物并且不能在蛇里面
                do {
                    eat.x = parseInt(Math.random()*max);
                    eat.y = parseInt(Math.random()*max);
                } while(f(eat.x,eat.y))
                arr[eat.x][eat.y]=1;
                arr[point[0].x][point[0].y]=2;
                arr[point[xiaosize-1].x][point[xiaosize-1].y]=2;
            }else
                arr[point[xiaosize-1].x][point[xiaosize-1].y]=2;
                xuanyan();
        },300)
    }
    function doKeyDown(event){
        if(event.keyCode>36&&event.keyCode<41)
            postion=event.keyCode;
    }
    //判断x和y是否在蛇上
    function f(x,y,flag) {
        for (let i=0;i< (flag!=null?flag:point.length);i++) {
          if(point[i].x===x&&point[i].y===y)
              return true;
        }
        return  false;
    }

</script>
</html>

简单飞机大战

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>

        *{
            margin: 0;
            padding: 0;
        }
        #contie span{
            width: 20px;
            height: 20px;
            display: inline-block;
        }
        .person{
            background:    red;
        }
        .kong{
            background: #c1e2b3;
        }
        .shitu{
            background: #8c8c8c;
        }
        .yellow{
            background: yellow;
        }
        .xiaozi{
            background: burlywood;
        }
        #context{
            position: absolute;
            right: 10%;
            top: 25%;
            font-size: 50px;
            color: #00FF00;
        }
    </style>
</head>
<body onkeydown="doKeyDown(event)">
<div id="contie">

</div>
<div id="context"></div>

</body>
<script>
    //0 空气 1 自己 2 敌人 3 自己的子弹 4 为敌人子弹
    //两张地图 下面为 地图 上面为 子弹
    let arr=[];
    let two=[];
    let max=18;
    let point=[{x:max-1,y:max/2}];//默认在最下面 玩家坐标
    let dom,dom2;
    let zidan;
    let diren;//敌人的集合
    let direnzidan;//敌人子弹的集合
    let dirensize=0;//敌人的数量
    let xiaom=0;//击杀敌人数量
    let zidians=0;//子弹数量
    let xielang=4;//玩家血量
    let map = new Map();
    map.set(0,"<span class=\"kong\"></span>");
    map.set(1,"<span class=\"shitu\"></span>");
    map.set(2,"<span class=\"yellow\"></span>");
    map.set(3,"<span class=\"xiaozi\"></span>");
    map.set(4,"<span class=\"person\"></span>");
    function initial() {
        dom=document.getElementById("contie");
        dom2=document.getElementById("context");
        zidan=new Linklist();
        diren=new Linklist();
        direnzidan=new Linklist();
        //初始化数据
        for (let i=0;i<max;i++){
            arr[i]=[];
            two[i]=[];
            for (let j=0;j<max;j++){
                two[i][j]=0;
                arr[i][j]=0;
            }
        }
        //渲染玩家
        for (let i=0;i<point.length;i++){
            arr[point[i].x][point[i].y]=1;
        }
        playgame();
    }
    //添加敌人
    function creatediren() {
        diren.add(new Node(0,parseInt(Math.random()*max),2));
    }
    //敌人移动的函数
    function dirmove(node) {
        node.y=postion123(node.y);
        node.x=postion123(node.x);
        //判断我移动的位置是否有玩家子弹
       if(two[node.x][node.y]===3){
           let s = zidan.search(node.x,node.y);
           s.x=0;//设置子弹对象不可达到
           two[node.x][node.y]=0;
           node.x=max;//设置敌人不可达到
           dirensize--;//敌人数量减
           xiaom++;
           info();
       }else //没有死亡就随机开火
       if(Math.random()>0.2){
           direnzidan.add(new Node(node.x+1,node.y,4));
        }
    }
    function info(str) {

    dom2.innerText="共打了"+zidians+"子弹 干掉"+xiaom+"敌人"+xielang+"血量"+(str?str:"");

    }
    //下一步的 坐标
    function postion123(x) {
        switch (x) {
            case 0:
                return 1;
            case max:
                return max-1;
            default:
               return x+(Math.random()>0.5?1:-1);
              }
    }
    //渲染函数 把 二维数组 转换
    function xuanyan() {
        dom.innerHTML="";
        for (let i=0;i<max;i++){
            for (let j=0;j<max;j++){
                if(two[i][j]!==0){//如果有子弹优先渲染子弹
                    dom.innerHTML+=map.get(two[i][j]);
                }else
                dom.innerHTML+=map.get(arr[i][j]);
            }
            dom.innerHTML+="<br>";
        }
    }
    function playgame() {
        info();
        xuanyan();
        let reomve={zidan:0,dzidan:0,diren:0}//记录我要清除的数量
        dom.hello=setInterval(function () {
            if(dirensize<3){//当敌人小于3 创建
                creatediren();
                dirensize++;
            }
            //渲染玩家子弹
            zidan.Gaidian(zidan,reomve.zidan,(s)=>{
                two[s.x][s.y]=0;
                if(s.x>=1){
                    two[s.x-1][s.y]=s.data;
                    s.x--;
                }else{//小于 1 出界面
                    reomve.zidan++;
                }
            },0);
            //渲染敌人
            diren.Gaidian(diren,reomve.diren,(s)=>{
                if(s.x<max){
                    arr[s.x][s.y]=0;
                    dirmove(s);
                    if(s.x<max)
                    arr[s.x][s.y]=s.data;
                }else{
                    reomve.diren++;
                }
            },max);
            //渲染敌人子弹
            direnzidan.Gaidian(direnzidan,reomve.dzidan,(s)=>{
                if(s.x<max){// s
                    two[s.x][s.y]=0;
                    s.x++;
                    if(s.x<max){
                        two[s.x][s.y]=s.data;
                        //判断我是否计中玩家
                       if( arr[s.x][s.y]===1){
                           xielang--;//减少血量
                           info();
                           if(xielang===0){//为0清除 游戏结束
                               clearInterval(dom.hello);
                               info("gameover");
                           }
                       }
                    }

                }else{
                    reomve.dzidan++;
                }
            },max);
            xuanyan();
        },50)
    }
    function doKeyDown(event){
        if(event.keyCode>36&&event.keyCode<41){
            postion=event.keyCode;
            //移动玩家
            let dian1 = dian(point[0].x,point[0].y,postion);
            //不可以动
            if(dian1[0]<0||dian1[0]>=max||dian1[1]<0||dian1[1]>=max){

            }else{
                //原来的清空
                arr[point[0].x][point[0].y]=0;
                point[0].x=dian1[0];//修改点
                point[0].y=dian1[1];
                arr[point[0].x][point[0].y]=1;//更新点
            }
        }else if(event.keyCode===32){//空格发射子弹
            //在原来对象的上面给一个子弹
            zidan.add(new Node(point[0].x-1,point[0].y,3));
            zidians++;
            info();
        }
    }
    function dian(x,y,key) {
        let arr;
        switch (key) {
            case 37://左键头 0
                arr=[x,y-1];
                break;
            case 38://上键头 1
                arr=[x-1,y];
                break;
            case 39://右箭头 2
                arr=[x,y+1];
                break;
            case 40://下箭头 3
                arr=[x+1,y];
                break;
        }
        return arr;
    }
    class Node{
        constructor(x,y,data,next) {
            this.x=x;
            this.y=y;
            this.data=data;
            this.next=next;
        }
    }
    class Linklist{
        constructor() {
        this.root=null;//第一个
        this.last=null;//最后一个
        }
        add(node){
            if(this.root==null){
                this.root=node;
                this.last=node;
            }else{
                this.last.next=node;
                this.last=this.last.next;
            }
        }
        //搜索x 和 y 返回对象
        search(x,y){
            let s=this.root;
            while(s!=null){
                if(s.x===x&&s.y===y) return s;
                s=s.next;
            }
        }
        //清理不用的对象  把 x为val 的干掉
        remove(a,val){
            for(let i=0;i<a;i++)
            this.root=this.deleteNode(this.root,val);
            let s = this.root;
            while(s!=null){
            if(s.next==null) break;
              s=s.next;
            }
            this.last=s;
        }
        deleteNode(head, val) {
            if(head==null) return null;
            if(head.x ===val){
                return head.next;
            }
            if(head.next==null) return head;
            if(head.next.x === val){
                head.next = head.next.next;
            }else{
                head.next=this.deleteNode(head.next,val);
            }return head;
        };
        //链表 不可达数量 回调 我清理的值
        Gaidian(node,xx,F,val){
            let s = node.root;
            xx=0;
            while(s!=null){
                F(s);
                s=s.next;
            }
            if(xx>10){//清理对象
                node.remove(xx,val);
            }
        }
    }
    initial();
</script>
</html>

本文地址:https://blog.csdn.net/YangjulongTrue/article/details/109266714

《html+js 实现 推箱子 贪吃蛇和简单的飞机大战.doc》

下载本文的Word格式文档,以方便收藏与打印。