zoukankan      html  css  js  c++  java
  • day121:MoFang:植物的状态改动(幼苗→成长期)&植物的浇水功能

    目录

    1.当果树种植以后在celery的异步任务中调整浇水的状态

    2.客户端通过倒计时判断时间,显示浇水道具

    3.客户端判断当前种植物状态控制图标的显示和隐藏

    4.当用户单击浇水图标, 则根据当前果树的种植时间和状态确定是否进入成长期

    1.当果树种植以后在celery的异步任务中调整浇水的状态

    在 进行果树种植的时候, 在服务端设置当前果树到等待浇水的redis变量中.通过celery不断进行周期任务的处理, 改动果树的浇水状态

    1.socket.py

    from datetime import datetime
    @socketio.on("use_prop", namespace="/mofang")
    def use_prop(data):
        """使用道具"""
        pid = data.get("pid")
        pet_key = data.get("pet_key",0)
        room = request.sid
        # 获取mongo中的用户信息
        user_info = mongo.db.user_info_list.find_one({"sid": request.sid})
        # 获取mysql中的用户信息
        user = User.query.get(user_info.get("_id"))
        if user is None:
            socketio.emit("pet_use_response", {"errno": status.CODE_NO_USER, "errmsg": errmsg.user_not_exists},
                          namespace="/mofang", room=room)
            return
    
        # 获取道具
        prop_data = Goods.query.get(pid)
        if prop_data is None:
            socketio.emit("pet_use_response", {"errno":status.CODE_NO_SUCH_PROP,"errmsg":errmsg.not_such_prop}, namespace="/mofang", room=room)
            return
    
        if int(prop_data.prop_type) == 0:
            """使用植物道具"""
            # 1. 判断当前的植物数量是否有空余
            tree_list = user_info.get("user_tree_list", [])
    
            # 当前用户最多可种植的数量
            setting = Setting.query.filter(Setting.name == "user_active_tree").first()
            if setting is None:
                user_tree_number = 3
            else:
                user_tree_number = int(setting.value)
            user_tree_number = user_info.get("user_tree_number", user_tree_number)
    
            if len(tree_list) >= user_tree_number:
                socketio.emit("prop_use_response", {"errno": status.CODE_NO_EMPTY, "errmsg": errmsg.prop_not_empty},
                              namespace="/mofang", room=room)
                return
    
            # 使用道具
            mongo.db.user_info_list.update_one({"sid":room},{"$push":{"user_tree_list":
                { # 植物状态
                    "time": int(datetime.now().timestamp()), # 种植时间
                    "status": 2, # 植物状态,2表示幼苗状态
                    "allow_water": False, # 是否允许浇水
                    "waters": 0, # 浇水次数
                    "shears": 0, # 使用剪刀次数
                }
            }})
    
            # 从种下去到浇水的时间
            pipe = redis.pipeline()
            pipe.multi()
            setting = Setting.query.filter(Setting.name == "tree_water_time").first()
            if setting is None:
                tree_water_time = 3600
            else:
                tree_water_time = int(setting.value)
            # 必须等时间到了才可以浇水
            pipe.setex("user_tree_water_%s_%s" % (user.id,len(tree_list)),int(tree_water_time),"_")
            # 必须等时间到了才可以到成长期
            setting = Setting.query.filter(Setting.name == "tree_growup_time").first()
            if setting is None:
                tree_growup_time = 3600
            else:
                tree_growup_time = int(setting.value)
            pipe.setex("user_tree_growup_%s_%s" % (user.id,len(tree_list)),tree_growup_time, "_")
            pipe.execute()
    
            # 设置定时任务进行浇水
            redis.append("tree_list_water","%s_%s," % (user.id,len(tree_list)))
            user_login({"uid": user.id})
    
        if int(prop_data.prop_type) == 1:
            """使用宠物道具"""
            # 1. 判断当前的宠物数量
            # 获取宠物列表
            pet_list = user_info.get("pet_list", [])
            if len(pet_list) > 1 and pet_list[0]['is_die'] == 0 and pet_list[1]['is_die'] == 0:
                socketio.emit("pet_use_response", {"errno":status.CODE_NO_EMPTY,"errmsg":errmsg.pet_not_empty}, namespace="/mofang", room=room)
                return
    
            # 2. 是否有空余的宠物栏位
            pet_number = user_info.get("pet_number",1)
            length = len(pet_list)
    
            if length == 2:
                live_leng = 0
                if pet_list[0]['is_die'] == 0:
                    live_leng += 1
                if pet_list[1]['is_die'] == 0:
                    live_leng += 1
            elif length == 1 and pet_list[0]['is_die'] == 0:
                live_leng = 1
            else:
                live_leng = 0
            if  live_leng >= pet_number:
                socketio.emit("pet_use_response", {"errno":status.CODE_NO_EMPTY,"errmsg":errmsg.pet_not_empty}, namespace="/mofang", room=room)
                return
    
            # 3. 初始化当前宠物信息
            # 获取有效期和防御值
            exp_data = Setting.query.filter(Setting.name=="pet_expire_%s" % pid).first()
            ski_data = Setting.query.filter(Setting.name=="pet_skill_%s" % pid).first()
    
            if exp_data is None:
                # 默认7天有效期
                expire = 7
            else:
                expire = exp_data.value
    
            if ski_data is None:
                skill  = 10
            else:
                skill  = ski_data.value
    
            # 在redis中设置当前宠物的饱食度
            pipe = redis.pipeline()
            pipe.multi()
            setting = Setting.query.filter(Setting.name == ("pet_hp_max_%s" % pid)).first()
            if setting is None:
                pet_hp_max = 7200
            else:
                pet_hp_max = int(setting.value)
    
            # 基本保存到mongo
            # 判断是否有挂了的宠物在列表中
            pet_data = {
                 "pid": pid,
                 "image": prop_data.image,
                 "created_time": int( datetime.now().timestamp() ),
                 "skill": skill,
                 "is_die": 0,
            }
    
            # 如果第一个宠物是挂了的
            if len(pet_list) == 0:
                mongo.db.user_info_list.update_one({"sid":room},{"$set":{"pet_list":[pet_data]}})
    
                pipe.setex("pet_%s_%s_hp" % (user.id, 1), pet_hp_max, "_")
                pipe.setex("pet_%s_%s_expire" % (user.id, 1), int(expire) * 24 * 60 * 60, "_")
            elif len(pet_list) == 1 and int(pet_list[0]["is_die"]) == 1:
                """只有一个挂了的宠物"""
                mongo.db.user_info_list.update_one({"sid":room},{"$set":{"pet_list":[pet_data]}})
    
                pipe.setex("pet_%s_%s_hp" % (user.id, 1), pet_hp_max, "_")
                pipe.setex("pet_%s_%s_expire" % (user.id, 1), int(expire) * 24 * 60 * 60, "_")
    
            elif len(pet_list) == 1 and int(pet_list[0]["is_die"]) == 0:
                """只有一个活着的宠物"""
                mongo.db.user_info_list.update_one({"sid": room}, {"$push": {"pet_list": pet_data}})
                pipe.setex("pet_%s_%s_hp" % (user.id, 2), pet_hp_max, "_")
                pipe.setex("pet_%s_%s_expire" % (user.id, 2), int(expire) * 24 * 60 * 60, "_")
            elif len(pet_list) == 2 and int(pet_list[0]["is_die"]) == 1:
                """有2个宠物,但是第1个挂了"""
                pet_list[0] = pet_data
                mongo.db.user_info_list.update_one({"sid": room}, {"$set": {"pet_list": pet_list}})
                pipe.setex("pet_%s_%s_hp" % (user.id, 1), pet_hp_max, "_")
                pipe.setex("pet_%s_%s_expire" % (user.id, 1), int(expire) * 24 * 60 * 60, "_")
            elif len(pet_list) == 2 and int(pet_list[1]["is_die"]) == 1:
                """有2个宠物,但是第2个挂了"""
                pet_list[1] = pet_data
                pipe.setex("pet_%s_%s_hp" % (user.id, 2), pet_hp_max, "_")
                pipe.setex("pet_%s_%s_expire" % (user.id, 2), int(expire) * 24 * 60 * 60, "_")
                mongo.db.user_info_list.update_one({"sid": room}, {"$set": {"pet_list": pet_list}})
    
            pipe.execute()
            pet_show()
    
        if int(prop_data.prop_type) == 3:
            """宠物喂食"""
    
            pet_list = user_info.get("pet_list")
            if len(pet_list) < 1:
                socketio.emit("pet_use_response", {"errno": status.CODE_NO_PET, "errmsg": errmsg.not_pet},
                              namespace="/mofang", room=room)
                return
    
            current_hp_time = redis.ttl("pet_%s_%s_hp" % (user.id,pet_key+1))
            setting = Setting.query.filter(Setting.name== ("pet_hp_max_%s" % (pet_list[pet_key]["pid"]))).first()
            if setting is None:
                pet_hp_max = 7200
            else:
                pet_hp_max = int(setting.value)
    
            current_pet_hp = math.ceil(current_hp_time / pet_hp_max * 100)
    
            if current_pet_hp > 90:
                """饱食度高于90%无法喂养"""
                socketio.emit("pet_use_response", {"errno": status.CODE_NO_FEED, "errmsg": errmsg.no_feed},
                              namespace="/mofang", room=room)
                return
    
            if current_pet_hp <= 0:
                socketio.emit("pet_use_response", {"errno": status.CODE_NO_PET, "errmsg": errmsg.not_pet},
                              namespace="/mofang", room=room)
                return
            setting = Setting.query.filter(Setting.name == "pet_feed_number").first()
            if setting is None:
                pet_feed_number = 0.1
            else:
                pet_feed_number = float(setting.value)
            prop_time = pet_hp_max * pet_feed_number
            time = int( current_hp_time + prop_time )
    
            redis.expire("pet_%s_%s_hp" % (user.id,pet_key+1),time)
            socketio.emit("pet_feed_response", {"errno": status.CODE_OK, "errmsg": errmsg.ok,"pet_key":pet_key,"hp_time":time},
                          namespace="/mofang", room=room)
        # 扣除背包中的道具数量
        prop_list = user_info.get("prop_list",{})
        for key,value in prop_list.items():
            if key == ("prop_%s" % pid):
                if int(value) > 1:
                    prop_list[key] = int(value) - 1
                else:
                    prop_list.pop(key)
                break
    
        mongo.db.user_info_list.update_one({"sid":room},{"$set":{"prop_list":prop_list}})
        user_prop()
    
        socketio.emit("prop_use_response", {"errno": status.CODE_OK, "errmsg": errmsg.ok},
                          namespace="/mofang", room=room)
    View Code

    2.celery

    mycelery.main.py代码

    from celery import Celery
    from application import init_app
    # 初始化celery对象
    app = Celery("flask")
    
    # 初始化flask
    flask_app = init_app("application.settings.dev").app
    # 加载配置
    app.config_from_object("mycelery.config")
    # 自动注册任务
    app.autodiscover_tasks(["mycelery.sms","mycelery.tree"])
    # 运行celery
    # 主程序终端下启动: celery -A mycelery.main worker -l info
    # 调度器终端下启动: celery -A mycelery.main beat

    mycelery.config.py代码

    # 任务队列地址
    broker_url = 'redis://127.0.0.1:6379/15'
    # 结果队列地址
    result_backend = "redis://127.0.0.1:6379/14"
    
    
    # 周期任务
    from mycelery.main import app
    app.conf.beat_schedule = {
        # Executes every Monday morning at 7:30 a.m.
        'tree_write_task': {
            'task': 'tree_write',
            'schedule': 30,
        },
    }

    接下来在终端下运行celery

    celery -A mycelery.main worker -l info
    celery -A mycelery.main beat

    2.客户端通过倒计时判断时间,显示浇水道具

    1.main.css

    .orchard-frame .tree-box .tree{
      position: relative;
    }
    .tree-popped{
      top: 4rem;
      right: 3rem;
      height: 3.4rem;
      width: 3.4rem;
      border-radius: 3.4rem;
    }
    .tree-popped img{
      width: 2.2rem!important;
      height: 2.2rem!important;
    }

    2.my_orchard.html

    <!DOCTYPE html>
    <html>
    <head>
        <title>用户中心</title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta charset="utf-8">
        <link rel="stylesheet" href="../static/css/main.css">
        <script src="../static/js/vue.js"></script>
        <script src="../static/js/axios.js"></script>
        <script src="../static/js/main.js"></script>
        <script src="../static/js/uuid.js"></script>
        <script src="../static/js/settings.js"></script>
        <script src="../static/js/socket.io.js"></script>
    </head>
    <body>
        <div class="app orchard orchard-frame" id="app">
        <div class="background">
          <img class="grassland2" src="../static/images/grassland2.png" alt="">
          <img class="mushroom1" src="../static/images/mushroom1.png" alt="">
          <img class="stake1" src="../static/images/stake1.png" alt="">
          <img class="stake2" src="../static/images/stake2.png" alt="">
        </div>
        <div class="pet-box">
          <div class="pet">
                    <span @click="feed(0)" class="popped" v-if="pet_list[0] && pet_list[0].hp<90 && pet_list[0].hp>0 && pet_food_num > 0">
                        <img class="pet-prop" src="../static/images/prop4.png" alt="">
                    </span>
                    <img v-if="pet_list.length > 0 && pet_list[0].hp>0" class="pet-item" :src="settings.static_url+pet_list[0].image" alt="">
          </div>
                <div class="pet" v-if="pet_number > 1">
                    <span @click="feed(1)" class="popped" v-if="pet_list[1] && pet_list[1].hp<90 && pet_list[1].hp>0 && pet_food_num > 0">
                        <img class="pet-prop" src="../static/images/prop4.png" alt="">
                    </span>
                    <img v-if="pet_list.length > 1  && pet_list[1].hp>0" class="pet-item" :src="settings.static_url+pet_list[1].image" alt="">
          </div>
          <div class="pet turned_off" v-if="pet_number==1">
            <img class="turned_image" src="../static/images/turned_off.png" alt="">
            <p>请购买宠物</p>
          </div>
        </div>
        <div class="tree-list">
          <div class="tree-box">
                    <div class="tree" v-for="tree in user_tree_data.user_tree_list">
                        <span class="popped tree-popped">
                            <img src="../static/images/prop3.png" alt="">
                        </span>
                        <img :src="tree_img(tree.status)" alt="">
                    </div>
                    <!-- 已激活但是未种植的树桩列表 -->
                    <div class="tree" v-for="i in active_tree">
                        <img src="../static/images/tree1.png" alt="">
                    </div>
                    <!-- 未激活树桩列表 -->
                    <div @click="unlock_tree" class="tree" v-for="i in lock_tree">
                        <img src="../static/images/tree0.png" alt="">
                    </div>
          </div>
    
        </div>
        <div class="prop-list">
          <div class="prop">
            <img src="../static/images/prop1.png" alt="">
            <span>{{fertilizer_num}}</span>
            <p>化肥</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop2.png" alt="">
            <span>{{shears}}</span>
            <p>修剪</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop3.png" alt="">
            <span>{{waters}}</span>
            <p>浇水</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop4.png" alt="">
            <span>{{pet_food_num}}</span>
            <p>宠物粮</p>
          </div>
        </div>
        <div class="pet-hp-list">
          <div class="pet-hp" v-for="pet,key in pet_list">
            <p>宠物{{key+1}} 饱食度</p>
            <div class="hp">
              <div :style="{ pet.hp+'%',backgroundColor:bg(pet.hp)}" class="process">{{pet.hp}}%</div>
            </div>
          </div>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
              namespace: '/mofang',
              token:"",
              socket: null,
                        pet_food_num:0, // 宠物粮数量
                        fertilizer_num:0,  // 化肥数量
                        waters:0,  // 浇水次数
                        shears:0, // 剪刀次数
                        pet_list:[],
                        user_tree_data:{
                            "total_tree": 9,       // 总树桩数量
                            "user_tree_number": 0, // 当前用户激活树桩数量
                            "user_tree_list":[     // 当前种植的树桩列表状态
    
                            ],
                        },
                        tree_status:{
    
                        },
                        // user_tree_data:{
                        //     "total_tree":9,        // 总树桩数量
                        //     "user_tree_number": 5, // 当前用户激活树桩数量
                        //     "user_tree_list":[     // 当前种植的树桩列表状态
                        //             { // 树桩状态
                        //                  "time":1609808084, // 种植时间
                        //                  "status":4,        // 植物状态
                        //                  "has_time": 300,   // 状态时间
                        //             },
                        //     ],
                        // },
                        // tree_status:{
                        //     "tree_status_0": "tree0.png", // 树桩
                        //     "tree_status_1": "tree1.png", // 空桩
                        //     "tree_status_2": "tree2.png", // 幼苗
                        //     "tree_status_3": "tree3.png", // 成长
                        //     "tree_status_4": "tree4.png", // 成熟
                        // },
                        pet_number:[],
              timeout: 0,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"orchard.html",params:{}},
                    }
                },
                computed:{
                    // 已激活但是未使用的树桩
                    active_tree(){
                        return parseInt(this.user_tree_data.user_tree_number - this.user_tree_data.user_tree_list.length);
                    },
                    // 未激活的剩余树桩
                    lock_tree(){
                        return parseInt( this.user_tree_data.total_tree-this.user_tree_data.user_tree_number);
                    },
                },
          created(){
                    this.show_pet_list();
                    this.show_tree_list();
                    this.get_prop_list();
          },
                methods:{
                    feed(pet_key){
                        // 我的背包
                        this.game.save({"pet_key":pet_key}); // 记录本次喂养的宠物下标
                        this.game.goFrame("package","package.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
    
                        api.addEventListener({
                            name: 'pet_feed_success'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.pet_list[ret.value.pet_key].hp = Math.ceil( ret.value.hp_time / this.pet_list[ret.value.pet_key].pet_hp_max * 100 )
                                    this.pet_list[ret.value.pet_key].hp_time = ret.value.hp_time;
                    this.game.save({"pet_list":this.pet_list})
                                }
                        });
    
                    },
                    bg(hp){
                        if(hp>90){
                            return "#f00";
                        }else if(hp>60){
                            return "#a00";
                        }else if(hp>30){
                            return "#600";
                        }else{
                            return "#300";
                        }
                    },
                    get_prop_list(){
                        // 更新道具列表信息
                        api.addEventListener({
                            name: 'update_prop_data'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.pet_food_num = this.game.get("pet_food_num");
                                    this.fertilizer_num = this.game.get("fertilizer_num");
                            }
                        });
                    },
                    tree_img(status){
                        return '../static/images/'+this.tree_status[status];
                    },
                    show_pet_list(){
                        api.addEventListener({
                                name: 'pet_show_success'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 显示宠物相关
                                    this.pet_list = this.game.get("pet_list");
                                    this.pet_number = parseInt(this.game.get("pet_number"));
                                    var timer = null;
                                    setInterval(()=>{
                                        // 保证定时器中每次读取的都是最新的宠物信息
                                        this.pet_list = this.game.get("pet_list");
                                        for( let i in this.pet_list){
                                                if(this.pet_list[i].hp_time<1 && this.pet_list[i].is_die==0){
                                                    // 宠物挂了
                                                    api.sendEvent({
                                                        name: 'pet_die',
                                                        extra: {
    
                                                        }
                                                    });
                                                }
                                                if(this.pet_list[i].hp_time>0){
                                                    this.pet_list[i].hp_time-=0.5;
                                                    this.pet_list[i].hp = Math.ceil( this.pet_list[i].hp_time / this.pet_list[i].pet_hp_max * 100 )
                                                }
                                        }
                                        this.game.save({"pet_list":this.pet_list});
                                    },500);
                                }
                        });
                    },
                    show_tree_list(){
                        api.addEventListener({
                                name: 'user_tree_data'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 用户种植植物信息
                                    this.user_tree_data.tree_total = parseInt(this.game.get("tree_total"));
                                    this.user_tree_data.user_tree_number = parseInt(this.game.get("user_tree_number"));
                                    this.user_tree_data.user_tree_list = this.game.get("user_tree_list");
                                    this.tree_status = this.game.get("tree_status");
                                    this.pet_food_num = this.game.get("pet_food_num");
                                    this.fertilizer_num = this.game.get("fertilizer_num");
                                    this.waters = this.game.get("waters");
                                    this.shears = this.game.get("shears");
                                }
                        });
                    },
                    unlock_tree(){
                        // 激活树桩通知
                        api.confirm({
                            title: '提示',
                            msg: '是否激活树桩?',
                            buttons: ['确定', '取消']
                        }, (ret, err)=>{
                            if( ret.buttonIndex == 1 ){
                                    api.sendEvent({
                                        name: 'active_tree',
                                        extra: {
    
                                            }
                                    });
                            }
                        });
    
                        // 激活成功!
                        api.addEventListener({
                            name: 'active_tree_success'
                        }, (ret, err)=>{
                            if( ret ){
                                 // 新增树桩的数量
                                         this.user_tree_data.user_tree_number+=1;
                                        this.game.save({"user_tree_number": this.user_tree_data.user_tree_number});
                            }
                        });
                    }
                }
            });
        }
        </script>
    </body>
    </html>
    View Code

    3.客户端判断当前种植物状态控制图标的显示和隐藏

    my_orchard.html代码

    <!DOCTYPE html>
    <html>
    <head>
        <title>用户中心</title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta charset="utf-8">
        <link rel="stylesheet" href="../static/css/main.css">
        <script src="../static/js/vue.js"></script>
        <script src="../static/js/axios.js"></script>
        <script src="../static/js/main.js"></script>
        <script src="../static/js/uuid.js"></script>
        <script src="../static/js/settings.js"></script>
        <script src="../static/js/socket.io.js"></script>
    </head>
    <body>
        <div class="app orchard orchard-frame" id="app">
        <div class="background">
          <img class="grassland2" src="../static/images/grassland2.png" alt="">
          <img class="mushroom1" src="../static/images/mushroom1.png" alt="">
          <img class="stake1" src="../static/images/stake1.png" alt="">
          <img class="stake2" src="../static/images/stake2.png" alt="">
        </div>
        <div class="pet-box">
          <div class="pet">
                    <span @click="feed(0)" class="popped" v-if="pet_list[0] && pet_list[0].hp<90 && pet_list[0].hp>0 && pet_food_num > 0">
                        <img class="pet-prop" src="../static/images/prop4.png" alt="">
                    </span>
                    <img v-if="pet_list.length > 0 && pet_list[0].hp>0" class="pet-item" :src="settings.static_url+pet_list[0].image" alt="">
          </div>
                <div class="pet" v-if="pet_number > 1">
                    <span @click="feed(1)" class="popped" v-if="pet_list[1] && pet_list[1].hp<90 && pet_list[1].hp>0 && pet_food_num > 0">
                        <img class="pet-prop" src="../static/images/prop4.png" alt="">
                    </span>
                    <img v-if="pet_list.length > 1  && pet_list[1].hp>0" class="pet-item" :src="settings.static_url+pet_list[1].image" alt="">
          </div>
          <div class="pet turned_off" v-if="pet_number==1">
            <img class="turned_image" src="../static/images/turned_off.png" alt="">
            <p>请购买宠物</p>
          </div>
        </div>
        <div class="tree-list">
          <div class="tree-box">
                    <div class="tree" v-for="tree in user_tree_data.user_tree_list">
                        <span class="popped tree-popped" v-if="tree.allow_water && tree.waters<1">
                            <img src="../static/images/prop3.png" alt="">
                        </span>
                        <img :src="tree_img(tree.status)" alt="">
                    </div>
                    <!-- 已激活但是未种植的树桩列表 -->
                    <div class="tree" v-for="i in active_tree">
                        <img src="../static/images/tree1.png" alt="">
                    </div>
                    <!-- 未激活树桩列表 -->
                    <div @click="unlock_tree" class="tree" v-for="i in lock_tree">
                        <img src="../static/images/tree0.png" alt="">
                    </div>
          </div>
    
        </div>
        <div class="prop-list">
          <div class="prop">
            <img src="../static/images/prop1.png" alt="">
            <span>{{fertilizer_num}}</span>
            <p>化肥</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop2.png" alt="">
            <span>{{shears}}</span>
            <p>修剪</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop3.png" alt="">
            <span>{{waters}}</span>
            <p>浇水</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop4.png" alt="">
            <span>{{pet_food_num}}</span>
            <p>宠物粮</p>
          </div>
        </div>
        <div class="pet-hp-list">
          <div class="pet-hp" v-for="pet,key in pet_list">
            <p>宠物{{key+1}} 饱食度</p>
            <div class="hp">
              <div :style="{ pet.hp+'%',backgroundColor:bg(pet.hp)}" class="process">{{pet.hp}}%</div>
            </div>
          </div>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
              namespace: '/mofang',
              token:"",
              socket: null,
                        pet_food_num:0, // 宠物粮数量
                        fertilizer_num:0,  // 化肥数量
                        waters:0,  // 浇水次数
                        shears:0, // 剪刀次数
                        pet_list:[],
                        user_tree_data:{
                            "total_tree": 9,       // 总树桩数量
                            "user_tree_number": 0, // 当前用户激活树桩数量
                            "user_tree_list":[     // 当前种植的树桩列表状态
    
                            ],
                        },
                        tree_status:{
    
                        },
                        // user_tree_data:{
                        //     "total_tree":9,        // 总树桩数量
                        //     "user_tree_number": 5, // 当前用户激活树桩数量
                        //     "user_tree_list":[     // 当前种植的树桩列表状态
                        //             { // 树桩状态
                        //                  "time":1609808084, // 种植时间
                        //                  "status":4,        // 植物状态
                        //                  "has_time": 300,   // 状态时间
                        //             },
                        //     ],
                        // },
                        // tree_status:{
                        //     "tree_status_0": "tree0.png", // 树桩
                        //     "tree_status_1": "tree1.png", // 空桩
                        //     "tree_status_2": "tree2.png", // 幼苗
                        //     "tree_status_3": "tree3.png", // 成长
                        //     "tree_status_4": "tree4.png", // 成熟
                        // },
                        pet_number:[],
              timeout: 0,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"orchard.html",params:{}},
                    }
                },
                computed:{
                    // 已激活但是未使用的树桩
                    active_tree(){
                        return parseInt(this.user_tree_data.user_tree_number - this.user_tree_data.user_tree_list.length);
                    },
                    // 未激活的剩余树桩
                    lock_tree(){
                        return parseInt( this.user_tree_data.total_tree-this.user_tree_data.user_tree_number);
                    },
                },
          created(){
                    this.show_pet_list();
                    this.show_tree_list();
                    this.get_prop_list();
          },
                methods:{
                    feed(pet_key){
                        // 我的背包
                        this.game.save({"pet_key":pet_key}); // 记录本次喂养的宠物下标
                        this.game.goFrame("package","package.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
    
                        api.addEventListener({
                            name: 'pet_feed_success'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.pet_list[ret.value.pet_key].hp = Math.ceil( ret.value.hp_time / this.pet_list[ret.value.pet_key].pet_hp_max * 100 )
                                    this.pet_list[ret.value.pet_key].hp_time = ret.value.hp_time;
                    this.game.save({"pet_list":this.pet_list})
                                }
                        });
    
                    },
                    bg(hp){
                        if(hp>90){
                            return "#f00";
                        }else if(hp>60){
                            return "#a00";
                        }else if(hp>30){
                            return "#600";
                        }else{
                            return "#300";
                        }
                    },
                    get_prop_list(){
                        // 更新道具列表信息
                        api.addEventListener({
                            name: 'update_prop_data'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.pet_food_num = this.game.get("pet_food_num");
                                    this.fertilizer_num = this.game.get("fertilizer_num");
                            }
                        });
                    },
                    tree_img(status){
                        return '../static/images/'+this.tree_status[status];
                    },
                    show_pet_list(){
                        var pet_timer = null;
                        api.addEventListener({
                                name: 'pet_show_success'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 显示宠物相关
                                    this.pet_list = this.game.get("pet_list");
                                    this.pet_number = parseInt(this.game.get("pet_number"));
                                    clearInterval(pet_timer);
                                    pet_timer = setInterval(()=>{
                                        // 保证定时器中每次读取的都是最新的宠物信息
                                        this.pet_list = this.game.get("pet_list");
                                        for( let i in this.pet_list){
                                                if(this.pet_list[i].hp_time<1 && this.pet_list[i].is_die==0){
                                                    // 宠物挂了
                                                    api.sendEvent({
                                                        name: 'pet_die',
                                                        extra: {
    
                                                        }
                                                    });
                                                }
                                                if(this.pet_list[i].hp_time>0){
                                                    this.pet_list[i].hp_time-=0.5;
                                                    this.pet_list[i].hp = Math.ceil( this.pet_list[i].hp_time / this.pet_list[i].pet_hp_max * 100 )
                                                }
                                        }
                                        this.game.save({"pet_list":this.pet_list});
                                    },500);
                                }
                        });
                    },
                    show_tree_list(){
                        var tree_timer = null; // 定时器标记符
                        api.addEventListener({
                                name: 'user_tree_data'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 用户种植植物信息
                                    this.user_tree_data.tree_total = parseInt(this.game.get("tree_total"));
                                    this.user_tree_data.user_tree_number = parseInt(this.game.get("user_tree_number"));
                                    this.user_tree_data.user_tree_list = this.game.get("user_tree_list");
                                    this.tree_status = this.game.get("tree_status");
                                    this.pet_food_num = this.game.get("pet_food_num");
                                    this.fertilizer_num = this.game.get("fertilizer_num");
                                    this.waters = this.game.get("waters");
                                    this.shears = this.game.get("shears");
                                    clearInterval(tree_timer);
                                    tree_timer = setInterval(()=>{
                                        var user_tree_list = this.game.get("user_tree_list");
                                        for(let tree of user_tree_list){
                                            if(tree.water_time>-2){
                                                tree.water_time-=1;
                                            }
                                            if(tree.water_time<=-2 && tree.allow_water==false){
                                                 // 通知服务端允许用户浇水
                                                 tree.allow_water=true;
                                                 this.waters+=1;
                                            }
                                        }
                                        this.user_tree_data.user_tree_list = user_tree_list;
                                        this.game.save({"user_tree_list":user_tree_list});
                                    },1000);
                                }
                        });
                    },
                    unlock_tree(){
                        // 激活树桩通知
                        api.confirm({
                            title: '提示',
                            msg: '是否激活树桩?',
                            buttons: ['确定', '取消']
                        }, (ret, err)=>{
                            if( ret.buttonIndex == 1 ){
                                    api.sendEvent({
                                        name: 'active_tree',
                                        extra: {
    
                                            }
                                    });
                            }
                        });
    
                        // 激活成功!
                        api.addEventListener({
                            name: 'active_tree_success'
                        }, (ret, err)=>{
                            if( ret ){
                                 // 新增树桩的数量
                                         this.user_tree_data.user_tree_number+=1;
                                        this.game.save({"user_tree_number": this.user_tree_data.user_tree_number});
                            }
                        });
                    }
                }
            });
        }
        </script>
    </body>
    </html>
    View Code

    4.当用户单击浇水图标, 则根据当前果树的种植时间和状态确定是否进入成长期

    1.socket.py

    @socketio.on("water_tree", namespace="/mofang")
    def water_tree(key):
        """浇水"""
        room = request.sid
        # 获取mongo中的用户信息
        query = {"sid": request.sid}
        user_info = mongo.db.user_info_list.find_one(query)
        # 获取mysql中的用户信息
        user = User.query.get(user_info.get("_id"))
        if user is None:
            socketio.emit("water_tree_response", {"errno": status.CODE_NO_USER, "errmsg": errmsg.user_not_exists},
                          namespace="/mofang", room=room)
            return
    
        print("给%s的植物%s" % (user.id,key))
        user_tree_list = user_info.get("user_tree_list",[])
        try:
            tree_data = user_tree_list[key]
        except Exception as e:
            socketio.emit("water_tree_response", {"errno": status.CODE_NO_SUCH_TREE, "errmsg": errmsg.tree_not_exists},
                          namespace="/mofang", room=room)   
            return
    
        if tree_data.get("allow_water",False) and int(tree_data.get("waters",1)) == 0:
            """允许浇水"""
            tree_data["waters"] = 1
            # 如果种植物的种植时间达到成长期,则修改种植物的成长状态
            growup = redis.ttl("user_tree_growup_%s_%s" % (user.id,key))
            if growup == -2:
                tree_data["status"] = 3
    
        mongo.db.user_info_list.update_one(query,{"$set":{"user_tree_list":user_tree_list}})
        socketio.emit("water_tree_response", {"errno": status.CODE_OK, "errmsg": errmsg.ok},
                      namespace="/mofang", room=room)
        user_login({"uid": user.id})

    2.客户端发起浇水通知

    <!DOCTYPE html>
    <html>
    <head>
        <title>用户中心</title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta charset="utf-8">
        <link rel="stylesheet" href="../static/css/main.css">
        <script src="../static/js/vue.js"></script>
        <script src="../static/js/axios.js"></script>
        <script src="../static/js/main.js"></script>
        <script src="../static/js/uuid.js"></script>
        <script src="../static/js/settings.js"></script>
        <script src="../static/js/socket.io.js"></script>
    </head>
    <body>
        <div class="app orchard orchard-frame" id="app">
        <div class="background">
          <img class="grassland2" src="../static/images/grassland2.png" alt="">
          <img class="mushroom1" src="../static/images/mushroom1.png" alt="">
          <img class="stake1" src="../static/images/stake1.png" alt="">
          <img class="stake2" src="../static/images/stake2.png" alt="">
        </div>
        <div class="pet-box">
          <div class="pet">
                    <span @click="feed(0)" class="popped" v-if="pet_list[0] && pet_list[0].hp<90 && pet_list[0].hp>0 && pet_food_num > 0">
                        <img class="pet-prop" src="../static/images/prop4.png" alt="">
                    </span>
                    <img v-if="pet_list.length > 0 && pet_list[0].hp>0" class="pet-item" :src="settings.static_url+pet_list[0].image" alt="">
          </div>
                <div class="pet" v-if="pet_number > 1">
                    <span @click="feed(1)" class="popped" v-if="pet_list[1] && pet_list[1].hp<90 && pet_list[1].hp>0 && pet_food_num > 0">
                        <img class="pet-prop" src="../static/images/prop4.png" alt="">
                    </span>
                    <img v-if="pet_list.length > 1  && pet_list[1].hp>0" class="pet-item" :src="settings.static_url+pet_list[1].image" alt="">
          </div>
          <div class="pet turned_off" v-if="pet_number==1">
            <img class="turned_image" src="../static/images/turned_off.png" alt="">
            <p>请购买宠物</p>
          </div>
        </div>
        <div class="tree-list">
          <div class="tree-box">
                    <div class="tree" v-for="tree,key in user_tree_data.user_tree_list">
                        <span @click="water_tree(key)" class="popped tree-popped" v-if="tree.allow_water && tree.waters<1">
                            <img src="../static/images/prop3.png" alt="">
                        </span>
                        <img :src="tree_img(tree.status)" alt="">
                    </div>
                    <!-- 已激活但是未种植的树桩列表 -->
                    <div class="tree" v-for="i in active_tree">
                        <img src="../static/images/tree1.png" alt="">
                    </div>
                    <!-- 未激活树桩列表 -->
                    <div @click="unlock_tree" class="tree" v-for="i in lock_tree">
                        <img src="../static/images/tree0.png" alt="">
                    </div>
          </div>
    
        </div>
        <div class="prop-list">
          <div class="prop">
            <img src="../static/images/prop1.png" alt="">
            <span>{{fertilizer_num}}</span>
            <p>化肥</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop2.png" alt="">
            <span>{{shears}}</span>
            <p>修剪</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop3.png" alt="">
            <span>{{waters}}</span>
            <p>浇水</p>
          </div>
          <div class="prop">
            <img src="../static/images/prop4.png" alt="">
            <span>{{pet_food_num}}</span>
            <p>宠物粮</p>
          </div>
        </div>
        <div class="pet-hp-list">
          <div class="pet-hp" v-for="pet,key in pet_list">
            <p>宠物{{key+1}} 饱食度</p>
            <div class="hp">
              <div :style="{ pet.hp+'%',backgroundColor:bg(pet.hp)}" class="process">{{pet.hp}}%</div>
            </div>
          </div>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
              namespace: '/mofang',
              token:"",
              socket: null,
                        pet_food_num:0, // 宠物粮数量
                        fertilizer_num:0,  // 化肥数量
                        waters:0,  // 浇水次数
                        shears:0, // 剪刀次数
                        pet_list:[],
                        user_tree_data:{
                            "total_tree": 9,       // 总树桩数量
                            "user_tree_number": 0, // 当前用户激活树桩数量
                            "user_tree_list":[     // 当前种植的树桩列表状态
    
                            ],
                        },
                        tree_status:{
    
                        },
                        // user_tree_data:{
                        //     "total_tree":9,        // 总树桩数量
                        //     "user_tree_number": 5, // 当前用户激活树桩数量
                        //     "user_tree_list":[     // 当前种植的树桩列表状态
                        //             { // 树桩状态
                        //                  "time":1609808084, // 种植时间
                        //                  "status":4,        // 植物状态
                        //                  "has_time": 300,   // 状态时间
                        //             },
                        //     ],
                        // },
                        // tree_status:{
                        //     "tree_status_0": "tree0.png", // 树桩
                        //     "tree_status_1": "tree1.png", // 空桩
                        //     "tree_status_2": "tree2.png", // 幼苗
                        //     "tree_status_3": "tree3.png", // 成长
                        //     "tree_status_4": "tree4.png", // 成熟
                        // },
                        pet_number:[],
              timeout: 0,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"orchard.html",params:{}},
                    }
                },
                computed:{
                    // 已激活但是未使用的树桩
                    active_tree(){
                        return parseInt(this.user_tree_data.user_tree_number - this.user_tree_data.user_tree_list.length);
                    },
                    // 未激活的剩余树桩
                    lock_tree(){
                        return parseInt( this.user_tree_data.total_tree-this.user_tree_data.user_tree_number);
                    },
                },
          created(){
                    this.show_pet_list();
                    this.show_tree_list();
                    this.get_prop_list();
          },
                methods:{
                    water_tree(tree_key){
                        // 给种植物浇水
                        api.sendEvent({
                            name: 'water_tree',
                            extra: {
                                key: tree_key,
                            }
                        });
                        api.addEventListener({
                            name: 'water_tree_success'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.user_tree_data.user_tree_list[ret.value.key]["waters"] = 1;
                                    this.waters-=1;
                                    this.game.save({"user_tree_list":this.user_tree_data.user_tree_list});
                            }
                        });
    
                    },
                    feed(pet_key){
                        // 我的背包
                        this.game.save({"pet_key":pet_key}); // 记录本次喂养的宠物下标
                        this.game.goFrame("package","package.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
    
                        api.addEventListener({
                            name: 'pet_feed_success'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.pet_list[ret.value.pet_key].hp = Math.ceil( ret.value.hp_time / this.pet_list[ret.value.pet_key].pet_hp_max * 100 )
                                    this.pet_list[ret.value.pet_key].hp_time = ret.value.hp_time;
                    this.game.save({"pet_list":this.pet_list})
                                }
                        });
    
                    },
                    bg(hp){
                        if(hp>90){
                            return "#f00";
                        }else if(hp>60){
                            return "#a00";
                        }else if(hp>30){
                            return "#600";
                        }else{
                            return "#300";
                        }
                    },
                    get_prop_list(){
                        // 更新道具列表信息
                        api.addEventListener({
                            name: 'update_prop_data'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.pet_food_num = this.game.get("pet_food_num");
                                    this.fertilizer_num = this.game.get("fertilizer_num");
                            }
                        });
                    },
                    tree_img(status){
                        return '../static/images/'+this.tree_status[status];
                    },
                    show_pet_list(){
                        var pet_timer = null;
                        api.addEventListener({
                                name: 'pet_show_success'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 显示宠物相关
                                    this.pet_list = this.game.get("pet_list");
                                    this.pet_number = parseInt(this.game.get("pet_number"));
                                    clearInterval(pet_timer);
                                    pet_timer = setInterval(()=>{
                                        // 保证定时器中每次读取的都是最新的宠物信息
                                        this.pet_list = this.game.get("pet_list");
                                        for( let i in this.pet_list){
                                                if(this.pet_list[i].hp_time<1 && this.pet_list[i].is_die==0){
                                                    // 宠物挂了
                                                    api.sendEvent({
                                                        name: 'pet_die',
                                                        extra: {
    
                                                        }
                                                    });
                                                }
                                                if(this.pet_list[i].hp_time>0){
                                                    this.pet_list[i].hp_time-=0.5;
                                                    this.pet_list[i].hp = Math.ceil( this.pet_list[i].hp_time / this.pet_list[i].pet_hp_max * 100 )
                                                }
                                        }
                                        this.game.save({"pet_list":this.pet_list});
                                    },500);
                                }
                        });
                    },
                    show_tree_list(){
                        var tree_timer = null; // 定时器标记符
                        api.addEventListener({
                                name: 'user_tree_data'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 用户种植植物信息
                                    this.user_tree_data.tree_total = parseInt(this.game.get("tree_total"));
                                    this.user_tree_data.user_tree_number = parseInt(this.game.get("user_tree_number"));
                                    this.user_tree_data.user_tree_list = this.game.get("user_tree_list");
                                    this.tree_status = this.game.get("tree_status");
                                    this.pet_food_num = this.game.get("pet_food_num");
                                    this.fertilizer_num = this.game.get("fertilizer_num");
                                    this.waters = this.game.get("waters");
                                    this.shears = this.game.get("shears");
                                    clearInterval(tree_timer);
                                    tree_timer = setInterval(()=>{
                                        var user_tree_list = this.game.get("user_tree_list");
                                        for(let tree of user_tree_list){
                                            if(tree.water_time>-2){
                                                tree.water_time-=1;
                                            }
                                            if(tree.water_time<=-2 && tree.allow_water==false){
                                                 // 通知服务端允许用户浇水
                                                 tree.allow_water=true;
                                                 this.waters+=1;
                                            }
                                            if(tree.growup_time>=-2){
                                                tree.growup_time-=1;
                                            }
                                            if(tree.growup_time<=-2 && tree.waters>0 && tree.status=="tree_status_2"){
                                                 // 通知服务端植物成长了
                                                 tree.status="tree_status_3";
                                            }
                                        }
                                        this.user_tree_data.user_tree_list = user_tree_list;
                                        this.game.print(this.user_tree_data.user_tree_list)
                                        this.game.save({"user_tree_list":user_tree_list});
                                    },1000);
                                }
                        });
                    },
                    unlock_tree(){
                        // 激活树桩通知
                        api.confirm({
                            title: '提示',
                            msg: '是否激活树桩?',
                            buttons: ['确定', '取消']
                        }, (ret, err)=>{
                            if( ret.buttonIndex == 1 ){
                                    api.sendEvent({
                                        name: 'active_tree',
                                        extra: {
    
                                            }
                                    });
                            }
                        });
    
                        // 激活成功!
                        api.addEventListener({
                            name: 'active_tree_success'
                        }, (ret, err)=>{
                            if( ret ){
                                 // 新增树桩的数量
                                         this.user_tree_data.user_tree_number+=1;
                                        this.game.save({"user_tree_number": this.user_tree_data.user_tree_number});
                            }
                        });
                    }
                }
            });
        }
        </script>
    </body>
    </html>
    my_orchard.html
    <!DOCTYPE html>
    <html>
    <head>
        <title>用户中心</title>
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta charset="utf-8">
        <link rel="stylesheet" href="../static/css/main.css">
        <script src="../static/js/vue.js"></script>
        <script src="../static/js/axios.js"></script>
        <script src="../static/js/main.js"></script>
        <script src="../static/js/uuid.js"></script>
        <script src="../static/js/settings.js"></script>
        <script src="../static/js/socket.io.js"></script>
    </head>
    <body>
        <div class="app orchard" id="app">
        <img class="music" :class="music_play?'music2':''" @click="music_play=!music_play" src="../static/images/player.png">
        <div class="orchard-bg">
                <img src="../static/images/bg2.png">
                <img class="board_bg2" src="../static/images/board_bg2.png">
            </div>
        <img class="back" @click="go_index" src="../static/images/user_back.png" alt="">
        <div class="header">
                <div class="info" @click="go_home">
                    <div class="avatar">
                        <img class="avatar_bf" src="../static/images/avatar_bf.png" alt="">
                        <img class="user_avatar" src="../static/images/avatar.png" alt="">
                        <img class="avatar_border" src="../static/images/avatar_border.png" alt="">
                    </div>
                    <p class="user_name">好听的昵称</p>
                </div>
                <div class="wallet">
                    <div class="balance" @click="user_recharge">
                        <p class="title"><img src="../static/images/money.png" alt="">钱包</p>
                        <p class="num">{{money}}</p>
                    </div>
                    <div class="balance">
                        <p class="title"><img src="../static/images/integral.png" alt="">果子</p>
                        <p class="num">99,999.00</p>
                    </div>
                </div>
          <div class="menu-list">
            <div class="menu">
              <img src="../static/images/menu1.png" alt="">
              排行榜
            </div>
            <div class="menu">
              <img src="../static/images/menu2.png" alt="">
              签到有礼
            </div>
            <div class="menu" @click="go_orchard_shop">
              <img src="../static/images/menu3.png" alt="">
              道具商城
            </div>
            <div class="menu">
              <img src="../static/images/menu4.png" alt="">
              邮件中心
            </div>
          </div>
            </div>
        <div class="footer" >
          <ul class="menu-list">
            <li class="menu">新手</li>
            <li class="menu" @click="go_my_package">背包</li>
            <li class="menu-center" @click="go_orchard_shop">商店</li>
            <li class="menu">消息</li>
            <li class="menu">好友</li>
          </ul>
        </div>
        </div>
        <script>
        apiready = function(){
            init();
            new Vue({
                el:"#app",
                data(){
                    return {
              music_play:true,
              namespace: '/mofang',
              token:"",
                        money:"",
                        settings_info:{
                            orchard: {},  // 种植园公共参数
                            user:{},      // 用户私有相关参数
                        },
              socket: null,
                        recharge_list: ['10','20','50','100','200','500','1000'],
              timeout: 0,
                        prev:{name:"",url:"",params:{}},
                        current:{name:"orchard",url:"orchard.html",params:{}},
                    }
                },
                beforeCreate(){
                    this.game.goFrame("orchard","my_orchard.html", this.current,{
                            x: 0,
                            y: 180,
                            w: 'auto',
                            h: 410,
                    },null);
                },
          created(){
            this.checkout();
                    this.money = this.game.fget("money");
          },
                methods:{
                    user_recharge(){
                        // 发起充值请求
                        api.actionSheet({
                            title: '余额充值',
                            cancelTitle: '取消',
                            buttons: this.recharge_list
                        }, (ret, err)=>{
                            if( ret ){
                                         if(ret.buttonIndex <= this.recharge_list.length){
                                                 // 充值金额
                                                 money = this.recharge_list[ret.buttonIndex-1];
                                                 // 调用支付宝充值
                                                 this.create_recharge(money);
                                         }
                            }else{
    
                            }
                        });
    
                    },
                    create_recharge(money){
                        // 获取历史信息记录
                        var token = this.game.get("access_token") || this.game.fget("access_token");
                        this.game.checkout(this, token, (new_access_token)=>{
                            this.axios.post("",{
                                "jsonrpc": "2.0",
                                "id": this.uuid(),
                                "method": "Recharge.create",
                                "params": {
                                    "money": money,
                                }
                            },{
                                headers:{
                                    Authorization: "jwt " + token,
                                }
                            }).then(response=>{
                                if(parseInt(response.data.result.errno)==1000){
                                    // 前往支付宝
                                    var aliPayPlus = api.require('aliPayPlus');
                                    aliPayPlus.payOrder({
                                         orderInfo: response.data.result.order_string,
                                         sandbox: response.data.result.sandbox, // 将来APP上线需要修改成false
                                     }, (ret, err)=>{
                                          pay_result = {
                                                9000:"支付成功",
                              8000:"正在处理中",
                              4000:"订单支付失败",
                              5000:"重复请求",
                              6001:"取消支付",
                              6002:"网络连接出错",
                                                6004:"支付结果未知",
                                            }
                                        api.alert({
                                            title: '支付结果',
                                            msg: pay_result[ret.code],
                                            buttons: ['确定']
                                        });
                                            // 通知服务端, 修改充值结果
                                            this.return_recharge(response.data.result.order_number,token);
                                    });
                                }else{
                                        this.game.print(response.data);
                                }
                            }).catch(error=>{
                                // 网络等异常
                                this.game.print(error);
                            });
                        })
                    },
                    return_recharge(out_trade_number,token){
                        this.axios.post("",{
                            "jsonrpc": "2.0",
                            "id": this.uuid(),
                            "method": "Recharge.return",
                            "params": {
                                "out_trade_number": out_trade_number,
                            }
                        },{
                            headers:{
                                Authorization: "jwt " + token,
                            }
                        }).then(response=>{
                            if(parseInt(response.data.result.errno)==1000){
                                this.money = response.data.result.money.toFixed(2);
                            }
                        })
                    },
            checkout(){
              var token = this.game.get("access_token") || this.game.fget("access_token");
              this.game.checkout(this,token,(new_access_token)=>{
                this.connect();
                            this.login();
                            this.user_package();
                            this.buy_prop();
                            this.unlock_package_number();
                            this.show_pet();
                            this.use_prop();
                            this.active_tree();
                            this.water_tree();
              });
            },
            connect(){
              // socket连接
              this.socket = io.connect(this.settings.socket_server + this.namespace, {transports: ['websocket']});
              this.socket.on('connect', ()=>{
                  this.game.print("开始连接服务端");
                                var id = this.game.fget("id");
                                this.socket.emit("login",{"uid":id});
                                this.socket.emit("user_prop");
              });
            },
                    login(){
                        this.socket.on("login_response",(message)=>{
                            this.settings_info.orchard = message.orchard_settings;
                            this.settings_info.user=message.user_settings;
                            this.game.fsave({
                                "orchard_settings":message.orchard_settings,
                                "user_settings":message.user_settings,
                            });
                            this.game.save({
                                "tree_total":message.tree_total,
                                "user_tree_number":message.user_tree_number,
                                "user_tree_list":message.user_tree_list,
                                "tree_status":message.tree_status,
                                "pet_food_num":message.pet_food_num,
                                "fertilizer_num":message.fertilizer_num,
                                "waters":message.waters,
                                "shears":message.shears,
                            });
                            setTimeout(()=>{
                                // 通知种植园页面获取到了当前用户的种植信息
                                api.sendEvent({
                                    name: 'user_tree_data',
                                    extra: {}
                                });
                            },500);
                        });
                    },
                    user_package(){
                        // 用户背包道具列表
                        this.socket.on("user_prop_response",(message)=>{
                            this.game.fsave({
                                "user_package":message.data,
                            });
                            // 界面中的道具信息
                            this.game.save({
                                "pet_food_num":message.pet_food_num,
                                "fertilizer_num":message.fertilizer_num,
                            });
                            api.sendEvent({
                                name: 'update_prop_data',
                                extra: {
    
                                }
                            });
    
                        })
                    },
            go_index(){
              this.game.goWin("root");
            },
            go_friends(){
              this.game.goFrame("friends","friends.html",this.current);
              this.game.goFrame("friend_list","friend_list.html",this.current,{
                  x: 0,
                  y: 190,
                  w: 'auto',
                  h: 'auto',
              },null,true);
            },
            go_home(){
              this.game.goWin("user","user.html", this.current);
            },
                    go_orchard_shop(){
                        // 种植园商店
                        this.game.goFrame("orchard_shop","shop.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                    go_my_package(){
                        // 我的背包
                        this.game.goFrame("package","package.html", this.current,null,{
                  type:"push",
                  subType:"from_top",
                  duration:300
              });
                    },
                    buy_prop(){
                        api.addEventListener({
                                name: 'buy_prop'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 用户购买道具
                                    this.socket.emit("user_buy_prop",ret.value);
                                }
                        });
                        this.socket.on("user_buy_prop_response",(message)=>{
                            alert(message.errmsg);
    
                        });
    
                    },
                    use_prop(){
                        // 使用道具
                        var pid = 0;
                        api.addEventListener({
                                name: 'use_prop'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 用户使用道具
                                    pid = ret.value.pid;
                                    var pet_key = this.game.get("pet_key");
                                    if(pet_key<1){
                                        pet_key = 0;
                                    }
                                    this.socket.emit("use_prop",{pid:ret.value.pid,pet_key:pet_key});
                                }
                        });
    
                        this.socket.on("prop_use_response",(message)=>{
                            if(parseInt(message.errno) === 1000){
                                api.sendEvent({
                                        name: 'prop_use_success',
                                        extra: {
                                            pid: pid
                                        }
                                });
                            }else{
                                api.alert({
                                        title: '提示',
                                        msg: message.errmsg,
                                });
    
                            }
                        });
    
                        this.socket.on("pet_feed_response",(message)=>{
                            if(parseInt(message.errno) === 1000){
                                api.sendEvent({
                                        name: 'pet_feed_success',
                                        extra: {
                                            pet_key: message.pet_key,
                                            hp_time: message.hp_time
                                        }
                                });
                            }else{
                                api.alert({
                                        title: '提示',
                                        msg: message.errmsg,
                                });
    
                            }
                        })
    
                    },
                    unlock_package_number(){
                        api.addEventListener({
                                name: 'unlock_package_number'
                        }, (ret, err)=>{
                                if( ret ){
                                    // 用户购买道具
                                    this.socket.emit("unlock_package");
                                }
                        });
    
                        this.socket.on("unlock_package_response",(message)=>{
                            if(parseInt(message.errno) === 1000){
                                api.sendEvent({
                                    name: 'unlock_package_success',
                                    extra: {
                                    }
                                });
                            }else{
                                api.alert({
                                        title: '提示',
                                        msg: message.errmsg,
                                });
    
                            }
    
                        })
                    },
                    show_pet(){
                        // 显示宠物
                        this.socket.emit("pet_show");
                        this.socket.on("pet_show_response",(message)=>{
                            if(parseInt(message.errno) === 1000){
                                // 把宠物信息保存到本地
                                this.game.save({"pet_list":message.pet_list})
                                this.game.save({"pet_number":message.pet_number})
                                setTimeout(()=>{
                                    api.sendEvent({
                                            name: 'pet_show_success',
                                            extra: {}
                                    });
                                },500);
                            }else{
                                api.alert({
                                        title: '提示',
                                        msg: message.errmsg,
                                });
                            }
    
                        });
    
                        api.addEventListener({
                            name: 'pet_die'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.socket.emit("pet_show");
                            }
                        });
    
    
                    },
                    active_tree(){
                        // 激活树桩
                        api.addEventListener({
                            name: 'active_tree'
                        }, (ret, err)=>{
                            if( ret ){
                                    this.socket.emit("active_tree");
                            }
                        });
    
                        this.socket.on("active_tree_response",(message)=>{
                            if(parseInt(message.errno) === 1000){
                                // 更新数据到本地
                                api.sendEvent({
                                        name: 'active_tree_success',
                                        extra: {}
                                });
                            }else{
                                api.alert({
                                        title: '提示',
                                        msg: message.errmsg,
                                });
                            }
    
                        })
                    },
                    water_tree(){
                        var key = null;
                        api.addEventListener({
                            name: 'water_tree'
                        }, (ret, err)=>{
                            if( ret ){
                                    key = ret.value.key;
                                    this.socket.emit("water_tree",key=key);
                            }
                        });
    
                        this.socket.on("water_tree_response",(message)=>{
                            if(parseInt(message.errno) === 1000){
                                // 更新数据到本地
                                api.sendEvent({
                                        name: 'water_tree_success',
                                        extra: {key:key}
                                });
                            }else{
                                api.alert({
                                        title: '提示',
                                        msg: message.errmsg,
                                });
                            }
    
                        })
    
                    }
                }
            });
        }
        </script>
    </body>
    </html>
    orchard.html
  • 相关阅读:
    白兔的字符串(字符串hash+模拟map)
    [TJOI2013]单词(AC自动机+前缀和维护)
    [SDOI2014]数数(ac自动机+数位DP)
    阿狸的打字机(AC自动机+dfs序 + 维护区间值)
    string(AC自动机 在线询问转离线询问)
    E
    JMX超详细解读
    快速生成100万数据人员信息数据
    聊聊spring之bean对象的实例化过程
    聊聊spring之贯穿全局的重要对象BeanDefinition
  • 原文地址:https://www.cnblogs.com/libolun/p/14261178.html
Copyright © 2011-2022 走看看