Cocos2Dx Là Gì – Giới Thiệu Công Cụ Lập Trình Game Cocos Creator

Giới Thiệu

Thực tế thì mình cũng chả phải là một lập trình viên chuyên game hay gì cả, chỉ là lần này mình có được nhận làm một project game ngắn hạn từ anh sếp và được recomend sử dụng Cocos Creator. Sau một thời gian không quá dài tiếp xúc với nó thì mình thấy nó cũng khá hay nên muốn chia sẻ cho mọi người về engine này

Theo như mình có được biết thì trước đây khi chưa có Cocos Creator thì mọi người vẫn sử dụng Cocos2d-x code bằng C++. Nhược điểm của thằng này là không có giao diện người lập trình phải tự tưởng tượng code và rồi chạy lên mới thấy được kết quả. Để khắc phục điều này, làm tăng hiệu suất và bắt kịp được với Unity, thì Cocos Creator đã được ra đời. Hiện tại thì thằng này chỉ hỗ trợ trên MAC và Window nên anh em nào dùng Ubuntu thì chắc sẽ hơi buồn.

Đang xem: Cocos2dx là gì

Vậy Cocos2d-x là gì thì Cocos2d-x là 1 Engine hỗ trợ lập trình Game đa nền tảng : Mobile ( IOS, ANDROID, Blackberry, TIZEN, WP) Window, MacOS, HTML5,.. đại loại là đủ cả. Theo wikipedia thì tác giả của Cocos2d-x là một người trung quốc có tên là Zhe Wang.

*

*

2012, at Zynga. With Rolando Abarca and Zhe Wang discussing Cocos2d-x’s and cocos2d-iphone’s roadmaps

Hiện tại thì nó vẫn được những bạn láng giếng phát triển khá là mạnh và không ngừng hoàn thiện để trở thành Unity phiên bản free, nhưng chặng đường chắc vẫn còn khá dài.

Thực Hành Tạo Và Deploy Game

Mình thì không thích dài dòng mà mình thấy các tốt nhất để học một cái gì là cứ cho vào làm luôn nó mới nhanh vỡ ra được, chứ cứ lý thuyết suông thì rất khó hình dung.

*

Đây là trang chủ để tải cocos creator : https://www.cocos.com/en/creator

Sau khi tải về và cài đặt (cài cái này khá là lâu nha) thì giao diện chính của creator sẽ như thế này

*

Giờ chúng ta sẽ đi luôn vào làm game đầu tiên như trong docs của cocos hướng dẫn. Dưới đây là nguồn assets làm game và game đã hoàn thành

Assets

Sau khi tải Assets ban đầu về chúng ta sẽ import nó vào creator, rất đơn giản chỉ cần kéo thả vào thôi

*

Phần Assets sẽ là nơi chứ các nguồn dữ liệu để ta dụng để tạo hình

*

Scene

Sau khi đã có Assets ta sẽ tạo các Scene. Scene là một bản bồ 2D và có thể mở chế độ 3D, giúp ta kéo tả, thay đổi tạo ra UI. Mỗi Scene sẽ là một màn hình kiểu như là trên web chúng ta sẽ có trang home, trang detail, trang about thì scene chính là các view đó. Ta có thể tạo nhiều scene và chuyển đổi giữa chúng trong game.

*

Thêm khác thực thể vào Scene

*

Ở đây ta có thể tùy kéo kéo chỉnh, thay đổi vị trí của các thực thể sao cho mình thấy ổn nhất. Có nhiều chế độ kéo thả

Di chuyển theo chiều X – Y đầu tiên chọn bên góc trái sau đó có thể di chuyển vị trí của thực thể

*

Thay đổi góc quay của thực thể. Chọn và ra scene thay đổi góc quay

*

Rsize kích thước thực thể chọn

*

và thay đổi kích thước

*

Ở trên scene ta chỉ cần nắm thế thôi là có thể kéo thả, thay đổi kích thước và dic chuyển khắp bản đồ

Properties

Thì ngoài việc kéo thả ở scene chúng ta cũng có thể thay đổi vị trí, thay đổi độ trong suốt, thêm các script, thêm animation và rất nhiều thức khác ở trong phần này

*

Position chính là vị trí của thực thể đó trên scene tính theo trục tọa đọ X-YRotaion là góc nghiêngScale là kiểu phóng to theo 2 chiều x hoặc yAnchor là để thay đổi vị trí của thực thể so với gốc tọa độ của chính nóSize chính là thay đổi kích thước width-Height của thực thểColor là màu của thực thểOpacity độ trong suốt…

Node Tree

Đây khi khu vực để ta xác định được đâu là thành phần cha con của nhau hoặc thằng nào ở lớp trên, thằng nào ở lớp dưới.

*

*

thằng nào càng ở dưới tức là nó đang trên lớp cao nhất. Kiểu như ở trong css có thuộc tính z-index khi ta sử dụng position vậy. Càng ở dưới thì z-index càng cao và có thể che lớp thằng kia. Giống như cái ground đang che đi cả thằng PurpleMonster.

Timeline

phần này dùng để tạo ra các animation đơn giảm chị cần thay đổi góc nghiêng hay thay đổi vị trí của thực thể. Đây là ví dụ về 1 animation nhảy

*

*

Tạo Hình Và Bắt Sự Kiện Cho Nhân Vật

Bây giờ sau khi đã hiểu hết các phần và chức năng của nó chúng ta sẽ đi vào làm game đầu tiên nha

Đầu tiên chúng ta cần kéo các thành phần của game vào để có một cái UI tổng quát

Tham khảo ngay  Stratis Coin Là Gì ? Toàn Tập Về Tiền Điện Tử Strat Stratis Coin Là Gì
*

Sau khi sử dụng hết các kiến thức ở trên để kéo thả ra một UI như trong hình, thì bây giờ công việc cần làm là add thêm các script để bắt sự kiện trong game. Tạo một folder scripts –> và new một file Player.js.

Tạo folder

*

Tạo file js

*

Click double vào file Player ta sẽ thấy một khung js có sẵn

// Player.js cc.Class({ extends: cc.Component, properties: { // foo: { // // ATTRIBUTES: // default: null, // The default value will be used only when the component attaching // // to a node for the first time // type: cc.SpriteFrame, // optional, default is typeof default // serializable: true, // optional, default is true // }, // bar: { // get () { // return this._bar; // }, // set (value) { // this._bar = value; // } // }, }, // LIFE-CYCLE CALLBACKS: // onLoad () {}, start () { }, // update (dt) {}, });Giờ thêm các properties // Player.js //… properties: { // main character”s jump height jumpHeight: 0, // main character”s jump duration jumpDuration: 0, // maximal movement speed maxMoveSpeed: 0, // acceleration accel: 0, }, //…Tiếp đến ta sẽ gắn js này cho thằng thực thể PurpleMonster để lát nữa sẽ xử lý sự kiện trong file js này. Quay về màn hình vào phần Node Tree nãy mình đã nói, chọn thực thể PurpleMonster sau đó để ý sang phần properties của nó. Ta sẽ xuống button Add Component chọn Custom component và chọn Player

*

Sau khi đã add được js vào trong nó sẽ hiện ra các thuộc tính ta vừa định nghĩa trong file Player ở trên và ta sẽ điền các thông số vào đây.

*

Bây giờ ta sẽ viết một cái hàm nhảy cho thằng này

// Player.js properties: { //… }, setJumpAction: function () { // jump up var jumpUp = cc.moveBy(this.jumpDuration, cc.v2(0, this.jumpHeight)).easing(cc.easeCubicActionOut()); // jump down var jumpDown = cc.moveBy(this.jumpDuration, cc.v2(0, -this.jumpHeight)).easing(cc.easeCubicActionIn()); // repeat return cc.repeatForever(cc.sequence(jumpUp, jumpDown)); },Sau khi đã có hàm nhảy rồi ta sẽ set hàm đó vào onLoad(). Điều này có tác dụng là nó sẽ chạy ngay sau khi thực thể lại được load ra// Player.js onLoad: function () { // initialize jump action this.jumpAction = this.setJumpAction(); this.node.runAction(this.jumpAction); },Ok test xem chạy không nha. Chọn vào nút

*

ở trên cùng giữa màn hình

*

cc.repeatForever sẽ giúp hành động xảy ra lặp lại mãi mãi. cc.sequence thực hiện hành động tuần tự. jumpUp, jumpDown là nhảy lên và nhảy xuống –> cứ như vậy cc.repeatForever(cc.sequence(jumpUp, jumpDown)) sẽ làm PurpleMonster nhảy mãi mãi và hàm được để ở onLoad() nên hàm sẽ được chạy ngay sau khi khi thực thể được load.

Xem thêm: Phương Pháp Tính Lãi Cơ Bản Trên Cổ Phiếu Là Gì? Lãi Cơ Bản Trên Cổ Phiếu (Earning Per Share

Đã tạo được hàm nhảy, tiếp đến chúng ta sẽ tạo hành động di chuyển sang trái, sang phải cho nhân vật.

// Player.js setJumpAction: function () { //… }, onKeyDown (event) { // set a flag when key pressed switch(event.keyCode) { case cc.macro.KEY.a: this.accLeft = true; break; case cc.macro.KEY.d: this.accRight = true; break; } }, onKeyUp (event) { // unset a flag when key released switch(event.keyCode) { case cc.macro.KEY.a: this.accLeft = false; break; case cc.macro.KEY.d: this.accRight = false; break; } },onKeyDown là khi ta nhấm phím, cònonKeyUp là khi ta nhả phím ra. Sẽ có 1 switch ở trong để kiểm tra xem ta bấm phím nào ở keydown và nhả phím nào ở keyup. Sau đó set hướng cho nó ở keydown cho hướng đấy thành true và khi nhả phím thì set lại thành false chỉ đơn giản vậy thôi.

Nhưng bận muốn game nhận được ác hiệu lệnh đó của mình thì bạn cần khởi tạo bàn phím bằng cách như sau

// Player.js onLoad: function () { // Initialize the jump action this.jumpAction = this.setJumpAction(); this.node.runAction(this.jumpAction); // Acceleration direction switch this.accLeft = false; this.accRight = false; // The main character”s current horizontal velocity this.xSpeed = 0; // Initialize the keyboard input listening cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this); }, onDestroy () { // Cancel keyboard input monitoring cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this); cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this); },Khởi tạo lắng nghe bàn phím khi load và hủy lắng nghe khi thực thể đó bị phá hủy

Cuối cùng là phần cập nhật vị trí của nhân vật khi ta bấm nút

// Player.js update: function (dt) { // update speed of each frame according to the current acceleration direction if (this.accLeft) { this.xSpeed -= this.accel * dt; } else if (this.accRight) { this.xSpeed += this.accel * dt; } // restrict the movement speed of the main character to the maximum movement speed if ( Math.abs(this.xSpeed) > this.maxMoveSpeed ) { // if speed reach limit, use max speed with current direction this.xSpeed = this.maxMoveSpeed * this.xSpeed / Math.abs(this.xSpeed); } // update the position of the main character according to the current speed this.node.x += this.xSpeed * dt; },Mình đã thử test thì thấy thằng update() này cứ 0,01 giây nó sẽ gọi một lần

update(dt) { console.log(“Run in function update() time : “, dt); }

*

Tức là nó sẽ gọi hàm gần như liên tục

if (this.accLeft) { this.xSpeed -= this.accel * dt; } else if (this.accRight) { this.xSpeed += this.accel * dt; }Phần này sẽ kiểm tra xem người dùng đang bắt nhân vật chạy về hướng nào. Sau đó sẽ thay đổi vị trí nhân vật theo hướng đó bằng cách trừ hay công tọa đọ X với một tốc độ tăng theo thời gian. Nhưng để phòng trường hợp tăng tốc độ quá nhanh thì một phần giới hạn tốc độ được thiết lập ở ngay phía dưới.

if ( Math.abs(this.xSpeed) > this.maxMoveSpeed ) { // if speed reach limit, use max speed with current direction this.xSpeed = this.maxMoveSpeed * this.xSpeed / Math.abs(this.xSpeed); }Phần cuối của hàm l à set vị trí cho nhân vật

Tham khảo ngay  Hàng Pre Order Là Gì? Dịch Vụ, Bán Hàng Order Nghĩa Là Gì

this.node.x += this.xSpeed * dt;

Tạo Hình Và Bắt Sự Kiện Cho Ngôi Sao

Sau khi đã thực hiện xong cho nhân vật tiếp đến chúng ta sẽ thực hiện cho ngôi sao. Do ngôi sao sẽ xuất hiện và mất đi khi nhân vật chạm tới nó. Tức là nó sẽ được tạo ra và phá hủy đi liên lục do vậy ở đây ta sẽ động chạm đến một khái niệm Prefab. Prefab là những node những thực thể ta đã tạo ra nhưng cần sử dụng đi sử dụng lại nhiều lần, nó giống như khái niệm component ở trong các framework React hay Vue vậy.

Thì bây giờ ta sẽ tạo ra các Prefab như vậy bằng cách kéo ngôi sao vào Scene và tạo một file script rồi add vào cho nó.

*

// Star.js properties: { // When the distance between the star and main character is less than this value, collection of the point will be completed pickRadius: 0, },

*

Rồi sau khi đã add script cho nó ta biến nó thành 1 một Prefab bằng cách. Kéo nó từ Scene xuống ô Assets vậy là xong

*

*

Tiếp đến là tạo sự kiện để set vị trí cho ngôi sao khi nó xuất hiện. Tạo một file Game.js

// Game.js properties: { // this property quotes the PreFab resource of stars starPrefab: { default: null, type: cc.Prefab }, // the random scale of disappearing time for stars maxStarDuration: 0, minStarDuration: 0, // ground node for confirming the height of the generated star”s position ground: { default: null, type: cc.Node }, // player node for obtaining the jump height of the main character and controlling the movement switch of the main character player: { default: null, type: cc.Node } },starPrefab ta để type là Prefab. bây giờ add script này cho thằng Canvas kéo lên phần Node Tree –> chọn Canvas –> rồi Properties chọn Add Component và chọn file script Game

Rồi giờ đến phần Generate sao bằng cách random vị trí

// Game.js onLoad: function () { // obtain the anchor point of ground level on the y axis this.groundY = this.ground.y + this.ground.height/2; // this.ground.top may also work // generate a new star this.spawnNewStar(); }, spawnNewStar: function() { // generate a new node in the scene with a preset template var newStar = cc.instantiate(this.starPrefab); // put the newly added node under the Canvas node this.node.addChild(newStar); // set up a random position for the star newStar.setPosition(this.getNewStarPosition()); }, getNewStarPosition: function () { var randX = 0; // According to the position of the ground level and the main character”s jump height, randomly obtain an anchor point of the star on the y axis var randY = this.groundY + Math.random() * this.player.getComponent(“Player”).jumpHeight + 50; // according to the width of the screen, randomly obtain an anchor point of star on the x axis var maxX = this.node.width/2; randX = (Math.random() – 0.5) * 2 * maxX; // return to the anchor point of the star return cc.v2(randX, randY); },Test nào

*

Rồi giờ gắn sao vào với tổng thể game

// Game.js spawnNewStar: function() { // … // Staging a reference of Game object on a star component newStar.getComponent(“Star”).game = this; },// Star.js getPlayerDistance: function () { // judge the distance according to the position of the player node var playerPos = this.game.player.getPosition(); // calculate the distance between two nodes according to their positions var dist = this.node.position.sub(playerPos).mag(); return dist; }, onPicked: function() { // When the stars are being collected, invoke the interface in the Game script to generate a new star this.game.spawnNewStar(); // then destroy the current star”s node this.node.destroy(); }, update: function (dt) { // judge if the distance between the star and main character is less than the collecting distance for each frame if (this.getPlayerDistance() this.pickRadius) { // invoke collecting behavior this.onPicked(); return; } },

Add score

Điểm sẽ bắt đầu từ 0 khi trò chơi bắt đầu. 1 điểm sẽ được thêm khi 1 sao được thu thập. Để hiển thị điểm số, trước tiên chúng ta nên tạo một node Label. Chọn Canvas trong Node Tree , nhấp chuột phải và chọn Create -> Create Renderer Nodes -> Node With Label. Một node label mới sẽ được tạo dưới node Canvas. Tiếp theo, chúng tôi sẽ sử dụng các bước sau để thiết lập node label này:

Thay đổi tên node thành scoreChọn node score và thiết lập position thành (0, 180)Chỉnh sửa thuộc tính String thành Score: 0Đặt Font Size là 50Kéo assets/mikado_outline_shadow(chú ý! Biểu tượng là

*

) vào thuộc tính Font của Label

*

Thêm logic ghi điểm vào script Game

// Game.js properties: { // … // reference of score label scoreDisplay: { default: null, type: cc.Label } },Tiếp đến là khởi tạo điểm trong onLoad()

// Game.js onLoad: function () { // … // initialize scoring this.score = 0; },Sau đó thêm một phương thức mới được đặt tên gainScore :

// Game.js gainScore: function () { this.score += 1; // update the words of the scoreDisplay Label this.scoreDisplay.string = “Score: ” + this.score; },

Invoke ghi điểm của trò chơi trong Star

// Star.js onPicked: function() { // when the stars are being collected, invoke the interface in the Game script to generate a new star this.game.spawnNewStar(); // invoke the scoring method of the Game script this.game.gainScore(); // then destroy the current star”s node this.node.destroy(); },

Kéo các thành phần vào logic game

Chọn Canvas nhìn sang Properties và để ý phần Game sẽ có các trường nhu sau

*

Đây chính là các properties ta đã định nghĩa trong file Game.js. Tiếp theo ta cần kéo các thành phần cần thiết vào đây.

*

Sau khi đã kéo các thành phần vào properties thì ta cần xóa node star trên Node Tree đi. Vì về sau ta sẽ generate các star bằng Prefab nên thằng node này sẽ không cần thiết nữa. Nếu không xóa đi nó sẽ bị hiện tượng lúc nào cũng có 2 ngôi sao và một ngôi sao không bao giờ biến mất như thế này. À tiện thể test xem kết quả luôn nhá

Tham khảo ngay  Đầu Tư Forex Có Nên Đầu Tư Forex Có Hợp Pháp Không? Lưu Ý Gì Khi Tham Gia Forex?

*

Xóa node star đi

*

Kết quả đã ok

Game Over

Ta sẽ thiết lập thời gian xuất hiện của ngôi sao để làm sao từ khi ngôi sao được xuất hiện mà 60s sau chẳng hạn, mà nó không được thu thập thì sẽ game over. Vây đầu tiên cần thêm biến đếm thời gian

// Game.js onLoad: function () { // … // initialize timer this.timer = 0; this.starDuration = 0; // generate a new star this.spawnNewStar(); // initialize scoring this.score = 0; },Sau đó thêm logic đặt lại bộ định thời vào cuối spawnNewStar phương thức, trong đó this.minStarDuration và this.maxStarDuration là các thuộc tính của Game được khai báo ở đầu. Chúng được sử dụng để quy định tỷ lệ ngẫu nhiên của thời gian sao:

// Game.js spawnNewStar: function() { // … // reset timer, randomly choose a value according the scale of star duration this.starDuration = this.minStarDuration + Math.random() * (this.maxStarDuration – this.minStarDuration); this.timer = 0; },Thêm logic cập nhật bộ đếm thời gian và phán đoán vượt quá thời lượng cho phương thức update:

// Game.js update: function (dt) { // update timer for each frame, when a new star is not generated after exceeding duration // invoke the logic of game failure if (this.timer > this.starDuration) { this.gameOver(); return; } this.timer += dt; },Cuối cùng, thêm phương thức gameOver

// Game.js gameOver: function () { this.player.stopAllActions(); //stop the jumping action of the player node cc.director.loadScene(“game”); }Để người chơi biết rằng ngồi sao sắp biến mất ta cần có cho nó một hiệu ứng bằng cách giảm opacity của nó xuống làm nó mờ dần đi.

// Star.js update: function() { // … // update the transparency of the star according to the timer in the Game script var opacityRatio = 1 – this.game.timer/this.game.starDuration; var minOpacity = 50; this.node.opacity = minOpacity + Math.floor(opacityRatio * (255 – minOpacity)); }

Thêm hiệu ứng âm thanh cho Player

Game mà im lặng thì rất khô khan, bây giờ chúng ta sẽ thêm cho nó hiệu ứng âm thanh khi nó thực hiện các hành động.

Đầu tiên, thêm hiệu ứng âm thanh nhảy. Mở Player.js và thêm thuộc tính tham jumpAudio

// Player.js properties: { // … // jumping sound effect resource jumpAudio: { default: null, type: cc.AudioClip }, },Sau đó viết lại phương thức setJumpAction chèn cuộc gọi lại để phát hiệu ứng âm thanh và phát âm thanh bằng cách thêm phương thức playJumpSound

// Player.js setJumpAction: function () { // jump up var jumpUp = cc.moveBy(this.jumpDuration, cc.v2(0, this.jumpHeight)).easing(cc.easeCubicActionOut()); // jump down var jumpDown = cc.moveBy(this.jumpDuration, cc.v2(0, -this.jumpHeight)).easing(cc.easeCubicActionIn()); // add a callback function to invoke other defined methods after the action is finished var callback = cc.callFunc(this.playJumpSound, this); // repeat unceasingly, and invoke callback to play sound after landing each time return cc.repeatForever(cc.sequence(jumpUp, jumpDown, callback)); }, playJumpSound: function () { // invoke sound engine to play the sound cc.audioEngine.playEffect(this.jumpAudio, false); },

Hiệu ứng âm thanh khi ghi điểm

Thêm thuộc tính âm thanh ghi điểm vào Game.js

// Game.js properties: { // … // scoring sound effect resource scoreAudio: { default: null, type: cc.AudioClip } },Sau đó chèn vào phương thức gainScore

// Game.js gainScore: function () { this.score += 1; // update the words of the scoreDisplay Label this.scoreDisplay.string = “Score: ” + this.score.toString(); // play the scoring sound effect cc.audioEngine.playEffect(this.scoreAudio, false); },Tiếp đến làm tương tự như kéo cá thành phần, giờ ta sẽ kéo các file audio vào ô thuộc tính tương ứng.

*

*

*

Đã hoàn tất giờ chúng ta thử trả nghiệm thôi

Build và Deploy

Build

Phần Build của nó rất đơn giản. Chọn Project -> chọn Build

*

Tiếp đén chọn Build và chờ thanh Build…

Xem thêm: Analytics Plus Network Là Gì ? Mẹo Xài Ps5 Cato Networks Plus Network Là Gì

hiện conpleted là được

*

*

Vậy là đã build xong giờ có thể test kết quả build bằng cách chọn Play

Deploy

Để đơn giản hóa việc deploy chúng ta sẽ sử dụng surge: https://surge.sh/

*

insttall rất đơn giản

npm install –global surgesau khi đã cài đặt ta sẽ vào thư mục mà vừa nãy ta build ra và mở terminal

*

Chạy lệnh surge

*

Sau đó thiết lập tên domain là xong

*

Và đây là kết quả :http://gamestar.surge.sh/

Tổng kết

Đến đây chắc hẳn mọi người đã biết cách làm sao để làm những game đơn giản với Cocos Creator rồi. Còn nếu muốn tạo những game phức tạp hơn thì cần phải đọc docs và tham khảo từ những sản phẩm đi trước rất nhiều nữa. Cảm ơn các bạn đã quan tâm đến bàì viết, rất vui và hẹn gặp lại ở những bài viết tiếp theo.

Nếu các bạn có hứng thú với game socket có thể tham khảo game mà mình và bạn trong team đã làm. Nó có tích hợp sử dụng cả websocket để chơi và blockchain để lưu kết quả nên, tuy hơi sơ sài nhưng chắc là sẽ giúp được ai đó nếu cần. Và đặc biệt là thằng này chưa hỗ chợ SocketIO nếu muốn tích hợp sẽ khá khó khăn theo như docs của nó có nói vậy, nên mình đành ngậm ngùi sử dụng Websocket. Đây là link game và cần có ví metamask mới chơi được nha:https://github.com/ngovannghia1997kma/HeadBall2

Rate this post

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Back to top button