甜品消消乐游戏

  (脚本源码在游戏UI设计最下方)

  

  三消游戏,存在L型消除有一点小Bug,当甜品在饼干附近消除时会清除饼干

  饼干作为游戏障碍物时不可移动的,多块饼干并排时会挡住甜品掉落

  发现消除类游戏的算法还是比较复杂的

  游戏小道具因算法绕的我头有点晕就没有实现

  甜品掉落速度可以在GameManager游戏管理类上设置fill Time值(我这里是0.25)

  emm,游戏开始界面有点low,未添加渲染动画

游戏项目已托管到Github上  传送门

甜品消消乐01_游戏基础界面  传送门

甜品消消乐02_游戏核心算法  传送门

甜品消消乐03_游戏UI设计     传送门

 (文章最下边有游戏脚本)

实现过程

素材导入,基本预制体的制作

  通过Gizmos影藏Scene场景中小摄像机

  (点击摄像机进行关闭)

  新建一个GameObject->New Sprite,甜甜圈拖动上Sprite上,将游戏分层开发(分为模型层和渲染层)

  当不知道甜甜圈尺寸时,可以新建一个3D Object->Cube,Cube默认长宽比例为1m

  将甜甜圈长宽缩放比例0.45

  将甜甜圈做成预设体

  制作格子背景

  设置格子缩放比例为0.65

  为设置格子背景在甜甜圈背面,将Gird背景的Order in Layout设置为-1

  将Gird设置成预设体

  (不需要用到Cube我就把它删除了)

游戏管理的创建,巧克力的生成

 

  新建一个GameObject->New Sprite,制作游戏背景

  (背景比摄像机范围稍微大一些,放曝光)

  

  添加GameManager游戏管理类脚本,挂在到GameObject(GameManager)上

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameManager : MonoBehaviour { //单例实例化
private static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
} set
{
_instance = value;
}
} //大网格的行列数
public int xColumn;
public int yRow; public GameObject gridPrefab; private void Awake()
{
_instance = this;
} // Use this for initialization
void Start () {
for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,new Vector3(x,y,),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
}
} // Update is called once per frame
void Update () { }
}

GameManager.cs

  巧克力块游戏背景

  大网格的行列数

    public int xColumn;
public int yRow;
    public GameObject gridPrefab;

    void Start () {
for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,new Vector3(x,y,),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
}
}

  (为了使背景在巧克力块后面,设置background的Order in Layout 为 -2)

  实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标

  实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标

  

  调整巧克力块背景

    public Vector3 CorrectPosition(int x ,int y)
{
//实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
// 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameManager : MonoBehaviour { //单例实例化
private static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
} set
{
_instance = value;
}
} //大网格的行列数
public int xColumn;
public int yRow; public GameObject gridPrefab; private void Awake()
{
_instance = this;
} // Use this for initialization
void Start () {
for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
}
} // Update is called once per frame
void Update () { } public Vector3 CorrectPosition(int x ,int y)
{
//实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
// 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
} }

GameManager.cs

甜品的类型枚举,结构体,字典的创建

  甜品的种类

    public enum SweetsType
{
EMPTY,
NORMAL,
BARRIER,
ROE_CLEAR,
COLUMN_CLEAR,
RAINBOWCANDY,
COUNT //标记类型
}

  甜品预制体的字典,我们可以通过甜品的种类来得到对应的甜品游戏物体

    public Dictionary<SweetsType, GameObject> sweetPrefabDict;

    [System.Serializable]
public struct SweetPrefab
{
public SweetsType type;
public GameObject prefab;
} public SweetPrefab[] sweetPrefabs;

  字典的实例化

        sweetPrefabDict = new Dictionary<SweetsType, GameObject>();
for(int i=;i<sweetPrefabs.Length;i++)
{
if (sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
}

甜品的生成

  甜品数组

 private GameObject[,] sweets;
void Start () {

        //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameObject[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
sweets[x,y] = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x, y), Quaternion.identity);
sweets[x,y].transform.SetParent(transform);
}
} }

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameSweet : MonoBehaviour { private int x; public int X
{
get
{
return x;
} set
{
x = value;
}
} private int y; public int Y
{
get
{
return y;
} set
{
y = value;
}
} private GameManager.SweetsType type; public GameManager.SweetsType Type
{
get
{
return type;
}
} public GameManager gameManager; public void Init(int _x,int _y,GameManager _gameManager,GameManager.SweetsType _type)
{
x = _x;
y = _y;
gameManager = _gameManager;
type = _type;
} }

GameSweet.cs 管理甜甜圈脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameManager : MonoBehaviour { //甜品的种类
public enum SweetsType
{
EMPTY,
NORMAL,
BARRIER,
ROE_CLEAR,
COLUMN_CLEAR,
RAINBOWCANDY,
COUNT //标记类型
} //甜品预制体的字典,我们可以通过甜品的种类来得到对应的甜品游戏物体
public Dictionary<SweetsType, GameObject> sweetPrefabDict; [System.Serializable]
public struct SweetPrefab
{
public SweetsType type;
public GameObject prefab;
} public SweetPrefab[] sweetPrefabs; //单例实例化
private static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
} set
{
_instance = value;
}
} //大网格的行列数
public int xColumn;
public int yRow; public GameObject gridPrefab; //甜品数组
private GameSweet[,] sweets; private void Awake()
{
_instance = this;
} // Use this for initialization
void Start () { //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x, y), Quaternion.identity);
newSweet.transform.SetParent(transform); sweets[x,y] = newSweet.GetComponent<GameSweet>();
sweets[x, y].Init(x, y, this, SweetsType.NORMAL);
}
} } // Update is called once per frame
void Update () { } public Vector3 CorrectPosition(int x ,int y)
{
//实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
// 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
} }

GameManager.cs

甜品移动

  添加甜品移动脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class MovedSweet : MonoBehaviour { private GameSweet sweet; private void Awake()
{
sweet = GetComponent<GameSweet>();
} public void Move(int newX,int newY)
{
sweet.X = newX;
sweet.Y = newY;
sweet.transform.localPosition = sweet.gameManager.CorrectPosition(newX, newY);
}
}

MovedSweet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameSweet : MonoBehaviour { private int x;
private int y;
public int X
{
get
{
return x;
} set
{
if (CanMove())
{
x = value;
}
}
}
public int Y
{
get
{
return y;
} set
{
if (CanMove())
{
y = value;
}
}
} private GameManager.SweetsType type;
public GameManager.SweetsType Type
{
get
{
return type;
}
} [HideInInspector]
public GameManager gameManager; public MovedSweet MovedComponet
{
get
{
return movedComponet;
}
}
private MovedSweet movedComponet; //判断甜品是否可以移动
public bool CanMove()
{
return movedComponet != null;
} public void Init(int _x,int _y,GameManager _gameManager,GameManager.SweetsType _type)
{
x = _x;
y = _y;
gameManager = _gameManager;
type = _type;
} }

GameSweet.cs

  判断甜品是否可以移动

    public bool CanMove()
{
return movedComponet != null;
}
    private int x;
private int y;
public int X
{
get
{
return x;
} set
{
if (CanMove())
{
x = value;
}
}
}
public int Y
{
get
{
return y;
} set
{
if (CanMove())
{
y = value;
}
}
}

移动的测试

  

  测试甜品移动到Vector.zero位置处

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class MovedSweet : MonoBehaviour { private GameSweet sweet; private void Awake()
{
sweet = GetComponent<GameSweet>();
} public void Move(int newX,int newY)
{
sweet.X = newX;
sweet.Y = newY;
sweet.transform.localPosition = sweet.gameManager.CorrectPosition(newX, newY);
}
}

MovedSweet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameSweet : MonoBehaviour { private int x;
private int y;
public int X
{
get
{
return x;
} set
{
if (CanMove())
{
x = value;
}
}
}
public int Y
{
get
{
return y;
} set
{
if (CanMove())
{
y = value;
}
}
} private GameManager.SweetsType type;
public GameManager.SweetsType Type
{
get
{
return type;
}
} [HideInInspector]
public GameManager gameManager; public MovedSweet MovedComponet
{
get
{
return movedComponet;
}
}
private MovedSweet movedComponet; //判断甜品是否可以移动
public bool CanMove()
{
return movedComponet != null;
} private void Awake()
{
movedComponet = GetComponent<MovedSweet>();
} public void Init(int _x,int _y,GameManager _gameManager,GameManager.SweetsType _type)
{
x = _x;
y = _y;
gameManager = _gameManager;
type = _type;
} }

GameSweet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameManager : MonoBehaviour { //甜品的种类
public enum SweetsType
{
EMPTY,
NORMAL,
BARRIER,
ROE_CLEAR,
COLUMN_CLEAR,
RAINBOWCANDY,
COUNT //标记类型
} //甜品预制体的字典,我们可以通过甜品的种类来得到对应的甜品游戏物体
public Dictionary<SweetsType, GameObject> sweetPrefabDict; [System.Serializable]
public struct SweetPrefab
{
public SweetsType type;
public GameObject prefab;
} public SweetPrefab[] sweetPrefabs; //单例实例化
private static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
} set
{
_instance = value;
}
} //大网格的行列数
public int xColumn;
public int yRow; public GameObject gridPrefab; //甜品数组
private GameSweet[,] sweets; private void Awake()
{
_instance = this;
} // Use this for initialization
void Start () { //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
// CorrectPosition(x, y)
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL],Vector3.zero,Quaternion.identity);
newSweet.transform.SetParent(transform); sweets[x,y] = newSweet.GetComponent<GameSweet>();
sweets[x, y].Init(x, y, this, SweetsType.NORMAL); // if (sweets[x, y].CanMove())
//{
// sweets[x, y].MovedComponet.Move();
// }
}
} } // Update is called once per frame
void Update () { } public Vector3 CorrectPosition(int x ,int y)
{
//实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
// 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
} }

GameManager.cs

甜品颜色

  添加脚本颜色脚本ColorSweet.cs

  通过更改Sweet下的Sprite来更改甜品的种类

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class ColorSweet : MonoBehaviour { public enum ColorType
{
YELLOW,
PUPLE,
RED,
BLUE,
GREEN,
PNGK,
ANY,
COUNT
} [System.Serializable]
public struct ColorSprite
{
public ColorType color;
public Sprite sprite;
} public ColorSprite[] colorSprites; private Dictionary<ColorType, Sprite> colorSpriteDict;
}

ColorSweet.cs

public enum ColorType
{
YELLOW,
PUPLE,
RED,
BLUE,
GREEN,
PNGK,
ANY,
COUNT
}

  每一种颜色对应一种甜品类型

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameManager : MonoBehaviour { //甜品的种类
public enum SweetsType
{
EMPTY,
NORMAL,
BARRIER,
ROE_CLEAR,
COLUMN_CLEAR,
RAINBOWCANDY,
COUNT //标记类型
} //甜品预制体的字典,我们可以通过甜品的种类来得到对应的甜品游戏物体
public Dictionary<SweetsType, GameObject> sweetPrefabDict; [System.Serializable]
public struct SweetPrefab
{
public SweetsType type;
public GameObject prefab;
} public SweetPrefab[] sweetPrefabs; //单例实例化
private static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
} set
{
_instance = value;
}
} //大网格的行列数
public int xColumn;
public int yRow; public GameObject gridPrefab; //甜品数组
private GameSweet[,] sweets; private void Awake()
{
_instance = this;
} // Use this for initialization
void Start () { //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
// CorrectPosition(x, y)
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL],Vector3.zero,Quaternion.identity);
newSweet.transform.SetParent(transform); sweets[x,y] = newSweet.GetComponent<GameSweet>();
sweets[x, y].Init(x, y, this, SweetsType.NORMAL); if (sweets[x, y].CanMove())
{
sweets[x, y].MovedComponet.Move(x,y);
} if (sweets[x, y].CanColor())
{
sweets[x, y].ColorComponet.SetColor((ColorSweet.ColorType)(Random.Range(, sweets[x, y].ColorComponet.NumColors)));
} }
} } // Update is called once per frame
void Update () { } public Vector3 CorrectPosition(int x ,int y)
{
//实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
// 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
} }

GameManager.cs

  当甜品可以移动时,甜品可以进行移动

                if (sweets[x, y].CanMove())
{
sweets[x, y].MovedComponet.Move(x,y);
}

  当甜品存在颜色使填充随机色

                if (sweets[x, y].CanColor())
{
sweets[x, y].ColorComponet.SetColor((ColorSweet.ColorType)(Random.Range(, sweets[x, y].ColorComponet.NumColors)));
}
sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
// CorrectPosition(x, y)
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL],Vector3.zero,Quaternion.identity);
newSweet.transform.SetParent(transform); sweets[x,y] = newSweet.GetComponent<GameSweet>();
sweets[x, y].Init(x, y, this, SweetsType.NORMAL); //当甜品可以移动时,甜品可以进行移动
if (sweets[x, y].CanMove())
{
sweets[x, y].MovedComponet.Move(x,y);
} //当甜品存在颜色使填充随机色
if (sweets[x, y].CanColor())
{
sweets[x, y].ColorComponet.SetColor((ColorSweet.ColorType)(Random.Range(, sweets[x, y].ColorComponet.NumColors)));
} }
}

空甜品的生成

  创建空游戏物体预制体

  产生甜品的方法

    public GameSweet CreateNewSweet(int x,int y,SweetsType type)
{
GameObject newSweet = Instantiate(sweetPrefabDict[type], CorrectPosition(x, y), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, y] = newSweet.GetComponent<GameSweet>();
sweets[x, y].Init(x,y,this,type); return sweets[x, y];
}
void Start () {

        //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY);
}
} }

填充核心算法

  填充全部甜品的方法

 public void AllFill()
{
while (Fill())
{ }
}

  当甜品填充满时返回true

    public bool Fill()
{
bool FilledNotFinshed = false; //用来判断本次是否完成 //行遍历
for(int y=yRow-;y>=;y--)
{
for(int x=;x<xColumn;x++)
{
GameSweet sweet = sweets[x, y]; //得到当前元素位置 //如果无法移动,则无法往下填充
if (sweet.CanMove())
{
GameSweet sweetBelow = sweets[x, y + ]; if(sweetBelow.Type == SweetsType.EMPTY)
{
sweet.MovedComponet.Move(x,y+);
sweets[x, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
}
}
} }
//最上排的特殊情况
for (int x = ; x < xColumn; x++)
{
GameSweet sweet = sweets[x, ]; if(sweet.Type == SweetsType.EMPTY)
{
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x,-), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, ] = newSweet.GetComponent<GameSweet>();
sweets[x, ].Init(x, -,this,SweetsType.NORMAL);
sweets[x, ].MovedComponet.Move(x, );
sweets[x, ].ColorComponet.SetColor((ColorSweet.ColorType)Random.Range(,sweets[x,].ColorComponet.NumColors));
FilledNotFinshed = true;
}
}
return FilledNotFinshed;
}

  在Start()中调用 AllFill()方法

    void Start() {

        //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY);
}
} AllFill();
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameManager : MonoBehaviour { //甜品的种类
public enum SweetsType
{
EMPTY,
NORMAL,
BARRIER,
ROE_CLEAR,
COLUMN_CLEAR,
RAINBOWCANDY,
COUNT //标记类型
} //甜品预制体的字典,我们可以通过甜品的种类来得到对应的甜品游戏物体
public Dictionary<SweetsType, GameObject> sweetPrefabDict; [System.Serializable]
public struct SweetPrefab
{
public SweetsType type;
public GameObject prefab;
} public SweetPrefab[] sweetPrefabs; //单例实例化
private static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
} set
{
_instance = value;
}
} //大网格的行列数
public int xColumn;
public int yRow; public GameObject gridPrefab; //甜品数组
private GameSweet[,] sweets; private void Awake()
{
_instance = this;
} // Use this for initialization
void Start() { //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY);
}
} AllFill();
} // Update is called once per frame
void Update () { } public Vector3 CorrectPosition(int x ,int y)
{
//实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
// 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
} //产生甜品的方法
public GameSweet CreateNewSweet(int x,int y,SweetsType type)
{
GameObject newSweet = Instantiate(sweetPrefabDict[type], CorrectPosition(x, y), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, y] = newSweet.GetComponent<GameSweet>();
sweets[x, y].Init(x,y,this,type); return sweets[x, y];
} //填充甜品的方法
public void AllFill()
{
while (Fill())
{ }
} public bool Fill()
{
bool FilledNotFinshed = false; //用来判断本次是否完成 //行遍历
for(int y=yRow-;y>=;y--)
{
for(int x=;x<xColumn;x++)
{
GameSweet sweet = sweets[x, y]; //得到当前元素位置 //如果无法移动,则无法往下填充
if (sweet.CanMove())
{
GameSweet sweetBelow = sweets[x, y + ]; if(sweetBelow.Type == SweetsType.EMPTY)
{
sweet.MovedComponet.Move(x,y+);
sweets[x, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
}
}
} }
//最上排的特殊情况
for (int x = ; x < xColumn; x++)
{
GameSweet sweet = sweets[x, ]; if(sweet.Type == SweetsType.EMPTY)
{
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x,-), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, ] = newSweet.GetComponent<GameSweet>();
sweets[x, ].Init(x, -,this,SweetsType.NORMAL);
sweets[x, ].MovedComponet.Move(x, );
sweets[x, ].ColorComponet.SetColor((ColorSweet.ColorType)Random.Range(,sweets[x,].ColorComponet.NumColors));
FilledNotFinshed = true;
}
}
return FilledNotFinshed;
}
}

GameManager.cs

  为了使游戏填充时间肉眼速度看得见,添加移动填充协成

移动填充的协成

  填充时间

 public float fillTime;

  填充甜品的方法

    public IEnumerator AllFill()
{
while (Fill())
{
yield return new WaitForSeconds(fillTime);
}
}
 void Start() {

        //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY);
}
} StartCoroutine(AllFill());
}

  此时出场动画会出现卡顿现象,通过修改MovedSweet.cs脚本添加协成

  使每一帧都会进行出场动画

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class MovedSweet : MonoBehaviour { private GameSweet sweet; private IEnumerator moveCoroutine; private void Awake()
{
sweet = GetComponent<GameSweet>();
} //开启或者结束一个协成
public void Move(int newX,int newY,float time)
{
if(moveCoroutine!=null)
{
StopCoroutine(moveCoroutine);
} moveCoroutine = MoveCoroutine(newX,newY,time);
StartCoroutine(moveCoroutine);
} //负责移动的协成
private IEnumerator MoveCoroutine(int newX,int newY,float time)
{
sweet.X = newX;
sweet.Y = newY; //每一帧移动一点点
Vector3 startPos = transform.position;
Vector3 endPos = sweet.gameManager.CorrectPosition(newX,newY); for(float t=;t<time;t+=Time.deltaTime)
{
sweet.transform.position = Vector3.Lerp(startPos,endPos,t/time);
yield return ;
} sweet.transform.position = endPos; }
}

MovedSweet.cs

  开启或者结束一个协成

public void Move(int newX,int newY,float time)
{
if(moveCoroutine!=null)
{
StopCoroutine(moveCoroutine);
} moveCoroutine = MoveCoroutine(newX,newY,time);
StartCoroutine(moveCoroutine);
}

  负责移动的协成

    private IEnumerator MoveCoroutine(int newX,int newY,float time)
{
sweet.X = newX;
sweet.Y = newY; //每一帧移动一点点
Vector3 startPos = transform.position;
Vector3 endPos = sweet.gameManager.CorrectPosition(newX,newY); for(float t=;t<time;t+=Time.deltaTime)
{
sweet.transform.position = Vector3.Lerp(startPos,endPos,t/time);
yield return ;
} sweet.transform.position = endPos;
}
 public bool Fill()
{
bool FilledNotFinshed = false; //用来判断本次是否完成 //行遍历
for(int y=yRow-;y>=;y--)
{
for(int x=;x<xColumn;x++)
{
GameSweet sweet = sweets[x, y]; //得到当前元素位置 //如果无法移动,则无法往下填充
if (sweet.CanMove())
{
GameSweet sweetBelow = sweets[x, y + ]; if(sweetBelow.Type == SweetsType.EMPTY)
{
sweet.MovedComponet.Move(x,y+,fillTime);
sweets[x, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
}
}
} }
//最上排的特殊情况
for (int x = ; x < xColumn; x++)
{
GameSweet sweet = sweets[x, ]; if(sweet.Type == SweetsType.EMPTY)
{
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x,-), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, ] = newSweet.GetComponent<GameSweet>();
sweets[x, ].Init(x, -,this,SweetsType.NORMAL);
sweets[x, ].MovedComponet.Move(x, ,fillTime);
sweets[x, ].ColorComponet.SetColor((ColorSweet.ColorType)Random.Range(,sweets[x,].ColorComponet.NumColors));
FilledNotFinshed = true;
}
}
return FilledNotFinshed;
}

障碍物_饼干

  制作饼干预制体

   void Start() {

        //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY);
}
} //在(4,4)这个坐标点生成障碍物
Destroy(sweets[, ].gameObject);
CreateNewSweet(,,SweetsType.BARRIER); StartCoroutine(AllFill());
}

斜向填充算法

  如果无法移动,其它甜品则无法往下填充

    public bool Fill()
{
bool FilledNotFinshed = false; //用来判断本次是否完成 //行遍历
for(int y=yRow-;y>=;y--)
{
for(int x=;x<xColumn;x++)
{
GameSweet sweet = sweets[x, y]; //得到当前元素位置 //如果无法移动,则无法往下填充
if (sweet.CanMove())
{
GameSweet sweetBelow = sweets[x, y + ]; if(sweetBelow.Type == SweetsType.EMPTY)//垂直填充
{
Destroy(sweetBelow.gameObject);
sweet.MovedComponet.Move(x,y+,fillTime);
sweets[x, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
}
else
{
//-1代表左,1代表右
for (int down = -; down <= ; down++)
{
if (down != )
{
int downX = x + down;
//排除边界的时候
//左下方
if (downX >= && downX < xColumn)
{
GameSweet downSweet = sweets[downX, y + ];
if (downSweet.Type == SweetsType.EMPTY)
{
bool canfill = true; //用来判断垂直填充是否可以满足填充要求
for (int aboutY = y; aboutY >= ; aboutY--)
{
GameSweet sweetAbove = sweets[downX, aboutY];
if (sweetAbove.CanMove())
{
break;
}
else if (!sweetAbove.CanMove() && sweetAbove.Type != SweetsType.EMPTY)
{
canfill = false;
break;
}
} if (!canfill)
{
Destroy(downSweet.gameObject);
sweet.MovedComponet.Move(downX, y + , fillTime);
sweets[downX, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
break;
}
}
}
}
}
}
} } }
//最上排的特殊情况
for (int x = ; x < xColumn; x++)
{
GameSweet sweet = sweets[x, ]; if(sweet.Type == SweetsType.EMPTY)
{
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x,-), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, ] = newSweet.GetComponent<GameSweet>();
sweets[x, ].Init(x, -,this,SweetsType.NORMAL);
sweets[x, ].MovedComponet.Move(x, ,fillTime);
sweets[x, ].ColorComponet.SetColor((ColorSweet.ColorType)Random.Range(,sweets[x,].ColorComponet.NumColors));
FilledNotFinshed = true;
}
}
return FilledNotFinshed;
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class MovedSweet : MonoBehaviour { private GameSweet sweet; private IEnumerator moveCoroutine; private void Awake()
{
sweet = GetComponent<GameSweet>();
} //开启或者结束一个协成
public void Move(int newX,int newY,float time)
{
if(moveCoroutine!=null)
{
StopCoroutine(moveCoroutine);
} moveCoroutine = MoveCoroutine(newX,newY,time);
StartCoroutine(moveCoroutine);
} //负责移动的协成
private IEnumerator MoveCoroutine(int newX,int newY,float time)
{
sweet.X = newX;
sweet.Y = newY; //每一帧移动一点点
Vector3 startPos = transform.position;
Vector3 endPos = sweet.gameManager.CorrectPosition(newX,newY); for(float t=;t<time;t+=Time.deltaTime)
{
sweet.transform.position = Vector3.Lerp(startPos,endPos,t/time);
yield return ;
} sweet.transform.position = endPos;
}
}

MovedSweet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class ColorSweet : MonoBehaviour { public enum ColorType
{
YELLOW,
PUPLE,
RED,
BLUE,
GREEN,
PNGK,
ANY,
COUNT
} [System.Serializable]
public struct ColorSprite
{
public ColorType color;
public Sprite sprite;
} public ColorSprite[] ColorSprites; private Dictionary<ColorType, Sprite> colorSpriteDict; private SpriteRenderer sprite; public int NumColors
{
get{ return ColorSprites.Length; }
} public ColorType Color
{
get
{
return color;
} set
{
SetColor(value);
}
} private ColorType color; public void Awake()
{
sprite = transform.Find("Sweet").GetComponent<SpriteRenderer>(); colorSpriteDict = new Dictionary<ColorType, Sprite>(); for(int i = ; i < ColorSprites.Length; i++)
{
if (!colorSpriteDict.ContainsKey(ColorSprites[i].color))
{
colorSpriteDict.Add(ColorSprites[i].color,ColorSprites[i].sprite);
}
}
} public void SetColor(ColorType newColor)
{
color = newColor;
if (colorSpriteDict.ContainsKey(newColor))
{
sprite.sprite = colorSpriteDict[newColor];
}
} }

ColorSweet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameSweet : MonoBehaviour { private int x;
private int y;
public int X
{
get
{
return x;
} set
{
if (CanMove())
{
x = value;
}
}
}
public int Y
{
get
{
return y;
} set
{
if (CanMove())
{
y = value;
}
}
} private GameManager.SweetsType type;
public GameManager.SweetsType Type
{
get
{
return type;
}
} [HideInInspector]
public GameManager gameManager; public MovedSweet MovedComponet
{
get
{
return movedComponet;
}
}
private MovedSweet movedComponet; public ColorSweet ColorComponet
{
get
{
return coloredCompent;
}
} private ColorSweet coloredCompent; //判断甜品是否可以移动
public bool CanMove()
{
return movedComponet != null;
} //判断是否可以着色
public bool CanColor()
{
return coloredCompent != null;
} private void Awake()
{
movedComponet = GetComponent<MovedSweet>();
coloredCompent = GetComponent<ColorSweet>();
} public void Init(int _x,int _y,GameManager _gameManager,GameManager.SweetsType _type)
{
x = _x;
y = _y;
gameManager = _gameManager;
type = _type;
} }

GameSweet.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameManager : MonoBehaviour { //甜品的种类
public enum SweetsType
{
EMPTY,
NORMAL,
BARRIER,
ROE_CLEAR,
COLUMN_CLEAR,
RAINBOWCANDY,
COUNT //标记类型
} //甜品预制体的字典,我们可以通过甜品的种类来得到对应的甜品游戏物体
public Dictionary<SweetsType, GameObject> sweetPrefabDict; [System.Serializable]
public struct SweetPrefab
{
public SweetsType type;
public GameObject prefab;
} public SweetPrefab[] sweetPrefabs; //单例实例化
private static GameManager _instance;
public static GameManager Instance
{
get
{
return _instance;
} set
{
_instance = value;
}
} //大网格的行列数
public int xColumn;
public int yRow; //填充时间
public float fillTime; public GameObject gridPrefab; //甜品数组
private GameSweet[,] sweets; private void Awake()
{
_instance = this;
} // Use this for initialization
void Start() { //字典的实例化
sweetPrefabDict = new Dictionary<SweetsType, GameObject>(); for(int i=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY);
}
} //在(4,4)这个坐标点生成障碍物
Destroy(sweets[, ].gameObject);
CreateNewSweet(,,SweetsType.BARRIER); StartCoroutine(AllFill());
} // Update is called once per frame
void Update () { } public Vector3 CorrectPosition(int x ,int y)
{
//实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
// 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
} //产生甜品的方法
public GameSweet CreateNewSweet(int x,int y,SweetsType type)
{
GameObject newSweet = Instantiate(sweetPrefabDict[type], CorrectPosition(x, y), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, y] = newSweet.GetComponent<GameSweet>();
sweets[x, y].Init(x,y,this,type); return sweets[x, y];
} //填充甜品的方法
public IEnumerator AllFill()
{
while (Fill())
{
yield return new WaitForSeconds(fillTime);
}
} public bool Fill()
{
bool FilledNotFinshed = false; //用来判断本次是否完成 //行遍历
for(int y=yRow-;y>=;y--)
{
for(int x=;x<xColumn;x++)
{
GameSweet sweet = sweets[x, y]; //得到当前元素位置 //如果无法移动,则无法往下填充
if (sweet.CanMove())
{
GameSweet sweetBelow = sweets[x, y + ]; if(sweetBelow.Type == SweetsType.EMPTY)//垂直填充
{
Destroy(sweetBelow.gameObject);
sweet.MovedComponet.Move(x,y+,fillTime);
sweets[x, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
}
else
{
//-1代表左,1代表右
for (int down = -; down <= ; down++)
{
if (down != )
{
int downX = x + down;
//排除边界的时候
//左下方
if (downX >= && downX < xColumn)
{
GameSweet downSweet = sweets[downX, y + ];
if (downSweet.Type == SweetsType.EMPTY)
{
bool canfill = true; //用来判断垂直填充是否可以满足填充要求
for (int aboutY = y; aboutY >= ; aboutY--)
{
GameSweet sweetAbove = sweets[downX, aboutY];
if (sweetAbove.CanMove())
{
break;
}
else if (!sweetAbove.CanMove() && sweetAbove.Type != SweetsType.EMPTY)
{
canfill = false;
break;
}
} if (!canfill)
{
Destroy(downSweet.gameObject);
sweet.MovedComponet.Move(downX, y + , fillTime);
sweets[downX, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
break;
}
}
}
}
}
}
} } }
//最上排的特殊情况
for (int x = ; x < xColumn; x++)
{
GameSweet sweet = sweets[x, ]; if(sweet.Type == SweetsType.EMPTY)
{
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x,-), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, ] = newSweet.GetComponent<GameSweet>();
sweets[x, ].Init(x, -,this,SweetsType.NORMAL);
sweets[x, ].MovedComponet.Move(x, ,fillTime);
sweets[x, ].ColorComponet.SetColor((ColorSweet.ColorType)Random.Range(,sweets[x,].ColorComponet.NumColors));
FilledNotFinshed = true;
}
}
return FilledNotFinshed;
}
}

GameManager.cs

Unity3D_(游戏)甜品消消乐01_游戏基础界面的更多相关文章

  1. Unity3D_(游戏)甜品消消乐03_游戏UI设计

    甜品消消乐01_游戏基础界面 传送门 甜品消消乐02_游戏核心算法 传送门 甜品消消乐03_游戏UI设计    传送门 (源码在文章最下面~) 实现过程 游戏界面UI 分数与时间的UI显示 有关游戏U ...

  2. Unity3D_(游戏)甜品消消乐02_游戏核心算法

    甜品消消乐01_游戏基础界面 传送门 甜品消消乐02_游戏核心算法 传送门 甜品消消乐03_游戏UI设计    传送门 GameManager脚本上修改Fill Time可以改变消消乐移动速度 实现过 ...

  3. Unity 3D游戏-消消乐(三消类)教程和源码

    Unity 消消乐教程和源码 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Start Game -- ...

  4. 消消乐、candy crush类三消游戏程序逻辑分析

    最近在开发一款类似消消乐的三消游戏,在碰到实现斜方向下落的时候卡住了很长时间.好几天没有思路,原本的思路是一次性预判多个宝石的一连串运动路径,运用缓动运动队列来实现宝石运动路径,例如 下落->滑 ...

  5. 热门游戏&lt;开心消消乐&gt;的“加壳”诡计!!

    好久没搞游戏了,前几天看了又又一次看了看<开心消消乐>的1.29最新版..于是故事開始了: 1.反编译分析 首先使用Androidkiller进行反编译,得到两个Smali代码目录:mal ...

  6. 用 Python 写个消消乐小游戏

    提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 Python 来做个简单的消消乐小游戏. 很多人学习python,不 ...

  7. 用Python写个开心消消乐小游戏

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受 ...

  8. 【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)

    [BZOJ4820][SDOI2017]硬币游戏(高斯消元) 题面 BZOJ 洛谷 题解 第一眼的感觉就是构\(AC\)自动机之后直接高斯消元算概率,这样子似乎就是\(BZOJ1444\)了.然而点数 ...

  9. 【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)

    [BZOJ1444][JSOI2009]有趣的游戏(高斯消元,AC自动机) 题面 BZOJ 题解 先把\(AC\)自动机构建出来,最好构成\(Trie\)图.然后这样子显然是在一个有向图中有一堆概率的 ...

随机推荐

  1. Hadoop单机模式/伪分布式模式/完全分布式模式

    一.Hadoop的三种运行模式(启动模式) 一.单机(非分布式)模式 这种模式在一台单机上运行,没有分布式文件系统,而是直接读写本地操作系统的文件系统. 默认情况下,Hadoop即处于该模式,用于开发 ...

  2. MySQL性能优化(七):其它优化

    原文:MySQL性能优化(七):其它优化 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/v ...

  3. O005、远程管理 KVM 虚机

    参考https://www.cnblogs.com/CloudMan6/p/5256018.html   上一节我们通过 virt-manager 在本地主机上创建并管理 KVM 虚机,其实 virt ...

  4. 一个密码经过多次MD5加密能否提高安全性?Java MD5盐值加解密

    什么是MD5? MD5(Message Digest Algorithm 5,信息摘要算法5),是计算机广泛使用的摘要算法(又称哈希算法)之一.MD5是将一段信息,通过其不可逆的字符串变换算法,产生了 ...

  5. laravel相关备忘

    此次笔记采用的是laravel5.1版本 1.从gitcheckout下来后,首先在env修改数据库相关 2.默认laravel没有model目录,默认有一个model文件User.php放在app里 ...

  6. Jansson库的使用简介

    一.Jansson的安装: 二.jansson相关的API: https://jansson.readthedocs.io/en/latest/apiref.html#c.json_t string ...

  7. ros 封ip,域名,端口,重定向

    1.封IP / ip firewall filter add chain=forward dst-address=192.168.0.1(想要封的IP) action=drop comment=&qu ...

  8. ubuntu16.04安装cuDNN

    cudnn的安装非常简单 (1)下载安装文件 按需求下载cudnn的安装文件:https://developer.nvidia.com/rdp/cudnn-archive Tar File的下载如下图 ...

  9. 10个不为人知的 Python 冷知识

    转载: 1. 省略号也是对象 ...这是省略号,在Python中,一切皆对象.它也不例外. 在 Python 中,它叫做 Ellipsis . 在 Python 3 中你可以直接写…来得到这玩意. 而 ...

  10. P1081 [NOIP2012]开车旅行[倍增]

    P1081 开车旅行    题面较为啰嗦.大概概括:一个数列,只能从一个点向后走,两种方案:A.走到和自己差的绝对值次小的点B.走到和自己差的绝对值最小点:花费为此差绝对值:若干询问从规定点向后最多花 ...