增加碰撞消息处理
This commit is contained in:
		
							parent
							
								
									2ac7ac6591
								
							
						
					
					
						commit
						f718a197a8
					
				|  | @ -45,7 +45,6 @@ void e2d::Game::start(bool cleanup) | |||
| 	auto sceneManager = SceneManager::getInstance(); | ||||
| 	auto actionManager = ActionManager::getInstance(); | ||||
| 	auto inputManager = InputManager::getInstance(); | ||||
| 	auto collisionManager = CollisionManager::getInstance(); | ||||
| 
 | ||||
| 	// 显示窗口
 | ||||
| 	::ShowWindow(window->getHWnd(), SW_SHOWNORMAL); | ||||
|  | @ -76,9 +75,8 @@ void e2d::Game::start(bool cleanup) | |||
| 			input->update();			// 获取用户输入
 | ||||
| 			timer->update();			// 更新定时器
 | ||||
| 			actionManager->update();	// 更新动作管理器
 | ||||
| 			sceneManager->update();		// 更新场景内容
 | ||||
| 			inputManager->update();		// 更新输入监听器
 | ||||
| 			collisionManager->update();	// 更新碰撞监听器
 | ||||
| 			sceneManager->update();		// 更新场景内容
 | ||||
| 			renderer->render();			// 渲染游戏画面
 | ||||
| 			GC::flush();				// 刷新内存池
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,13 +9,16 @@ e2d::Collider::Collider(Node * parent) | |||
| 	, _geometry(nullptr) | ||||
| 	, _enabled(true) | ||||
| 	, _shape(Collider::Shape::None) | ||||
| 	, _notify(true) | ||||
| { | ||||
| 	_shape = Game::getInstance()->getConfig()->getDefaultColliderShape(); | ||||
| 	CollisionManager::getInstance()->__addCollider(this); | ||||
| } | ||||
| 
 | ||||
| e2d::Collider::~Collider() | ||||
| { | ||||
| 	SafeRelease(_geometry); | ||||
| 	CollisionManager::getInstance()->__removeCollider(this); | ||||
| } | ||||
| 
 | ||||
| e2d::Color e2d::Collider::getColor() const | ||||
|  | @ -28,6 +31,11 @@ e2d::Collider::Shape e2d::Collider::getShape() const | |||
| 	return _shape; | ||||
| } | ||||
| 
 | ||||
| e2d::Node * e2d::Collider::getNode() const | ||||
| { | ||||
| 	return _parentNode; | ||||
| } | ||||
| 
 | ||||
| ID2D1Geometry * e2d::Collider::getGeometry() const | ||||
| { | ||||
| 	return _geometry; | ||||
|  | @ -36,7 +44,12 @@ ID2D1Geometry * e2d::Collider::getGeometry() const | |||
| void e2d::Collider::setShape(Shape shape) | ||||
| { | ||||
| 	_shape = shape; | ||||
| 	this->_recreate(); | ||||
| 	this->recreate(); | ||||
| } | ||||
| 
 | ||||
| void e2d::Collider::setCollisionNotify(bool notify) | ||||
| { | ||||
| 	_notify = notify; | ||||
| } | ||||
| 
 | ||||
| void e2d::Collider::setEnabled(bool enabled) | ||||
|  | @ -54,9 +67,9 @@ void e2d::Collider::setColor(Color color) | |||
| 	_color = color; | ||||
| } | ||||
| 
 | ||||
| void e2d::Collider::_render() | ||||
| void e2d::Collider::render() | ||||
| { | ||||
| 	if (_geometry && _enabled) | ||||
| 	if (_geometry && _enabled && _visible) | ||||
| 	{ | ||||
| 		auto renderer = Renderer::getInstance(); | ||||
| 		// »ñÈ¡´¿É«»Ë¢
 | ||||
|  | @ -88,7 +101,22 @@ e2d::Collider::Relation e2d::Collider::getRelationWith(Collider * collider) cons | |||
| 	return Relation::Unknown; | ||||
| } | ||||
| 
 | ||||
| void e2d::Collider::_recreate() | ||||
| bool e2d::Collider::isEnabled() const | ||||
| { | ||||
| 	return _enabled; | ||||
| } | ||||
| 
 | ||||
| bool e2d::Collider::isVisible() const | ||||
| { | ||||
| 	return _visible; | ||||
| } | ||||
| 
 | ||||
| bool e2d::Collider::isCollisionNotify() const | ||||
| { | ||||
| 	return _notify; | ||||
| } | ||||
| 
 | ||||
| void e2d::Collider::recreate() | ||||
| { | ||||
| 	SafeRelease(_geometry); | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,34 @@ | |||
| #include "..\e2dcommon.h" | ||||
| 
 | ||||
| e2d::Collision::Collision() | ||||
| 	: _active(nullptr) | ||||
| 	, _passive(nullptr) | ||||
| 	, _relation(Collider::Relation::Unknown) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| e2d::Collision::Collision(Node* active, Node* passive, Collider::Relation relation) | ||||
| 	: _active(active) | ||||
| 	, _passive(passive) | ||||
| 	, _relation(relation) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| e2d::Collision::~Collision() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| e2d::Node * e2d::Collision::getActive() const | ||||
| { | ||||
| 	return _active; | ||||
| } | ||||
| 
 | ||||
| e2d::Node * e2d::Collision::getPassive() const | ||||
| { | ||||
| 	return _passive; | ||||
| } | ||||
| 
 | ||||
| e2d::Collider::Relation e2d::Collision::getRelation() const | ||||
| { | ||||
| 	return _relation; | ||||
| } | ||||
|  | @ -22,8 +22,6 @@ void e2d::CollisionManager::destroyInstance() | |||
| } | ||||
| 
 | ||||
| e2d::CollisionManager::CollisionManager() | ||||
| 	: _activeNode(nullptr) | ||||
| 	, _passiveNode(nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  | @ -31,73 +29,61 @@ e2d::CollisionManager::~CollisionManager() | |||
| { | ||||
| } | ||||
| 
 | ||||
| void e2d::CollisionManager::__remove(Node * node) | ||||
| void e2d::CollisionManager::__addCollider(Collider * collider) | ||||
| { | ||||
| 	if (node) | ||||
| 	_colliders.push_back(collider); | ||||
| } | ||||
| 
 | ||||
| void e2d::CollisionManager::__removeCollider(Collider * collider) | ||||
| { | ||||
| 	auto iter = std::find(_colliders.begin(), _colliders.end(), collider); | ||||
| 	if (iter != _colliders.end()) | ||||
| 	{ | ||||
| 		auto iter = std::find(_collisionNodes.begin(), _collisionNodes.end(), node); | ||||
| 		if (iter != _collisionNodes.end()) | ||||
| 		{ | ||||
| 			_collisionNodes.erase(iter); | ||||
| 		} | ||||
| 		_colliders.erase(iter); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void e2d::CollisionManager::updateCollider(Node * node) | ||||
| void e2d::CollisionManager::__updateCollider(Collider* collider) | ||||
| { | ||||
| 	if (node) | ||||
| 	{ | ||||
| 		if (node->getCollider()->_shape != Collider::Shape::None) | ||||
| 		{ | ||||
| 			node->getCollider()->_recreate(); | ||||
| 			_collisionNodes.insert(node); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void e2d::CollisionManager::update() | ||||
| { | ||||
| 	// 判断碰撞监听是否打开
 | ||||
| 	if (Game::getInstance()->isPaused() || | ||||
| 		!Game::getInstance()->getConfig()->isCollisionEnabled() || | ||||
| 		SceneManager::getInstance()->isTransitioning()) | ||||
| 	{ | ||||
| 		_collisionNodes.clear(); | ||||
| 		SceneManager::getInstance()->isTransitioning() || | ||||
| 		!collider->isCollisionNotify()) | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto iter1 = _collisionNodes.begin(); iter1 != _collisionNodes.end(); iter1++) | ||||
| 	for (size_t i = 0; i < _colliders.size(); i++) | ||||
| 	{ | ||||
| 		auto node1 = (*iter1); | ||||
| 		// 判断与其他碰撞体的交集情况
 | ||||
| 		auto iter2 = iter1; | ||||
| 		iter2++; | ||||
| 		for (; iter2 != _collisionNodes.end(); iter2++) | ||||
| 		auto active = collider->getNode(); | ||||
| 		auto passive = _colliders[i]->getNode(); | ||||
| 		// 判断两物体是否是相互冲突的物体
 | ||||
| 		if (active == passive || | ||||
| 			active->getParentScene() != passive->getParentScene() || | ||||
| 			!CollisionManager::isCollidable(active, passive)) | ||||
| 		{ | ||||
| 			auto node2 = (*iter2); | ||||
| 			// 判断两物体是否是相互冲突的物体
 | ||||
| 			if (CollisionManager::isCollidable(node1, node2)) | ||||
| 			{ | ||||
| 				// 判断两碰撞体交集情况
 | ||||
| 				Collider::Relation relation = node1->getCollider()->getRelationWith(node2->getCollider()); | ||||
| 				// 忽略 UNKNOWN 和 DISJOIN 情况
 | ||||
| 				if (relation != Collider::Relation::Unknown &&  | ||||
| 					relation != Collider::Relation::Disjoin) | ||||
| 				{ | ||||
| 					// 更新碰撞监听器
 | ||||
| 					CollisionManager::__update(node1, node2); | ||||
| 				} | ||||
| 			} | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		// 判断两碰撞体交集情况
 | ||||
| 		Collider::Relation relation = active->getCollider()->getRelationWith(passive->getCollider()); | ||||
| 		// 忽略 UNKNOWN 和 DISJOIN 情况
 | ||||
| 		if (relation != Collider::Relation::Unknown && | ||||
| 			relation != Collider::Relation::Disjoin) | ||||
| 		{ | ||||
| 			_collision = Collision(active, passive, relation); | ||||
| 			active->onCollision(_collision); | ||||
| 			// 更新碰撞监听器
 | ||||
| 			CollisionManager::__updateListeners(); | ||||
| 		} | ||||
| 	} | ||||
| 	_collisionNodes.clear(); | ||||
| 	_collision = Collision(); | ||||
| } | ||||
| 
 | ||||
| void e2d::CollisionManager::addName(const String & name1, const String & name2) | ||||
| { | ||||
| 	if (!name1.isEmpty() && !name2.isEmpty()) | ||||
| 	{ | ||||
| 		_collisionList.insert(HashPair(name1.getHashCode(), name2.getHashCode())); | ||||
| 		_collisionList.insert(std::make_pair(name1.getHashCode(), name2.getHashCode())); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -107,7 +93,7 @@ void e2d::CollisionManager::addName(const std::vector<std::pair<String, String> | |||
| 	{ | ||||
| 		if (!name.first.isEmpty() && !name.second.isEmpty()) | ||||
| 		{ | ||||
| 			_collisionList.insert(HashPair(name.first.getHashCode(), name.second.getHashCode())); | ||||
| 			_collisionList.insert(std::make_pair(name.first.getHashCode(), name.second.getHashCode())); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -119,8 +105,10 @@ bool e2d::CollisionManager::isCollidable(Node * node1, Node * node2) | |||
| 
 | ||||
| bool e2d::CollisionManager::isCollidable(const String & name1, const String & name2) | ||||
| { | ||||
| 	UINT hashName1 = name1.getHashCode(), hashName2 = name2.getHashCode(); | ||||
| 	HashPair pair1 = HashPair(hashName1, hashName2), pair2 = HashPair(hashName2, hashName1); | ||||
| 	UINT hashName1 = name1.getHashCode(),  | ||||
| 		hashName2 = name2.getHashCode(); | ||||
| 	auto pair1 = std::make_pair(hashName1, hashName2),  | ||||
| 		pair2 = std::make_pair(hashName2, hashName1); | ||||
| 	for (auto& pair : _collisionList) | ||||
| 	{ | ||||
| 		if (pair == pair1 || pair == pair2) | ||||
|  | @ -131,56 +119,16 @@ bool e2d::CollisionManager::isCollidable(const String & name1, const String & na | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| e2d::Node * e2d::CollisionManager::getActiveNode() | ||||
| e2d::Collision e2d::CollisionManager::getCollision() const | ||||
| { | ||||
| 	return _activeNode; | ||||
| 	return _collision; | ||||
| } | ||||
| 
 | ||||
| e2d::Node * e2d::CollisionManager::getPassiveNode() | ||||
| { | ||||
| 	return _passiveNode; | ||||
| } | ||||
| 
 | ||||
| bool e2d::CollisionManager::isCausedBy(const String & name1, const String & name2) | ||||
| { | ||||
| 	String activeName = _activeNode->getName(); | ||||
| 	String passiveName = _passiveNode->getName(); | ||||
| 	return (activeName == name1 && passiveName == name2) || | ||||
| 		(activeName == name2 && passiveName == name1); | ||||
| } | ||||
| 
 | ||||
| bool e2d::CollisionManager::isCausedBy(Node * node1, Node * node2) | ||||
| { | ||||
| 	return (_activeNode == node1 && _passiveNode == node2) || | ||||
| 		(_activeNode == node2 && _passiveNode == node1); | ||||
| } | ||||
| 
 | ||||
| e2d::Node* e2d::CollisionManager::isCausedBy(Node * node) | ||||
| { | ||||
| 	if (_activeNode == node) | ||||
| 		return _passiveNode; | ||||
| 	if (_passiveNode == node) | ||||
| 		return _activeNode; | ||||
| 	return nullptr; | ||||
| } | ||||
| 
 | ||||
| e2d::Node* e2d::CollisionManager::isCausedBy(const String& name) | ||||
| { | ||||
| 	if (_activeNode->getName() == name) | ||||
| 		return _activeNode; | ||||
| 	if (_passiveNode->getName() == name) | ||||
| 		return _passiveNode; | ||||
| 	return nullptr; | ||||
| } | ||||
| 
 | ||||
| void e2d::CollisionManager::__update(Node * active, Node * passive) | ||||
| void e2d::CollisionManager::__updateListeners() | ||||
| { | ||||
| 	if (_listeners.empty() || Game::getInstance()->isPaused()) | ||||
| 		return; | ||||
| 
 | ||||
| 	_activeNode = active; | ||||
| 	_passiveNode = passive; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < _listeners.size(); ++i) | ||||
| 	{ | ||||
| 		auto listener = _listeners[i]; | ||||
|  | @ -197,9 +145,6 @@ void e2d::CollisionManager::__update(Node * active, Node * passive) | |||
| 			++i; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	_activeNode = nullptr; | ||||
| 	_passiveNode = nullptr; | ||||
| } | ||||
| 
 | ||||
| e2d::Listener * e2d::CollisionManager::addListener(const Function& func, const String& name, bool paused) | ||||
|  |  | |||
|  | @ -80,7 +80,6 @@ e2d::Node::~Node() | |||
| 	SafeRelease(_outline); | ||||
| 
 | ||||
| 	ActionManager::getInstance()->clearAllBindedWith(this); | ||||
| 	CollisionManager::getInstance()->__remove(this); | ||||
| 	for (auto child : _children) | ||||
| 	{ | ||||
| 		GC::release(child); | ||||
|  | @ -89,9 +88,6 @@ e2d::Node::~Node() | |||
| 
 | ||||
| void e2d::Node::_update() | ||||
| { | ||||
| 	// 更新转换矩阵
 | ||||
| 	_updateTransform(); | ||||
| 
 | ||||
| 	if (_children.empty()) | ||||
| 	{ | ||||
| 		if (_autoUpdate && !Game::getInstance()->isPaused()) | ||||
|  | @ -106,9 +102,8 @@ void e2d::Node::_update() | |||
| 		_sortChildren(); | ||||
| 
 | ||||
| 		// 遍历子节点
 | ||||
| 		size_t size = _children.size(); | ||||
| 		size_t i; | ||||
| 		for (i = 0; i < size; ++i) | ||||
| 		for (i = 0; i < _children.size(); ++i) | ||||
| 		{ | ||||
| 			auto child = _children[i]; | ||||
| 			// 访问 Order 小于零的节点
 | ||||
|  | @ -129,9 +124,14 @@ void e2d::Node::_update() | |||
| 		this->_fixedUpdate(); | ||||
| 
 | ||||
| 		// 访问其他节点
 | ||||
| 		for (; i < size; ++i) | ||||
| 		for (; i < _children.size(); ++i) | ||||
| 			_children[i]->_update(); | ||||
| 	} | ||||
| 
 | ||||
| 	// 更新转换矩阵
 | ||||
| 	updateTransform(); | ||||
| 	// 保留差别属性
 | ||||
| 	_extrapolate = this->getProperty(); | ||||
| } | ||||
| 
 | ||||
| void e2d::Node::_render() | ||||
|  | @ -141,9 +141,6 @@ void e2d::Node::_render() | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	// 更新转换矩阵
 | ||||
| 	_updateTransform(); | ||||
| 
 | ||||
| 	if (_children.empty()) | ||||
| 	{ | ||||
| 		// 转换渲染器的二维矩阵
 | ||||
|  | @ -156,9 +153,8 @@ void e2d::Node::_render() | |||
| 		// 子节点排序
 | ||||
| 		_sortChildren(); | ||||
| 
 | ||||
| 		size_t size = _children.size(); | ||||
| 		size_t i; | ||||
| 		for (i = 0; i < size; ++i) | ||||
| 		for (i = 0; i < _children.size(); ++i) | ||||
| 		{ | ||||
| 			auto child = _children[i]; | ||||
| 			// 访问 Order 小于零的节点
 | ||||
|  | @ -178,7 +174,7 @@ void e2d::Node::_render() | |||
| 		this->onRender(); | ||||
| 
 | ||||
| 		// 访问剩余节点
 | ||||
| 		for (; i < size; ++i) | ||||
| 		for (; i < _children.size(); ++i) | ||||
| 			_children[i]->_render(); | ||||
| 	} | ||||
| } | ||||
|  | @ -207,10 +203,7 @@ void e2d::Node::_renderOutline() | |||
| void e2d::Node::_renderCollider() | ||||
| { | ||||
| 	// 绘制自身的几何碰撞体
 | ||||
| 	if (_collider._visible) | ||||
| 	{ | ||||
| 		_collider._render(); | ||||
| 	} | ||||
| 	_collider.render(); | ||||
| 
 | ||||
| 	// 绘制所有子节点的几何碰撞体
 | ||||
| 	for (auto child : _children) | ||||
|  | @ -219,11 +212,53 @@ void e2d::Node::_renderCollider() | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void e2d::Node::_updateTransform() | ||||
| void e2d::Node::updateTransform() | ||||
| { | ||||
| 	if (!_needTransform) | ||||
| 		return; | ||||
| 
 | ||||
| 	_updateSelfTransform(); | ||||
| 	CollisionManager::getInstance()->__updateCollider(&_collider); | ||||
| 
 | ||||
| 	if (_needTransform) | ||||
| 	{ | ||||
| 		_updateSelfTransform(); | ||||
| 	} | ||||
| 
 | ||||
| 	// 为节点创建一个轮廓
 | ||||
| 	ID2D1RectangleGeometry * rectGeo = nullptr; | ||||
| 	ID2D1TransformedGeometry * transformedGeo = nullptr; | ||||
| 
 | ||||
| 	auto factory = Renderer::getFactory(); | ||||
| 	HRESULT hr = factory->CreateRectangleGeometry( | ||||
| 		D2D1::RectF(0, 0, _width, _height), | ||||
| 		&rectGeo | ||||
| 	); | ||||
| 
 | ||||
| 	if (SUCCEEDED(hr)) | ||||
| 	{ | ||||
| 		factory->CreateTransformedGeometry( | ||||
| 			rectGeo, | ||||
| 			_finalMatri, | ||||
| 			&transformedGeo | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	SafeRelease(rectGeo); | ||||
| 	SafeRelease(_outline); | ||||
| 	_outline = transformedGeo; | ||||
| 
 | ||||
| 	// 通知子节点进行转换
 | ||||
| 	for (auto& child : _children) | ||||
| 	{ | ||||
| 		child->_needTransform = true; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void e2d::Node::_updateSelfTransform() | ||||
| { | ||||
| 	_needTransform = false; | ||||
| 
 | ||||
| 	// 计算中心点坐标
 | ||||
| 	D2D1_POINT_2F pivot = { _width * _pivotX, _height * _pivotY }; | ||||
| 	// 变换 Initial 矩阵,子节点将根据这个矩阵进行变换
 | ||||
|  | @ -251,35 +286,8 @@ void e2d::Node::_updateTransform() | |||
| 		_finalMatri = _finalMatri * _parent->_initialMatri; | ||||
| 	} | ||||
| 
 | ||||
| 	// 为节点创建一个轮廓
 | ||||
| 	ID2D1RectangleGeometry * rectGeo; | ||||
| 	ID2D1TransformedGeometry * transformedGeo; | ||||
| 
 | ||||
| 	auto factory = Renderer::getFactory(); | ||||
| 	factory->CreateRectangleGeometry( | ||||
| 		D2D1::RectF(0, 0, _width, _height), | ||||
| 		&rectGeo | ||||
| 	); | ||||
| 	factory->CreateTransformedGeometry( | ||||
| 		rectGeo, | ||||
| 		_finalMatri, | ||||
| 		&transformedGeo | ||||
| 	); | ||||
| 
 | ||||
| 	SafeRelease(rectGeo); | ||||
| 	SafeRelease(_outline); | ||||
| 	_outline = transformedGeo; | ||||
| 
 | ||||
| 	// 更新碰撞体
 | ||||
| 	CollisionManager::getInstance()->updateCollider(this); | ||||
| 	// 标志已执行过变换
 | ||||
| 	_needTransform = false; | ||||
| 
 | ||||
| 	// 通知子节点进行转换
 | ||||
| 	for (auto& child : _children) | ||||
| 	{ | ||||
| 		child->_needTransform = true; | ||||
| 	} | ||||
| 	_collider.recreate(); | ||||
| } | ||||
| 
 | ||||
| void e2d::Node::_sortChildren() | ||||
|  | @ -425,6 +433,11 @@ e2d::Node::Property e2d::Node::getProperty() const | |||
| 	return std::move(prop); | ||||
| } | ||||
| 
 | ||||
| e2d::Node::Property e2d::Node::getExtrapolate() const | ||||
| { | ||||
| 	return this->getProperty() - _extrapolate; | ||||
| } | ||||
| 
 | ||||
| e2d::Collider* e2d::Node::getCollider() | ||||
| { | ||||
| 	return &_collider; | ||||
|  | @ -462,8 +475,6 @@ void e2d::Node::setPos(double x, double y) | |||
| 
 | ||||
| 	_posX = float(x); | ||||
| 	_posY = float(y); | ||||
| 	_extrapolate.posX += x; | ||||
| 	_extrapolate.posY += y; | ||||
| 	_needTransform = true; | ||||
| } | ||||
| 
 | ||||
|  | @ -518,8 +529,6 @@ void e2d::Node::setScale(double scaleX, double scaleY) | |||
| 
 | ||||
| 	_scaleX = float(scaleX); | ||||
| 	_scaleY = float(scaleY); | ||||
| 	_extrapolate.scaleX += scaleX; | ||||
| 	_extrapolate.scaleY += scaleY; | ||||
| 	_needTransform = true; | ||||
| } | ||||
| 
 | ||||
|  | @ -540,8 +549,6 @@ void e2d::Node::setSkew(double angleX, double angleY) | |||
| 
 | ||||
| 	_skewAngleX = float(angleX); | ||||
| 	_skewAngleY = float(angleY); | ||||
| 	_extrapolate.skewAngleX += angleX; | ||||
| 	_extrapolate.skewAngleY += angleY; | ||||
| 	_needTransform = true; | ||||
| } | ||||
| 
 | ||||
|  | @ -551,7 +558,6 @@ void e2d::Node::setRotation(double angle) | |||
| 		return; | ||||
| 
 | ||||
| 	_rotation = float(angle); | ||||
| 	_extrapolate.rotation += angle; | ||||
| 	_needTransform = true; | ||||
| } | ||||
| 
 | ||||
|  | @ -582,8 +588,6 @@ void e2d::Node::setPivot(double pivotX, double pivotY) | |||
| 
 | ||||
| 	_pivotX = std::min(std::max(float(pivotX), 0.f), 1.f); | ||||
| 	_pivotY = std::min(std::max(float(pivotY), 0.f), 1.f); | ||||
| 	_extrapolate.pivotX += pivotX; | ||||
| 	_extrapolate.pivotY += pivotY; | ||||
| 	_needTransform = true; | ||||
| } | ||||
| 
 | ||||
|  | @ -604,8 +608,6 @@ void e2d::Node::setSize(double width, double height) | |||
| 
 | ||||
| 	_width = float(width); | ||||
| 	_height = float(height); | ||||
| 	_extrapolate.width += width; | ||||
| 	_extrapolate.height += height; | ||||
| 	_needTransform = true; | ||||
| } | ||||
| 
 | ||||
|  | @ -786,7 +788,7 @@ void e2d::Node::removeChildren(const String& childName) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void e2d::Node::clearAllChildren() | ||||
| void e2d::Node::removeAllChildren() | ||||
| { | ||||
| 	// 所有节点的引用计数减一
 | ||||
| 	for (auto child : _children) | ||||
|  | @ -840,7 +842,7 @@ void e2d::Node::stopAction(const String& name) | |||
| 
 | ||||
| bool e2d::Node::containsPoint(const Point& point) | ||||
| { | ||||
| 	_updateTransform(); | ||||
| 	updateTransform(); | ||||
| 	if (_outline) | ||||
| 	{ | ||||
| 		BOOL ret = 0; | ||||
|  | @ -859,8 +861,8 @@ bool e2d::Node::containsPoint(const Point& point) | |||
| 
 | ||||
| bool e2d::Node::intersects(Node * node) | ||||
| { | ||||
| 	_updateTransform(); | ||||
| 	node->_updateTransform(); | ||||
| 	updateTransform(); | ||||
| 	node->updateTransform(); | ||||
| 	if (_outline) | ||||
| 	{ | ||||
| 		D2D1_GEOMETRY_RELATION relation; | ||||
|  |  | |||
|  | @ -441,14 +441,10 @@ public: | |||
| 
 | ||||
| 
 | ||||
| class Node; | ||||
| class CollisionManager; | ||||
| 
 | ||||
| // 碰撞体
 | ||||
| class Collider | ||||
| { | ||||
| 	friend class Node; | ||||
| 	friend class CollisionManager; | ||||
| 
 | ||||
| public: | ||||
| 	// 碰撞体形状
 | ||||
| 	enum class Shape | ||||
|  | @ -470,13 +466,24 @@ public: | |||
| 	}; | ||||
| 
 | ||||
| public: | ||||
| 	Collider( | ||||
| 		Node * parent | ||||
| 	); | ||||
| 
 | ||||
| 	virtual ~Collider(); | ||||
| 
 | ||||
| 	// 设置碰撞体形状
 | ||||
| 	virtual void setShape( | ||||
| 	void setShape( | ||||
| 		Shape shape | ||||
| 	); | ||||
| 
 | ||||
| 	// 是否触发碰撞事件
 | ||||
| 	void setCollisionNotify( | ||||
| 		bool notify | ||||
| 	); | ||||
| 
 | ||||
| 	// 启用或关闭该碰撞体
 | ||||
| 	virtual void setEnabled( | ||||
| 	void setEnabled( | ||||
| 		bool enabled | ||||
| 	); | ||||
| 
 | ||||
|  | @ -491,37 +498,44 @@ public: | |||
| 	); | ||||
| 
 | ||||
| 	// 判断两碰撞体的交集关系
 | ||||
| 	virtual Relation getRelationWith( | ||||
| 	Relation getRelationWith( | ||||
| 		Collider * pCollider | ||||
| 	) const; | ||||
| 
 | ||||
| 	// 是否启用碰撞体
 | ||||
| 	bool isEnabled() const; | ||||
| 
 | ||||
| 	// 是否可见
 | ||||
| 	bool isVisible() const; | ||||
| 
 | ||||
| 	// 是否触发碰撞事件
 | ||||
| 	bool isCollisionNotify() const; | ||||
| 
 | ||||
| 	// 获取绘制颜色
 | ||||
| 	Color getColor() const; | ||||
| 
 | ||||
| 	// 获取形状
 | ||||
| 	Shape getShape() const; | ||||
| 
 | ||||
| 	// 获取绑定节点
 | ||||
| 	Node* getNode() const; | ||||
| 
 | ||||
| 	// 获取 ID2D1Geometry* 对象
 | ||||
| 	ID2D1Geometry* getGeometry() const; | ||||
| 
 | ||||
| protected: | ||||
| 	Collider( | ||||
| 		Node * parent | ||||
| 	); | ||||
| 
 | ||||
| 	virtual ~Collider(); | ||||
| 
 | ||||
| 	E2D_DISABLE_COPY(Collider); | ||||
| 
 | ||||
| 	// 重新生成
 | ||||
| 	void _recreate(); | ||||
| 	void recreate(); | ||||
| 
 | ||||
| 	// 渲染碰撞体
 | ||||
| 	void _render(); | ||||
| 	void render(); | ||||
| 
 | ||||
| protected: | ||||
| 	E2D_DISABLE_COPY(Collider); | ||||
| 
 | ||||
| protected: | ||||
| 	bool	_enabled; | ||||
| 	bool	_visible; | ||||
| 	bool	_notify; | ||||
| 	Color	_color; | ||||
| 	Node *	_parentNode; | ||||
| 	Shape	_shape; | ||||
|  | @ -529,6 +543,36 @@ protected: | |||
| }; | ||||
| 
 | ||||
| 
 | ||||
| // 碰撞事件
 | ||||
| class Collision | ||||
| { | ||||
| public: | ||||
| 	Collision(); | ||||
| 
 | ||||
| 	Collision( | ||||
| 		Node* active, | ||||
| 		Node* passive, | ||||
| 		Collider::Relation relation | ||||
| 	); | ||||
| 
 | ||||
| 	~Collision(); | ||||
| 
 | ||||
| 	// 获取发生碰撞的主动方
 | ||||
| 	Node* getActive() const; | ||||
| 
 | ||||
| 	// 获取发生碰撞的被动方
 | ||||
| 	Node* getPassive() const; | ||||
| 
 | ||||
| 	// 获取交集关系
 | ||||
| 	Collider::Relation getRelation() const; | ||||
| 
 | ||||
| protected: | ||||
| 	Node * _active; | ||||
| 	Node* _passive; | ||||
| 	Collider::Relation _relation; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| // 资源
 | ||||
| class Resource | ||||
| { | ||||
|  |  | |||
|  | @ -5,13 +5,9 @@ | |||
| namespace e2d | ||||
| { | ||||
| 
 | ||||
| class Game; | ||||
| class Input; | ||||
| class Renderer; | ||||
| 
 | ||||
| class Node; | ||||
| class Task; | ||||
| class Action; | ||||
| class Player; | ||||
| class Collider; | ||||
| class Transition; | ||||
| 
 | ||||
|  | @ -249,6 +245,7 @@ private: | |||
| class CollisionManager | ||||
| { | ||||
| 	friend class Node; | ||||
| 	friend class Collider; | ||||
| 
 | ||||
| public: | ||||
| 	// 获取碰撞体管理器实例
 | ||||
|  | @ -265,7 +262,7 @@ public: | |||
| 
 | ||||
| 	// 添加可互相碰撞物体的名称
 | ||||
| 	void addName( | ||||
| 		const std::vector<std::pair<String, String> >& names | ||||
| 		const std::vector<std::pair<String, String>>& names | ||||
| 	); | ||||
| 
 | ||||
| 	// 判断两个物体是否是可碰撞的
 | ||||
|  | @ -280,35 +277,8 @@ public: | |||
| 		const String& name2 | ||||
| 	); | ||||
| 
 | ||||
| 	// 获取碰撞发生时的主动体
 | ||||
| 	Node * getActiveNode(); | ||||
| 
 | ||||
| 	// 获取碰撞发生时的被动体
 | ||||
| 	Node * getPassiveNode(); | ||||
| 
 | ||||
| 	// 判断发生碰撞的节点名称是否相同
 | ||||
| 	bool isCausedBy( | ||||
| 		const String& name1, | ||||
| 		const String& name2 | ||||
| 	); | ||||
| 
 | ||||
| 	// 判断两物体是否发生碰撞
 | ||||
| 	bool isCausedBy( | ||||
| 		Node * node1, | ||||
| 		Node * node2 | ||||
| 	); | ||||
| 
 | ||||
| 	// 判断发生碰撞的任意一方名称是否相同
 | ||||
| 	// 若相同,返回其指针,否则返回空
 | ||||
| 	Node * isCausedBy( | ||||
| 		const String& name | ||||
| 	); | ||||
| 
 | ||||
| 	// 判断物体是否发生碰撞
 | ||||
| 	// 如果是,返回与其相撞的节点指针,否则返回空
 | ||||
| 	Node * isCausedBy( | ||||
| 		Node * node | ||||
| 	); | ||||
| 	// 获取碰撞事件
 | ||||
| 	Collision getCollision() const; | ||||
| 
 | ||||
| 	// 添加碰撞监听
 | ||||
| 	Listener * addListener( | ||||
|  | @ -354,14 +324,6 @@ public: | |||
| 	// 强制清除所有监听器
 | ||||
| 	void clearAllListeners(); | ||||
| 
 | ||||
| 	// 更新碰撞体
 | ||||
| 	void updateCollider( | ||||
| 		Node * node | ||||
| 	); | ||||
| 
 | ||||
| 	// 更新碰撞体管理器
 | ||||
| 	void update(); | ||||
| 
 | ||||
| private: | ||||
| 	CollisionManager(); | ||||
| 
 | ||||
|  | @ -369,24 +331,29 @@ private: | |||
| 
 | ||||
| 	E2D_DISABLE_COPY(CollisionManager); | ||||
| 
 | ||||
| 	void __remove( | ||||
| 		Node* node | ||||
| 	// 添加碰撞体
 | ||||
| 	void __addCollider( | ||||
| 		Collider* collider | ||||
| 	); | ||||
| 
 | ||||
| 	// 移除碰撞体
 | ||||
| 	void __removeCollider( | ||||
| 		Collider* collider | ||||
| 	); | ||||
| 
 | ||||
| 	// 更新碰撞体
 | ||||
| 	void __updateCollider( | ||||
| 		Collider* collider | ||||
| 	); | ||||
| 
 | ||||
| 	// 更新监听器
 | ||||
| 	void __update( | ||||
| 		Node * active, | ||||
| 		Node * passive | ||||
| 	); | ||||
| 	void __updateListeners(); | ||||
| 
 | ||||
| private: | ||||
| 	typedef std::pair<UINT, UINT> HashPair; | ||||
| 	 | ||||
| 	e2d::Node * _activeNode; | ||||
| 	e2d::Node * _passiveNode; | ||||
| 	std::set<Node*> _collisionNodes; | ||||
| 	std::set<HashPair> _collisionList; | ||||
| 	Collision _collision; | ||||
| 	std::vector<Collider*> _colliders; | ||||
| 	std::vector<Listener*> _listeners; | ||||
| 	std::set<std::pair<UINT, UINT>> _collisionList; | ||||
| 
 | ||||
| 	static CollisionManager * _instance; | ||||
| }; | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ namespace e2d | |||
| 
 | ||||
| class Action; | ||||
| class Transition; | ||||
| class CollisionManager; | ||||
| 
 | ||||
| class Node : | ||||
| 	public Ref | ||||
|  | @ -14,6 +15,7 @@ class Node : | |||
| 	friend class Scene; | ||||
| 	friend class Collider; | ||||
| 	friend class Transition; | ||||
| 	friend class CollisionManager; | ||||
| 
 | ||||
| public: | ||||
| 	// 节点属性
 | ||||
|  | @ -48,6 +50,11 @@ public: | |||
| 	// 渲染节点
 | ||||
| 	virtual void onRender() {} | ||||
| 
 | ||||
| 	// 节点发生碰撞
 | ||||
| 	virtual void onCollision( | ||||
| 		Collision other | ||||
| 	) {} | ||||
| 
 | ||||
| 	// 获取节点显示状态
 | ||||
| 	virtual bool isVisible() const; | ||||
| 
 | ||||
|  | @ -124,6 +131,9 @@ public: | |||
| 	// 获取节点属性
 | ||||
| 	virtual Property getProperty() const; | ||||
| 
 | ||||
| 	// 获取差别属性
 | ||||
| 	virtual Property getExtrapolate() const; | ||||
| 
 | ||||
| 	// 获取节点碰撞体
 | ||||
| 	virtual Collider * getCollider(); | ||||
| 
 | ||||
|  | @ -159,12 +169,12 @@ public: | |||
| 		const String& childName | ||||
| 	); | ||||
| 
 | ||||
| 	// 移除所有节点
 | ||||
| 	virtual void removeAllChildren(); | ||||
| 
 | ||||
| 	// 从父节点移除
 | ||||
| 	virtual void removeFromParent(); | ||||
| 
 | ||||
| 	// 移除所有节点
 | ||||
| 	virtual void clearAllChildren(); | ||||
| 
 | ||||
| 	// 设置节点是否显示
 | ||||
| 	virtual void setVisible( | ||||
| 		bool value | ||||
|  | @ -375,6 +385,9 @@ public: | |||
| 	// 停止所有动作
 | ||||
| 	virtual void stopAllActions(); | ||||
| 
 | ||||
| 	// 更新转换矩阵
 | ||||
| 	void updateTransform(); | ||||
| 
 | ||||
| protected: | ||||
| 	E2D_DISABLE_COPY(Node); | ||||
| 
 | ||||
|  | @ -395,8 +408,8 @@ protected: | |||
| 		Scene * scene | ||||
| 	); | ||||
| 
 | ||||
| 	// 更新节点二维矩阵
 | ||||
| 	void _updateTransform(); | ||||
| 	// 更新自身转换矩阵
 | ||||
| 	void _updateSelfTransform(); | ||||
| 
 | ||||
| 	// 子节点排序
 | ||||
| 	void _sortChildren(); | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ | |||
|     <ClCompile Include="..\..\core\Base\Time.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Base\Window.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Collider.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Collision.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Color.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Config.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Font.cpp" /> | ||||
|  |  | |||
|  | @ -260,5 +260,8 @@ | |||
|     <ClCompile Include="..\..\core\Manager\InputManager.cpp"> | ||||
|       <Filter>Manager</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\core\Common\Collision.cpp"> | ||||
|       <Filter>Common</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
|  | @ -203,6 +203,7 @@ | |||
|     <ClCompile Include="..\..\core\Base\Time.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Base\Window.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Collider.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Collision.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Color.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Config.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Font.cpp" /> | ||||
|  |  | |||
|  | @ -260,5 +260,8 @@ | |||
|     <ClCompile Include="..\..\core\Manager\InputManager.cpp"> | ||||
|       <Filter>Manager</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\core\Common\Collision.cpp"> | ||||
|       <Filter>Common</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
|  | @ -222,6 +222,7 @@ | |||
|     <ClCompile Include="..\..\core\Base\Time.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Base\Window.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Collider.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Collision.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Color.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Config.cpp" /> | ||||
|     <ClCompile Include="..\..\core\Common\Font.cpp" /> | ||||
|  |  | |||
|  | @ -243,6 +243,9 @@ | |||
|     <ClCompile Include="..\..\core\Manager\InputManager.cpp"> | ||||
|       <Filter>Manager</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="..\..\core\Common\Collision.cpp"> | ||||
|       <Filter>Common</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="..\..\core\easy2d.h" /> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue