-
So I am making a level editor for my game (with zoom & stuff) and i am stuck with converting the touch position to the world position. I tried using Camera::unprojectGL since I saw other people use it and it always seems to return the camera position itself (in other words, it returns visibleSize / 2).
#include "EditorScene.h"
#include "GameObject.h"
#include "EditorUI.h"
using namespace ax;
using namespace ax::extension;
bool EditorScene::init()
{
if (!Scene::init())
return false;
auto winSize = Director::getInstance()->getVisibleSize();
m_background = Sprite::createWithSpriteFrameName("SN_Background1.png");
m_background->setPosition(winSize / 2);
m_background->setScale(2);
addChild(m_background);
m_gridNode = DrawNode::create();
for (int j = -40; j < winSize.y / 40 + 40; j++)
{
for (int i = -40; i < winSize.x / 40 + 40; i++)
{
Vec2 origin = Vec2(i * 40, winSize.y - (j * 40));
Vec2 destination = Vec2(i * 40 + 40, winSize.y - (j * 40) - 40);
m_gridNode->drawRect(origin, destination, Color4B(127, 127, 127, 255));
}
}
m_gridNode->drawRect({0, 0}, sn::res, Color4B(35, 255, 0, 255), 4.0f);
addChild(m_gridNode);
m_batchNode = SpriteBatchNode::create("SN_BlockSheet.png");
addChild(m_batchNode);
m_editorUi = EditorUI::create(this);
addChild(m_editorUi, 9999);
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = AX_CALLBACK_2(EditorScene::onTouchBegan, this);
touchListener->onTouchMoved = AX_CALLBACK_2(EditorScene::onTouchMoved, this);
touchListener->onTouchEnded = AX_CALLBACK_2(EditorScene::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
auto keyboardListener = EventListenerKeyboard::create();
keyboardListener->onKeyPressed = AX_CALLBACK_2(EditorScene::onKeyPressed, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
return true;
}
void EditorScene::onEnter()
{
Scene::onEnter();
scheduleOnce([this](float) { Inspector::getInstance()->openForCurrentScene(); }, 1.f, "inspectorSchedule");
}
static Vec2 s_initialTouchPos;
static bool s_didSwipe;
bool EditorScene::onTouchBegan(Touch* touch, Event* event)
{
s_initialTouchPos = touch->getLocation();
s_didSwipe = false;
return true;
}
void EditorScene::onTouchEnded(Touch* touch, Event* event)
{
Vec2 currentTouchPos = touch->getLocation();
Vec2 delta = currentTouchPos - s_initialTouchPos;
auto winSize = Director::getInstance()->getVisibleSize();
auto camera = Director::getInstance()->getRunningScene()->getDefaultCamera();
if (!s_didSwipe)
{
Vec3 pos3 = camera->unprojectGL(Vec3(currentTouchPos.x, currentTouchPos.y, 0));
Vec2 pos = Vec2(pos3.x, pos3.y);
SNLOG("touch: {} {}", currentTouchPos.x, currentTouchPos.y);
SNLOG("pos3: {} {} {}", pos3.x, pos3.y, pos3.z);
SNLOG("pos: {} {}", pos.x, pos.y);
}
}
void EditorScene::onTouchMoved(Touch* touch, Event* event)
{
Vec2 currentTouchPos = touch->getLocation();
Vec2 delta = currentTouchPos - s_initialTouchPos;
auto winSize = Director::getInstance()->getVisibleSize();
auto camera = Director::getInstance()->getRunningScene()->getDefaultCamera();
if ((delta.length() > 15.0f || s_didSwipe))
{
s_didSwipe = true;
camera->setPosition(camera->getPosition() - delta * camera->getZoom());
updateUI();
s_initialTouchPos = currentTouchPos;
}
}
void EditorScene::onKeyPressed(ax::EventKeyboard::KeyCode keyCode, ax::Event* event)
{
switch (keyCode)
{
case EventKeyboard::KeyCode::KEY_O:
zoomIn();
break;
case EventKeyboard::KeyCode::KEY_P:
zoomOut();
break;
default:
break;
}
}
void EditorScene::updateUI()
{
auto camera = Director::getInstance()->getRunningScene()->getDefaultCamera();
auto winSize = Director::getInstance()->getVisibleSize();
m_editorUi->setPosition(camera->getPosition() - winSize / 2 * camera->getZoom());
m_editorUi->setScale(camera->getZoom());
}
void EditorScene::zoom(float zoomDiff)
{
auto winSize = Director::getInstance()->getVisibleSize();
auto camera = Director::getInstance()->getRunningScene()->getDefaultCamera();
float zoom = camera->getZoom();
if (zoom < 0.5f && zoomDiff < 0) // zoom too big
return;
if (zoom > 1.5f && zoomDiff > 0) // zoom too small
return;
camera->setZoom(zoom + zoomDiff);
SNLOG("zoom: {}", camera->getZoom());
updateUI();
}
void EditorScene::zoomIn()
{
zoom(-0.05f);
}
void EditorScene::zoomOut()
{
zoom(0.05f);
}
#pragma once
#include "SceneFunc.h"
#include "axmol.h"
class EditorUI;
class EditorScene : public ax::Scene
{
public:
ax::Sprite* m_background;
ax::SpriteBatchNode* m_batchNode;
ax::DrawNode* m_gridNode;
EditorUI* m_editorUi;
public:
bool init() override;
void onEnter() override;
bool onTouchBegan(ax::Touch* touch, ax::Event* event);
void onTouchMoved(ax::Touch* touch, ax::Event* event);
void onTouchEnded(ax::Touch* touch, ax::Event* event);
void onKeyPressed(ax::EventKeyboard::KeyCode keyCode, ax::Event* event);
void updateUI();
void zoom(float s_zoomDiff);
void zoomIn();
void zoomOut();
CREATE_FUNC(EditorScene);
}; Here's the output:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
Can you please show the expected values versus the actual values? So, for the output you're displaying in your post above, what values did you actually expect to see, and what is the size of the view? Also, there are a few methods in the Node class that may help with conversions, such as:
|
Beta Was this translation helpful? Give feedback.
-
Try the following to see if it will help. Add this method to your class:
Change this line: To: That should give you the results you are after, even with camera zooming and moving the camera around. In your original post you mention that you want the world coordinates, yet your use of Original code is from here. |
Beta Was this translation helpful? Give feedback.
Try the following to see if it will help.
Add this method to your class:
Change this line:
Vec3 pos3 = camera->unprojectGL(Vec3(currentTouchPos.x, curr…