Cocos2d-x 3.x实现轨道棋游戏的代码示例

ChatGPT4o 使用 ChatGPT 4o 回答

问题:

你知道轨道棋这个玩具吗,就是一个4x4格子组成的棋盘,分为内外两个圈,圈是逆时针旋转,双方交替落子,每一方落子后棋子沿着圈的标注方向位移一格,直到有一方以一行/一列/斜角任意一种方式落子四颗为胜利,可以帮我用cocos3.x版本的代码写一个这样的游戏吗?

回答:

当然可以!下面是一个简单的实现轨道棋游戏的代码示例。这个示例使用Cocos2d-x 3.x版本的C++代码来实现。请注意,这只是一个基本的实现,可能需要根据具体需求进行调整和扩展。

首先,确保你已经安装了Cocos2d-x 3.x,并且已经创建了一个新的Cocos2d-x项目。

1. 创建棋盘和棋子类

我们需要创建一个棋盘类和一个棋子类来管理游戏逻辑和显示。

ChessPiece.h

#ifndef __CHESS_PIECE_H__
#define __CHESS_PIECE_H__

#include "cocos2d.h"

class ChessPiece : public cocos2d::Sprite
{
public:
    static ChessPiece* createPiece(int player);
    int getPlayer() const { return _player; }

private:
    int _player;
};

#endif // __CHESS_PIECE_H__

ChessPiece.cpp

#include "ChessPiece.h"

USING_NS_CC;

ChessPiece* ChessPiece::createPiece(int player)
{
    ChessPiece* piece = new (std::nothrow) ChessPiece();
    if (piece && piece->initWithFile(player == 1 ? "player1.png" : "player2.png"))
    {
        piece->_player = player;
        piece->autorelease();
        return piece;
    }
    CC_SAFE_DELETE(piece);
    return nullptr;
}

2. 创建棋盘类

GameBoard.h

#ifndef __GAME_BOARD_H__
#define __GAME_BOARD_H__

#include "cocos2d.h"
#include "ChessPiece.h"

class GameBoard : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    CREATE_FUNC(GameBoard);

private:
    void initBoard();
    void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event);
    bool checkWin(int player);
    void movePieces();

    ChessPiece* _board[4][4];
    int _currentPlayer;
};

#endif // __GAME_BOARD_H__

GameBoard.cpp

#include "GameBoard.h"

USING_NS_CC;

Scene* GameBoard::createScene()
{
    auto scene = Scene::create();
    auto layer = GameBoard::create();
    scene->addChild(layer);
    return scene;
}

bool GameBoard::init()
{
    if (!Layer::init())
    {
        return false;
    }

    initBoard();
    _currentPlayer = 1;

    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchEnded = CC_CALLBACK_2(GameBoard::onTouchEnded, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

    return true;
}

void GameBoard::initBoard()
{
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            _board[i][j] = nullptr;
        }
    }
}

void GameBoard::onTouchEnded(Touch* touch, Event* event)
{
    Vec2 location = touch->getLocation();
    int row = static_cast<int>(location.y / 100);
    int col = static_cast<int>(location.x / 100);

    if (row >= 0 && row < 4 && col >= 0 && col < 4 && _board[row][col] == nullptr)
    {
        auto piece = ChessPiece::createPiece(_currentPlayer);
        piece->setPosition(Vec2(col * 100 + 50, row * 100 + 50));
        this->addChild(piece);
        _board[row][col] = piece;

        if (checkWin(_currentPlayer))
        {
            CCLOG("Player %d wins!", _currentPlayer);
            // Handle win condition
        }
        else
        {
            movePieces();
            _currentPlayer = 3 - _currentPlayer; // Switch player
        }
    }
}

bool GameBoard::checkWin(int player)
{
    // Check rows, columns, and diagonals for a win
    for (int i = 0; i < 4; ++i)
    {
        if ((_board[i][0] && _board[i][0]->getPlayer() == player) &&
            (_board[i][1] && _board[i][1]->getPlayer() == player) &&
            (_board[i][2] && _board[i][2]->getPlayer() == player) &&
            (_board[i][3] && _board[i][3]->getPlayer() == player))
        {
            return true;
        }

        if ((_board[0][i] && _board[0][i]->getPlayer() == player) &&
            (_board[1][i] && _board[1][i]->getPlayer() == player) &&
            (_board[2][i] && _board[2][i]->getPlayer() == player) &&
            (_board[3][i] && _board[3][i]->getPlayer() == player))
        {
            return true;
        }
    }

    if ((_board[0][0] && _board[0][0]->getPlayer() == player) &&
        (_board[1][1] && _board[1][1]->getPlayer() == player) &&
        (_board[2][2] && _board[2][2]->getPlayer() == player) &&
        (_board[3][3] && _board[3][3]->getPlayer() == player))
    {
        return true;
    }

    if ((_board[0][3] && _board[0][3]->getPlayer() == player) &&
        (_board[1][2] && _board[1][2]->getPlayer() == player) &&
        (_board[2][1] && _board[2][1]->getPlayer() == player) &&
        (_board[3][0] && _board[3][0]->getPlayer() == player))
    {
        return true;
    }

    return false;
}

void GameBoard::movePieces()
{
    // Move pieces in the inner and outer circles
    ChessPiece* temp = _board[0][0];
    for (int i = 0; i < 3; ++i)
    {
        _board[i][0] = _board[i + 1][0];
        _board[i][0]->setPosition(Vec2(i * 100 + 50, 50));
    }
    for (int i = 0; i < 3; ++i)
    {
        _board[3][i] = _board[3][i + 1];
        _board[3][i]->setPosition(Vec2(350, i * 100 + 50));
    }
    for (int i = 3; i > 0; --i)
    {
        _board[i][3] = _board[i - 1][3];
        _board[i][3]->setPosition(Vec2(i * 100 + 50, 350));
    }
    for (int i = 3; i > 1; --i)
    {
        _board[0][i] = _board[0][i - 1];
        _board[0][i]->setPosition(Vec2(50, i * 100 + 50));
    }
    _board[0][1] = temp;
    _board[0][1]->setPosition(Vec2(50, 150));
}

3. 更新 AppDelegate.cpp

确保在 AppDelegate.cpp 中启动 GameBoard 场景。

#include "AppDelegate.h"
#include "GameBoard.h"

USING_NS_CC;

AppDelegate::AppDelegate() {}

AppDelegate::~AppDelegate() {}

bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::create("My Game");
        director->setOpenGLView(glview);
    }

    // create a scene. it's an autorelease object
    auto scene = GameBoard::createScene();

    // run
    director->runWithScene(scene);

    return true;
}

4. 资源文件

确保你有 player1.pngplayer2.png 这两个图片文件,分别代表两个玩家的棋子。

5. 编译和运行

编译并运行你的项目,你应该会看到一个简单的轨道棋游戏。

这个示例只是一个基本的实现,可能需要根据具体需求进行调整和扩展,例如添加更多的游戏逻辑、优化移动算法、处理游戏结束等。希望这个示例能帮助你开始你的轨道棋游戏开发!