• 8种家居环境很败“性” 2019-06-28
  • 2018年全军院校招生计划下达:计划招收学员3.05万名 2019-06-15
  • 晋城市举办干部素质提升工程第十八期专题讲座 2019-06-15
  • 抖音广告出现对英烈邱少云不敬内容 今日头条致歉 2019-06-13
  • 超半数巴西民众对世界杯不感兴趣--旅游频道 2019-06-12
  • 外交部举行中外媒体吹风会:王毅介绍上合组织青岛峰会情况 2019-06-12
  • 2018网络中国节·端午 2019-06-04
  • 韩媒:韩美商定暂停原定8月“乙支自由卫士”联演 2019-06-03
  • 重庆市公安局交通管理局互联网交通安全服务管理平台 2019-06-03
  • 俄侦察船穿越英吉利海峡 英国急派军舰战机监视 2019-05-28
  • 网购陷阱多 女子花3000元买5套化妆品只有2套是真的 2019-05-28
  • 环保约谈濂溪区主要负责同志 谢一平要求立行立改真抓真改 2019-05-25
  • 官宣!广东签约北京3冠功勋 大莫助拳阿联未来可期 2019-05-25
  • 党建第一责任与发展第一要务相融合br全面提升机关党建工作水平 2019-05-22
  • 卡纳瓦罗:对比赛结果不满意 晋级机会各占一半 2019-05-22
  • 福建体彩网31选7走势图: 士郎 Unity3D热更新技术点——ToLua(下)

    8
    回复
    1670
    查看
    打印 上一主题 下一主题
    [ 复制链接 ]
    排名
    1
    昨日变化

    7932

    主题

    8490

    帖子

    3万

    积分

    Rank: 16

    UID
    1231
    好友
    186
    蛮牛币
    11521
    威望
    30
    注册时间
    2013-7-29
    在线时间
    4052 小时
    最后登录
    2019-7-16

    活力之星原创精华达人突出贡献奖财富之证游戏蛮牛QQ群会员蛮牛妹VIP

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

    x
    上一篇文章中我们通过一个小的案例,介绍了ToLua在Unity中的基本使用方法,而这次,我们将通过一个更为复杂的例子,继续深入了解ToLua的使用方法及其原理。


    ToLua文件目录
    我们首先来了解一下ToLua的文件目录。
    Tolua集成主要分为两部分,一部分是运行时需要的代码包括一些手写的和自动生成的绑定代码,另一部分是编辑器相关代码,主要提供代码生成、编译lua文件等操作,具体就是Unity编辑器中提供的功能。


    接下来我们具体介绍一下Tolua文件列表中文件的用途:


    1.Editor
    Editor下Custom/CustomSettings.cs 自定义配置文件,用于定义哪些类作为静态类型、哪些类需要导出、哪些附加委托需要导出等

    我们需要注册到Lua中的类型也都需要在这里导入,在Tolua中已经为我们提供了Unity大部分基础类型,若我们需要导入自己的类型或Tolua没有导入的类型可以在其中添加,如下图所示:



    2.Source
    在Source文件夹中有Generate文件夹及LuaConst.cs脚本,Generate中主要是生成用于交互的绑定代码wrap脚本,LuaConst.cs是一些lua路径等配置文件。 若在CustomSettings中做了修改,需要在菜单栏的Lua选项中,重新生成的Wrap文件,当重新生成Wrap文件后,会发现我们新添加类型也生成了相应的Wrap文件,如下图所示:



    [size=0.9em]Clear wrap files后会自动重新生成wrap文件


    3.ToLua
    Tolua文件夹中有如下文件

    1)BaseType: 一些基础类型的绑定代码
    2)Core: 提供的一些核心功能,包括封装的「LuaFunction」「LuaTable」 「LuaThread」「LuaState」「LuaEvent」、调用tolua原生代码等等。
    3)Examples: Tolua示例
    4)Misc: 杂项,包含LuaClient,LuaCoroutine(协程),LuaLooper(用于tick),LuaResLoader(用于加载lua文件)
    5)Reflection: 反射相关

    我们这里只了解一下Tolua中的文件结构及相关文件的作用,具体的脚本绑定及生成流程我们不做过多赘述,如需要了解可以查询相关资料,若有较多反馈,在之后我们可以开一篇新的文章,具体介绍tolua


    Tolua跳一跳
    现在我们已经大致了解了Tolua这个方案,接下来我们通过一个Demo,来看在Unity中,我们如何使用Tolua开发项目。
    本文中以一个仿照微信跳一跳的小游戏作为案例来讲解,案例非常简单,但希望读者有unity基础,本文主要讲解Tolua的用法,代码逻辑方面的讲解可能会相对偏少



    一.开发前准备
    在之前,我们已经导入了Tolua资源。在这个项目中,我们需要使用到DoTween插件,可以在Asset Store自行下载。


    二.Lua虚拟机管理器
    • 我们需要用C#脚本来开启Lua虚拟机并调用Lua???,那么不同的逻辑就会有不同的C#脚本来开启虚拟机并调用Lua???,这无疑是很耗费性能且繁琐的,所以我们可以自己做一些封装,先将C#脚本中所必须的方法做一个缓存,如下代码所示: LuaManager.cs



    [AppleScript] 纯文本查看 复制代码
    public class LuaManager : MonoBehaviour {
        private static LuaManager _instance;
        public static LuaManager Instance{
            get{
                return _instance;
            }
        }
        private LuaClient _luaClient;
        public LuaClient LuaClient
        {
            get
            {
                return _luaClient;
            }
        }
        void Awake () {
            _instance = this;
            //跨场景不销毁
            DontDestroyOnLoad(this.gameObject);
            _luaClient = this.gameObject.AddComponent<LuaClient>();
        }
    }


    • 在代码中,我们直接使用LuaClient,LuaClient我们可以理解成是ToLua内部对自己的一种封装,可以视为tolua环境的一个启动。我们需要将LuaClient中的protected LuaState luaState = null;改为public,同时我们可以在LuaClient中再封装一个调用Lua??楹姆椒?。

    [AppleScript] 纯文本查看 复制代码
    public virtual void CallFunc(string func, GameObject obj)
        {
            LuaFunction luaFunc = luaState.GetFunction(func);
            luaFunc.Call(obj);
            luaFunc.Dispose();
            luaFunc = null;
        }


    然后我们在场景中创建一个空物体,添加LuaManager.cs脚本




    三.自建C#方法工具类
    • 在使用Tolua开发中,ToLua提供的方法有限,有时我们可能找不到很好的方法来代替C#中的功能,或者不清楚某个功能的使用方法,这时候我们可以在C#中封装好一些功能,然后导入到Lua中,便可以直接在Lua中使用。这里可以创建一个C#脚本,我们命名为Util.cs,因为Lua中数值只存在number类型,如果需要我们可以封装int和float类型



    [AppleScript] 纯文本查看 复制代码
    public static int Int(object o)
        {
            return Convert.ToInt32(o);
        }
    public static float Float(object o)
        {
            return (float)Math.Round(Convert.ToSingle(o), 2);
        }
       


    • 同时还有我们可能需要使用到的Dotween的部分方法

       
    [AppleScript] 纯文本查看 复制代码
     public static void DoMove(GameObject obj, Vector3 vec, float time)
        {
            obj.transform.DOMove(vec, time);
        }
    
        public static void DoScale(GameObject obj, float f, float time)
        {
            obj.transform.DOScale(f, time);
        }
    
        public static void DoScale(GameObject obj, Vector3 vec, float time)
        {
            obj.transform.DOScale(vec, time);
        }


    之前我们介绍过,如果需要添加导入lua的类型,需要在CustomSettings.cs中添加




    可以看到我们在其中加入了 _GT(typeof(Util)),然后重新生成wrap文件



    如图所示,Source/Generate中生成了UtilWrap文件


    四.开始界面
    再之前的动图中可以看到我们的项目中的开始界面,只搭建了背景及一个开始按钮,读者也可以自行扩展。 * 这里我们需要用到Button事件,我们同样可以通过封装一个C#脚本给lua提供一个按钮事件


    BtnEvent.cs
    [AppleScript] 纯文本查看 复制代码
    public class UIEvent : MonoBehaviour {
        public static void AddButtonOnClick(GameObject game, LuaFunction function)
        {
            if (game == null)
                return;
            Button btn = game.GetComponent<Button>();
            btn.onClick.AddListener(
                delegate () {
                    function.Call(game);
                }
            );
        }
    }


    • 接下来就是在lua中的调用了。 我们可以在Project面板中找到lua文件夹,我们可以把我们的Lua脚本文件放在这个文件夹下(当然,也可以根据自己的习惯修改Lua文件夹,但我们查找Lua文件的路径就需要修改),文件夹下有名为Main.lua的Lua文件,在这个脚本中,我们可以定义我们所需的全局类型:


    [AppleScript] 纯文本查看 复制代码
    --主入口函数。从这里开始lua逻辑
    --这里定义我们所需的全局类型
    function Main()
        GameObject = UnityEngine.GameObject
        Transform = UnityEngine.Transform
        ParticleSystem = UnityEngine.ParticleSystem
        Color = UnityEngine.Color
        Util = Util.New()
        SceneManagement = UnityEngine.SceneManagement
        Input = UnityEngine.Input
        KeyCode = UnityEngine.KeyCode
        Time = UnityEngine.Time
        Camera = UnityEngine.Camera
        AudioSource = UnityEngine.AudioSource
        Resources = UnityEngine.Resources
        www = UnityEngine.WWW
        print("logic start")
    end
    
    --场景切换通知
    function OnLevelWasLoaded(level)
        collectgarbage("collect")
        Time.timeSinceLevelLoad = 0
    end
    
    function OnApplicationQuit()
    end


    • 然后我们创建Login.lua,我们的开始界面逻辑将会写在这个脚本中:

    [AppleScript] 纯文本查看 复制代码
    Login = {}--定义Login类
    local this = Login
    require('Music')--加载Music???
    local ui 
    local manager
    function this.Awake(object)
        manager = GameObject.Find('Manager')
        manager : AddComponent(typeof(AudioSource))
        coroutine.start(Music.PlaySound)--开启协程
        ui = object
        local loginBtn = ui.transform : Find("Login").gameObject
        UIEvent.AddButtonOnClick(loginBtn, LoginOnClick)
    end
    
    function LoginOnClick()
          --场景切换
        SceneManagement.SceneManager.LoadScene("Jump")
    
    end



    在这个lua脚本中,可以看出,其实Lua中调用unity的方法和C#十分相似,想必有Unity基础的读者很容易看明白以上的代码。
    其中要注意的是,unity中的物体无法绑定lua脚本,所以无法通过如c#中定义public的值可以在Inspector面板进行赋值,所以代码中我们必须通过GameObject.Find()或者Transform:Find()来找到物体

    还有一个重要的地方,需要注意我们调用类的方法、属性、字段时「.」和「:」的区别

    • 我们希望在游戏中有背景音乐,所以在这里,我们使用协程来下载一首音乐,并挂之前创建的在Manager上

    [AppleScript] 纯文本查看 复制代码
    --协程下载
    --这里使用Tolua中提供的coroutine.www
    Music = {}
    local this = Music
    function this.PlaySound()
        local audio = GameObject.Find('Manager') : GetComponent('AudioSource')
        local url = www('https://etnly.oss-cn-shanghai.aliyuncs.com/%E5%B2%A1%E9%83%A8%E5%95%93%E4%B8%80%20-%20%E9%81%BA%E3%82%B5%E3%83%AC%E3%82%BF%E5%A0%B4%E6%89%80%EF%BC%8F%E6%96%9C%E5%85%89.ogg')
        coroutine.www(url)
        audio.clip = url : GetAudioClip()
        audio : Play()
    end



    • 接下来我们来看如何在C#中调用刚才写好的lua??椋?/font>

    [AppleScript] 纯文本查看 复制代码
    public class Login : MonoBehaviour {
        void Start () {
            LuaManager.Instance.LuaClient.luaState.DoFile("Login.lua");
            LuaManager.Instance.LuaClient.CallFunc("Login.Awake", this.gameObject);
        }
    
    }

    四.角色逻辑
    开始游戏界面完成后,我们就着手于游戏主场景,首先我们可以新建场景,使用plane、cube等基础物体,搭建一个简单的跳一跳场景。



    • 接下来,我们用Lua实现角色的跳跃,这里我们可以使用刚体来让角色实现向前跳跃的动作:

    [AppleScript] 纯文本查看 复制代码
    local player
    local rigidbody
    function this.Awake(obj)
        player = obj
        rigidbody = player : GetComponent('Rigidbody')
    end
    function this.StartJump(time)
        --跳跃逻辑,这里的time可以理解为我们按下按钮的时间 
        rigidbody : AddForce(Vector3(1, 1, 0) * time * 7,
        UnityEngine.ForceMode.Impulse)
    end 
    


    同样的,首先我们要找到角色,然后获取其中的刚体组建。

    • 在跳一跳游戏中,我们通过某一个按键(这里我们使用空格键)让角色开始跳跃,角色跳跃的力度是更具按下屏幕或者按钮的时间来决定的,所以这里我们需要获取到我们按下按钮的时间

    [AppleScript] 纯文本查看 复制代码
    function this.Update()
        if Input.GetKeyDown(KeyCode.Space) then
            startTime = Time.time--获取按下空格时的时间
        end
        if Input.GetKeyUp(KeyCode.Space) then
            endTime = Time.time - startTime--计算按下空格至松开的时间
            this.StartJump(endTime)
        end
    end


    然后实现角色在蓄力(也就是按住按钮)时的动作,以及粒子效果,如下图所示


    • 我们的角色是由一个圆柱体和一个球体组成,所以在蓄力时,我们需要压缩圆柱体同时球体的位置也要下移:

    [AppleScript] 纯文本查看 复制代码
    if Input.GetKey(KeyCode.Space) then
        --角色压缩效果
        if body.transform.localScale.y < 0.11 and body.transform.localScale.y > 0.05 then
            body.transform.localScale = body.transform.localScale + Vector3(1, -1, 1) * 0.05 * Time.deltaTime
            head.transform.localPosition = head.transform.localPosition + Vector3(0, -1, 0) * 0.05 * Time.deltaTime
        end
    end


    在这里,body时角色的身体,head时头部,我们都需要先找到物体然后在对其进行操作

    • 蓄力时的粒子效果,读者可以自行在unity中编辑,这里就不做过多赘述,相关代码如下:

    particle : GetComponent(‘ParticleSystem’) : Play()
    我们应该在按下空格时就开启粒子,所以这里应该放在判断按下空格中

    • 当我们松开空格时,角色需要恢复之前的大小及位置,粒子效果也需要停止,同时角色跳跃。

    [AppleScript] 纯文本查看 复制代码
    --DoTween恢复角色
    Util.DoScale(body, 0.1, 0.5)
    Util.DoLocalMoveY(head, 0.8, 0.5)
    particle : GetComponent('ParticleSystem') : Stop()


    这里我们用DoTween来恢复角色大小。

    • 关于角色的逻辑,最后一步就是判定角色是否跳到了下一个盒子

    [AppleScript] 纯文本查看 复制代码
    --如果跳到此盒子,便给该盒子添加脚本,并移动摄像机
    function this.OnCollisionStay(object)
        if object.transform.tag == 'Cube' then
            if(object : GetComponent('BoxControl') == nil) then
                this.CameraMove()
                object : AddComponent(typeof(BoxControl))
            end
        elseif object.transform.tag == 'Plane' then
            --重新开始游戏
            Time.timeScale = 0
            ui : SetActive(true)
            Continue.ReStart(ui)
        end
    
    end
    
    function this.CameraMove()
        --DoTween控制摄像机移动效果
        Util.DoMove(Camera.main, (player.transform.position + cameraRelativePosition), 1)
    end


    在这里我们角色如果跳到了下一个盒子,就会给当前盒子添加一个脚本,并移动摄像机,如果没有跳到则打开一个ui界面,并调用一个叫Continue的???


    Continue.lua
    [AppleScript] 纯文本查看 复制代码
    Continue = {}
    local this = Continue
    function this.ReStart(obj)
        local reStartBtn = obj.transform : Find("ReStart").gameObject
        UIEvent.AddButtonOnClick(reStartBtn, ReStartOnClick)
    end
    
    function ReStartOnClick ()
        SceneManagement.SceneManager.LoadScene("Jump")
    end



    最后就是角色控制的C#代码,和之前开始界面类似,不过这里多了Update和OnCollisionStay

    [AppleScript] 纯文本查看 复制代码
    void Start () {     
            LuaManager.Instance.LuaClient.luaState.DoFile("Player.lua");
            LuaManager.Instance.LuaClient.CallFunc("Play.Awake", this.gameObject);
    }
    void Update () {
            LuaManager.Instance.LuaClient.CallFunc("Play.Update", gameObject);
    }
    private void OnCollisionStay(Collision collision)   {        
            LuaManager.Instance.LuaClient.CallFunc("Play.OnCollisionStay", collision.gameObject);
    }

    上面提到了会给跳到的盒子加入一个脚本,那么接下来我们就来看关于盒子的逻辑
    五.盒子逻辑
    • 首先,当角色跳到当前盒子上,我们就应该把这个脚本绑定到该盒子,再之前角色的逻辑中已经有说明。我们可以在图中可以看到,当按下空格,角色压缩是盒子也会同时被压缩,松开空格后盒子复原






    [AppleScript] 纯文本查看 复制代码
    if Input.GetKey(KeyCode.Space) then
        --盒子压缩效果
        if currentBox.transform.localScale.y < 0.51 and currentBox.transform.localScale.y > 0.3 then
            currentBox.transform.localScale = currentBox.transform.localScale + Vector3(0, -1, 0) * 0.15 * Time.deltaTime
            currentBox.transform.localPosition = currentBox.transform.localPosition + Vector3(0, -1, 0) * 0.15 * Time.deltaTime
        end
    end
    if Input.GetKeyUp(KeyCode.Space) then
        --DoTween恢复盒子
        Util.DoLocalMoveY(currentBox, 0.25, 0.2)
        Util.DoScale(currentBox, Vector3(oldScale.x, oldScale.y, oldScale.z), 0.2)
    end
    


    • 然后当角色跳到新的盒子上,就应该根据当前位置,生成一个新的大小和颜色随机的盒子,具体代码逻辑如下

    [AppleScript] 纯文本查看 复制代码
     福建36选7和值走势图 www.00-na.com function this.GenerateBox()
        boxPrefab = Resources.Load('Prefabs/Cube')
        local newBox = GameObject.Instantiate(boxPrefab)
        --盒子随机位置、大小、颜色
        randomScale = Util.Random(0.5, 1)
        newBox.transform.position = currentBox.transform.position + Vector3(Util.Random(1.5, maxDistance), 0, 0)
        plane.transform.localPosition = plane.transform.localPosition + Vector3(Util.Random(1.5, maxDistance), 0, 0)
        newBox.transform.localScale = Vector3(randomScale, 0.5, randomScale)
        newBox : GetComponent('Renderer').material.color = Color(Util.Random(0.0, 1.0), Util.Random(0.0, 1.0), Util.Random(0.0, 1.0))
    end



    • 最后一步,就是删除之前的盒子,我们可以判断盒子是否在摄像机范围内(在本项目中,我们摄像机范围内应该只有两个盒子,当前和新生成的盒子),不在摄像机范围内的盒子,我们可以将其删除

    [AppleScript] 纯文本查看 复制代码
    function this.Update(obj)
        if this.IsInView(obj.transform.position) then
            GameObject.Destroy(obj, 1)
        end
    end
    --判断盒子是否在摄像机范围内,如果不在,便将其销毁
    function this.IsInView(worldPos)
        local cameraTrans = Camera.main.transform
        local viewPos = Camera.main : WorldToViewportPoint(worldPos)
        local dir = (worldPos - cameraTrans.position).normalized
        local dot = Vector3.Dot(cameraTrans.forward, dir)
        if dot > 0 and viewPos.x > 0 and viewPos.x < 1 and viewPos.y > 0 and viewPos.y < 1 then
            return false
        end
        return true
    end


    BoxControl.cs
    [AppleScript] 纯文本查看 复制代码
    void Start () {       
            LuaManager.Instance.LuaClient.luaState.DoFile("BoxControl.lua");
            LuaManager.Instance.LuaClient.CallFunc("Box.Awake", this.gameObject);
    
        }
    void Update () {
            LuaManager.Instance.LuaClient.CallFunc("Box.Update", this.gameObject);
        }
    

    到此为止,我们使用Tolua制作的跳一跳小游戏就完成了。项目虽小,但包含了Tolua的大部分功能的常见使用方法。
    感谢作者知乎@朔宇


    7日久生情
    1958/5000
    排名
    4092
    昨日变化

    0

    主题

    1259

    帖子

    1958

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    254705
    好友
    1
    蛮牛币
    1795
    威望
    0
    注册时间
    2017-11-16
    在线时间
    337 小时
    最后登录
    2019-7-16
    沙发
    2019-5-8 14:48:22 只看该作者
    6666666666666666666666666666666666666
    7日久生情
    4120/5000
    排名
    278
    昨日变化

    1

    主题

    144

    帖子

    4120

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    3603
    好友
    0
    蛮牛币
    9706
    威望
    0
    注册时间
    2013-9-10
    在线时间
    2033 小时
    最后登录
    2019-7-16
    板凳
    2019-5-8 20:36:09 只看该作者
    好,点赞一个
    6蛮牛粉丝
    1089/1500
    排名
    2236
    昨日变化

    1

    主题

    166

    帖子

    1089

    积分

    Rank: 6Rank: 6Rank: 6

    UID
    232255
    好友
    1
    蛮牛币
    1552
    威望
    0
    注册时间
    2017-7-15
    在线时间
    294 小时
    最后登录
    2019-7-16
    地板
    2019-5-9 08:38:00 只看该作者
    好,点赞一个
    3偶尔光临
    183/300
    排名
    16955
    昨日变化

    1

    主题

    40

    帖子

    183

    积分

    Rank: 3Rank: 3Rank: 3

    UID
    173093
    好友
    0
    蛮牛币
    106
    威望
    0
    注册时间
    2016-9-30
    在线时间
    102 小时
    最后登录
    2019-5-24
    5#
    2019-5-16 10:49:03 只看该作者
    感谢分享
    排名
    317
    昨日变化

    15

    主题

    510

    帖子

    3268

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    8069
    好友
    31
    蛮牛币
    7831
    威望
    0
    注册时间
    2013-11-14
    在线时间
    935 小时
    最后登录
    2019-7-12
    QQ
    6#
    2019-5-17 12:34:28 只看该作者
    期待
    排名
    317
    昨日变化

    15

    主题

    510

    帖子

    3268

    积分

    Rank: 7Rank: 7Rank: 7Rank: 7

    UID
    8069
    好友
    31
    蛮牛币
    7831
    威望
    0
    注册时间
    2013-11-14
    在线时间
    935 小时
    最后登录
    2019-7-12
    QQ
    7#
    2019-5-17 12:34:30 只看该作者
    期待
    排名
    34885
    昨日变化

    0

    主题

    17

    帖子

    42

    积分

    Rank: 1

    UID
    290237
    好友
    0
    蛮牛币
    20
    威望
    0
    注册时间
    2018-7-18
    在线时间
    17 小时
    最后登录
    2019-5-28
    8#
    2019-5-22 14:44:24 只看该作者
    感谢分享
    5熟悉之中
    635/1000
    排名
    5544
    昨日变化

    2

    主题

    54

    帖子

    635

    积分

    Rank: 5Rank: 5

    UID
    145209
    好友
    0
    蛮牛币
    845
    威望
    0
    注册时间
    2016-4-11
    在线时间
    323 小时
    最后登录
    2019-7-4
    9#
    2019-5-29 09:49:19 只看该作者
    tolua 可以断点吗?
    您需要登录后才可以回帖 登录 | 注册帐号

    本版积分规则

  • 8种家居环境很败“性” 2019-06-28
  • 2018年全军院校招生计划下达:计划招收学员3.05万名 2019-06-15
  • 晋城市举办干部素质提升工程第十八期专题讲座 2019-06-15
  • 抖音广告出现对英烈邱少云不敬内容 今日头条致歉 2019-06-13
  • 超半数巴西民众对世界杯不感兴趣--旅游频道 2019-06-12
  • 外交部举行中外媒体吹风会:王毅介绍上合组织青岛峰会情况 2019-06-12
  • 2018网络中国节·端午 2019-06-04
  • 韩媒:韩美商定暂停原定8月“乙支自由卫士”联演 2019-06-03
  • 重庆市公安局交通管理局互联网交通安全服务管理平台 2019-06-03
  • 俄侦察船穿越英吉利海峡 英国急派军舰战机监视 2019-05-28
  • 网购陷阱多 女子花3000元买5套化妆品只有2套是真的 2019-05-28
  • 环保约谈濂溪区主要负责同志 谢一平要求立行立改真抓真改 2019-05-25
  • 官宣!广东签约北京3冠功勋 大莫助拳阿联未来可期 2019-05-25
  • 党建第一责任与发展第一要务相融合br全面提升机关党建工作水平 2019-05-22
  • 卡纳瓦罗:对比赛结果不满意 晋级机会各占一半 2019-05-22
  • 体彩浙江飞鱼开奖结果 极速时时彩开奖结果 贵州快3开奖最大遗漏 2019法甲转会一览 6场半全场18100期开奖 网球比分怎么计算 捷克酷喜乐彩色铅笔 2012七乐彩走势图 忍者棒球rom 福建22选5开奘 江苏7位数历史开奖号码 七乐彩走势图坐标 群英会复式中奖规则 重庆快乐十分最快开奖结果查询 彩票官网双色球兑奖