游戏示例 - 移动的小人

跟随本章教程,制作一个简单的移动小人,帮助你快速了解 Easy2D 的使用方法。

准备

学会了 Easy2D 的基本操作之后,我们来制作一个简单的小程序,按上下左右键移动画面中的小人。

先准备一张人物的图片,将它拷贝到工程目录下,重命名为 man.png。

准备图片

在 VS 中写好我们新手入门里学习的基本代码,运行后显示一个 640*480 大小的窗口。

main.cpp

#include <easy2d/easy2d.h>

using namespace easy2d;

int main()
{
    if (Game::init())
    {
        // 设置窗口标题和窗口大小
        Window::setTitle("Moving Man");
        Window::setSize(640, 480);

        /* 设计游戏内容 */

        Game::start();
    }
    Game::destroy();
    return 0;
}

创建 Man 类

在代码第 2 行插入一个新的类,取名为 Man,继承 Sprite 类。

class Man : public Sprite
{
public:
    Man() {}
};

在 Man 的构造函数中调用父类的构造函数,将图片的文件名 “man.png” 传给 Sprite。

class Man : public Sprite
{
public:
    Man()
    {
        // 加载图片
        this->open("man.png");
    }
};

设计游戏内容的部分,创建一个场景和一个 Man 对象,然后将 Man 的对象添加到场景中。

添加后的完整代码如下所示

main.cpp

#include <easy2d/easy2d.h>

using namespace easy2d;

class Man : public Sprite
{
public:
    Man()
    {
        // 加载图片
        this->open("man.png");
    }
};

int main()
{
    if (Game::init())
    {
        // 设置窗口标题和窗口大小
        Window::setTitle("Moving Man");
        Window::setSize(640, 480);

        // 创建场景
        auto scene = gcnew Scene;
        // 进入该场景
        SceneManager::enter(scene);

        // 创建一个 Man 对象
        auto hero = gcnew Man;
        // 将 Man 添加到场景中
        scene->addChild(hero);

        Game::start();
    }
    Game::destroy();
    return 0;
}

运行后,程序将显示一个人物图片。

我们用新手入门学过的方法,把居中的代码写在 Man 的构造函数中,让 Man 在屏幕上居中显示。

class Man : public Sprite
{
public:
    Man()
    {
        // 加载图片
        this->open("man.png");
        // 居中显示在屏幕上
        this->setAnchor(0.5f, 0.5f);
        this->setPos(Window::getWidth() / 2, Window::getHeight() / 2);
    }
};

运行后的效果如下图所示

准备图片

实现移动

给 Man 类添加一个名称为 onUpdate 的函数,返回值类型为 void,参数为空

class Man : public Sprite
{
public:
    Man()
    {
        // 加载图片
        this->open("man.png");
        // 居中显示在屏幕上
        this->setAnchor(0.5f, 0.5f);
        this->setPos(Window::getWidth() / 2, Window::getHeight() / 2);
    }

    void onUpdate()
    {
        // onUpdate 函数
    }
};

onUpdate 是一个特殊的函数,它在每一帧画面刷新前被 Easy2D 自动调用,所以这个函数在一秒钟里会被调用 60 次左右。我们可以在这个函数里判断有没有按键按下。

Input 类用来获取用户的输入,Input::isDown 函数用来判断一个键是否正被按下,这个函数需要一个 int 类型的参数,这个参数代表键盘上的一个键。

KeyCode 类枚举了常用按键的键值,例如 KeyCode::Up 代表上键。你可以用下面的代码判断上键是否被按下:

void onUpdate()
{
    if (Input::isDown(KeyCode::Up))
    {
        // 上键被按下
    }
    else
    {
        // 上键没被按下
    }
}

上键被按下时,我们先获取 Man 当前的 Y 坐标,然后重新设置它的 Y 坐标为当前值减 2,这样就实现了按上键向上移动的功能。

void onUpdate()
{
    if (Input::isDown(KeyCode::Up))
    {
        // 获取当前 Y 坐标
        float y = this->getPosY();
        // 重新设置它的坐标
        this->setPosY(y - 2);
    }
}

Node 类的 Node::movePos 函数可以直接移动节点,所以上面的代码可以简写成

void onUpdate()
{
    if (Input::isDown(KeyCode::Up))
    {
        // Man 的 Y 坐标减少 2
        this->movePosY(-2);
    }
}

同理,可以将其他三个按键的判断也加入到 onUpdate 函数中

void onUpdate()
{
    if (Input::isDown(KeyCode::Up))
    {
        // Man 的 Y 坐标减少 2
        this->movePosY(-2);
    }

    if (Input::isDown(KeyCode::Down))
    {
        // Man 的 Y 坐标增加 2
        this->movePosY(2);
    }

    if (Input::isDown(KeyCode::Left))
    {
        // Man 的 X 坐标减少 2
        this->movePosX(-2);
    }

    if (Input::isDown(KeyCode::Right))
    {
        // Man 的 X 坐标增加 2
        this->movePosX(2);
    }
}

一般的游戏中,上键和下键,左键和右键,是不能同时生效的,否则的话同时按住上键和下键人物就不动了,所以我们修改代码如下:

void onUpdate()
{
    if (Input::isDown(KeyCode::Up))
    {
        // Man 的 Y 坐标减少 2
        this->movePosY(-2);
    }
    else if (Input::isDown(KeyCode::Down))
    {
        // Man 的 Y 坐标增加 2
        this->movePosY(2);
    }

    if (Input::isDown(KeyCode::Left))
    {
        // Man 的 X 坐标减少 2
        this->movePosX(-2);
    }
    else if (Input::isDown(KeyCode::Right))
    {
        // Man 的 X 坐标增加 2
        this->movePosX(2);
    }
}

运行游戏,一个按上下左右移动的小人就完成了!

完整代码

main.cpp

#include <easy2d/easy2d.h>

using namespace easy2d;

class Man : public Sprite
{
public:
    Man()
    {
        // 加载图片
        this->open("man.png");
        // 居中显示在屏幕上
        this->setAnchor(0.5f, 0.5f);
        this->setPos(Window::getWidth() / 2, Window::getHeight() / 2);
    }

    void onUpdate()
    {
        if (Input::isDown(KeyCode::Up))
        {
            // Man 的 Y 坐标减少 2
            this->movePosY(-2);
        }
        else if (Input::isDown(KeyCode::Down))
        {
            // Man 的 Y 坐标增加 2
            this->movePosY(2);
        }

        if (Input::isDown(KeyCode::Left))
        {
            // Man 的 X 坐标减少 2
            this->movePosX(-2);
        }
        else if (Input::isDown(KeyCode::Right))
        {
            // Man 的 X 坐标增加 2
            this->movePosX(2);
        }
    }
};

int main()
{
    if (Game::init())
    {
        // 设置窗口标题和窗口大小
        Window::setTitle("Moving Man");
        Window::setSize(640, 480);

        // 创建场景
        auto scene = gcnew Scene;
        // 进入该场景
        SceneManager::enter(scene);

        // 创建一个 Man 对象
        auto hero = gcnew Man;
        // 将 Man 添加到场景中
        scene->addChild(hero);

        Game::start();
    }
    Game::destroy();
    return 0;
}

这个页面对你有帮助吗?