Unity 制作愤怒的小鸟

  • 一、项目准备
  • 二、切片
  • 三、实现小鸟的拖拽与飞出
    • 1. 添加并设置Spring Joint 2D
    • 2. 实现小鸟跟随鼠标移动
    • 3. 限定小鸟最大拖拽距离
    • 4. 实现小鸟飞出
    • 5. 实现弹弓的划线
    • 6. 让小鸟不能重复拖拽
  • 四、场景搭建
  • 五、实现小鸟攻击猪
    • 1. 猪的受伤与死亡
    • 2. 猪的加分
  • 六、实现多只鸟的控制
  • 七、小鸟尾迹的实现
  • 八、给猪造房子
  • 九、游戏胜利、失败界面
    • 1. 显示胜利、失败基本界面
    • 2. 星星粒子效果
    • 3. 星星显示
  • 十、暂停界面
    • 1. 界面以及动画
    • 2. 实现暂停和继续
    • 3. 实现Restart Level
  • 十一、相机跟随
    • 1. 跟随第一只小鸟
    • 2. 按顺序跟随多只小鸟
  • 参考

参考视频: 【SiKi学院Unity】Unity初级案例 - 愤怒的小鸟


一、项目准备

资源下载: http://www.sikiedu.com/course/134

新建工程:

选择2D,填写项目名称并选择项目路径:

将资源中的ImageMusic复制到项目文件夹中:



二、切片

选择猪和鸟的第一章图片,将其Sprite Mode改为MultipleApply

如下图所示进行切片:

发现四个爆炸烟雾未切分好,手动切分一下:

Apply:

在场景中拖入弹弓和小鸟,设置层级关系:


三、实现小鸟的拖拽与飞出

1. 添加并设置Spring Joint 2D

为小鸟添加Spring Joint 2D组件,添加后会自动添加刚体组件:

同时给弹弓右部加上刚体组件,并设置为Static(防止其受重力影响):

将弹弓右部的刚体拖到Spring Joint 2D中,并设置Spring Joint 2D的各项参数:

2. 实现小鸟跟随鼠标移动

添加碰撞体和Bird脚本:

bird.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bird : MonoBehaviour
{private bool isClick = false;private void Update(){MoveWithMouse();}private void MoveWithMouse(){// 让小鸟跟随鼠标的位置if (isClick){transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);}}// 鼠标按下private void OnMouseDown(){isClick = true;   }// 鼠标抬起private void OnMouseUp(){isClick = false;}}

此时小鸟被鼠标拖拽时会跟随鼠标移动。

3. 限定小鸟最大拖拽距离

首先在弹弓右部设置一个点,作为小鸟绕着转的点:

Bird.cs中声明rightPos 和 maxDis变量:

    public Transform rightPos;   // 弹弓右部点,即拖拽小鸟时让其跟着转public float maxDis;  // 最大推拽距离

修改MoveWithMouse()如下:

    private void MoveWithMouse(){// 让小鸟跟随鼠标的位置if (isClick){transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);// 限定小鸟最大拖拽距离if (Vector2.Distance(transform.position, rightPos.position) >= maxDis){transform.position = rightPos.position + (transform.position - rightPos.position).normalized * maxDis;}}}

Inspector面板中将rightPos拖拽到bird脚本中,并设置maxDis,此时小鸟被限定了拖拽距离:

4. 实现小鸟飞出

鼠标按下时,刚体状态设置为动力学。
在鼠标松开时,动力学设为false,一段时间后禁用SpringJoint2D组件:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bird : MonoBehaviour
{private SpringJoint2D springJoint;private Rigidbody2D rb;public Transform rightPos;   // 弹弓右部点,即拖拽小鸟时让其跟着转public float maxDis;  // 最大推拽距离private bool isClick = false;private void Start(){springJoint = GetComponent<SpringJoint2D>();rb = GetComponent<Rigidbody2D>();}private void Update(){MoveWithMouse();}private void MoveWithMouse(){// 让小鸟跟随鼠标的位置if (isClick){transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);// 限定小鸟最大拖拽距离if (Vector2.Distance(transform.position, rightPos.position) >= maxDis){transform.position = rightPos.position + (transform.position - rightPos.position).normalized * maxDis;}}}// 鼠标按下private void OnMouseDown(){isClick = true;rb.isKinematic = true;}// 鼠标抬起private void OnMouseUp(){isClick = false;rb.isKinematic = false;Invoke(nameof(Fly), 0.12f);}private void Fly(){springJoint.enabled = false;}}

5. 实现弹弓的划线

在弹弓上创建一个leftPos点,此时leftPosrightPos两个点用于划线:

left添加Line Renderer组件:

设置材质、颜色和长度:

将该组件复制到right上:

编写代码:
bird.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Bird : MonoBehaviour
{private SpringJoint2D springJoint;private Rigidbody2D rb;[Header("弹弓")]public Transform rightPos;   // 弹弓右部点,即拖拽小鸟时让其跟着转; 同时画线public Transform leftPos;    // 弹弓左部点, 画线public LineRenderer leftLine;public LineRenderer rightLine;[Space]public float maxDis;  // 最大推拽距离private bool isClick = false;private void Start(){springJoint = GetComponent<SpringJoint2D>();rb = GetComponent<Rigidbody2D>();}private void Update(){MoveWithMouse();}private void MoveWithMouse(){// 让小鸟跟随鼠标的位置if (isClick){transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);transform.position += new Vector3(0, 0, -Camera.main.transform.position.z);// 限定小鸟最大拖拽距离if (Vector2.Distance(transform.position, rightPos.position) >= maxDis){transform.position = rightPos.position + (transform.position - rightPos.position).normalized * maxDis;}DrawLine();}}// 鼠标按下private void OnMouseDown(){isClick = true;rb.isKinematic = true;}// 鼠标抬起private void OnMouseUp(){isClick = false;rb.isKinematic = false;DeleteLine();  // 删除弹弓的线Invoke(nameof(Fly), 0.12f);}// 飞出private void Fly(){springJoint.enabled = false;}// 画线private void DrawLine(){// 设置线的两个端点leftLine.SetPosition(0, leftPos.position);leftLine.SetPosition(1, transform.position);rightLine.SetPosition(0, rightPos.position);rightLine.SetPosition(1, transform.position);}// 删除线private void DeleteLine(){leftLine.SetPosition(1, leftPos.position);rightLine.SetPosition(1, rightPos.position);}
}

此时拖拽小鸟时可正常划线,松开则线消失。

6. 让小鸟不能重复拖拽

此时小鸟被拖拽放飞后,再次按住小鸟任然能回到弹弓上。

为了解决该bug,给小鸟添加一个bool参数:

    private bool flied = false;  // 是否飞过,用以让小鸟不能重复拖拽

鼠标抬起后,设置为true:

    // 鼠标抬起private void OnMouseUp(){isClick = false;flied = true;rb.isKinematic = false;DeleteLine();  // 删除弹弓的线Invoke(nameof(Fly), 0.12f);}

鼠标按下后,如果flied已经为true,则无效:

    // 鼠标按下private void OnMouseDown(){if (flied)return;isClick = true;rb.isKinematic = true;}

此时小鸟只能被拖拽一次。


四、场景搭建

选择场景1进行切割:

将地面拖入并添加碰撞体:

创建预制体相关文件夹,并将其拖入:

设置地面:

同理,设置天空:


五、实现小鸟攻击猪

添加猪,并添加相关组件并设置图层:

将鸟和猪的角阻力都设置为2,防止其在地面滚动不停止:

1. 猪的受伤与死亡

给猪添加Pig脚本:

设置猪受到小鸟的碰撞时,受伤和死亡应该达到的相对速度:

    public float hurtSpeed = 5.0f;  // 受伤速度public float deadSpeed = 10.0f;  // 死亡速度

设置猪受伤后的图片:

    // 受伤图片public Sprite hurtSprite;

拖入相应的烟雾的图片到场景中:

创建boom动画:

打开Animation进行相应的调整:

同时将该动画取消循环播放:

Boom添加一个脚本Boom:

编写代码:
Boom.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Boom : MonoBehaviour
{public void DestorySelf(){Destroy(gameObject);}
}

Animation中设置,当播放完之后执行该函数,即销毁自身:

Boom物体制成预制体:

猪的死亡逻辑:

若相对速度大于死亡速度:则死亡;
若相对速度只是大于受伤速度:此时猪若是受伤状态,则死亡;反之则受伤

Pig.cs中,实现猪的受伤与死亡:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Pig : MonoBehaviour
{private SpriteRenderer spriteRenderer;// 受伤图片public Sprite hurtSprite;public GameObject boomPrefab;[Header("相对速度")]public float hurtSpeed = 5.0f;  // 受伤速度public float deadSpeed = 10.0f;  // 死亡速度private bool isHurt = false;private void Start(){spriteRenderer = GetComponent<SpriteRenderer>();}private void OnCollisionEnter2D(Collision2D collision){float relativeV = collision.relativeVelocity.magnitude;print(relativeV);// 大于死亡速度if (relativeV >= deadSpeed){Dead();}// 大于受伤速度else if (relativeV >= hurtSpeed){if (isHurt)Dead();else{isHurt = true;spriteRenderer.sprite = hurtSprite;}}}// 死亡,生成爆炸动画和分数private void Dead(){Instantiate(boomPrefab, transform.position, Quaternion.identity);Destroy(gameObject);}}

2. 猪的加分

切割分数图片:

拖拽出一个分数并制为预制体:

编写pig.cs代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Pig : MonoBehaviour
{private SpriteRenderer spriteRenderer;// 受伤图片public Sprite hurtSprite;public GameObject boomPrefab;public GameObject scorePrefab;[Header("相对速度")]public float hurtSpeed = 5.0f;  // 受伤速度public float deadSpeed = 10.0f;  // 死亡速度private bool isHurt = false;[Space]public float scoreYOffset = 0.65f;  // 分数相对猪的Y位置private void Start(){spriteRenderer = GetComponent<SpriteRenderer>();}private void OnCollisionEnter2D(Collision2D collision){float relativeV = collision.relativeVelocity.magnitude;print(relativeV);// 大于死亡速度if (relativeV >= deadSpeed){Dead();}// 大于受伤速度else if (relativeV >= hurtSpeed){if (isHurt)Dead();else{isHurt = true;spriteRenderer.sprite = hurtSprite;}}}// 死亡,生成爆炸动画和分数private void Dead(){GameManager.instance.pigs.Remove(this);Instantiate(boomPrefab, transform.position, Quaternion.identity);GameObject scoreObject = Instantiate(scorePrefab, transform.position + new Vector3(0, scoreYOffset, 0),Quaternion.identity);Destroy(scoreObject, 1.5f);Destroy(gameObject);}}

六、实现多只鸟的控制

将小鸟制为预制体,并复制两只:

创建一个Game Manager空物体,新建并挂上GameManager脚本:

使用单例模式并用列表存储小鸟和猪:

public class GameManager : MonoBehaviour
{public static GameManager instance;public List<Bird> birds;public List<Pig> pigs;private void Awake(){instance = this;}}

Bird中编写,让小鸟飞出几秒后销毁,并生成爆炸动画,并从GameManager的列表中移除:

private bool isClick = false;private bool flied = false;  // 是否飞过,用以让小鸟不能重复拖拽// 飞出private void Fly(){springJoint.enabled = false;Invoke(nameof(DestroySelf), flyTime);}// 飞出5秒后销毁private void DestroySelf(){GameManager.instance.birds.Remove(this);Instantiate(boomPrefab, transform.position, Quaternion.identity);Destroy(gameObject);}

同理,猪死亡时,在GameManger的列表中也需要删除:

    // 死亡,生成爆炸动画和分数private void Dead(){GameManager.instance.pigs.Remove(this);Instantiate(boomPrefab, transform.position, Quaternion.identity);GameObject scoreObject = Instantiate(scorePrefab, transform.position + new Vector3(0, scoreYOffset, 0),Quaternion.identity);Destroy(scoreObject, 1.5f);Destroy(gameObject);}

GameManager中,起初启用第一只小鸟、禁用其他小鸟的脚本和SpringJoint,并在小鸟销毁后判断游戏状态以及是否启用下一只小鸟:
GameManager.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GameManager : MonoBehaviour
{public static GameManager instance;public List<Bird> birds;public List<Pig> pigs;private Vector3 originBirdPos;  // 小鸟初始位置private void Awake(){instance = this;if (birds.Count > 0)originBirdPos = birds[0].transform.position;InitBird();}// 初始化小鸟private void InitBird(){for(int i = 0; i <birds.Count; i++){if (i == 0){birds[i].transform.position = originBirdPos;birds[i].enabled = true;birds[i].GetComponent<SpringJoint2D>().enabled = true;}else{birds[i].enabled = false;birds[i].GetComponent<SpringJoint2D>().enabled = false;}}}// 判断游戏状态 及 是否启用下一只小鸟public void Next(){if (pigs.Count == 0){// 游戏胜利}else{if (birds.Count == 0){// 游戏失败}else{InitBird();}}}}

在小鸟销毁后,调用`Next()`: `bird.cs`:

    // 飞出5秒后销毁private void DestroySelf(){GameManager.instance.birds.Remove(this);GameManager.instance.Next();Instantiate(boomPrefab, transform.position, Quaternion.identity);Destroy(gameObject);}

最后在Inspector面板中拖拽小鸟和猪后,可正常控制多只小鸟。


七、小鸟尾迹的实现

导入素材中的Unity包:

只添加Weapon Trail

给小鸟添加Trail Renderer组件:

设置拖尾的材质、持续时间已经宽度:

同时加载到其他预制体上:

拖尾效果:


八、给猪造房子

切割:

以方形木头为例:

Pig.cs脚本中添加bool的isPig,让木块等也能使用:

    [Space]public bool isPig = false;// 死亡,生成爆炸动画和分数private void Dead(){if (isPig)GameManager.instance.pigs.Remove(this);Instantiate(boomPrefab, transform.position, Quaternion.identity);GameObject scoreObject = Instantiate(scorePrefab, transform.position + new Vector3(0, scoreYOffset, 0),Quaternion.identity);Destroy(scoreObject, 1.5f);Destroy(gameObject);}

将之前的猪勾选isPig

将木头挂载该脚本并不勾选isPig,然后设置hurtSpeed等参数 :

木头需要组件: 刚体、碰撞体、Pig脚本

同理,新增其他物品。

设置简单的场景如下:

运行效果:


九、游戏胜利、失败界面

1. 显示胜利、失败基本界面

切割:

制作UI(参考第15集).

Lose UI:

Win UI:

在游戏胜利时,根据关卡中的剩余小鸟数量,判断应该获得的星星数量,GameManager.cs部分代码如下:

    [Header("UI")]public GameObject winUI;public GameObject loseUI;[Header("胜利得到星星的数量需要的小鸟存活数")]public int birdNumOf3Star;public int birdNumOf2Star;// 判断游戏状态 及 是否启用下一只小鸟public void Next(){if (pigs.Count == 0){// 游戏胜利winUI.SetActive(true);}else{if (birds.Count == 0){// 游戏失败loseUI.SetActive(true);}else{InitBird();}}}public void WinLevel(){if (birds.Count >= birdNumOf3Star)  // 3颗星星{}else if (birds.Count >= birdNumOf2Star) // 2颗{}else // 1颗{}}

同时,为Win UI创建一个Win.cs的脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Win : MonoBehaviour
{// 动画播放完(显示UI后) 显示星星public void ShowStar(){GameManager.instance.WinLevel();}
}

在动画结束后调用:

2. 星星粒子效果

切割星星:

三颗星星的摆放:

根据https://www.bilibili.com/video/BV1qb411c76x?p=16第16到18集设置星星的粒子效果。

3. 星星显示

GameManager.cs中,利用协程,每隔0.7s,显示一颗星星:

    public GameObject[] starsUI = new GameObject[3];public void WinLevel(){if (birds.Count >= birdNumOf3Star)  // 3颗星星{StartCoroutine("ShowTheStar", 3);}else if (birds.Count >= birdNumOf2Star) // 2颗{StartCoroutine("ShowTheStar", 2);}else // 1颗{StartCoroutine("ShowTheStar", 1);}}// 每隔0.7秒,显示一颗星星IEnumerator ShowTheStar(int num){for(int i = 0; i < num; i++){starsUI[i].SetActive(true);yield return new WaitForSeconds(0.7f);}}

Insepctor面板中拖入星星:

此时正常显示星星:


十、暂停界面

1. 界面以及动画

P20

暂停按钮:

暂停面板:

实现暂停动画:

实现继续动画:

两个动画都取消循环播放:

2. 实现暂停和继续

Animator中创建两个Trigger参数,并将两个动画相连:

Pause动画与Resume的连线:

创建PausePanle脚本并放入Pause Panel:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PausePanel : MonoBehaviour
{private Animator anim;// Start is called before the first frame updatevoid Start(){anim = GetComponent<Animator>();}// 点击继续按钮public void Resume(){anim.SetTrigger("resume");}// 继续动画结束后,调用public void AfterResume(){this.gameObject.SetActive(false);anim.SetTrigger("pause");  // 切换回暂停动画,下次active true时则调用暂停动画}}

GameManager.cs中添加代码:

    [Space]public GameObject pausePanel;// 暂停按钮调用函数public void PauseGame(){pausePanel.SetActive(true);}

Inspector面板中,拖入Pause Panel:

Pause Btn添加点击事件,为GameManager的暂停方法:

Resume Btn添加点击事件,为Pause PanelPause方法:

Resume动画结束时,调用AfterResume函数:

效果:

3. 实现Restart Level

GameManager.cs中添加重启关卡方法:

using UnityEngine.SceneManagement;// 重启关卡public void RestartLevel(){SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);}

在各个重启按钮中调用:


运行效果:


十一、相机跟随

1. 跟随第一只小鸟

打开Package Manager:

下载Cinemachine:

添加一个2D Camera

将第一只小鸟拖入Follow,让相机跟随小鸟:

调节部分参数,以选取合适位置:

同时创建一个名为Camera BG的空物体,为其加上Polygon碰撞体,勾选Is Trigger,用作相机的范围,(即小鸟若超出该范围,相机则不跟随):

在刚刚的CM vcam1中,添加CinemachineConfiner

将刚刚的Camera BG拖入:

2. 按顺序跟随多只小鸟

GameManager中引入:

using Cinemachine;

若报错,则导入Cinemachine示例程序场景:

GameManager.cs更改的代码:

using Cinemachine;[Header("相机和弹弓")]public CinemachineVirtualCamera virtualCamera;public Transform slingshotLeftPos;    // 弹弓左部点,用于小鸟死后视角回到弹弓// 初始化小鸟private void InitBird(){for(int i = 0; i <birds.Count; i++){if (i == 0){birds[i].transform.position = originBirdPos;birds[i].enabled = true;birds[i].GetComponent<SpringJoint2D>().enabled = true;virtualCamera.Follow = birds[i].transform;  // 相机跟随小鸟}else{birds[i].enabled = false;birds[i].GetComponent<SpringJoint2D>().enabled = false;}}}// 判断游戏状态 及 是否启用下一只小鸟public void Next(){virtualCamera.Follow = slingshotLeftPos;virtualCamera.transform.position = slingshotLeftPos.position;if (pigs.Count == 0){// 游戏胜利winUI.SetActive(true);}else{if (birds.Count == 0){// 游戏失败loseUI.SetActive(true);}else{InitBird();}}}

最终演示效果:


参考

【SiKi学院Unity】Unity初级案例 - 愤怒的小鸟

Unity 制作愤怒的小鸟相关推荐

  1. unity制作愤怒的小鸟笔记

    1.穿透效果 层级(小鸟和弹弓都属于BirdHood层) 前弹弓属于BirdHood层的第3层 后弹弓属于BirdHood层的第1层 小鸟属于BirdHood层的第2层 层级关系小鸟可以在实现穿透效果 ...

  2. unity制作愤怒的小鸟

    文章目录 一. 介绍 SpringJoint2D .line renderer制作发射绳 基类bird脚本的基础功能 给bird添加飞行拖尾效果 pig类 游戏胜利的小星星烟花界面 摄像机跟随移动 游 ...

  3. Unity制作2D动作平台游戏视频教程

    Metroidvania工具包:打造统一的2D行动平台 流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确 ...

  4. Unity制作游戏中的场景

    Unity制作游戏中的场景 1.2.3  场景 在Unity中,场景(Scene)就是游戏开发者制作游戏时,所使用的游戏场景.它是一个三维空间,对应的三维坐标轴分别是X轴.Y轴和Z轴本文选自Unity ...

  5. arkit unity_凯蒂猫! 如何使用ARKit和Unity制作增强现实应用程序。

    arkit unity by Francesco Pallotta 由Francesco Pallotta 凯蒂猫! 如何使用ARKit和Unity制作增强现实应用程序. (Hello, Kitty! ...

  6. unity 制作书本 翻页效果

    unity 制作书籍翻页效果 unity C# 翻书效果 2D 真实翻页 不使用插件 自制 实现思路: 将书本分为两边,一边一个翻页实现: 下图为书本的右面,以OA为分界线,△OAB是下一面的如上图的 ...

  7. Unity 制作简单的任务动画

    Unity 制作简单的任务动画 1.添加人物模型到unity 我使用的是unity store中的免费模型: https://assetstore.unity.com/packages/3d/char ...

  8. Unity 制作萌系live2d桌宠:屏幕自适应+交互

    目录 准备工作 使用unity显示live2d人物 全屏+背景透明+点击穿透+置顶 屏幕自适应 交互 本文在之前的博客如何使用unity制作萌萌的live2d桌宠的基础上对项目继续改进,解决了屏幕自适 ...

  9. Unity制作格斗游戏核心思路总结

    http://anchorart9.com/2016/05/22/unity%E5%88%B6%E4%BD%9C%E6%A0%BC%E6%96%97%E6%B8%B8%E6%88%8F%E6%A0%B ...

最新文章

  1. windows form窗体应用程序,建一个记事本参考代码,重点是打开,保存,另存为...
  2. Mac下配置Maven
  3. 集合70多种推荐算法,东北大学老师用Java写了一个开源库,在GitHub上收获近1500个Star...
  4. 七位世界级Java大师的杰作
  5. ElementUI中el-radio-group使用v-model绑定是属性为String字符串类型时不回显数据
  6. idea.config.path is invalid 问题
  7. node开启子线程_多进程 amp; Node.js web 实现
  8. 图论 公约数 找环和链 BZOJ [NOI2008 假面舞会]
  9. halcon学习笔记——(4)HDevelop language(结构语句)
  10. WebSpider和一些杂七杂八
  11. 基于数字证书的UKEY安全登录 与身份认证技术研究
  12. ARCGIS中坐标转换及地理坐标、投影坐标的定义(转载)
  13. 【C语言】易错题 and 易混淆知识
  14. Cesium之3D拉伸显示行政区
  15. SE:5.面向对象(上)
  16. linux yum安装redis
  17. 抢鞋软件bot服务器系统,抢鞋机器人bot安卓版
  18. hackthebox Busqueda EASY难度 一把梭哈
  19. linux下printf终端打印输出颜色控制
  20. java web 网上商城_JavaWeb项目--网上商城 (6-2)

热门文章

  1. 计算机中丢失tcalc,【图】通达信指标公式全部丢失,怎样能找回来_炒股软件,炒股,炒股公式,股票指标,股票软件_股票软件技术交流论坛_理想论坛 - 股票论坛...
  2. 盘点国内外十类垂直型社交网站
  3. 黑苹果OC引导AX201网卡教程,小新Pro13不换网卡也能上网
  4. 【D3.js 学习总结】12、D3布局-集群图
  5. 经典网页设计:30个创意的 CSS 应用案例
  6. python 节点关系图_python 可视化节点关系(一):networkx
  7. MeeGo系统和SailFish系统_我是亲民_新浪博客
  8. uni-app swiper实现公告栏上下循环滚动(整理)
  9. 打印机扫描显示服务器磁盘已满,打印机内存已满怎么办 打印机清除内存方法...
  10. mysql获取中文拼音_mysql获取汉字拼音