【 Cocos Creator 項目實戰】益智游戲《2048》(附帶完整源碼工程)

本文乃Siliphen原創,轉載請注明出處

目錄

游戲介紹

概述

游戲整體流程

游戲框架設計

主要流程控制類

本文項目的代碼組織結構

構建游戲世界

數字方塊

地圖

?觸摸手勢識別

防觸摸抖動

判斷用戶輸入的方向

地圖

任意大小的地圖

初始化地圖大小

地圖繪制

合并和移動

合并和移動的邏輯

絲滑的合并和移動動畫

本文的完整實現源碼工程


游戲介紹

《2048》是一款曾經風靡全球的數字益智游戲。

目前(2023.08.14)在 App Store 的情況如下圖:

關于這個游戲的更多情況可看看百度百科:百度百科-驗證

概述

本文講解用 Cocos Creator 實現經典《2048》的核心流程和算法。

Cocos Creator 版本:Cocos Creator 3.8.0

本文實現的游戲效果如下:

?

可以隨意調整地圖大小。可隨意調整方塊移動速度。

上圖分別演示了 4 x 4 ,7 x 10 地圖大小的效果。

可在這個地址運行體驗下本文實現的版本:Cocos Creator | 2048

文本末尾給出完整實現的源碼工程。

游戲整體流程

游戲執行一輪玩家操作的流程:等待玩家輸入操作 -> 用戶滑動屏幕 -> 移動數字方塊 -> 合并方塊 -> 空白地方隨機出現一個數字方塊 -> 等待玩家輸入操作

以上流程是游戲玩家操作一次,游戲執行一輪的分解動作循環。

游戲通關條件:合成數字方塊2048。

游戲失敗條件:當整個棋盤都填滿數字方塊,且沒有可以合并的方塊。

游戲框架設計

主要流程控制類

從調用先后順序開始依次如下:

類名

作用

UiTouch

處理用戶觸摸輸入

Merge

處理移動、合并的邏輯和動畫。

FlowRound.fillEntity()

在地圖空白處隨機生成一個數字方塊。

FlowRound.judge()

判斷輸贏。

本文項目的代碼組織結構

構建游戲世界

《2048》的游戲世界只有2個實體:數字方塊、棋盤地圖。

棋盤是數字方塊的容器。后面的移動和合并算法,都是作用在棋盤上計算的。

數字方塊

// 實體
export class Entity {// 實體所代表的數值public val : number ;// 表現public presentation = new EntityPresentation() ;}// 實體表現
export class EntityPresentation {public root : Node ;}

地圖

地圖數據本質是個二維數組。定義如下:

export class Map {// 單件public static ins : Map = null ;// 地圖單元格public grid = new Array< Array< MapCell > >() ;// 格子寬高public size = new Size() ; // 表現public presentation = new MapPresentation() ;}// 地圖表現
export class MapPresentation {// 根節點public root : Node ;}// 地圖單元格
export class MapCell {// 單元格上的實體public entity : Entity = null ;// 單元格所在的局部空間的坐標public pos : Vec3 = null ;}

我們規定地圖單元格(0,0)的位置在地圖顯示的左下角。x , y 的增長分別向右邊和上邊延伸。如下圖:

?觸摸手勢識別

防觸摸抖動

在觸摸按下時記錄按下的坐標,在觸摸結束時用結束時的坐標減去按下時的坐標,得到一個向量。

判斷這個向量的長度,大于某個數值后,就認為是有效的輸入。

如果只是個很小的滑動,可能是抖動造成的,為了防止玩家誤操作,可以丟棄這種輸入。

判斷用戶輸入的方向

用上一步減法得到的向量就可以判斷用戶操作的方向。

主要是用到 Math.atan2 這個系統函數。atan2 判斷一個向量與 x 軸正方向的夾角,單位是弧度。

注意:atan2 的參數是 ( y , x ) , 不是( x , y ),y 是第一個參數。

不習慣使用弧度的話,可以轉換成角度。

判斷角度代碼如下:

// 手勢識別
export class GestureRecognition {// 返回:上左下右 1234 從上開始順時針。0 無效方向public static exe( v : Vec2 ) : number {let rad = Math.atan2( v.y , v.x ) ;let degree = rad * ( 180 / Math.PI ) ;if( 45 < degree && degree < 135 ){return 1 ;} else if( -45 < degree && degree < 45  ){return 2 ;} else if( -135 < degree && degree < -45 ){return 3 ;}else if( 135 < degree && degree < 180 || -180 < degree && degree < -135 ){return 4 ;}// console.log( "度數:" + degree ) ;return 0 ;}}

地圖

任意大小的地圖

本文的實現,可設置任意地圖大小。

如下圖:

上圖展示了這些尺寸的地圖大小效果:3 x 3 , 5 x 5 , 6 x 4 , 7 x 10

不同地圖尺寸對應不同的地圖根結點縮放值。

要實現可指定任意大小的地圖的前提是,動態繪制地圖。

先初始化地圖二維數組結構的大小,然后,地圖繪制類再處理地圖的繪制。

初始化地圖大小

// 地圖數據初始化
export class MapInit {public static exe( map : Map ) {map.presentation.root = find( "Canvas/Map" ) ;// 地圖寬高let mapWidth = 3 ; let mapHeight = 3 ; map.size = new Size( mapWidth , mapHeight ) ;for( let y = 0 ; y < mapHeight ; ++y ) {let row = new Array< MapCell >( ) ;map.grid.push(row) ;for( let x = 0 ; x < mapWidth ; ++x ){let cell = new MapCell() ; row.push( cell ) ;} // end for} // end for}}

地圖繪制

本文實現的中心對其的地圖布局,地圖的幾何中心點與其父節點的原點重疊。

算法是,先算出整個地圖的大小,然后寬高分別除以2,先算出 ( 0 , 0 ) 起始邏輯坐標單元格的位置。

先算出左下角的起始單元格的位置,后續可以統一處理其他單元格位置。僅僅是通過不斷累加間隔就行。

地圖繪制 具體實現查看源碼工程的類 MapDraw

設置地圖大小位置:MapInit.exe 函數

合并和移動

這個是2048的核心玩法實現,也是最難的部分。

合并和移動的邏輯

可以先算方塊邏輯上的合并,后算方塊邏輯上的移動。

也可以合并和移動合并在一起計算。

上下左右的合并和移動要分別處理。

這里列舉用戶向左( <- )滑動的處理算法,其他3個方向的以此類推。為了說明原理和簡單起見以下為描述性偽代碼。

// 一行行遍歷地圖。從左到右(->)
for( let y = 0 ; y < map.size.height ; ++y ) {for( let x = 0 ; x < map.size.width ; ++x ) {let cell = map.grid[ y ][ x ] ;// 如果單元格上沒有實體,略過。因為我們只處理實體。不處理空格。if( cell.entity == null ) continue ;let cell2 = 向右(->)查找一個最近的實體所在的單元格。if( cell2 != null && cell2 和 cell 的實體數字相同 ){   // 這表示找到一個可以合并的實體2個實體合并,合并和的實體放在 cell 單元格的位置上。}以 cell 單元格為起點向左(<-)查找一個連續的空位的最右邊的那個空位這個空位便是 cell 上的方塊實體要移動到的位置。} // end for
} // end for

算法圖示:

絲滑的合并和移動動畫

如果只是按照上一步說的先在邏輯上計算合并和移動的結果,然后直接更新畫面顯示,會顯得很生硬。

大部分的瞬間更新結果都會讓畫面顯得生硬。好的做法是,有個滑動和合并的移動緩動動畫。

加入動畫后,流程就變成了:

所有的方塊都會先移動到一邊,然后進行合并,如果合并后留出了空位,需要再移動。保證移動后,中間不留空位。

這個流程需要對以上的邏輯處理進行改造。

具體實現查看源碼工程的類 Merge

本文的完整實現源碼工程

源碼工程下載地址:Cocos Store

作者創作不易,您的支持讓我創造出更多更好的作品。?:)

【 Cocos Creator 項目實戰】系列文章鏈接:

【 Cocos Creator 項目實戰】益智游戲《2048》

??????【Cocos Creator 項目實戰 】消滅星星加強版

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/42453.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/42453.shtml
英文地址,請注明出處:http://en.pswp.cn/news/42453.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構----結構--線性結構--棧,隊列

數據結構----結構–線性結構–棧&#xff0c;隊列 一.棧&#xff1a;Stack 1.棧的特點&#xff1a; ? 先進后出&#xff1a;FILO&#xff08;對一組數據有倒敘要求時可以用棧&#xff09; 2.棧的實現 順序存儲&#xff1a;數組實現&#xff1a; ? 缺點&#xff1a;空間…

無涯教程-Perl - sysread函數

描述 該函數等效于C /操作系統函數read(),因為它繞過了諸如print,read和seek之類的函數所采用的緩沖系統,它僅應與相應的syswrite和sysseek函數一起使用。 它從FILEHANDLE中讀取LENGTH個字節,并將輸出放入SCALAR中。如果指定了OFFSET,則將數據從OFFSET字節寫入SCALAR,從而有效…

IC流程中 DFT 學習筆記(2)

引言 DFT是ASIC芯片設計流程中不可或缺的環節。其主要目的是在芯片前端設計驗證完成后插入一些諸如寄存器鏈等可供測試的邏輯&#xff0c;算是IC后端設計的范疇&#xff0c;屬于結構測試而非功能測試。主要是在ASIC芯片流片完成后&#xff0c;通過這些已插入的邏輯&#xff0c…

手機照片誤刪怎么辦,電腦照片誤刪怎么辦怎么才能找回,EasyRecovery來幫您

手機照片誤刪怎么辦&#xff0c;電腦照片誤刪怎么辦怎么才能找回&#xff0c;EasyRecovery 2023來幫您&#xff01;&#xff01;&#xff01; EasyRecovery 2023是一款操作安全、價格便宜、用戶自主操作的 數據恢復 方案&#xff0c;它支持從各種各樣的 存儲介質 恢復刪除 或者…

Vue3.X 創建簡單項目

一、環境安裝與檢查 首先&#xff0c;我們要確保我們安裝了構建vue框架的環境&#xff0c;不會安裝的請自行百度&#xff0c;有很多安裝教程。檢查環境 node -v # 如果沒有安裝nodejs請安裝&#xff0c;安裝教程自行百度 vue -V# 沒有安裝&#xff0c;請執行npm install -g v…

Cesium for unity 1.5.0使用注意事項

Cesium for Unity Quickstart – Cesium 1.Unity版本僅支持Unity2021.3.2f1以后版 2.僅支持 3D (URP)和3D (HDRP)渲染管線 3.如果Package Manager中不出現My Registries選項&#xff0c;請在 Edit > Project Settings...>Package Manager中重命名或刪除重新添加Packag…

深入淺出PHP封裝根據商品ID獲取淘寶商品詳情數據方法

要通過淘寶的API獲取商品詳情&#xff0c;您可以使用淘寶開放平臺提供的接口來實現。以下是一種使用PHP編程語言實現的示例&#xff0c;展示如何通過淘寶開放平臺API獲取商品詳情&#xff1a; 首先&#xff0c;確保您已注冊成為淘寶開放平臺的開發者&#xff0c;并創建一個應用…

【微服務實戰】01-工程結構概覽

文章目錄 工程結構概覽:定義應用分層及依賴關系1.應用分層2.定義Entity3.倉儲層3.1 工作單元&#xff1a;事務管理3.2 倉儲層 4.領域事件5.APIController最佳實踐 工程結構概覽:定義應用分層及依賴關系 1.應用分層 領域模型層基礎設施層 ? 倉儲應用層 ? Api、后臺任務Job共…

TCP服務器實現—多進程版,多線程版,線程池版

目錄 前言 1.存在的問題 2.多進程版 3.多線程版 4.線程池版 總結 前言 在上一篇文章中使用TCP協議實現了一個簡單的服務器&#xff0c;可以用來服務端和客戶端通信&#xff0c;但是之前的服務器存在一個問題&#xff0c;就是當有多個客戶端連接服務器的時候&#xff0c;服…

002-Spring boot 自動配置相關分析

目錄 自動配置 EnableAutoConfiguration開啟自動配置讀取配置提前過濾自動配置配置包 AutoConfigurationPackage 自動配置 EnableAutoConfiguration 開啟自動配置 在Spring 啟動類上的 SpringBootApplication 中有 EnableAutoConfiguration 讀取配置 Import(AutoConfigurat…

后端返回圖片,前端接收并顯示的解決方案

后端圖片數據返回 后端通過二進制流的形式&#xff0c;寫入response中 controller層 /*** 獲取簽到二維碼*/GetMapping("/sign-up-pict")public void signUpPict(Long id, Long semId, HttpServletResponse response) throws NoSuchAlgorithmException {signUpServ…

musl libc ldso 動態加載研究筆記:01

前言 musl 是一個輕量級的標準C庫&#xff0c;建立在系統調用之上&#xff0c;可以認為是【用戶態】的C 庫&#xff0c;與 glibc 或者 uClibc 屬于同一類。 基于 musl 的 gcc 工具鏈包括交叉編譯工具鏈&#xff0c;可以用于編譯 Linux 或者其他的操作系統&#xff0c;如當前 L…

深入解析 MyBatis 中的 <foreach> 標簽:優雅處理批量操作與動態 SQL

在當今的Java應用程序開發中&#xff0c;數據庫操作是一個不可或缺的部分。MyBatis作為一款頗受歡迎的持久層框架&#xff0c;為我們提供了一種優雅而高效的方式來管理數據庫操作。在MyBatis的眾多特性中&#xff0c;<foreach>標簽無疑是一個強大的工具&#xff0c;它使得…

構建可遠程訪問的企業內部論壇

文章目錄 前言1.cpolar、PHPStudy2.Discuz3.打開PHPStudy&#xff0c;安裝網頁論壇所需軟件4.進行網頁運行環境的構建5.運行Discuz網頁程序6.使用cpolar建立穿透內網的數據隧道&#xff0c;發布到公網7.對云端保留的空白數據隧道進行配置8.Discuz論壇搭建完畢 前言 企業在發展…

Python中import模塊導入的實現原理

歡迎關注博主 Mindtechnist 或加入【Linux C/C/Python社區】一起探討和分享Linux C/C/Python/Shell編程、機器人技術、機器學習、機器視覺、嵌入式AI相關領域的知識和技術。 Python中import模塊導入的實現原理 什么是模塊import搜索路徑import導入模塊的原理圖書推薦 專欄&…

京東門詳一碼多端探索與實踐 | 京東云技術團隊

本文主要講述京東門詳業務在支撐過程中遇到的困境&#xff0c;面對問題我們在效率提升、質量保障等方向的探索和實踐&#xff0c;在此將實踐過程中問題解決的思路和方案與大家一起分享&#xff0c;也希望能給大家帶來一些新的啟發 一、背景 1.1、京東門詳介紹 1.1.1、京東門…

VB+SQL上機考試系統設計與實現

摘 要 隨著計算機技術的迅猛發展,學校教學和管理的信息化發展也有長足的進步,這就要求各個環節都均衡發展,從軟硬件雙方面把學校建設成一流的信息管理、教育教學的平臺。本文設計開發的考試管理系統也是其中重要的一個方面。該系統本著減輕教師工作負擔、提高工作效率、優…

六、分組背包

六、分組背包 題記算法題目代碼 題記 一個旅行者有一個最多能裝V公斤的背包和有N件物品&#xff0c;它們的重量分別是W[1]&#xff0c;W[2]&#xff0c;…,W[n]&#xff0c;它們的價值分別為C[1],C[2],…,C[n]。這些物品被劃分為若干組&#xff0c;每組中的物品互相沖突&#…

【es6】函數參數設置默認值

1、es6之前的函數參數默認值寫法 1.1、使用短路或||的寫法 當y為空時&#xff0c;y判斷為false &#xff0c;走||右邊的&#xff0c;所以y world;當y不為空時&#xff0c;y判斷為true&#xff0c;不需要再運行||右邊的&#xff0c;所以 y y function log(x, y) {y y || W…

數據的深海潛行:數據湖、數據倉庫與數據湖庫之間的微妙關系

導言&#xff1a;數據的重要性與存儲挑戰 在這個信息爆炸的時代&#xff0c;數據已經成為企業的核心資產&#xff0c;而如何高效、安全、便捷地存儲這些數據&#xff0c;更是每個組織面臨的重大挑戰。 數據作為組織的核心資產 數據在過去的幾十年里從一個輔助工具演變成企業的…