Nếu bạn không có biện pháp, bạn không thể cải thiện nó. Seymour Cray
STDIO Tiếp tục chuỗi bài viết về hướng dẫn làm game, hôm nay tôi sẽ hướng dẫn cách hiện thực GameScene. Cụ thể trong bài viết này tôi sẽ giúp các bạn khởi tạo một layer mới trong game và vẽ các suit lên đó.
Nội dung bài viết

Giới thiệu

Bạn đã đọc qua các bài viết về cocos2d-x của STDIO, bạn muốn thử viết một game hoàn chỉnh nhưng chưa biết nên bắt đầu từ đâu? Thông qua chuỗi bài viết về hướng dẫn làm game, tôi sẽ hướng dẫn các bạn hiện thực lại game ZERO một cách đơn giản. Hy vọng rằng, qua đó sẽ giúp bạn làm quen cách để hoàn thành một game, cũng như cách tổ chức project trong game.

Tiếp tục chuỗi bài viết về hướng dẫn làm game, hôm nay tôi sẽ hướng dẫn cách hiện thực GameScene. Cụ thể trong bài viết này tôi sẽ giúp các bạn khởi tạo một layer mới trong game và vẽ các suit lên đó. 

Tiền đề bài viết

Sau khi hoàn thành khoá học phát triển games tại STDIO, được sự cho phép của anh La Kiến Vinh, tôi quyết định chia sẻ lại các kiến thức, cũng như kinh nghiệm tôi học được cho cộng đồng.

Đối tượng hướng đến

Bài viết hướng đến các đối tượng đã nắm qua một số kiến thức cơ bản của cocos2d-x.

Hiện thực

Trước khi hiện thực GameScene vào file config.h định nghĩa thêm để được như sau:

#ifndef __CONFIG_H__
#define __CONFIG_H__

#include "cocos2d.h"
USING_NS_CC;

#define TRANSITION_TIME 1.0f

static const float      SCREEN_DESIGN_WIDTH     = 1080.0f;
static const float      SCREEN_DESIGN_HEIGHT    = 1920.0f;

static const char *PATH_SPR_BOARD = "spr_board.png";
static const char *PATH_SPR_CLOCK = "spr_clock.png";

static const char *PATH_CONF_POS = "conf_objects_pos.plist";

static const char *PATH_SPR_BTN_PLAY = "spr_btn_play.png";
static const char *PATH_SPR_BTN_PLAY_PRESS = "spr_btn_play_press.png";
static const char *PATH_SPR_TITLE_ZERO = "spr_title_zero.png";

static const int        TIMER_OPACITY = 255;

static const float      FP_EPSILON = 0.000001f;
static const float      MIN_SUITS_PER_SIDE = 1;
static const float      MAX_SUITS_PER_SIDE = 4;

static const float SUIT_DISTANCE = 80.0f;

static const char       *PATH_SPR_SUITS[] =
{
	"spr_suit_spade.png",
	"spr_suit_heart.png",
	"spr_suit_diamond.png",
	"spr_suit_club.png"
};

enum
{
	zBACKGROUND = 0,
	zGAME_BOARD,
	zGAME_PLAY,
	zUI,
};

enum
{
	SUIT_SPADE = 0,
	SUIT_HEART,
	SUIT_DIAMOND,
	SUIT_CLUB
};

#endif // __CONFIG_H__

Lưu ý: Trong bài viết này tôi xin phép dùng từ suit để nói đến các đối tượng (cơ, rô, chuồn, bích)  trong game Zero.

Tại GameScene.h

Ta thêm vào các thuộc tính cũng như phương thức để được như sau:

#ifndef __GAME_SCENE_H__
#define __GAME_SCENE_H__

#include "cocos2d.h"
USING_NS_CC;

class GameScene : public cocos2d::Layer
{
public:
	// there's no 'id' in cpp, so we recommend returning the class instance pointer
	static cocos2d::Scene* createScene();

	// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
	virtual bool init();

	void generateNextChallenge();

	// implement the "static create()" method manually
	CREATE_FUNC(GameScene);

private:
	Layer           *_layerPresentation;

	int				_nLeftSuits;
	int				_nRightSuits;

	Vec2			_centerSuitPostionLeft;
	Vec2			_centerSuitPostionRight;

	Size visibleSize;
	Vec2 origin;
};

#endif // __GAME_SCENE_H__

Trong GameScene.cpp

Hiện thực hàm init

Tạo background và gắn board vào tương tự như bài viết trước:

// Creat color for background
this->addChild(LayerColor::create(Color4B(29, 233, 182, 255)), zBACKGROUND);

// board
Sprite *board = Sprite::createWithSpriteFrameName(PATH_SPR_BOARD);
board->setPosition(PositionManager::getInstance()->_board);
this->addChild(board, zGAME_BOARD);

Khởi tạo layer _layerPresentation:

_layerPresentation = Layer::create();
this->addChild(_layerPresentation, zGAME_PLAY);

Khởi tạo giá trị cho _centerSuitPostionLeft và _centerSuitPostionRight:

_centerSuitPostionLeft = Vec2(visibleSize.width * 0.23, visibleSize.height*(0.5f));
_centerSuitPostionRight = Vec2(visibleSize.width * 0.77, visibleSize.height*(0.5f));

Gọi hàm generateNextChallenge (Hàm này có nhiệm vụ reset lại layer game và vẽ lại khi bạn chọn đúng)

generateNextChallenge();

Hiện thực hàm getSuitPosition

Nhiệm vụ của hàm này là lấy position cho từng suit

Vec2* getSuitPosition(int numSuits)
{
	Vec2* suitPosition = new Vec2[numSuits];

	if (numSuits == 1)
		suitPosition[0] = Vec2(0, 0);
	else if (numSuits == 2)
	{
		suitPosition[0] = Vec2(-SUIT_DISTANCE, 0);
		suitPosition[1] = Vec2(SUIT_DISTANCE, 0);
	}
	else if (numSuits == 3)
	{
		suitPosition[0] = Vec2(0, -SUIT_DISTANCE);
		suitPosition[1] = Vec2(-SUIT_DISTANCE, SUIT_DISTANCE);
		suitPosition[2] = Vec2(SUIT_DISTANCE, SUIT_DISTANCE);
	}
	else if (numSuits == 4)
	{
		suitPosition[0] = Vec2(-SUIT_DISTANCE, -SUIT_DISTANCE * 0.9f);
		suitPosition[1] = Vec2(SUIT_DISTANCE, -SUIT_DISTANCE * 0.9f);
		suitPosition[2] = Vec2(-SUIT_DISTANCE, SUIT_DISTANCE);
		suitPosition[3] = Vec2(SUIT_DISTANCE, SUIT_DISTANCE);
	}

	return suitPosition;
}

Hiện thực hàm drawSuitsTable

Nhiệm vụ của hàm này là vẽ suit

void drawSuitsTable(int numSuits, Vec2 centerPosition, float originX, float originY, Layer *layerPresentation)
{
	// index random suit list
	static std::vector<int> suitsSet;
	suitsSet.push_back(SUIT_SPADE);
	suitsSet.push_back(SUIT_HEART);
	suitsSet.push_back(SUIT_DIAMOND);
	suitsSet.push_back(SUIT_CLUB);

	Vec2* suitPosition = getSuitPosition(numSuits);

	std::random_shuffle(suitsSet.begin(), suitsSet.end());	

	int currentSuit = 0;

	srand(time(NULL));
	int suitType = rand() % 4 + 1;

	for (int i = 0; i < numSuits; ++i)
	{
		Sprite* sprite = Sprite::createWithSpriteFrameName(PATH_SPR_SUITS[suitsSet.at(currentSuit)]);	 //create(PATH_SPR_SUITS[0)]);
		currentSuit = (currentSuit + 1) % suitType;
		sprite->setPosition(Vec2(originX, originY) + centerPosition + suitPosition[i]);
		layerPresentation->addChild(sprite);
	}
}

Hiện thực hàm generateNextChallenge

void GameScene::generateNextChallenge()
{
	_layerPresentation->removeAllChildrenWithCleanup(true);

	// randomize number of every suit
    _nLeftSuits = MIN_SUITS_PER_SIDE + CCRANDOM_0_1()*(MAX_SUITS_PER_SIDE - MIN_SUITS_PER_SIDE + 1 - FP_EPSILON);
    _nRightSuits = MIN_SUITS_PER_SIDE + CCRANDOM_0_1()*(MAX_SUITS_PER_SIDE - MIN_SUITS_PER_SIDE + 1 - FP_EPSILON);

	drawSuitsTable(_nLeftSuits, _centerSuitPostionLeft, origin.x, origin.y, _layerPresentation);
	drawSuitsTable(_nRightSuits, _centerSuitPostionRight, origin.x, origin.y, _layerPresentation);
}

Download

SOURCE_CODE

Bạn cần hỗ trợ các dự án kết nối không dây?

Quí doanh nghiệp, cá nhân cần hỗ trợ, hợp tác các dự án IoT, kết nối không dây. Vui lòng liên hệ, hoặc gọi trực tiếp 0942.111912.

  • TỪ KHÓA
  • Arduino
  • ESP32
  • ESP8266
  • Wifi
  • Bluetooth
  • Zigbee
  • Raspberry Pi
THẢO LUẬN
ĐÓNG