当前位置:主页 > 查看内容

游戏制作-推箱子游戏html5版(可以在线预览)

发布时间:2021-07-13 00:00| 位朋友查看

简介:用 html 做了一款推箱子的小游戏只做了一个关卡屏幕触控和键盘方向键控制小人推箱子、重新开始、上一步及通关等功能直接上图 预览地址 效果链接只看看不如亲自体验一下因为写了键盘监听的缘故键盘事件都被停用了 http://h5demo.yyfuncdn.com/res/gameDemo/so……

用 html 做了一款推箱子的小游戏(只做了一个关卡),屏幕触控和键盘方向键控制小人推箱子、重新开始、上一步及通关等功能,直接上图:

预览地址

效果链接(只看看不如亲自体验一下,因为写了键盘监听的缘故,键盘事件都被停用了):
http://h5demo.yyfuncdn.com/res/gameDemo/sokoban/

手机扫码运行:
在这里插入图片描述

下面是所有的项目文件:

game.html 文件是项目的运行文件,里面包含了创建舞台、创建游戏场景、人物等内容的操作,最后还设置了键盘操控
.

游戏源码被放到下面公众号里面啦,有需要的小伙伴可以扫码关注,发送 “推箱子” 获取哦
在这里插入图片描述

感谢大家支持……^ ^
.

项目代码

<!DOCTYPE html>
<html>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
    <script src='js/pixi.js'></script>
    <script src='js/background.js'></script>
    <script src="js/wall.js"></script>
    <script src="js/box.js"></script>
    <script src="js/ball.js"></script>
    <script src="js/role.js"></script>
    <script src="js/text.js"></script>
    <script src="js/reset.js"></script>
    <meta name="viewport" content="width=device-width,height=device-height"/>
    <style>
        body{
            background-color:black;
        }
        canvas{
            width:100%;
            max-width:500px;
            position: absolute;
            left:50%;
            top:50%;
            transform:translate(-50%,-50%);
        }
     </style>
</head>
<body>
    <script>
        //创建舞台
        var app = new PIXI.Application(560,800);
        document.body.appendChild(app.view);
        //生成背景
        var bg = new Background(560,800);
        //创建地图数组
        var mapArr = [];
        //地图二维数组初始化
        function init(){
            var width = 40;
            var height = 40;
            var left = 20;
            var up = 200;
            for(var i = 0;i < 14;i++) {
                mapArr.push([]);
                for(var j = 0;j < 9;j++) {
                    mapArr[i].push([]);
                    mapArr[i][j] = {type:null};
                }
            }
            //墙方块在数组中的位置
            var wallx = [0,0,0,0,0,0,0,1,1,2,2,2,2,2,3,3,3,4,4,4,5,5,5,5,5,5,5,6,6,7,7,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,12,12,12,13,13,13,13,13,13,13,13,13];
            var wally = [0,1,2,3,4,5,6,0,6,0,6,7,8,9,0,6,9,0,6,9,0,1,2,3,5,6,9,0,9,0,3,5,6,8,9,0,3,6,9,0,3,4,9,0,3,4,9,0,1,9,1,5,9,1,2,3,4,5,6,7,8,9];
            //生成墙方块
            for(var i = 0;i < wallx.length;i++) {
                var x = wallx[i];
                var y = wally[i];
                var wall = new Wall();
                wall.pos(left+x*width,up+y*height);
                wall.posArr = {x:x,y:y};
                mapArr[x][y] = {type:"wall"};
            }
            //箱子在数组中的位置
            var boxx = [4,6,7,7,9,9,10,10,11,11];
            var boxy = [7,3,2,7,6,7,2,5,6,7];
            //生成箱子
            for(var i = 0;i < boxx.length;i++) {
                var x = boxx[i];
                var y = boxy[i];
                var box = new Box();
                box.pos(left+x*width,up+y*height);
                box.posArr = {x:x,y:y};
                mapArr[x][y] = {type:"box",obj:box};
                boxArr.push(box);
            }
            //球体在数组中的位置
            var ballx = [1,1,1,1,1,2,2,2,2,2];
            var bally = [1,2,3,4,5,1,2,3,4,5];
            //生成球体
            for(var i = 0;i < ballx.length;i++) {
                var x = ballx[i];
                var y = bally[i];
                var ball = new Ball();
                ball.pos(left+x*width,up+y*height);
                ball.posArr = {x:x,y:y};
                mapArr[x][y] = {type:"ball",obj:ball};
                ballArr.push({obj:ball,type:false});
            }
        }
        //用于保存球体对象的数组
        var ballArr = [];
        //用于保存箱子对象的数组
        var boxArr = [];
        var moveArr = [];
        init();
        //生成小人
        var role = new Role();
        role.pos(20+7*40,200+4*40);
        role.posArr = {x:7,y:4};
        bg.setobj(role);
        //生成文字
        var text = new Text();
        text.setPos(280,100,280,700);
        //生成重置按钮
        var reset = new Reset();
        reset.setPos(100,100);
        reset.setPos1(450,100);
        //用于控制移动
        var control = true;
    
        document.onkeydown = keyDown;
        function keyDown(event) {//键盘监听
            var event = event || window.event;
            switch (event.keyCode) {
                case 37:
                    bg.wasd("a");
                    break;
                case 39:
                    bg.wasd("d"); 
                    break;
                case 38:
                    bg.wasd("w");
                    break;
                case 40:
                    bg.wasd("s");
                    break;
            }
            return false;
        }
    </script>
    
    <div style="display:none;">
        <script type="text/javascript" src="https://s4.cnzz.com/z_stat.php?id=1279820148&web_id=1279820148"></script>
    </div>
</body>
</html>


背景被封装进了 Background 对象,用于触控控制小人的移动,监测是否触墙、箱子是否入库、一起推动箱子的操作

//背景对象
function Background(width,height) {
    var self = this;
    this.view = new PIXI.Sprite.fromImage("res/background.png");
    app.stage.addChild(this.view);
    this.view.height = height;
    this.view.width = width;

    //获取到控制对象
    var obj = null;
    this.setobj = function(dx) {
        obj = dx;
    }
    //定义变量 pos 用于记录鼠标按下的位置
    var pos;
    //开启交互
    this.view.interactive = true;
    //绑定鼠标按下事件
    this.view.on("pointerdown",function(event) {
        pos = event.data.getLocalPosition(app.stage);
    })
    //撤销事件
    this.revocation = function() {
        if(moveArr.length == 0)return;
        switch (moveArr[moveArr.length-1].direction) {
            case "a":
                self.move(role,"d");
                if(moveArr[moveArr.length-1].obj != null){
                    self.shiftOut(moveArr[moveArr.length-1].obj);
                    self.moveChangeMapArr(moveArr[moveArr.length-1].obj,"d");
                    self.immigrate(moveArr[moveArr.length-1].obj);
                }
                break;
            case "d":
                self.move(role,"a");
                if(moveArr[moveArr.length-1].obj != null) {
                    self.shiftOut(moveArr[moveArr.length-1].obj);
                    self.moveChangeMapArr(moveArr[moveArr.length-1].obj,"a");
                    self.immigrate(moveArr[moveArr.length-1].obj);
                }
                break;
            case "w":
                self.move(role,"s");
                if(moveArr[moveArr.length-1].obj != null) {
                    self.shiftOut(moveArr[moveArr.length-1].obj);
                    self.moveChangeMapArr(moveArr[moveArr.length-1].obj,"s");
                    self.immigrate(moveArr[moveArr.length-1].obj);
                }
                break;
            case "s":
                self.move(role,"w");
                if(moveArr[moveArr.length-1].obj != null) {
                    self.shiftOut(moveArr[moveArr.length-1].obj);
                    self.moveChangeMapArr(moveArr[moveArr.length-1].obj,"w");
                    self.immigrate(moveArr[moveArr.length-1].obj);
                }
                break;
            default:
                break;
        }
        moveArr.splice(moveArr.length-1,1);
    }
    //用于判断角色的移动
    this.wasd = function(type) {
        if(!control) {
           return;
        }
        var dx = self.roleCrash(obj,type);
        if(dx.type == false) {
            return;
        } 
        moveArr.push({direction:type,obj:null});
        if(dx.obj != null){
            var state = self.boxCrash(dx.obj,type);
            if(state == false) {
                moveArr.splice(moveArr.length-1,1);
                return;
            }
            moveArr[moveArr.length-1].obj = dx.obj;
            self.shiftOut(dx.obj);
            self.moveChangeMapArr(dx.obj,type);
            self.immigrate(dx.obj);
        }
        self.move(obj,type);
    }
    //检查箱子是否移出球体位置
    this.shiftOut = function(obj) {
        for(var i = 0;i < ballArr.length;i++){
            if(obj.posArr.x == ballArr[i].obj.posArr.x && obj.posArr.y == ballArr[i].obj.posArr.y) {
                ballArr[i].type = false;
                mapArr[obj.posArr.x][obj.posArr.y] = {type:"ball",obj:ballArr[i].obj};
                return;
            }
        }
    }
    //检查箱子是否移动至球体位置
    this.immigrate = function(obj) {
        for(var i = 0;i < ballArr.length;i++) {
            if(obj.posArr.x == ballArr[i].obj.posArr.x && obj.posArr.y == ballArr[i].obj.posArr.y) {
                ballArr[i].type = true;
            }
        }
        for(var i = 0;i < ballArr.length;i++) {
            if(ballArr[i].type == false) {
                return;
            }
        }
        reset.win();
    }
    //检查角色触碰到的物体并返回物体类型及物体对象
    this.boxCrash = function(obj,type) {
        var state = true;
        switch (type) {
            case "a":
                if(mapArr[obj.posArr.x-1][obj.posArr.y].type == "wall") {
                    state = false;
                }
                if(mapArr[obj.posArr.x-1][obj.posArr.y].type == "box") {
                    state = false;
                }
                break;
            case "d":
                if(mapArr[obj.posArr.x+1][obj.posArr.y].type == "wall") {
                    state = false;
                }
                if(mapArr[obj.posArr.x+1][obj.posArr.y].type == "box") {
                    state = false;
                }
                break;  
            case "w":
                if(mapArr[obj.posArr.x][obj.posArr.y-1].type == "wall") {
                    state = false;
                }
                if(mapArr[obj.posArr.x][obj.posArr.y-1].type == "box") {
                    state = false;
                }
                break;
            case "s":
                if(mapArr[obj.posArr.x][obj.posArr.y+1].type == "wall") {
                    state = false;
                }
                if(mapArr[obj.posArr.x][obj.posArr.y+1].type == "box") {
                    state = false;
                }
                break;
            default:
                break;
        }
        return state;
    }
    //检查角色触碰到的物体并返回物体类型及物体对象
    this.roleCrash = function(obj,type) {
        var state = {type:true,obj:null};
        switch (type) {
            case "a":
                obj.wl(0);
                if(mapArr[obj.posArr.x-1][obj.posArr.y].type == "wall") {
                    state = {type:false,obj:mapArr[obj.posArr.x-1][obj.posArr.y]};
                }
                if(mapArr[obj.posArr.x-1][obj.posArr.y].type == "box") {
                    state = {type:true,obj:mapArr[obj.posArr.x-1][obj.posArr.y].obj};
                }
                break;
            case "d":
                obj.wl(1);
                if(mapArr[obj.posArr.x+1][obj.posArr.y].type == "wall") {
                    state = {type:false,obj:mapArr[obj.posArr.x+1][obj.posArr.y]};
                }
                if(mapArr[obj.posArr.x+1][obj.posArr.y].type == "box") {
                    state = {type:true,obj:mapArr[obj.posArr.x+1][obj.posArr.y].obj};
                }
                break;  
            case "w":
                obj.wl(2);
                if(mapArr[obj.posArr.x][obj.posArr.y-1].type == "wall") {
                    state = {type:false,obj:mapArr[obj.posArr.x][obj.posArr.y-1]};
                }
                if(mapArr[obj.posArr.x][obj.posArr.y-1].type == "box") {
                    state = {type:true,obj:mapArr[obj.posArr.x][obj.posArr.y-1].obj};
                }
                break;
            case "s":
                obj.wl(3);
                if(mapArr[obj.posArr.x][obj.posArr.y+1].type == "wall") {
                    state = {type:false,obj:mapArr[obj.posArr.x][obj.posArr.y+1]};
                }
                if(mapArr[obj.posArr.x][obj.posArr.y+1].type == "box") {
                    state = {type:true,obj:mapArr[obj.posArr.x][obj.posArr.y+1].obj};
                }
                break;
            default:
                break;
        }
        return state;
    }
    //控制箱子移动并改变箱子在地图数组中的位置
    this.moveChangeMapArr = function(obj,type) {
        switch (type) {
            case "a":
                if(mapArr[obj.posArr.x][obj.posArr.y].type != "ball") {
                    mapArr[obj.posArr.x][obj.posArr.y] = {type:null};
                }
                obj.view.x += -40;
                obj.posArr.x += -1;
                mapArr[obj.posArr.x][obj.posArr.y] = {type:"box",obj};
                break;
            case "d":
                if(mapArr[obj.posArr.x][obj.posArr.y].type != "ball") {
                    mapArr[obj.posArr.x][obj.posArr.y] = {type:null};
                }
                obj.view.x += 40;
                obj.posArr.x += 1;
                mapArr[obj.posArr.x][obj.posArr.y] = {type:"box",obj};
                break;  
            case "w":
                if(mapArr[obj.posArr.x][obj.posArr.y].type != "ball") {
                    mapArr[obj.posArr.x][obj.posArr.y] = {type:null};
                }
                obj.view.y += -40;
                obj.posArr.y += -1;
                mapArr[obj.posArr.x][obj.posArr.y] = {type:"box",obj};
                break;
            case "s":
                if(mapArr[obj.posArr.x][obj.posArr.y].type != "ball") {
                    mapArr[obj.posArr.x][obj.posArr.y] = {type:null};
                }
                obj.view.y += 40;
                obj.posArr.y += 1;
                mapArr[obj.posArr.x][obj.posArr.y] = {type:"box",obj};
                break;
            default:
                break;
        }
    }
    //角色移动方法
    this.move = function(obj,type) {
        switch (type) {
            case "a":
                obj.view.x += -40;
                obj.posArr.x += -1;
                break;
            case "d":
                obj.view.x += 40;
                obj.posArr.x += 1;
                break;  
            case "w":
                obj.view.y += -40;
                obj.posArr.y += -1;
                break;
            case "s":
                obj.view.y += 40;
                obj.posArr.y += 1;
                break;
            default:
                break;
        }
    }
    //绑定鼠标抬起事件&&用抬起的位置与按下的位置做比对来辨别行动的方向
    this.view.on("pointerup",function(event) {
        if(pos == undefined || obj == null){
            return;
        }
        var posup = event.data.getLocalPosition(app.stage);
        if(Math.abs(posup.x - pos.x) > Math.abs(posup.y - pos.y)) {
            if(posup.x - pos.x > 0) {
                self.wasd("d");
            }else if(posup.x - pos.x < 0) {
                self.wasd("a");
            }
        }else if(Math.abs(posup.x - pos.x) < Math.abs(posup.y - pos.y)) {
            if(posup.y - pos.y > 0) {
                self.wasd("s");
            }else if(posup.y - pos.y < 0) {
                self.wasd("w");
            }
        }
    })
}

从新开始按钮单独封装在了 Reset 对象中

function Reset(){
    var self = this;

    var style1 = {
        fontFamily: 'Arial',
        fontStyle: 'normal',
        fontSize:30,
        fontWeight: 'bold',
        fill: '#bf8735',
    }
    this.view = new PIXI.Text("重新开始",style1);
    app.stage.addChild(this.view);
    this.view.anchor.set(0.5,0.5);
    var style2 = {
        fontFamily: 'Arial',
        fontStyle: 'normal',
        fontSize:30,
        fontWeight: 'bold',
        fill: '#bf8735',
    }
    this.revocation = new PIXI.Text("上一步",style2);
    app.stage.addChild(this.revocation);
    this.revocation.anchor.set(0.5,0.5);

    var style = {
        fontFamily: 'Arial',
        fontStyle: 'normal',
        fontSize:40,
        fontWeight: 'bold',
        fill: '#f5286e',
    }

    var text = new PIXI.Text("恭 喜 过 关",style);
    app.stage.addChild(text);
    text.anchor.set(0.5,0.5);
    text.x = 280;
    text.y = 300;
    text.visible = false;

    this.win = function() {
        text.visible = true;
        self.setPos(280,400);
        self.revocation.visible = false;
        control = false;
    }
    //设置位置方法
    this.setPos = function(x,y) {
        self.view.x = x;
        self.view.y = y;
    }
    this.setPos1 = function(x,y) {
        self.revocation.x = x;
        self.revocation.y = y;
    }
    //开启重置按钮的交互
    this.view.interactive = true;
    this.revocation.interactive = true;
    //绑定点击事件
    this.revocation.on("pointertap",function() {
        bg.revocation();
    })

    this.view.on("pointertap",function() {
        self.revocation.visible = true;
        text.visible = false;
        moveArr = [];
        self.setPos(100,100);
        var boxx = [4,6,7,7,9,9,10,10,11,11];
        var boxy = [7,3,2,7,6,7,2,5,6,7];
        for(var i = 0;i < boxArr.length;i++) {
            var box = boxArr[i];
            mapArr[box.posArr.x][box.posArr.y] = {type:null};
            mapArr[boxx[i]][boxy[i]] = {type:"box",obj:box};
            box.posArr = {x:boxx[i],y:boxy[i]};
            box.pos(20+boxx[i]*40,200+boxy[i]*40);
        }
        role.pos(20+7*40,200+4*40);
        role.posArr = {x:7,y:4};
        for(var i = 0;i < ballArr.length;i++) {
            var ball = ballArr[i];
            ball.type = false;
            mapArr[ball.obj.posArr.x][ball.obj.posArr.y] = {type:"ball",obj:ball.obj};
        }

    })
}

以下其他对象没有什么特别的,只是单独的对象,每次使用调用

球对象(蓝色的目标点)

//球对象
function Ball(){
    var self = this;
    this.view = new PIXI.Sprite.fromImage("res/blueball.png");
    app.stage.addChild(this.view);
    this.view.anchor.set(0.5,0.5);
    this.view.alpha = 0.7;
    this.posArr;
    //设置位置方法
    this.pos = function(x,y) {
        self.view.x = x;
        self.view.y = y;
    }
}

箱子对象

//箱子对象
function Box(){
    var self = this;
    this.view = new PIXI.Sprite.fromImage("res/bluebox.png");
    app.stage.addChild(this.view);
    this.view.anchor.set(0.5,0.5);
    this.posArr;
    //设置位置方法
    this.pos = function(x,y){
        self.view.x = x;
        self.view.y = y;
    }
}

角色对象

//角色对象
function Role() {
    var self = this;
    var urlArr = ["res/left.png","res/right.png","res/up.png","res/down.png"];
    this.view = new PIXI.Sprite.fromImage(urlArr[3]);
    app.stage.addChild(this.view);
    this.view.anchor.set(0.5,0.5);
    this.posArr;
    //设置角色纹理
    this.wl = function(num) {
        var url = new PIXI.Texture.fromImage(urlArr[num]);
        self.view.texture = url;    
    }
    //设置位置方法
    this.pos = function(x,y) {
        self.view.x = x;
        self.view.y = y;
    }
}

文本对象

function Text(){
    var self = this;
    //设置标题样式
    var style = {
        fontFamily: 'Arial',
        fontSize: 40,
        fontStyle: 'normal',
        fontWeight: 'bold',
        fill:'#bf8735',
        stroke: '#000fff',
        strokeThickness: 5
    }
    //设置说明样式
    var style2 = {
        fontFamily: 'Arial',
        fontStyle: 'normal',
        fontWeight: 'bold',
        fill: '#000fff'
    }

    this.view = new PIXI.Text("推 箱 子",style);
    this.view.anchor.set(0.5,0.5);
    app.stage.addChild(this.view);

    this.explain = new PIXI.Text("滑动屏幕或键盘方向键控制小人移动",style2);
    this.explain.anchor.set(0.5,0.5);
    app.stage.addChild(this.explain);
    //设置位置方法
    this.setPos = function(viewx,viewy,explainx,explainy) {
        self.view.x = viewx;
        self.view.y = viewy;
        self.explain.x = explainx;
        self.explain.y = explainy;
    }
}

墙对象

function Text(){
    var self = this;
    //设置标题样式
    var style = {
        fontFamily: 'Arial',
        fontSize: 40,
        fontStyle: 'normal',
        fontWeight: 'bold',
        fill:'#bf8735',
        stroke: '#000fff',
        strokeThickness: 5
    }
    //设置说明样式
    var style2 = {
        fontFamily: 'Arial',
        fontStyle: 'normal',
        fontWeight: 'bold',
        fill: '#000fff'
    }

    this.view = new PIXI.Text("推 箱 子",style);
    this.view.anchor.set(0.5,0.5);
    app.stage.addChild(this.view);

    this.explain = new PIXI.Text("滑动屏幕或键盘方向键控制小人移动",style2);
    this.explain.anchor.set(0.5,0.5);
    app.stage.addChild(this.explain);
    //设置位置方法
    this.setPos = function(viewx,viewy,explainx,explainy) {
        self.view.x = viewx;
        self.view.y = viewy;
        self.explain.x = explainx;
        self.explain.y = explainy;
    }
}
;原文链接:https://blog.csdn.net/dayouyu001/article/details/115627594
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐