Unity3D消消樂實現原理
基本原理:
遍歷所有寶石集合,判斷行和列三連的情況,刪除三連,更新上方寶石位置.
1.定義一個寶石指令碼,功能:隨機指定寶石型別,指定寶石位置,iTween動畫,銷燬,顏色
指令碼掛在到一個空的預製體上,所有型別的寶石��這個空物體生成,using UnityEngine; using System.Collections; public class Gemstone : MonoBehaviour { public float xOffset = -4.0f; //x方向的偏移 public float yOffset = -1.5f; //y方向的偏移 public int rowIndex = 0; //行號 public int columnIndex = 0; //列號 public GameObject[] gemstoneBgs; //寶石(gemstone)的陣列 public int gemstoneType; //寶石(gemstone)的型別 public GameController gameController; public SpriteRenderer spriteRenderer; public bool isSelected{ set{ if(value){ spriteRenderer.color = Color.red; }else{ spriteRenderer.color = Color.white; } } } private GameObject gemstoneBg; // Use this for initialization void Awake(){ } void Start () { gameController = GameObject.Find ("GameController").GetComponent<GameController> (); spriteRenderer = gemstoneBg.GetComponent<SpriteRenderer> (); } // Update is called once per frame void Update () { } public void UpdatePosition(int _rowIndex,int _columnIndex){ //調整gemstone(寶石)的位置 rowIndex = _rowIndex; columnIndex = _columnIndex; this.transform.position = new Vector3 (columnIndex*1.2f + xOffset, rowIndex*1.2f + yOffset, 0); } public void TweenToPostion(int _rowIndex,int _columnIndex){ rowIndex = _rowIndex; columnIndex = _columnIndex; iTween.MoveTo (this.gameObject, iTween.Hash ("x",columnIndex * 1.2f + xOffset,"y",rowIndex*1.2f + yOffset,"time",0.3f)); } public void RandomCreateGemstoneBg(){ //生成隨機的寶石型別 if (gemstoneBg != null) return; gemstoneType = Random.Range (0, gemstoneBgs.Length); gemstoneBg = Instantiate(gemstoneBgs[gemstoneType]) as GameObject; gemstoneBg.transform.parent = this.transform; } //滑鼠點選的回撥方法 public void OnMouseDown(){ gameController.Select (this); } public void Dispose(){ Destroy (this.gameObject); Destroy (gemstoneBg.gameObject); gameController = null; } }
將所有的寶石預製體拖到集合目錄下
2.定義管理指令碼
宣告一下欄位:
Start裡面初始化;
定義如下方法:
將Controller指令碼掛在到一個空物體上,新增Audio Source元件/// <summary> /// 生成寶石的方法 /// </summary> /// <returns>返回一個定義好的寶石.</returns> /// <param name="rowIndex">Row 行座標.</param> /// <param name="columnIndex">Column 列座標.</param> public Gemstone AddGemstone(int rowIndex,int columnIndex){ //生成寶石 //克隆一個寶石 Gemstone c = Instantiate (gemstone) as Gemstone; c.transform.parent = this.transform;//指定父物體 c.GetComponent<Gemstone>().RandomCreateGemstoneBg();//呼叫寶石本身上寶石指令碼的隨機指定寶石型別的方法 c.GetComponent<Gemstone>().UpdatePosition (rowIndex,columnIndex);//呼叫借用行號和列號自動排列(指定位置)的方法 return c; } /// <summary> /// 查詢行號和列好對應寶石的方法 /// </summary> /// <returns>The gemstone.</returns> /// <param name="rowIndex">Row index.</param> /// <param name="columnIndex">Column index.</param> public Gemstone GetGemstone(int rowIndex,int columnIndex){ //通過行號和列號,取得所對應位置的寶石 ArrayList temp = gemstoneList [rowIndex] as ArrayList; Gemstone c = temp [columnIndex] as Gemstone; return c; } public void SetGemstone(int rowIndex,int columnIndex, Gemstone c){ //設定所對應列號和列號位置的寶石 ArrayList temp = gemstoneList [rowIndex] as ArrayList; temp [columnIndex] = c; } //點選當前寶石的時候,指定當前寶石的color,如果當前寶石為空時,表示是第一次點選,那麼顏色指定為紅色,如果不為空的話,表示是第二點選(即交換的物件) public void Select(Gemstone c){ //Destroy (c.gameObject); //測試,讓所點選的物體消失 if (currentGemstone == null) { currentGemstone = c; currentGemstone.isSelected = true; return; }else{ if( Mathf.Abs(currentGemstone.rowIndex - c.rowIndex) + Mathf.Abs(currentGemstone.columnIndex - c.columnIndex) == 1 ){//判斷是否挨著的 StartCoroutine (ExangeAndMatches(currentGemstone,c));//開啟協程,實現寶石交換並且檢測是否匹配 }else{ GetComponent<AudioSource>().PlayOneShot(errorClip); } currentGemstone.isSelected = false; currentGemstone = null; } } IEnumerator ExangeAndMatches(Gemstone c1,Gemstone c2){ //實現寶石交換並且檢測是否匹配 Exchange(c1,c2);//呼叫交換寶石的方法 yield return new WaitForSeconds (0.5f);//等待0.5s if(CheckHorizontalMatches() || CheckVerticalMatches() ){//經過水平檢測和垂直檢測後,如若有成功匹配的 RemoveMatches();//執行刪除寶石的方法 } else{//如果沒有匹配的寶石,直接在交換回來 // Debug.Log ("沒有檢測到相同的寶石,交換回來!!"); Exchange(c1,c2); } } /// <summary> /// 水平檢測的方法,返回一個布林值 /// </summary> /// <returns><c>true</c>, if horizontal matches was checked, <c>false</c> otherwise.</returns> bool CheckHorizontalMatches(){ //實現檢測水平方向的匹配 bool isMatches = false; //遍歷列表中的所有寶石 for (int rowIndex = 0; rowIndex < rowNum; rowIndex++) { for(int columnIndex =0; columnIndex < columnNum - 2; columnIndex++){ //判斷相同行挨著的寶石的型別 if((GetGemstone (rowIndex,columnIndex).gemstoneType == GetGemstone (rowIndex,columnIndex + 1).gemstoneType ) && (GetGemstone (rowIndex,columnIndex).gemstoneType == GetGemstone (rowIndex,columnIndex + 2).gemstoneType )){ // Debug.Log ("發現行相同的寶石"); //將三聯的寶石放到三聯數組裡面 AddMatches (GetGemstone (rowIndex,columnIndex)); AddMatches (GetGemstone (rowIndex,columnIndex + 1)); AddMatches (GetGemstone (rowIndex,columnIndex + 2)); isMatches = true; } } } return isMatches; } /// <summary> /// 垂直檢測的方法,同事也會返回一個布林值 /// </summary> /// <returns><c>true</c>, if vertical matches was checked, <c>false</c> otherwise.</returns> bool CheckVerticalMatches(){ //實現檢測垂直方向的匹配 bool isMatches = false; //遍歷所有寶石 for(int columnIndex = 0; columnIndex < columnNum; columnIndex++){ for(int rowIndex = 0; rowIndex < rowNum -2 ;rowIndex++){ //判斷相同列挨著的寶石的型別 if((GetGemstone(rowIndex,columnIndex).gemstoneType == GetGemstone (rowIndex + 1,columnIndex).gemstoneType ) & (GetGemstone(rowIndex,columnIndex).gemstoneType == GetGemstone (rowIndex + 2,columnIndex).gemstoneType ) ){ // Debug.Log ("發現列相同的寶石"); //將三聯的寶石放到三聯列表裡 AddMatches (GetGemstone (rowIndex,columnIndex)); AddMatches (GetGemstone (rowIndex +1,columnIndex)); AddMatches (GetGemstone (rowIndex +2,columnIndex)); isMatches = true; } } } return isMatches; } void AddMatches(Gemstone c){ if(matchesGemstone == null) matchesGemstone = new ArrayList(); int index = matchesGemstone.IndexOf (c); //檢測該寶石是否已在陣列當中 if(index == -1){//如果沒有在三聯列表裡,新增進去 matchesGemstone.Add (c); } } /// <summary> /// 刪除三聯的寶石 /// </summary> void RemoveMatches(){ //刪除匹配的寶石 for(int i=0; i< matchesGemstone.Count; i++){//遍歷三聯的列表 Gemstone c = matchesGemstone[i] as Gemstone; RemoveGemstone(c);//呼叫刪除寶石的方法 } matchesGemstone = new ArrayList ();//重新更新三聯列表 StartCoroutine (WaitForCheckMatchesAgain ());//開啟攜程,檢測是否還有因為銷燬三聯寶石以後還有自動匹配的三聯寶石,如果有直接銷燬 } IEnumerator WaitForCheckMatchesAgain(){ yield return new WaitForSeconds (0.5f); if (CheckHorizontalMatches () || CheckVerticalMatches ()) { RemoveMatches (); } } void RemoveGemstone(Gemstone c){ //刪除寶石 //Debug.Log ("刪除寶石!"); c.Dispose (); GetComponent<AudioSource>().PlayOneShot (match3Clip); for (int i=c.rowIndex +1; i<rowNum; i++) {//更新銷燬寶石對應列上方寶石的位置,下滑的動畫 Gemstone temGemstone = GetGemstone (i,c.columnIndex); temGemstone.rowIndex --; SetGemstone(temGemstone.rowIndex,temGemstone.columnIndex,temGemstone); //temGemstone.UpdatePosition (temGemstone.rowIndex,temGemstone.columnIndex); temGemstone.TweenToPostion (temGemstone.rowIndex,temGemstone.columnIndex); } Gemstone newGemstone = AddGemstone (rowNum, c.columnIndex);//在空缺的位置新增寶石 newGemstone.rowIndex--; SetGemstone (newGemstone.rowIndex, newGemstone.columnIndex, newGemstone); //newGemstone.UpdatePosition (newGemstone.rowIndex, newGemstone.columnIndex); newGemstone.TweenToPostion (newGemstone.rowIndex, newGemstone.columnIndex); } /// <summary> /// 交換寶石的方法 /// </summary> /// <param name="c1">C1.</param> /// <param name="c2">C2.</param> public void Exchange(Gemstone c1,Gemstone c2){ //實現寶石之間交換位置 GetComponent<AudioSource>().PlayOneShot (swapClip); //播放交換的聲音 SetGemstone (c1.rowIndex, c1.columnIndex, c2); SetGemstone (c2.rowIndex, c2.columnIndex, c1); //交換c1,c2的行號 int tempRowIndex; tempRowIndex = c1.rowIndex; c1.rowIndex = c2.rowIndex; c2.rowIndex = tempRowIndex; //交換c1,c2的列號 int tempColumnIndex; tempColumnIndex = c1.columnIndex; c1.columnIndex = c2.columnIndex; c2.columnIndex = tempColumnIndex; //c1.UpdatePosition (c1.rowIndex, c1.columnIndex); //c2.UpdatePosition (c2.rowIndex, c2.columnIndex); //ITween動畫將兩個寶石移動到指定的行號和列號的位置上 c1.TweenToPostion (c1.rowIndex, c1.columnIndex); c2.TweenToPostion (c2.rowIndex, c2.columnIndex); } }
工程下載連結:
http://download.csdn.net/detail/gaoheshun/9900322
完整Unity3D工程消消樂升級版:
http://download.csdn.net/detail/gaoheshun/9900326
相關推薦
Unity3D消消樂實現原理
基本原理: 遍歷所有寶石集合,判斷行和列三連的情況,刪除三連,更新上方寶石位置. 1.定義一個寶石指令碼,功能:隨機指定寶石型別,指定寶石位置,iTween動畫,銷燬,顏色 using UnityEngine; using System.Collections;
RocketMQ源碼分析之RocketMQ事務消息實現原理中篇----事務消息狀態回查
下一個 核心 with chcon detail 偏移 ffffff begin n) 上節已經梳理了RocketMQ發送事務消息的流程(基於二階段提交),本節將繼續深入學習事務狀態消息回查,我們知道,第一次提交到消息服務器時消息的主題被替換為RMQ_SYS_TRANS_H
基於Unity3D引擎的簡易版開心消消樂
閒來無事,寫點東西。想到之前有用過u3d,也是怕自己以後忘了,放csdn上留存一下。 先上程式碼。 思路是通過給一個圖形新增指令碼Grid.cs ,再通過總控的指令碼使用兩個for迴圈批量生成圖形方塊。 using UnityEngine; using System.Col
【轉】消息隊列原理
精彩 調用 管理 應用程序 利用 耦合 不能 開發者 一段 發布-訂閱消息模式 一、訂閱雜誌 我們很多人都訂過雜誌,其過程很簡單。只要告訴郵局我們所要訂的雜誌名、投遞的地址,付了錢就OK。出版社定期會將出版的雜誌交給郵局,郵局會根據訂閱的列表,將雜誌送達消費者手中。這樣我
Unity開發了一款開心消消樂
遊戲開發 Unity3D 開心消消樂 三消 介紹2016年公司投資了一款三消項目,一共花費了300萬,後來項目死了。我對項目做了簡單的整理,自己做了一個相對比較完整的三消遊戲。原項目過於復雜,我做了很多簡化,不過也含有最初項目60%的核心技術,近期準備分享給大家。 菜單界面 地圖場景
Java常用消息隊列原理介紹及性能對比
創新 序列化 knowledge rom sage 特定 了解 代碼 lang 消息隊列使用場景為什麽會需要消息隊列(MQ)?解耦 在項目啟動之初來預測將來項目會碰到什麽需求,是極其困難的。消息系統在處理過程中間插入了一個隱含的、基於數據的接口層,兩邊的處理過程都要實現
牛客練習賽30 D 消消樂 二分圖 最小覆蓋
ace main char left algorithm fde endif tor shu POJ 2226 比這題難一點在於它要求覆蓋的行或者列只能覆蓋*不能覆蓋到.我們同樣可以構造二分圖,對於原圖中的每一個‘*‘都可以把它當做一條邊,連接的是它所在*聯通列的最上一點
牛客練習賽30消消樂
r神在和小b比賽玩一個名為“消消樂”的遊戲,在一個n*m的棋盤上,一些棋子分佈在格點上,遊戲玩家有一個名為超藍光波的武器,可以消除一行或者一列的所有棋子,使用超藍光波需要耗費一點能量,消除完所有的棋子之後,花費能量越少得分越高。 r神為了超過排名第一的小b,奪得榮譽稱號“天下第一”,他需要尋求你的幫助,他希望
消消樂實驗總結與反思
問題重述 背景介紹: 《開心消消樂》是一款樂元素研發的三消類休閒遊戲。遊戲中消除的物件為小動物的頭像,包括小浣熊、小狐狸、小青蛙和小雞等動物頭像。玩家通過移動動物頭像位置湊夠同行/同列3個或3個以上即可消除。 現在定義消消樂規則如下: 1.遊戲中共允許K種物件,分佈在大小為M×N的格
JavaScript實戰操作—成語消消樂
一 預覽 二 開發步驟 基本面向過程的思想。沒有面向物件的部分。 準備好成語庫。db.js 選出每一關的成語。 對成語進行亂序。 初始化表格的同時,將單個字放到每個單元格的按鈕上展示。 對tbody進行點選事件的監聽。事件函式中獲取btn。用變數記錄選中的文字
Gaussian-Jordan列主元消元 matlab實現
可能的問題:無唯一解;輸入極小近似0;列主元太小; function x = my_solve(A,b) matrix = [A,b]; R = my_rref(matrix); x = R(:,end); function x = my_rref(matrix) n
CCF201512-2 消除類遊戲(消消樂)
問題描述 消除類遊戲是深受大眾歡迎的一種遊戲,遊戲在一個包含有n行m列的遊戲棋盤上進行,棋盤的每一行每一列的方格上放著一個有顏色的棋子,當一行或一列上有連續三個或更多的相同顏色的棋子時,這些棋子都被消除。當有多處可以被消除時,這些地方的棋子將同時被消除。
從零開始製作基於Unity引擎的寶石消消樂——開篇設計(一)
市場上有些消消樂真好玩,比如hxxxxxpop,pxxxxsaga這類,所以這下想自己從零開始先做一個消消樂,然後再一點點新增遊戲內容進去,順便問下有沒有遊戲公司要找程式撈一下我。 前言 市場上已經有很多消消樂的遊戲了,前段時間剛想做一個簡單的消消樂,在網上翻了
牛客練習賽30D——消消樂
比賽的時候不會做… 然後今天才得知是一道原題,一道二分圖最小覆蓋點的模板題… 為什麼大佬什麼演算法都會,什麼題都做過… 程式碼: #include <bits/stdc++.h> using
kafka消息通信原理學習(1)
coord 例子 eba alt sub 序列化 strac system str 關於 Topic 和 Partition: Topic: 在 kafka 中,topic 是一個存儲消息的邏輯概念,可以認為是一個消息集合。每條消息發送到 kafka 集群的消息都有一個
碎片化 《消消樂》
MainActivity public class MainActivity extends AppCompatActivity { private Toolbar toolbar; @Override protected void onCreate
Python PIL自動定位消消樂
先看定位好的效果圖:自動定位黃色的星星。 from PIL import Image, ImageDraw import math import operator from functools import reduce src_img = Image.open("xxl.png
net.sz.framework 框架 ORM 消消樂超過億條資料排行榜分析 天王蓋地虎
序言 天王蓋地虎, 老婆馬上生孩子了,在家待產,老婆喜歡玩消消樂類似的休閒遊戲,閒置狀態,無聊的分析一下消消樂遊戲的一些技術問題; 由於我主要是伺服器研發,客戶端屬於半吊子,所以就分析一下消消樂排行榜問題; 第一章 消消樂排行榜大致分為好友排行榜和全國排行榜; 好友排行榜和全國排行榜的其實是重合的只是需要
計蒜之道複賽 騰訊消消樂
騰訊消消樂 狀壓dp 題目連結 題意是就點進去題目鏈說的那樣. 看一下資料由於n<18 然後考慮用狀壓dp dp[i][s] 表示消去i次得到的狀態為s的方案數,1代表刪了0代表還沒刪,當我們列舉到一個狀態s時,取出所有0位,然後列舉其中的一
自制遊戲 消消樂 程式碼 my.js
/** * Created by wxraopf on 2017-11-17. */ var lastCell = {}; var _lastCell = {}; var isMove = false; Vue.component('obj-list', { p