基类是设计模式中的模板方法模式,主要存放了一些通用的代码。
当时使用了U2D和U3D把2D UI和3D UI给区分开了,基类里面存放的主要的是本地矩阵和世界矩阵,角度、锚点、缩放、z顺序等。
Node.h
#pragma once
namespace U2D
{
class CNode;
class CUI;
class Cobject;
class CAnimate;
class CAnimateEx;
class CAnimation;
enum MovementEvent;
typedef void (CNode::*event_selector)(CUI*);
typedef void (CNode::*collider_selector)(int, Cobject*, int);//前面的int是自己的第几个碰撞区,中间的是对方的指针,后面的int是对方的第几个碰撞区
typedef void (CNode::*animate_selector)(CAnimate*, MovementEvent);
typedef void (CNode::*animation_selector)(CAnimation*, MovementEvent, char *);
typedef void (CNode::*animateEx_selector)(CAnimateEx*, MovementEvent, int);//后面的int应该是索引在第几张图片
class CNode
{
friend class CScene;
protected:
CNode *parent; //父节点
public:
Matrix3 local_matrix; //自身矩阵
Matrix3 world_matrix; //世界矩阵
sColor local_color; //自身颜色
sColor world_color; //世界颜色
Vector2 pos; //坐标偏移
Vector2 scale; //缩放
Vector2 anchor; //锚点
float angle; //角度
bool visible; //是否可见
bool flip; //是否翻转
int zOrder = 0;
bool auto_sort = false;
//set
void setParent(CNode *parent) { this->parent = parent; }
void setVisible(bool visible) { this->visible = visible; }
void setAlpha(BYTE alpha) { local_color.a = (float)alpha / 255; }
void setPosition(float x, float y) { this->pos.x = x; this->pos.y = y; }
void setPosition(Vector2 p) { this->pos = p; }
void setX(float x) { pos.x = x; }
void setY(float y) { pos.y = y; }
void setScale(float sx, float sy) { this->scale.x = sx; this->scale.y = sy; }
void setFilp(bool flip) { this->flip = flip; }
void setColor(BYTE r, BYTE g, BYTE b) { local_color.r = (float)r / 255; local_color.g = (float)g / 255; local_color.b = (float)b / 255; }
void setAnchor(float ox, float oy) { this->anchor.x = ox; this->anchor.y = oy; }
void setAngle(float angle) { this->angle = angle; }
//get
int getZorder() { return zOrder; }
CNode*getPraent() { return parent; }
sColor &getWorldColor() { return world_color; }
Matrix3 &getWorldMatrix() { return world_matrix; }
sColor &getlocalColor() { return local_color; }
Matrix3 &getlocalMatrix() { return local_matrix; }
float getScaleX() { return scale.x; }//水平翻转比值
float getScaleY() { return scale.y; }//垂直翻转比值
BYTE getAlpha() { return local_color.a * 255; }
Vector2 getPosition() { return pos; }
float getAngle() { return angle; }
//bool
bool isVisible() { return visible; }
bool isFlip() { return flip; }
void setZorder(int z) { this->zOrder = z; this->auto_sort = false; }
CNode();
virtual ~CNode() {};
};
class CElement :public CNode
{
public:
virtual void draw() {};
virtual RECT getBoundBox() = 0;
virtual ~CElement() {};
};
//碰撞aabb
struct COLLIDER//这个是对象和对象的碰撞
{
#define MaxHitArea 5 //最多只有5个碰撞点
CAnimateEx *animEx; //动画加强版的指针
struct
{
int hitIndex;//碰撞的索引
RECT hitRect;//碰撞的范围
}lastAabb[MaxHitArea], nowAabb[MaxHitArea]; //碰撞点的数组,最多只有5个,不然效率低了
int lastAabbNum; //上一个碰撞的编号
int nowAabbNum; //现在的碰撞编号
struct
{
int hitIndex;
bool lastIn;
bool nowIn;
}hitQueue[MaxHitArea];
int hitQueueNum;
collider_selector listener_enter; //碰撞监听[进入]
collider_selector listener_exit;//碰撞监听[离开]
COLLIDER(CAnimateEx *animEx, collider_selector fun_enter, collider_selector fun_exit);
void GenerateHitQueue();
static bool Intersects(RECT &a, RECT &b)
{
if (a.left<b.right && a.right>b.left &&
a.top<b.bottom && a.bottom>b.top)
{
return true;
}
return false;
}
};
}
Node.cpp
#include "Engine.h"
namespace U2D
{
CNode::CNode()
{
scale = Vector2(1.0, 1.0);
anchor = Vector2(0.5, 0.5);
pos = Vector2(0, 0);
visible = true;
flip = false;
angle = 0;
if (CPlateForm::getInstance()->getAutoSort() == true)
auto_sort = true;
else
auto_sort = false;
}
COLLIDER::COLLIDER(CAnimateEx *animEx, collider_selector fun_enter, collider_selector fun_exit)
{
this->animEx = animEx;
listener_enter = fun_enter;
listener_exit = fun_exit;
lastAabbNum = 0;
nowAabbNum = 0;
hitQueueNum = 0;
}
void COLLIDER::GenerateHitQueue()
{
if (lastAabbNum > nowAabbNum)
{
hitQueueNum = lastAabbNum;
for (int i = 0; i < hitQueueNum; i++)
{
hitQueue[i].hitIndex = lastAabb[i].hitIndex;
hitQueue[i].lastIn = true;
if (i < nowAabbNum)
hitQueue[i].nowIn = true;
else
hitQueue[i].nowIn = false;
}
}
else
{
hitQueueNum = nowAabbNum;
for (int i = 0; i < hitQueueNum; i++)
{
hitQueue[i].hitIndex = nowAabb[i].hitIndex;
hitQueue[i].nowIn = true;
if (i < lastAabbNum)
hitQueue[i].lastIn = true;
else
hitQueue[i].lastIn = false;
}
}
}
}