方格游戏

年后复工,写了一个方格游戏练练手。

最开始想的游戏名字是雪人回家,找不到合适的雪人头像,就简单的称呼为方格游戏吧,哈哈。

项目地址(打开就能玩)

http://mumuqiuer.gitee.io/snowman/

目前没有移动版本,只能在PC上玩。

游戏说明:

使用键盘上下左右四个箭头按键移动小女孩,在倒计时结束前到达小房子的位置即游戏挑战成功。

每次限制移动一格,红绿方格代表正负分值,走过的方格不再积分。

倒计时,系统设置时间为30秒,可以自行修改时间,调节游戏难度。

游戏比的是限定时间内的得分高低。当然,游戏时间结束了还没回家,就是0分。哈哈。

游戏复盘功能,棋盘不变,可以重走一遍。战绩记录每次重玩的得分,快来和小伙伴一较高低!

不想玩本局了,还可以再来一局,棋盘则会重新生成,每格分数随机。

游戏实现思路

h5+vue+js实现

移动原理是css的位置偏移 translate(x,y)

难点

1、获取当前移动到达的目标格的分值。

初始化一个方格字典数组。在棋盘创建时,同步更新字典中记录的对应方格分值。每次移动累积偏移量,都去遍历字典数组,通过比较偏移量,确定目标方格,从而获取目标方格的分值。

2、游戏复盘。

确保方格显示的分值不变,上次走过并置为0的方格需要复原。在棋盘数组中,记录两个分值,一个是随机出的方格分值 score ,一个是修改过的分值 usedScore 。score 在一局游戏中始终不变,usedScore 的值动态改变,记录失效后的分值0。棋盘的显示,usedScore 为0就显示 usedScore,否则显示 score 。

游戏源码分享

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <title>方格游戏</title>
    <link rel="shortcut icon" href="favicon.ico">
    <meta name="keywords" content="方格游戏">
    <meta name="description" content="方格游戏">
    <script src="vue.js"></script>
    <style>
        body{
            width: 100%;
            height:100%;
            margin:0;
            background: #fff;
            overflow: hidden;
            box-sizing: border-box;
        }
        div.container{
            width: 100%;
            display: flex;
            justify-content: center;
            margin-top:80px;
            text-align: center;
        }
        div.container div.chess{
            width:700px;
            height:700px;
            display: flex;
            justify-content: flex-start;
            flex-wrap: wrap;
            box-sizing: border-box;
            margin:0 20px;
        }
        div.container div.score{
            width:300px;
            margin:0 20px;
            border:1px solid #999;
            background: #999;
        }

        /*游戏计时器*/
        div.head{
            width:100%;
            height:64px;
            box-sizing: border-box;
            text-align: center;
            position: fixed;
            top: 0;
            background: #999;
            padding:12px;
        }
        div.head span,div.score span{
            font-size: 24px;
            font-weight: bold;
            color:red;
            padding:0 4px
        }

        /*雪人*/
        div.snowman{
            width:80px;
            height:80px;
            margin:10px;
            text-align: center;
            background: url("head.jpg") no-repeat;
            cursor: pointer;
            z-index: 2;
        }

        div.chess-grid{
            width:100px;
            height:100px;
            line-height:100px;
            box-sizing: border-box;
            text-align: center;
            border:1px solid #ccc;
            color: #fff;
        }

        /*雪人的家*/
        div.home{
            width:100px;
            height:80px;
            margin:12px 7px;
            background: url("home.jpg") no-repeat;
        }

        /*控制器*/
        div.control{
            width:100%;
            height:60px;
            line-height:60px;
            text-align: center;
            display: flex;
            justify-content: center;
            position: fixed;
            bottom: 0;
            background: #999;
        }
        div.btn{
            width:200px;
            height:40px;
            line-height: 40px;
            box-sizing: border-box;
            border:1px solid #ccc;
            margin:10px;
            color: #fff;
            cursor: pointer;
        }
        div.auto{
            background: green;
        }
        div.refresh{
            background: red;
        }
        div.game_start_btn{
            margin:0 auto;
        }
    </style>
</head>
<body>
<div id="root">
    <div class="head" v-show="!showControl">
        <div v-show="!showTime" class="game_start_btn btn" @click="game_start">开始游戏</div>
        <div v-show="showTime">倒计时<span>{
   
   {gameTime}}</span>秒 </div>
    </div>

    <div class="container">
        <div class="chess">
            <div class="chess-grid"><div class="snowman" :style="moveStyle" title="按键盘方向键移动我哦"></div></div>
            <div class="chess-grid" v-for="(item,index) in chess" :key="index" :style="{background:item.background}">{
   
   {item.usedScore == 0 ? item.usedScore : item.score}}分</div>
            <div class="chess-grid"><div class="home"></div></div>
        </div>

        <div class="score">
            <p>倒计时设置(10 ~ 60s):<input type="number" v-model="userSetGameTime" min="10" max="60"/></p>
            <hr>
            <p>战绩</p>
            <div v-for="(score,index) in gameScores" :key="index">第{
   
   {index+1}}战得分<span>{
   
   {score}}</span>分</div>
        </div>
    </div>

    <div class="control" v-show="showControl">
        <div class="btn auto" @click="game_review">本局复盘</div>
        <div class="btn refresh" @click="game_update">再来一局</div>
    </div>
</div>

<script>
    new Vue({
        el: "#root",
        data: {
            showControl:false,//是否显示本局复盘、再来一局
            showTime:false,//是否显示倒计时 不显示倒计时的时候会显示开始游戏按钮
            is_get_home:false,
            gameTime:30,//系统设置的游戏时间 30秒一局游戏
            userSetGameTime:30,//用户设置的游戏时间
            gameScores:[],//单机多人游戏 游戏复盘,存储历史得分
            currentScore:0,//当前一局游戏的得分
            moveDown:0,
            moveRitht:0,
            chess:[],//存储随机的分数和背景色数组
            moveStyle:{transform:"translate(0,0)"},//偏移样式
            dictionary:[//棋盘各块偏移量对照字典 最后一格为终点格
                {"score":0," i":0, "r":100, "d":0},
                {"score":0, "i":1, "r":200, "d":0},
                {"score":0,"i":2, "r":300, "d":0},
                {"score":0,"i":3, "r":400, "d":0},
                {"score":0,"i":4, "r":500, "d":0},
                {"score":0,"i":5, "r":600, "d":0},
                {"score":0,"i":6, "r":0, "d":100},
                {"score":0,"i":7, "r":100, "d":100},
                {"score":0,"i":8, "r":200, "d":100},
                {"score":0,"i":9, "r":300, "d":100},
                {"score":0,"i":10, "r":400, "d":100},
                {"score":0,"i":11, "r":500, "d":100},
                {"score":0,"i":12, "r":600, "d":100},
                {"score":0,"i":13, "r":0, "d":200},
                {"score":0,"i":14, "r":100, "d":200},
                {"score":0,"i":15, "r":200, "d":200},
                {"score":0,"i":16, "r":300, "d":200},
                {"score":0,"i":17, "r":400, "d":200},
                {"score":0,"i":18, "r":500, "d":200},
                {"score":0,"i":19, "r":600, "d":200},
                {"score":0,"i":20, "r":0, "d":300},
                {"score":0,"i":21, "r":100, "d":300},
                {"score":0,"i":22, "r":200, "d":300},
                {"score":0,"i":23, "r":300, "d":300},
                {"score":0,"i":24, "r":400, "d":300},
                {"score":0,"i":25, "r":500, "d":300},
                {"score":0,"i":26, "r":600, "d":300},
                {"score":0,"i":27, "r":0, "d":400},
                {"score":0,"i":28, "r":100, "d":400},
                {"score":0,"i":29, "r":200, "d":400},
                {"score":0,"i":30, "r":300, "d":400},
                {"score":0,"i":31, "r":400, "d":400},
                {"score":0,"i":32, "r":500, "d":400},
                {"score":0,"i":33, "r":600, "d":400},
                {"score":0,"i":34, "r":0, "d":500},
                {"score":0,"i":35, "r":100, "d":500},
                {"score":0,"i":36, "r":200, "d":500},
                {"score":0,"i":37, "r":300, "d":500},
                {"score":0,"i":38, "r":400, "d":500},
                {"score":0,"i":39, "r":500, "d":500},
                {"score":0,"i":40, "r":600, "d":500},
                {"score":0,"i":41, "r":0, "d":600},
                {"score":0,"i":42, "r":100, "d":600},
                {"score":0,"i":43, "r":200, "d":600},
                {"score":0,"i":44, "r":300, "d":600},
                {"score":0,"i":45, "r":400, "d":600},
                {"score":0,"i":46, "r":500, "d":600},
                {"score":0,"i":47, "r":600, "d":600}
            ]
        },
        methods: {
            //生成随机分数棋格
            createChess:function(){
                //7*7方格,掐头去尾,需要生成47个随机数。
                var score;
                var bgColor;
                for(var i=0;i<47;i++){
                    // 按奇数偶数对应正负分值
                    if(i%2 ==0){
                        //正数 加分
                        score =Math.round(Math.random()*10)+2;
                        bgColor="#16a05d";
                    }else{
                        //负数 减分
                        score =-Math.round(Math.random()*6)-1;
                        bgColor="#e21918";
                    }
                    this.chess.push({
                        "score":score,
                        "usedScore":100,//随便指定一个现今规则不可能有的一个分数即可
                        "background":bgColor
                    });
                    //同步更新对照字典,存储分值。
                    this.dictionary[i].score = score;
                }
            },

            //键盘事件 四个箭头按键,控制上下左右四个方向的移动。
            letMove:function(e){
                e||event;
                //当游戏倒计时显示时,即游戏还未结束,才能触发键盘事件,开始移动。
                if(this.showTime){
                    switch(e.keyCode){
                        case 39:
                            //向右移动
                            this.moveRitht +=100;
                            break;
                        case 40:
                            //向下移动
                            this.moveDown +=100;
                            break;
                        case 37:
                            //向左移动
                            this.moveRitht -=100;
                            break;
                        case 38:
                            //向上移动
                            this.moveDown -=100;
                            break;
                        default:
                            return;
                    }

                    //判断界限值 不能超出棋盘活动
                    this.moveRitht < 0 ? this.moveRitht = 0 : this.moveRitht;
                    this.moveRitht > 600 ? this.moveRitht = 600 : this.moveRitht;

                    this.moveDown < 0 ? this.moveDown = 0 : this.moveDown;
                    this.moveDown > 600 ? this.moveDown = 600 : this.moveDown;

                    this.moveStyle.transform = "translate("+this.moveRitht+"px,"+this.moveDown+"px)";

                    //根据偏移的位置,统计得分。
                    this.countScore(this.moveRitht,this.moveDown);
                }

            },

            //计算得分
            countScore:function(r,d){
                //遍历偏移量字典,根据当前所在的位置,获取对应的分值。
                //偏移量字典(len=48)比棋格(len=47)多了一个终点的位置信息。
                if(!(r == 600 && d == 600)){
                    //不在家,赋值false 防止回家后再离开的情形
                    this.is_get_home = false;
                    for(var i=0;i<48;i++){
                        if(r == this.dictionary[i].r && d == this.dictionary[i].d){
                            if(this.chess[i].usedScore !=0){
                                this.currentScore += this.dictionary[i].score;
                                //分数一次性有效 走过的分数变为0.
                                //为了复盘,不直接改变分数,新分数存储到 usedScore
                                this.chess[i].usedScore = 0;
                            }
                        }
                    }
                }else{
                    //雪人到家
                    this.is_get_home = true;
                }

            },

            //计时器,每次时间-1,时间单位秒。
            timer:function(){
                this.gameTime -= 1
            },

            //用户点击游戏开始 创建定时器 显示倒计时
            game_start:function(){
                if(this.gameTime != this.userSetGameTime){
                    //系统设置的游戏时长和用户设置的游戏时长冲突,则使用用户设置的时长
                    this.gameTime = this.userSetGameTime;
                }
                this.showTime=true;
                timer1=setInterval(this.timer, 1000);
            },

            game_review:function(){
                this.parameter_reset();
                this.resetUsedScore();
            },

            //恢复棋盘 使用过的分数初始化
            resetUsedScore:function(){
                var len = 47;
                while(len--){
                    this.chess[len].usedScore = 100;
                }
            },

            //本局重玩,只需要重置参数。
            parameter_reset:function(){
                this.showControl=false;
                this.is_get_home = false;
                this.showTime=false;//先不显示倒计时,显示开始游戏按钮。
                this.moveRitht=0;
                this.moveDown=0;
                this.moveStyle.transform = "translate(0,0)";
                this.currentScore=0;
            },

            //页面初始化 游戏重新开始
            game_update:function(){
                this.parameter_reset();
                this.gameScores=[];
                this.chess=[];
                this.createChess();
            }
        },
        watch:{
            //监测游戏时间
            gameTime(){
                if(this.gameTime == 0){
                    clearInterval(timer1);
                    this.showControl=true;
                    this.showTime=false;//倒计时结束,关闭倒计时结果显示
                    if(this.is_get_home){
                        //游戏结束:倒计时结束,雪人进入小屋。当前得分计入。
                        this.gameScores.push(this.currentScore);
                    }else{
                        //游戏失败: 倒计时结束,但雪人未进入小屋。本局得分为0。
                        this.currentScore=0;
                        this.gameScores.push(0);
                    }
                }
            }
        },
        created(){
            //注册键盘事件
            var _this = this;
            document.addEventListener("keydown", _this.letMove);
        },
        mounted(){
            this.game_update();
        }
    })
</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/Irene1991/article/details/104969667
今日推荐