Search…

Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 5: Hiện thực GameScene - Vẽ Suit

30/09/20204 min read
Hướng dẫn khởi tạo một layer mới trong game và vẽ các suit với Cocos2d-x

Hướng dẫn hiện thực lại game ZERO 1 cách đơn giản. Giúp làm quen cách để hoàn thành 1 game, cũng như cách tổ chức project trong game.

Bài viết này giúp khởi tạo một layer mới trong game và vẽ các suit lên đó. 

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 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

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 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ài chung series

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024