怎么样做网站赚钱吗,淄博做网站公司有哪些,怎样查看网站开发,WORDPRESS导购主题 WYZDG上期链接#xff1a;Unity2D游戏制作入门 | 11(之人物属性及伤害计算)-CSDN博客
上期我们聊到了人物的自身属性和受伤时的计算#xff0c;我们先给人物和野猪挂上属性和攻击属性的代码#xff0c;然后通过触发器触发受伤的事件。物体#xff08;人物也好敌人也行#xff…上期链接Unity2D游戏制作入门 | 11(之人物属性及伤害计算)-CSDN博客
上期我们聊到了人物的自身属性和受伤时的计算我们先给人物和野猪挂上属性和攻击属性的代码然后通过触发器触发受伤的事件。物体人物也好敌人也行受伤时通常是在被攻击者的内部进行计算的这是有好处的比如使用人物更复杂的血量计算方式我们在人物内部让它自己自动计算就好了我们使用关键词this来将Attacker内部的变量的访问权限赋给Character然后我们又使用了计时器让被攻击的物体在受到攻击后可以有短暂的无敌时间计时器的写法你还知道吗先创建三个变量一个布尔二个浮点创建新的能赋给人物无敌的函数然后判断人物如果不如那么人物的无敌状态就是True然后赋给无敌时间一个浮点变量我们是在Unity窗口手动赋给的另一个浮点变量是内部进行使用它在函数判断人物是否处在无敌时才用公共无敌时间赋给那个私有的浮点变量这样就在内部激活了人物的无敌时间我们在update中计算人物无敌的倒计时到点了就切换人物无敌状态为flase然后在人物的Character中的TakeDamage函数中我们判断人物如果不是无敌则进入扣血规则然后如果人物的当前血量足够扣除一次血量则正常减血如果人物血量为2敌人攻击为5那么人物直接判断血量归零不然人物死亡而无敌状体的赋给与否全在人物扣血那部分功能中执行如果人物血量归零那么将无法触发无敌状态。总的来说上次就是多了两份通用的代码文件分别是物体的属性和攻击仅对需要这些的物体有用如果是场景的死物一般不给属性如血量也可以给看你设定攻击应该是不要加上去的除了陷阱啥的虽然多了两份代码我们还是要弄清两份代码之间的访问和运行的逻辑以及什么时候用它们。这期我们看看角色的 受伤和死亡的逻辑和动画 。代码先下方:
public class PlayerAnimations : MonoBehaviour
{private Animator anim;//创建好这个组件变量后如果不知道如何通关代码控制组件可以去看代码手册private Rigidbody2D rb;//这个2D不能忽略不然不报错但是人物跑不起来。private Player_control playercon;//人物控制private physicsCheck physicsCheck;private void Awake(){physicsCheck GetComponentphysicsCheck();anim GetComponentAnimator();rb GetComponentRigidbody2D();playercon GetComponentPlayer_control();}private void Update(){SetAnimatons();//每帧时时检测判断是否需要切换动画。}public void SetAnimatons()//需要做很多动画的切换我们用这个函数来执行所有的动画切换。{anim.SetBool(isGround, physicsCheck.isGround);anim.SetFloat(velocityX,math.abs(rb.velocity.x));anim.SetFloat(velocityY,rb.velocity.y);anim.SetBool(shift, playercon.isShift);anim.SetBool(isDead, playercon.isDead);}public void PlayerHurt(){anim.SetTrigger(hurt);}}public class Player_control : MonoBehaviour
{public PlayerInputControl inputControl;public Vector2 inputDirection;//public变量表示一个公开的方法它代表我在Unity窗口中可以查看得到。private Rigidbody2D rb;private physicsCheck physicsCheck;//创建物理检测变量private SpriteRenderer rbSprite;[Header(基本参数)]public float speed;public float walkSpeed;public float jumpForce;public float hurtForce;[Header(按键按下)]public bool isShiftfalse;[Header(状态)]public bool isHurt;public bool isDead;private void Awake(){physicsCheck GetComponentphysicsCheck();rb GetComponentRigidbody2D();inputControl new PlayerInputControl();inputControl.GamePlayer.Jump.started Jump;//按下空格那一瞬间执行事件Jump//inputControl.GamePlayer.Walk.performed Walk;rbSprite GetComponentSpriteRenderer();}private void OnEnable(){inputControl.Enable();}private void OnDisable(){inputControl.Disable();}private void Update(){inputDirection inputControl.GamePlayer.Move.ReadValueVector2();isShift Keyboard.current.shiftKey.isPressed;//检测按键}private void FixedUpdate()//固定频率运行即0.02秒执行一次。跟物理有关的放在这执行{if (!isHurt){if (isShift physicsCheck.isGround)Walk();elseMove();}}public void Move(){rb.velocity new Vector2(inputDirection.x*speed*Time.deltaTime,rb.velocity.y);//人物翻转if(inputDirection.x0)rbSprite.flipX false;if(inputDirection.x0)rbSprite.flipX true;}private void Jump(InputAction.CallbackContext obj){if (physicsCheck.isGround){rb.AddForce(jumpForce * transform.up, ForceMode2D.Impulse);//第一个参数表示给哪个方向施加力}}}private void Walk(){rb.velocity new Vector2(inputDirection.x * walkSpeed * Time.deltaTime, rb.velocity.y);//人物翻转if (inputDirection.x 0)rbSprite.flipX false;if (inputDirection.x 0)rbSprite.flipX true;}public void GetHurt(Transform attcker){isHurt true;//受伤了//接下来执行反弹不过前提是先把人物的速度停下来。rb.velocity Vector2.zero;//表示物体的xy轴速度全设置为了。//接下来计算受伤的方向然后ta要朝反方向弹射。Vector2 dirnew Vector2((transform.position.x-attcker.position.x),0).normalized;/*这里对上行代码进行说明dir是direction方向的简写。计算方向我们就用人物坐标减去野猪或是其他的attacker的坐标对于x轴来说如果人物在敌人左边那么它应该是负数所以我们根据正负数作为它的方向乘上它的反冲力hurtForce现实加速的效果。dir算完后我们需要不是数值的大小而是方向值我们按下键盘时dir有-1和1两种数值。如果人物离野猪很远那么x的值会非常大乘反弹力会更大反而离得近数值会很小所以我们要把数值归一化即用到normalized的方法。*/rb.AddForce(dir*hurtForce,ForceMode2D.Impulse);//添加瞬时的力反弹人物}public void PlayerDead(){isDead true;inputControl.GamePlayer.Disable();}
}public class Character : MonoBehaviour
{[Header(基本属性)]public float maxHp;//最大血量public float currentHp;//当前血量[Header(受伤无敌)]public float invincibleTime;//无敌时间private float invincibleCounter;//一个计数器内部计算即可不需要在窗口可以看得到public bool invincible;//为了能看见无敌我们创建一个布尔值public UnityEventTransform Ontakedamage;public UnityEvent Ondie;private void Start()//开始游戏时要满血{currentHp maxHp;}private void Update(){if(invincible){invincibleCounter-Time.deltaTime;if(invincibleCounter 0){invincible false;}}}//受到伤害public void TakeDamage(Attack attcker){if (invincible)return;//Debug.Log(attcker.damage);if (currentHp - attcker.damage 0)//血量健康才能减血{currentHp - attcker.damage;//如果学过python你会知道这行代码等于currentHp currentHp - attcker.damage;TriggerInvincible();//触发无敌//执行受伤Ontakedamage?.Invoke(attcker.transform);}else{currentHp0;//触发死亡Ondie?.Invoke();}}//受伤触发无敌private void TriggerInvincible(){if(!invincible){invincible true;invincibleCounter invincibleTime;}}
}public class HurtAninmation : StateMachineBehaviour
{override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){animator.GetComponentPlayer_control().isHurt false;}
}正文
玩家如果受到伤害那么应该有对应的受伤动画甚至血量归零时人物播放死亡的动画。找到我们之前的素材我们可以先看看guid指导的动画内容找到受伤的内容。我们先点击player然后创建人物的动画文件一定放在人物动画管理的文件下这样方便找然后创建人物的hurt动画用右边的那四张图片我们之前切割好的然后Samples采样率我们调整到合适的数值14的话感觉还是有点快了所以我选了9。
死亡动画编号为42-53。
先将Animator中出现的我们刚刚创建的两个动画删去我们注意到我们的人物在任何情况下都可能受伤如我们跑步撞到野猪在空中碰到敌人这些都可能使人物受伤。如果人物受伤应该凌驾在所有动画之上我们先前制作的所有动画如跳跃、闲置、跑步等接下来我们创建新的方法。先不调用受伤动画来看一个有意思的方法UP话。玩家如果进行受伤的状态 那么玩家应该有闪烁的状态来表示玩家在这个阶段是受伤无敌的状态。我们在下图的这个地方创建新的动画的Layer图层注意这些图层的名字下有一条线
我们点击动画图层右边的齿轮可以发现有一个名为Weight权重的东西这个权重会影响当前的这一层的动画的播放你可以理解为它的优先级是多少。下面的Blending为混合模式Override是完全覆盖的意思。我们先将HurtLayer动画图层的权重拉到1然后混合模式切换成Additive叠加模式即当前层动画不会覆盖之前层BaseLayer的动画在之前层的基础上为它进行添加。 我们在这个新地方创建新的空的状态然后创建新的受伤动画即bule_hurt2。在这里我们不调用任何的图片现在录制我们的动画片段。 这个地方关键我们去到人物的右边的组件Sprite Renderer看到Color我们修改它RGB的通道也可以修改它的阿尔法值怎么说呢就是修改物体的透明程度1的话就显示0就隐身了如果是改RGB中的值人物就会变色如变成红色等。然后我们在动画管理下的Add Property找到对应组件的功能即我们找到Sprite Renderer下的控制color的选项即可。
我们先在BaseLayer中删除我们创建的bule_hurt2动画然后添加到HurtLayer中去。对了hutr2一个六帧采样率设置6即可然后可以可以拖拽右边的6个点到1:0的位置然后再0:2、 0:4 、1:0的位置分别设置阿尔法值为0.5、1、0.5。弄好后链接一根线到bule_hurt2再创建一个新的参数为trigger类型的名称取hurt你会注意到它右边是圆形的图案这是触发器。在触发hurt2的条件中添加hurt参数这个条件其他的条件如退出时间、转换时间都弄为无或是0和之前的那些动画差不多就行一旦hurt左边红框的圆圈内被勾选了即启动了那么会自动播放这个受伤的动画。
如果要由播放受伤的动画播放完了我们需要回到之间的动画所以设置受伤播放完后回到初始的状态这里返回的条件就设置为无即什么都不加。 我们进入到代码把它测试一下我们打开代码PlayerAnimations。trigger的方法我们不能在update中执行它是单次执行的函数所以创建一个新的函数。
....
public void PlayerHurt(){anim.SetTrigger(hurt);}那么我们时候执行调用PlayerHurt()呢应该在Character代码中去执行受伤我们需要播放人物的动画以及人物被弹走不能再往前走当然我们受伤被弹走一般是不允许进行键盘操作的甚至我们需要播放受伤的声音。这里又很关键了试想一下除了刚刚提到要被弹飞等事件也可能还要调整一下我们ui的显示就在受伤后有很多事情需要去执行。想让一次受伤去触发其他各种各样的代码或以后做UI都要来执行对应的方法我们需要使用Unity的事件的方式。
public void TakeDamage(Attack attcker){if (invincible)return;//Debug.Log(attcker.damage);if (currentHp - attcker.damage 0)//血量健康才能减血{currentHp - attcker.damage;//如果学过python你会知道这行代码等于currentHp currentHp - attcker.damage;TriggerInvincible();//执行受伤}else{currentHp0;//触发死亡}}接上面的内容我们需要调用Unity的命名空间接下来创建这些事件我们先创建一个类型为UnityEvent的变量现在要先弄受伤的事件然后再public UnityEvent的尖括号中我们可以传入一些参数例如在受伤时希望每次受伤都能按受伤的这个方向的反方向被击退无论敌人还是人物都应该是这样的。传递方向进去其实也就是坐标那么我们Transform类型的组件传进去。
using UnityEngine.Events;
public UnityEventTransform Ontakedamage;可能上面代码看得不是很懂返回unity窗口就能直观地看到了记得先保存写完的代码Character组件就多了事情的内容了。这个东西是unity自带的它的好处是以后我们学习UI时点击的时候也会有这种事件的处理方式。在这个事件当中我们可以点击加号来添加各种各样的函数方法各种各样的功能。那么在一个事件触发时候这里可以执行所有你添加进去的方法。如我们之前提到的人物受伤如果触发了很可能我们要调用ui、播放音乐、执行方法播放动画所有的内容都可以放在这里。
应用举例我们把playerAnimations拖拽下去我们找到代码中的playerHurt的函数方法然后可以选择在何时运行它如在游戏运行或是编辑器里时这里我们选择只在游戏运行时执行。 接下来我们会到代码文件Character中回看这行代码public UnityEventTransform Ontakedamage;**这个关于事件Ontakedamage刚才的加号是代表我们把各种各样的方法注册到这个事件当中接下来我们需要把这个事件启动起来它其实有一个固定的写法。**注意新写入的代码Ontakedamage?.Invoke(attcker.transform);问号代表判断一下有没有任何方法添加进来很可能之前的列表是空的那我们就可能报错了所以加上问号。**后面接点Invoke表示启动当前事件的内容不要忘记打上括号。**然后因为刚刚我们创建时有设置了参数所以需要传一个transform进去谁攻击我我就朝反方向移动那么我们就要获得attcker它的transform了。这样我们就实现了该函数TakeDamage(Attack attcker)受伤数值减少、触发无敌然后执行所以注册过来的受伤的函数方法。目前我们只注册了受伤时播放闪烁的动画
public void TakeDamage(Attack attcker){if (invincible)return;//Debug.Log(attcker.damage);if (currentHp - attcker.damage 0)//血量健康才能减血{currentHp - attcker.damage;//如果学过python你会知道这行代码等于currentHp currentHp - attcker.damage;//触发无敌TriggerInvincible();//执行受伤Ontakedamage?.Invoke(attcker.transform);}运行游戏如果人物经过野猪会有一个人物闪烁的效果**我经过测试发现如果把野猪的Is trigger给关掉或胶囊触发器关闭不使用那么人物经过野猪不管是顶着它走还是穿过它都不能能触发受伤闪烁的效果。**这样我们就学习了如何触发事件来执行一些方法。接下来我们给人物受伤切换回我们之前想要的受伤动画然后按照我们之前给没有素材的动画添加受伤会变红闪烁的效果即可然后这样我们就有了红色受伤的动画那么我们还需要让人物反弹回去。
我们受伤被击退的事件应该在人物控制的代码中被执行因为控制人物的方向要被打断如果一直向前跑但是受伤后需要被弹开。所以我们在player_control里面创建新的方法来执行一个人物反弹的效果。我们需要设置一下玩家的状态受伤就要阻止我们其他的移动也要反弹一段距离。所以需要创建是否受伤的布尔值类型的变量isHurt。然后反弹的时候希望有一个力把它弹开一段距离。 public bool isHurt;public float hurtForce;
....private void FixedUpdate()//固定频率运行即0.02秒执行一次。跟物理有关的放在这执行{if (!isHurt)//没有进入受伤状态才能走动{if (isShift physicsCheck.isGround)Walk();elseMove();}}
.....public void GetHurt(Transform attcker){isHurt true;//受伤了//接下来执行反弹不过前提是先把人物的速度停下来。rb.velocity Vector2.zero;//表示物体的xy轴速度全设置为了。//接下来计算受伤的方向然后ta要朝反方向弹射。Vector2 dirnew Vector2((transform.position.x-attcker.position.x),0).normalized;/*这里对上行代码进行说明dir是direction方向的简写。计算方向我们就用人物坐标减去野猪或是其他的attacker的坐标对于x轴来说如果人物在敌人左边那么它应该是负数所以我们根据正负数作为它的方向乘上它的反冲力hurtForce现实加速的效果。dir算完后我们需要不是数值的大小而是方向值我们按下键盘时dir有-1和1两种数值。如果人物离野猪很远那么x 的值会非常大乘反弹力会更大反而离得近数值会很小所以我们要把数值归一化即用到normalized的 方法。 */rb.AddForce(dir*hurtForce,ForceMode2D.Impulse);//添加瞬时的力反弹人物}保存上面写好的代码会回到unity的窗口我们需要把我们写好的人物受伤的函数方法添加到Ontakedamage这个事件中去然后我们给人物被攻击的力改成8我们发现人物被弹走后停不下来原因是isHurt一直没用变回flase。
我们留意到animator中我们看到受伤动画状态的右边即我们可以添加一个代码在这个动画执行的过程中做一些代码的变化我们先添加一个叫HurtAninmation的代码。输入完名称后按下回车键然后它会为你创建这个新的代码不过代码被放在了我们project下的Assets下了和一些文件目录同级了。 双击打开代码我们可以看到这是一个unity自动为我们写好的模板我们可以直接拿来用。它继承了**StateMachineBehaviour也就是状态机的行为**在做敌人我们也会单独来写。取消方法前面的注释就可以用了。第一方法是当进去这个状态时执行第二方法是当在执行这个动画的过程中我执行函数方法如果这个状态也可称为动画时间比较久那么函数一直执行第三个是当状态退出后我们执行某某方法。So当我们受伤播完并退出后我们更改我们的人物isHurt的状态为flase即可。
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex){animator.GetComponentPlayer_control().isHurt false;}注意我们用Ontakedamage事件的这个方法我们即播放了动画又可以播放脚本里的函数的逻辑。最后一个我们要做的就是人物的死亡在任何状态下我们的人物都会死亡所以我们到动画控制器中添加死亡的动画然后HurtLayer的动画图层我们把混合的模式改为Override覆盖。我们在Parameter中添加死亡参数进行判断isDead布尔值。然后给Any State连一根线到死亡动画中去条件为isDead为true时其他要么无要么为0。 注意一下我们的人物是否会一直进入死亡状态呢不一定如果我们重新开始游戏那么人物要刷新状态并退出死亡的动画退出的条件大家应该都熟练了isDead为flse其他要么无要么为0。
接下来把死亡动画链接到函数我们需要在Character代码中添加死亡的事件方法。因为在人物死亡时可能也要执行很多的事情比如跳出UI的面板除了通知你Game Over还要通知你很多的信息比如通知你的敌人不要继续攻击人物不要再移动了。但是这次我们不需要传递任何参数就是人物只是死亡。
//#Characte.cspublic UnityEvent Ondie;//新加入对应代码第22行
..........
public void TakeDamage(Attack attcker){if (invincible)return;//Debug.Log(attcker.damage);if (currentHp - attcker.damage 0)//血量健康才能减血{currentHp - attcker.damage;//如果学过python你会知道这行代码等于currentHp currentHp - attcker.damage;TriggerInvincible();//触发无敌//执行受伤Ontakedamage?.Invoke(attcker.transform);}else{currentHp0;//触发死亡Ondie?.Invoke();}}那么人物的死亡是一个布尔值所以它不是单次执行的没有必要单独去写我们直接把状态连接到Animation当中即可并通过人物控制停止我们所有的人物操作如移动。
//#Player_control.cs
public bool isDead;
...
public void PlayerDead(){isDead true;inputControl.GamePlayer.Disable();//我们之前输入系统的人物操作相关的内容。我们只关闭人物的操作正常的ui操作还要保留的。}然后在PlaterAnimation中把状态连接起来。
public void SetAnimatons()//需要做很多动画的切换我们用这个函数来执行所有的动画切换。{........anim.SetBool(isDead, playercon.isDead);}然后设置人物的血量为6进行死亡测试不过你会发现人物会反复死亡这是因为人物的死亡动画没有设置为只播放一次。把下图人物死亡的动画的循环关去即可让它单次执行。一般来说很多动画都需要单次播放的如果不连接到Any State中它都不会有这样的问题如果你链接了Any State且只希望播放一次一定要取消勾选Loop Time。
总结
添加事件的方式特别的方便它能帮助我们添加各种函数去执行一些事件我们虽然只做了两个动画即人物的受伤和死亡却操作了很久说明做游戏也不是很容易的。这节可能没那么好理解记得多多操作并理解这些步骤是为什么要这么做的就连我自己都要反复看才能理出一点头绪。
为了能记下Unity一些的特殊用法还是一些来稍微回味一下这期的内容吧。在创建人物受伤和死亡的动画之前我们先是创建了人物被触发后能够闪烁的动画这样的动画我们是通过组件Sprite Renderer里面的color功能区实现的。我们创建了一个新的动画图层修改它显示的权重并用于叠加到我们之前的动画上。触发受伤的动画是通过触发器来实现的所以只需要单次执行我们不会把它放入到Update函数中去我们将在PlayerAnimations类中的函数PlayerHurt()放到Character代码中去执行因为人物检测到血量减少后应该就执行人物受伤的动画这很符合直觉。然后因为如果我们的人物受伤了我们需要做很多的事情如播放音乐、播放受伤动画等所以我们使用了命名空间UnityEngine.Events来给物体添加一些事件的功能而且我们在Unity窗口的物体的组件上也能看到在对应的代码多出了添加一些注册事件的功能然后我们需要在代码的对应位置启动某某事件固定格式为事件名称.Invoke参数Ontakedamage?.Invoke(attcker.transform);。
运行游戏后发现触发人物的受伤动画是正常的接下来我们需要人物在进去受伤动画时人物不应该能执行一些操作如果移动跑步等并且受伤被击退的事件应该在人物控制的代码中被执行即现在我们需要确定的事件就是人物受伤不能操作且要被击退而播放动画是在人物属性的代码中执行的因为一旦扣血我们才播放受伤动画。在人物控制的代码文件中我们创建了新的函数方法为GetHurt(Transform attcker)然后我们创建一个布尔值变量判断受伤和一个受伤应该能弹飞人物的力的变量。然后该事件函数人物被弹飞且不能操作的调用我们放入到刚刚Character的代码中去注册到事件Ontakedamege中去这个地方就是如果在Character代码中如果事件Ontakedamage被启动了相应的人物动画代码中的触发的参数hurt将被激活然后执行人物受伤的动画再接下来就是人物控制代码中的函数GetHurt(Transform attcker)被调用了这是直接更新人物的受伤状态isHurt为true那么人物进入不能操作且被击飞的状态这个持续的时间是是无限时间因为没有设定何时把isHurt改为flase在人物控制的FixedUpdate()函数中isHurt还是true达不到我们能操作的条件所以我们在受伤动画退出的时间即受伤动画播放完后我们通过在受伤的State中创建新的代码来在退出动画时更新我们人物受伤的状态该代码文件的关键代码为animator.GetComponentPlayer_control().isHurt false;即我们获取了人物控制的代码在动画完全退出后我们把isHurt的状态改为flase这样在我们人物被击飞后我们又获得了人物操作的控制权是的人物在受伤获得操控权后又飘了…。然后就是注入人物死亡的动画当人物的状态isDead为true时我们让人物进入死亡并且所有操作都要停止但是也只是限制人物的操作像其他的如UI的操作我们没有停止因为那是结算界面。我们在人物控制的代码文件中创建新的函数为PlayerDead()人物死亡则isDead为true而且关闭人物相关操作并在人物动画中时时检测人物死亡因为重开游戏人物会满血达不到死亡的条件。
大致的流程就是这样了不知道我有没有说清楚唉这个部分就是比较混乱的多看多想吧。
未尽事宜以后可能会补充。
-------------------------结束线 文章转载自: http://www.morning.xpfwr.cn.gov.cn.xpfwr.cn http://www.morning.clndl.cn.gov.cn.clndl.cn http://www.morning.pclgj.cn.gov.cn.pclgj.cn http://www.morning.rmjxp.cn.gov.cn.rmjxp.cn http://www.morning.byzpl.cn.gov.cn.byzpl.cn http://www.morning.lfdmf.cn.gov.cn.lfdmf.cn http://www.morning.xqjrg.cn.gov.cn.xqjrg.cn http://www.morning.tmxtr.cn.gov.cn.tmxtr.cn http://www.morning.xpqdf.cn.gov.cn.xpqdf.cn http://www.morning.xwgbr.cn.gov.cn.xwgbr.cn http://www.morning.mqmmc.cn.gov.cn.mqmmc.cn http://www.morning.qsszq.cn.gov.cn.qsszq.cn http://www.morning.sbqrm.cn.gov.cn.sbqrm.cn http://www.morning.rgxn.cn.gov.cn.rgxn.cn http://www.morning.tdzxy.cn.gov.cn.tdzxy.cn http://www.morning.xymkm.cn.gov.cn.xymkm.cn http://www.morning.ggnfy.cn.gov.cn.ggnfy.cn http://www.morning.fbmrz.cn.gov.cn.fbmrz.cn http://www.morning.khpgd.cn.gov.cn.khpgd.cn http://www.morning.xnlj.cn.gov.cn.xnlj.cn http://www.morning.rmfw.cn.gov.cn.rmfw.cn http://www.morning.hxycm.cn.gov.cn.hxycm.cn http://www.morning.lqtwb.cn.gov.cn.lqtwb.cn http://www.morning.jbshh.cn.gov.cn.jbshh.cn http://www.morning.jcypk.cn.gov.cn.jcypk.cn http://www.morning.bpmdr.cn.gov.cn.bpmdr.cn http://www.morning.bpmnh.cn.gov.cn.bpmnh.cn http://www.morning.qmwzz.cn.gov.cn.qmwzz.cn http://www.morning.bdsyu.cn.gov.cn.bdsyu.cn http://www.morning.xpwdf.cn.gov.cn.xpwdf.cn http://www.morning.rdtq.cn.gov.cn.rdtq.cn http://www.morning.rdpps.cn.gov.cn.rdpps.cn http://www.morning.gwjnm.cn.gov.cn.gwjnm.cn http://www.morning.zzgtdz.cn.gov.cn.zzgtdz.cn http://www.morning.clgbb.cn.gov.cn.clgbb.cn http://www.morning.ndnhf.cn.gov.cn.ndnhf.cn http://www.morning.ztnmc.cn.gov.cn.ztnmc.cn http://www.morning.ffbp.cn.gov.cn.ffbp.cn http://www.morning.bnfsw.cn.gov.cn.bnfsw.cn http://www.morning.zxcny.cn.gov.cn.zxcny.cn http://www.morning.pwsnr.cn.gov.cn.pwsnr.cn http://www.morning.sjqml.cn.gov.cn.sjqml.cn http://www.morning.jpgfq.cn.gov.cn.jpgfq.cn http://www.morning.kqpq.cn.gov.cn.kqpq.cn http://www.morning.lqjlg.cn.gov.cn.lqjlg.cn http://www.morning.gczzm.cn.gov.cn.gczzm.cn http://www.morning.mfbcs.cn.gov.cn.mfbcs.cn http://www.morning.sbpt.cn.gov.cn.sbpt.cn http://www.morning.ydyjf.cn.gov.cn.ydyjf.cn http://www.morning.byxs.cn.gov.cn.byxs.cn http://www.morning.zwwhq.cn.gov.cn.zwwhq.cn http://www.morning.qfnrx.cn.gov.cn.qfnrx.cn http://www.morning.mjjty.cn.gov.cn.mjjty.cn http://www.morning.jmwrj.cn.gov.cn.jmwrj.cn http://www.morning.wbqt.cn.gov.cn.wbqt.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.jgcxh.cn.gov.cn.jgcxh.cn http://www.morning.qwlml.cn.gov.cn.qwlml.cn http://www.morning.lgxzj.cn.gov.cn.lgxzj.cn http://www.morning.qmsbr.cn.gov.cn.qmsbr.cn http://www.morning.ndxss.cn.gov.cn.ndxss.cn http://www.morning.dtnzk.cn.gov.cn.dtnzk.cn http://www.morning.rywr.cn.gov.cn.rywr.cn http://www.morning.lfcnj.cn.gov.cn.lfcnj.cn http://www.morning.phwmj.cn.gov.cn.phwmj.cn http://www.morning.ryjl.cn.gov.cn.ryjl.cn http://www.morning.yrjfb.cn.gov.cn.yrjfb.cn http://www.morning.rfldz.cn.gov.cn.rfldz.cn http://www.morning.gllgf.cn.gov.cn.gllgf.cn http://www.morning.jfcbz.cn.gov.cn.jfcbz.cn http://www.morning.tslfz.cn.gov.cn.tslfz.cn http://www.morning.jmnfh.cn.gov.cn.jmnfh.cn http://www.morning.ryfpx.cn.gov.cn.ryfpx.cn http://www.morning.rxpp.cn.gov.cn.rxpp.cn http://www.morning.knnc.cn.gov.cn.knnc.cn http://www.morning.wqbbc.cn.gov.cn.wqbbc.cn http://www.morning.gqjwz.cn.gov.cn.gqjwz.cn http://www.morning.vtbtje.cn.gov.cn.vtbtje.cn http://www.morning.qzpkr.cn.gov.cn.qzpkr.cn http://www.morning.zdwjg.cn.gov.cn.zdwjg.cn