找回密码
 立即注册

扫一扫,访问微社区

查看: 18524|回复: 14

微信小程序游戏类demo:经典扫雷,绘制一张 10*10 的地图

 火.. [复制链接]
发表于 2017-3-3 15:17:45 | 显示全部楼层 |阅读模式

undefined不会玩扫雷

作者:jixiaod

微信小程序这几天很火,9号正式发布,今天19号过了10天,到现在略有降温的趋势。个大厂商对微信小程序的态度很不看好,最激进的要数[罗辑思维],直接下架了自己的[得到APP]。滴滴、京东等APP也只保留了最精简的功能,某些担心过于完善的功能会抢夺APP本身的用户。不过这也印证了小程序的初衷,小而精、用完即走。(并不否认腾讯微信平台确实流氓的事实)

PS:墨迹天气也开发了微信小程序版本,并且在1月9号第一时间发布,欢迎使用。

作为技术人员,怎能不亲手试试小程序开发呢?扫雷 Minesweeper

实现思路:
  • 如果不了解扫雷的游戏规则,请自行 Google
  • 绘制一张 10*10 的地图,并且标注地雷和非地雷,并且需要用数字表示每个点周围地雷的数量
  • 用 mineMap[x][y] 表示一个点位
    • mineMap[x][y] < 0 (代码中 == -1) 初始状态
    • 0 < mineMap[x][y] < 9 该点周围地雷的数量
    • mineMap[x][y] == 9 表示该点是地雷
    • mineMap[x][y] > 9 (代码中 == 10)表示该点插旗

如何跑起来?
  • 下载&安装微信小程序开发工具
  • 配置 wechat-app-minesweeper 代码目录到开发工具即可
玩法
  • 需要注意的是,由于没有鼠标右键标记Flag,简单做了 Flag 切换,开启后,方可标记Flag
  • 最初的想法是通过 tap 和 longtap 来区分扫雷和Flag,但是开发工具不能区分这俩个事件,只能作罢







[mw_shl_code=html,true]//index.js
//获取应用实例
var app = getApp()

Page({

    data: {
        mineMap: {},
        timesGo: 0,
        minesLeft: 0
    },

    mineMap: {},
    mineMapMapping: {},
    rowCount: 10,
    colCount: 10,
    mineCount: 10,
    minMineCount: 10,
    maxMineCount: 20,
    minesLeft: 0,
    timesGo: 0,
    timeInterval: null,
    flagOn: false,
    flags: 0,
    endOfTheGame: false,
    safeMinesGo: 0,

    onLoad: function() {

        this.setData({
            minesLeft: 0,
            timesGo: 0
        });
        this.drawMineField();
    },

    setGame: function() {

        this.drawMineField();
        this.createMinesMap();
        this.setMinesLeft();
        this.timeGoReset();
        this.timeGoClock();
        this.endOfTheGame = false;
        this.safeMinesGo = 0;
    },

    setMinesLeft: function() {
        this.minesLeft = this.mineCount;
        this.setData({minesLeft: this.minesLeft});
    },

    timeGoClock: function() {
        var self = this;
        this.timeInterval = setInterval(function () {
            // console.log(self.data.timesGo);
            self.timesGo = self.timesGo + 1;
            self.setData({timesGo: self.timesGo});
            
        }, 1000);
    },

    timeGoStop: function() {
     
        clearInterval(this.timeInterval);
    },

    timeGoReset: function() {
        clearInterval(this.timeInterval);
        this.timesGo = 0;
        this.setData({timesGo: this.timesGo});
    },

    createMinesMap: function() {

        var tmpMineMap = {};
        // initalize mine map with 0.
        for (var row = 0; row < this.rowCount; row++) {

            tmpMineMap[row] = [];
            for (var col = 0; col < this.colCount; col++) {

                tmpMineMap[row][col] = 0;
            }
        }
         //console.log(tmpMineMap);
         
        // laying mines with 9
        this.mineCount = this.rangeRandom(this.minMineCount, this.maxMineCount);

        var tmpCount = this.mineCount;
        //console.log("Mine count: ", tmpCount);
        while (tmpCount > 0) {

            var row = this.rangeRandom(0, this.rowCount - 1);
            var col = this.rangeRandom(0, this.colCount - 1);

            if (tmpMineMap[row][col] != 9) {

                tmpMineMap[row][col] = 9;
                tmpCount--;
            }
        }

        // calculate numbers around mines.
        for (var row = 0; row < this.rowCount; row++) {
            for (var col = 0; col < this.colCount; col++) {
                var startRow = row - 1;
                var startCol = col - 1;
                //console.log("check====== r" +startRow +"c"+startCol );
                for (var r = row-1; r < row+2; r++) {
                    for (var c = col-1; c < col+2; c++) {
                        //console.log("go: r"+r+":c"+c);
                        if (c >= 0 && c < this.colCount
                            && r >= 0 && r < this.rowCount
                        && !(r === row && c === col)
                        && tmpMineMap[r][c] == 9
                        && tmpMineMap[row][col] != 9) {
                            tmpMineMap[row][col]++;
                        }
                    }
                }
            }
        }
        this.mineMapMapping = tmpMineMap;
    },

    drawMineField: function() {

        var tmpMineMap = {};
        for (var row = 0; row < this.rowCount; row++) {

            tmpMineMap[row] = [];
            for (var col = 0; col < this.colCount; col++) {

                tmpMineMap[row][col] = -1;
            }
        }
        this.mineMap = tmpMineMap;
        //console.log(this.mineMap);

        this.setData({
            mineMap: this.mineMap
        })

    },

    demining: function(event) {

        if (JSON.stringify(this.mineMapMapping) == "{}") return;


        var x = parseInt(event.target.dataset.x);
        var y = parseInt(event.target.dataset.y);
        var value = parseInt(event.target.dataset.value);
        //console.log("value:" + value +" x:"+x +" y:"+y);

        //flag this field as mine.
        if (this.flagOn) {

            this.flag(x, y, value);
            return;
        }

        // if field has been opened, return.
        if (value > 0) return;
         
        var valueMapping = this.mineMapMapping[x][y];
        //console.log(this.mineMapMapping);
        //console.log(valueMapping);

        if (valueMapping < 9) {
            this.mineMap[x][y] = valueMapping;
            this.setData({mineMap: this.mineMap});
            this.safeMinesGo++;
            console.log("Safe mine go: " + this.safeMinesGo);
            if ((this.safeMinesGo + this.mineCount) == (this.rowCount * this.colCount)) {
                this.success();
            }
        }

        // When digg the mine.
        if (valueMapping == 9) {
            this.failed();
        }

        // Open the fields with 0 mines arround.
        if (valueMapping == 0) {

            this.openZeroArround(x, y);
            this.setData({mineMap:this.mineMap});
        }
    },

    success: function() {

        wx.showToast({
            title: 'GOOD!',
            duration: 3000
        })
        this.timeGoStop();
        this.endOfTheGame = true;
    },

    failed: function() {
        wx.showToast({
            title: 'SORRY!',
            duration: 3000
        })

        this.showAll();
        this.timeGoStop();
        this.endOfTheGame = true;
    },

    // Open the fields arround 0 field recursively.
    openZeroArround: function(row, col) {
        //console.log("click" + row + " " + col)
        for (var r = (row-1); r < (row+2); r++) {
            for (var c = (col-1); c < (col+2); c++) {
                //console.log("go: r"+r+":c"+c);
                if (r >= 0 && r < this.rowCount
                    && c >= 0 && c < this.colCount
                && !(r === row && c === col)
                && this.mineMap[r][c] < 0) {

                    this.mineMap[r][c] = this.mineMapMapping[r][c];
                    this.safeMinesGo++;

                    if (this.mineMapMapping[r][c] == 0) {
                        this.openZeroArround(r, c);
                    }

                }
            }
        }
        console.log("Safe mine go: " + this.safeMinesGo);
        if ((this.safeMinesGo + this.mineCount) == (this.rowCount * this.colCount)) {
            this.success();
        }

    },

    flagSwitch: function(e) {

        if (e.detail.value) {

            this.flagOn = true;
        } else {

            this.flagOn = false;
        }
    },

    flag: function(x, y, value) {

        if (value > 0 && value < 10) return;

        // if flaged already, set the original state.
        if (value == 10) {

            this.pullUpFlag(x, y);
            return;
        }

        if (this.minesLeft <= 0) return;

        this.minesLeft = this.minesLeft - 1;
        this.mineMap[x][y] = 10;

        this.setData({mineMap: this.mineMap, minesLeft: this.minesLeft});
    },

    pullUpFlag: function(x, y) {

        if (this.minesLeft < this.mineCount) {
            this.minesLeft = this.minesLeft + 1;
        }
        this.mineMap[x][y] = -1;
        this.setData({mineMap: this.mineMap, minesLeft: this.minesLeft});
    },

    rangeRandom: function(x, y) {
        var z = y - x + 1;
        return Math.floor(Math.random() * z + x);
    },

    showAll: function() {
        this.mineMap = this.mineMapMapping;
        this.setData({mineMap: this.mineMap});
    }

});[/mw_shl_code]


游客,如果您要查看本帖隐藏内容请回复

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

0

主题

2

回帖

12

金钱

新人求带

积分
0
发表于 2018-3-1 16:18:40 | 显示全部楼层
正需要,支持楼主大人了!

0

主题

28

回帖

160

金钱

新人求带

积分
0
发表于 2018-11-23 17:17:26 | 显示全部楼层
谢谢楼主的分享

0

主题

1

回帖

12

金钱

新人求带

积分
0
发表于 2019-3-31 15:49:53 | 显示全部楼层
十分感谢楼主的分享,课程作业很需要参照。

0

主题

1

回帖

12

金钱

新人求带

积分
0
发表于 2019-4-15 10:19:16 | 显示全部楼层
参考一下
回复

使用道具 举报

0

主题

10

回帖

92

金钱

新人求带

积分
0
发表于 2019-7-4 15:03:03 | 显示全部楼层
999999999999999999999999999999

0

主题

3

回帖

14

金钱

新人求带

积分
0
发表于 2019-7-11 15:29:47 | 显示全部楼层
999999999999999999999999999999

0

主题

15

回帖

29

金钱

新人求带

积分
0
发表于 2019-8-3 22:30:31 来自手机 | 显示全部楼层
回复

使用道具 举报

0

主题

4

回帖

12

金钱

新人求带

积分
0
发表于 2019-8-23 08:59:29 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

0

主题

28

回帖

68

金钱

新人求带

积分
0
发表于 2019-12-17 10:57:49 | 显示全部楼层
粗放预估i后的一天
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|微信小程序开发|教程|文档|资源汇总_即速论坛 ( 粤ICP备14097199号-1  

GMT+8, 2024-4-27 05:59 , Processed in 0.129702 second(s), 31 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表