CEGUI 动画

CEGUI 动画最新的版本支持动画,使用Animation类.项目中使用的是7.1的版本,不支持动画,leader说不使用最新版本的CEGUI库,就使用7.1,无奈,自己写一个动画类吧.CEGUI中播放动画是将一个动画的每帧连续不断的画到屏幕上,就形成了动画.就像小时候在书的边页上面画的小人,每一页都画一个小人,每个小人的动作都有点不同,这样快速翻书的时候,小人就成了动画.源代码如最后所贴,原理性的东西就不多讲,…

大家好,又见面了,我是你们的朋友全栈君。

最新的版本支持动画,使用Animation类.项目中使用的是7.1的版本,不支持动画,leader说不使用最新版本的CEGUI库,就使用7.1,无奈,自己写一个动画类吧.
CEGUI中播放动画是将一个动画的每帧连续不断的画到屏幕上,就形成了动画.
就像小时候在书的边页上面画的小人,每一页都画一个小人,每个小人的动作都有点不同,这样快速翻书的时候,小人就成了动画.
源代码如最后所贴,原理性的东西就不多讲,这个可以看书,或者自己分析源代码.
在此把整个过程概述一下,记录一下我在这个过程遇到的难点.
1. 定义自己的动画窗口类,继承自Window类,class DynamicImage : public Window {…}
2. 给DynamicImage添加两个属性:TimeInterval,每帧播放的时间间隔.FrameImage,设置某一帧的图像.
  TimeInterval属性就是保存一个时间间隔值在成员变量中.FrameImage属性就是插入一帧图像,设置的格式就像其它控件一样”set:setname image:imagename”.比如一个动画由10帧组成,那设置10个这个属性,每一个属性值是其中的一帧图像.
3. 在DynamicImage类中重载一下updateSelf()这个函数,渲染过程就在这个函数中实现. 在windows窗口消息的过程中会调用injectTimePulse(),而在injectTimePulse()中又调用了updateSelf(),所以在窗口消息循环中就可以连续不断的绘制动态的表情了.详细请看源码.
  用一个成员变量将所有的帧保存起来,所谓绘制动画就是在固定的间隔时间内连续不断的绘制出这些帧.就形成了动画.
4. 为了方便使用,用tolua++,将DynamicImage打包一下,这样在lua/layout_xml中就可以直接使用这个窗口类了.由于这个窗口类并没有定义自己的WindowRender,所以不需要在scheme中添加对应的解析项.
  打包的方式:准备工作 一.CEGUI的解决方案中有一个叫tolua++cegui的项目,生成这个项目,并将生成的可执行文件以及运行所需要的dll文件放在\cegui\src\ScriptingModules\LuaScriptModule\package目录下面.在这个目录下面有一个叫make.bat的批处理文件,将它里面的内容修改一下,将第一行改成:tolua++cegui_d -o lua_CEGUI.cpp -L exceptions.lua CEGUI.pkg, 意思就是说,使用exceptions.lua和CEGUI.pkg这两个文件来生成一个叫lua_CEGUI.cpp的文件放在当前目录下.
  准备工作 二. 在上面说的那个目录下面有一个叫elements的目录,在这个目录中添加自己定义的窗口pkg文件.至于里面的格式,参考其它文件怎么写的,这个pkg里面写的函数就是可以在lua中使用的函数. 再在CEGUI.pkg这个文件中添加刚才那个文件的名称$pfile “elements/DynamicImage.pkg”, 再在HelperFunctions.pkg文件中添加支持在lua创建这个类的函数:
  function CEGUI.toDynamicImage(w)
      return tolua.cast(w,”CEGUI::DynamicImage”)
  end
  准备工作完成. 运行make.bat文件,将生成的lua_CEGUI.cpp文件放到上级目录下面,然后生成一下CEGUI的库,OK了,然后就可以在自己的项目中使用这个类了.

补充一下:在要System里面添加一个这个类的的Factory:WindowFactoryManager::addFactory< TplWindowFactory<DynamicImage> >();

CEGUI 动画
CEGUI 动画
View Code

#ifndef _CEGUIDynamicImage_h_
#define _CEGUIDynamicImage_h_

#include "../CEGUIBase.h"
#include "../CEGUIWindow.h"
#include "../CEGUIImage.h"
#include "CEGUIDynamicImageProperties.h"
#include <vector>

#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4251)
#endif


namespace CEGUI
{
class CEGUIEXPORT DynamicImage : public Window
{
public:
static const String EventNamespace;
static const String WidgetTypeName;

void addFrameImage(const String& frameImage); // 添加帧图像
void setTimeInterval(unsigned int timeInterval); // 设置每帧播放间隔时间
unsigned int getTimeInterval() const; // 获取每帧播放时间间隔

DynamicImage(const String &type, const String &name);
virtual ~DynamicImage(void);

protected:
virtual bool testClassName_impl(const String& class_name) const
{
if (class_name=="DynamicImage") return true;
return Window::testClassName_impl(class_name);
}

virtual void updateSelf(float elapsed);

private:
unsigned int m_timeInterval; // 每帧播放的时间间隔
unsigned int m_render_frame_id; // 待渲染的帧ID
std::vector<Image> m_frameVector; // 帧容器;

private:
static DynamicImageProperties::TimeInterval d_timeInterval;
static DynamicImageProperties::FrameImage d_frameImage;

void addDynamicImageProperties(void);
};
}

#endif

CEGUI 动画
CEGUI 动画
View Code

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <Windows.h>
#include "elements/CEGUIDynamicImage.h"
#include "CEGUIImagesetManager.h"
#include "CEGUIExceptions.h"
#include "CEGUIPropertyHelper.h"
#include "CEGUIGeometryBuffer.h"


namespace CEGUI
{
const String DynamicImage::EventNamespace("DynamicImage");
const String DynamicImage::WidgetTypeName("CEGUI/DynamicImage");

DynamicImageProperties::TimeInterval DynamicImage::d_timeInterval;
DynamicImageProperties::FrameImage DynamicImage::d_frameImage;

DynamicImage::DynamicImage(const String &type, const String &name):
Window(type, name),
m_timeInterval(1)
{
addDynamicImageProperties();
d_textParsingEnabled = false;
}

DynamicImage::~DynamicImage(void)
{

}

//-------------------------------------------------------------------------------------------------------------
// 添加帧图像
void DynamicImage::addFrameImage(const String& frameImage)
{
m_frameVector.push_back(*PropertyHelper::stringToImage(frameImage));
}

//-------------------------------------------------------------------------------------------------------------
// 设置每帧播放间隔时间
void DynamicImage::setTimeInterval(unsigned int timeInterval)
{
m_timeInterval = timeInterval;
}

//-------------------------------------------------------------------------------------------------------------
// 获取每帧播放时间间隔
unsigned int DynamicImage::getTimeInterval() const
{
return m_timeInterval;
}

//-------------------------------------------------------------------------------------------------------------
// 更新自己
void DynamicImage::updateSelf(float elapsed)
{
if (m_frameVector.size() > 0)
{
Window::updateSelf(elapsed);

static int frameId = 0; // 帧ID
if (frameId >= m_frameVector.size())
frameId = 0;

static unsigned int t_lastTime = 0;
unsigned int t_nowTime = GetTickCount();
unsigned int t_elapsed = t_nowTime - t_lastTime;

Size t_image_size = m_frameVector[frameId].getSize(); // 图像的大小(从图像对应的xml文件中读取出来)
Rect t_win_clip_rect = getClipRect(); // 此窗口的裁剪区域,即此窗口的position&size定义的区域
d_geometry->setClippingRegion(t_win_clip_rect); // 设置裁剪的区域,即,窗口的裁剪区域
Rect t_image_rect(Point(0,0),t_image_size); // Image在此窗口中显示的区域(从0点开始,即左上角,尺寸为图像的尺寸)
d_geometry->reset(); // 清空原来的图像

if (t_elapsed >= m_timeInterval)
{
t_lastTime = t_nowTime;
m_frameVector[frameId].draw(*d_geometry, t_image_rect,0); // 在指定范围内画出此帧图像
frameId++;
}
else
{
m_frameVector[frameId].draw(*d_geometry, t_image_rect,0); // 在指定范围内画出此帧图像
}
}
}

//-------------------------------------------------------------------------------------------------------------
// 添加属性
void DynamicImage::addDynamicImageProperties(void)
{
addProperty(&d_frameImage);
addProperty(&d_timeInterval);
}
}

CEGUI 动画
CEGUI 动画
View Code

#ifndef _CEGUIDynamicImageProperties_h_
#define _CEGUIDynamicImageProperties_h_

#include "../CEGUIProperty.h"

namespace CEGUI
{
namespace DynamicImageProperties
{
// 每帧播放的间隔时间
class TimeInterval : public Property
{
public:
TimeInterval() : Property("TimeInterval","每帧播放的间隔时间,值为毫秒.","1"){}
String get(const PropertyReceiver* receiver) const;
void set(PropertyReceiver* receiver, const String& value);
};

// 某一帧图像
class FrameImage : public Property
{
public:
FrameImage() : Property("FrameImage","某一帧播放的图像.格式:set:[imageset name] image:[image name].",""){}
String get(const PropertyReceiver* receiver) const;
void set(PropertyReceiver* receiver, const String& value);
};
}
}

#endif

CEGUI 动画
CEGUI 动画
View Code

#include "elements/CEGUIDynamicImageProperties.h"
#include "elements/CEGUIDynamicImage.h"
#include "CEGUIPropertyHelper.h"
#include "CEGUIExceptions.h"

namespace CEGUI
{
namespace DynamicImageProperties
{
// 每帧播放的间隔时间
String TimeInterval::get(const PropertyReceiver* receiver) const
{
return PropertyHelper::uintToString(static_cast<const DynamicImage*>(receiver)->getTimeInterval());
}

void TimeInterval::set(PropertyReceiver* receiver, const String& value)
{
static_cast<DynamicImage*>(receiver)->setTimeInterval(PropertyHelper::stringToUint(value));
}

// 某一帧图像
String FrameImage::get(const PropertyReceiver* receiver) const
{
return "";
}

void FrameImage::set(PropertyReceiver* receiver, const String& value)
{
static_cast<DynamicImage*>(receiver)->addFrameImage(value);
}
}
}

上面是CEGUI自定义类的源码,下面是使用这个类的demo.这个是直接使用C++方式创建窗口

CEGUI 动画
CEGUI 动画
View Code

void mywin()
{
using namespace CEGUI;

WindowManager& winmgr = WindowManager::getSingleton();
SchemeManager::getSingleton().create("TaharezLook.scheme");

Window* background = winmgr.createWindow("CEGUI/DynamicImage", "root_wnd");
background->subscribeEvent(DynamicImage::EventMouseClick, Event::Subscriber(&handleMouseClicked));
background->setProperty("UnifiedPosition", "{ {0,100},{0,100}}");
background->setProperty("UnifiedSize", "{ {0,32},{0,32}}");
background->setProperty("TimeInterval", "100");
background->setProperty("FrameImage", "set:FaceImageset image:Face5_1");
background->setProperty("FrameImage", "set:FaceImageset image:Face5_2");
background->setProperty("FrameImage", "set:FaceImageset image:Face5_3");
background->setProperty("FrameImage", "set:FaceImageset image:Face5_4");
System::getSingleton().setGUISheet(background);
}

这个使用lua+xml

CEGUI 动画
CEGUI 动画
View Code

local winmgr = CEGUI.WindowManager:getSingleton();
local system = CEGUI.System:getSingleton();
local schmgr = CEGUI.SchemeManager:getSingleton();
schmgr:create("TaharezLook.scheme");

function select_mode(mode)
local face = nil;
if (mode == 1) then
------------------------------------------------------------------------------
-- 直接使用xml来创建动画窗口
print("mode : 1.");
face = winmgr:loadWindowLayout("CEGUIWin1.xml");
else
------------------------------------------------------------------------------
-- 使用lua来创建窗口
print("mode : not 1.");
face = winmgr:createWindow("CEGUI/DynamicImage");
face:subscribeEvent("MouseClick", "handleMouseClicked");
face:setProperty("UnifiedPosition", "{ {0,100},{0,100}}");
face:setProperty("UnifiedSize", "{ {0,32},{0,32}}");
face:setProperty("TimeInterval", "100");
face:setProperty("FrameImage", "set:FaceImageset image:Face5_1");
face:setProperty("FrameImage", "set:FaceImageset image:Face5_2");
face:setProperty("FrameImage", "set:FaceImageset image:Face5_3");
face:setProperty("FrameImage", "set:FaceImageset image:Face5_4");
end

system:setGUISheet(face);
end

function handleMouseClicked(event)
print("face clicked.");
end

select_mode(1);

CEGUI 动画
CEGUI 动画
View Code

<?xml version="1.0" encoding="UTF-8"?>
<GUILayout >
<Window Type="CEGUI/DynamicImage" Name="Root">
<Property Name="UnifiedPosition" Value ="{ {0,0},{0,0}}" />
<Property Name="UnifiedSize" Value ="{ {0,32},{0,32}}" />
<Property Name="TimeInterval" Value ="100" />
<Property Name="FrameImage" Value ="set:FaceImageset image:Face5_1" />
<Property Name="FrameImage" Value ="set:FaceImageset image:Face5_2" />
<Property Name="FrameImage" Value ="set:FaceImageset image:Face5_3" />
<Property Name="FrameImage" Value ="set:FaceImageset image:Face5_4" />
<Event Name="MouseClick" Function ="handleMouseClicked" />
</Window>
</GUILayout>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163724.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 2020最新版Net加壳工具

    2020最新版Net加壳工具VirboxProtector发布最新版本Net加壳工具:VirboxProtector2.VirboxProtector为.NETFramework编写的软件做代码保护,防止代码被反编译,防止IL代码在内存被Dump。同时可配合授权产品实现软件的许可管理。加密技术VirboxProtector.NET版通过多种保护方式来防止反编译,加密后可让任何现有工具都无法反编译。JIT加密将.NET所有方法的IL指令经过加密,仅在.NET虚拟机进行J.

  • js匿名函数和命名函数_jsp调用java方法

    js匿名函数和命名函数_jsp调用java方法由衷的感叹,js真是烦。学到现在,渐渐理解了什么是:语言都是通用的,没有好不好,只有擅长不擅长。继承,多态,甚至指针,c能实现,c++,java有,javascript(和java是雷锋和雷峰塔的区别,名字上不知道坑了多少人)也能变通实现。温故知新,今天又回味了一遍,匿名函数作为函数参数。代码很短,五脏俱全。functiontest(a,b){a+=1;b(a);}test(3,func…

  • 基于OpenCv的人脸识别(Python完整代码)

    基于OpenCv的人脸识别(Python完整代码)目前人脸识别有很多较为成熟的方法,这里调用OpenCv库,而OpenCV又提供了三种人脸识别方法,分别是LBPH方法、EigenFishfaces方法、Fisherfaces方法。本文采用的是LBPH(LocalBinaryPatternsHistogram,局部二值模式直方图)方法。opencv是一个开源的的跨平台计算机视觉库,内部实现了图像处理和计算机视觉方面的很多通用算法,对于python而言,在引用opencv库的时候需要写为importcv2。其中,cv2是opencv的C++命名空间名称

  • PHP实现执行定时任务的几种思路详解

    PHP实现执行定时任务的几种思路详解

    2021年10月22日
  • matlab中直方图的定义_matlab绘制直方图

    matlab中直方图的定义_matlab绘制直方图MATLAB中直方图均衡化和规定化处理函数格式如下:(1)J=imhist(I,n)(2)J=imhist(I,map)(3)[counts,X]=imhist(I,?)(4)J=histeq(I,n)(5)J=histeq(I,map,n)(6)[J,counts]=histeq(I,?)说明:对于…

    2022年10月19日
  • 1.4 Go语言从入门到精通:Go代理goproxy[通俗易懂]

    1.4 Go语言从入门到精通:Go代理goproxy[通俗易懂]1.4Go语言从入门到精通:Go代理goproxy

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号