|
|
@@ -14,8 +14,14 @@ namespace oxygine
|
|
|
_defaultTouchThreshold = val;
|
|
|
}
|
|
|
|
|
|
- SlidingActor::SlidingActor():_prevPos(0, 0), _speed(0, 0), _sliding(false), _downPos(0, 0), _rad(_defaultTouchThreshold), _downTime(0), _down(false), _maxSpeed(250), _snapSize(0, 0),
|
|
|
- _movingX(false), _movingY(false), _snapSpeed(1.0f)
|
|
|
+ SlidingActor::SlidingActor():
|
|
|
+ _sliding(false),
|
|
|
+ _rad(_defaultTouchThreshold),
|
|
|
+ _maxSpeed(250),
|
|
|
+ _downTime(0),
|
|
|
+ _downPos(0, 0),
|
|
|
+ _speed(0, 0),
|
|
|
+ _lastTime(0), _current(0), _lastIterTime(0)
|
|
|
{
|
|
|
_clip = initActor(new ClipRectActor,
|
|
|
arg_attachTo = this);
|
|
|
@@ -23,6 +29,9 @@ namespace oxygine
|
|
|
_clip->addEventListener(TouchEvent::TOUCH_DOWN, CLOSURE(this, &SlidingActor::_newEvent));
|
|
|
_clip->addEventListener(TouchEvent::TOUCH_UP, CLOSURE(this, &SlidingActor::_newEvent));
|
|
|
_clip->addEventListener(TouchEvent::MOVE, CLOSURE(this, &SlidingActor::_newEvent));
|
|
|
+
|
|
|
+ //for (int i = 0; i < NUM; ++i)
|
|
|
+ // _prev[i] = Vector2(0,0);
|
|
|
}
|
|
|
|
|
|
void SlidingActor::destroy()
|
|
|
@@ -57,11 +66,6 @@ namespace oxygine
|
|
|
_drag.snapClient2Bounds();
|
|
|
}
|
|
|
|
|
|
- void SlidingActor::setSnapPageSize(const Vector2 &size)
|
|
|
- {
|
|
|
- _snapSize = size;
|
|
|
- }
|
|
|
-
|
|
|
void SlidingActor::setContent(spActor content)
|
|
|
{
|
|
|
if (_content)
|
|
|
@@ -78,12 +82,17 @@ namespace oxygine
|
|
|
updateDragBounds();
|
|
|
}
|
|
|
|
|
|
+ void SlidingActor::setLocked(bool locked)
|
|
|
+ {
|
|
|
+ _drag.setDragEnabled(!locked);
|
|
|
+ }
|
|
|
+
|
|
|
void SlidingActor::updateDragBounds()
|
|
|
{
|
|
|
if (!_content)
|
|
|
return;
|
|
|
- float w = _content->getWidth() - _clip->getWidth();
|
|
|
- float h = _content->getHeight() - _clip->getHeight();
|
|
|
+ float w = std::max(0.0f, _content->getWidth() - _clip->getWidth());
|
|
|
+ float h = std::max(0.0f, _content->getHeight() - _clip->getHeight());
|
|
|
RectF bounds(-w, -h, w, h);
|
|
|
|
|
|
_drag.setDragBounds(bounds);
|
|
|
@@ -103,124 +112,187 @@ namespace oxygine
|
|
|
return d;
|
|
|
}
|
|
|
|
|
|
+ const timeMS fdt = 1000/60;
|
|
|
+ //const float fdt = 20;
|
|
|
+
|
|
|
+ //int lastPosStep = 20;
|
|
|
void SlidingActor::doUpdate(const UpdateState &us)
|
|
|
{
|
|
|
if (!_content)
|
|
|
return;
|
|
|
|
|
|
- float dt = us.dt/1000.0f;
|
|
|
- Vector2 contentPos = _content->getPosition();
|
|
|
-
|
|
|
- if (_holded && (getTimeMS() > _downTime + 100))
|
|
|
+ //static float ml = 0;
|
|
|
+ //ml = max(_speed.length(), ml);
|
|
|
+ //log::messageln("sp: %.2f", ml);
|
|
|
+
|
|
|
+ int ct = getTimeMS();
|
|
|
+ if (_lastIterTime + NUM * fdt < ct)
|
|
|
+ _lastIterTime = ct;
|
|
|
+
|
|
|
+ if (_drag.isDragging())
|
|
|
{
|
|
|
- Vector2 dist = contentPos - _prevPos;
|
|
|
- if (dist.sqlength() < 1)
|
|
|
- _speed = Vector2(0, 0);
|
|
|
+ Vector2 pos = _content->getPosition();
|
|
|
+ //log::messageln("%d) pos %.2f %.2f", _current, pos.x, pos.y);
|
|
|
+ _prev[_current].pos = pos;
|
|
|
+ _prev[_current].tm = ct;
|
|
|
+ _current = (_current + 1) % NUM;
|
|
|
+
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
- if (!_down)
|
|
|
+ if (_sliding)
|
|
|
{
|
|
|
- dt *= 20 * _snapSpeed;
|
|
|
- bool callSnap = false;
|
|
|
-
|
|
|
- if (_snapSize.x >= 0.999 && _movingX)
|
|
|
+ const RectF &bounds = _drag.getDragBounds();
|
|
|
+ while (_lastIterTime + fdt <= ct)
|
|
|
{
|
|
|
- float d = getOffset(_content->getX(), (float)_snapSize.x) * dt;
|
|
|
- _content->setX(_content->getX() - d);
|
|
|
-
|
|
|
- if (d == 0)
|
|
|
+ Vector2 pos = _content->getPosition();
|
|
|
+ Vector2 newpos = pos + _speed * (fdt / 1000.0f);
|
|
|
+ if (newpos.x < bounds.getLeft())
|
|
|
{
|
|
|
- _movingX = false;
|
|
|
- callSnap = true;
|
|
|
+ newpos.x = bounds.getLeft();
|
|
|
+ _speed.x = 0;
|
|
|
+ }else
|
|
|
+ if (newpos.x > bounds.getRight())
|
|
|
+ {
|
|
|
+ newpos.x = bounds.getRight();
|
|
|
+ _speed.x = 0;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
-
|
|
|
- if (_snapSize.y && _movingY)
|
|
|
- {
|
|
|
- float d = getOffset(_content->getY(), (float)_snapSize.y) * dt;
|
|
|
- _content->setY(_content->getY() - d);
|
|
|
- if (d == 0)
|
|
|
+ if (newpos.y < bounds.getTop())
|
|
|
{
|
|
|
- _movingY = false;
|
|
|
- callSnap = true;
|
|
|
+ newpos.y = bounds.getTop();
|
|
|
+ _speed.y = 0;
|
|
|
+ }else
|
|
|
+ if (newpos.y > bounds.getBottom())
|
|
|
+ {
|
|
|
+ newpos.y = bounds.getBottom();
|
|
|
+ _speed.y = 0;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
- if (callSnap && _cbSlideDone)
|
|
|
- _cbSlideDone(0);
|
|
|
- }
|
|
|
-
|
|
|
- if (!_sliding)
|
|
|
- return;
|
|
|
|
|
|
- if (_speed.length() < 0.001)
|
|
|
- {
|
|
|
- _sliding = false;
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
+ _speed *= 0.97f;
|
|
|
+ _content->setPosition(newpos);
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- Vector2 newPos = contentPos + _speed * dt;
|
|
|
- _content->setPosition(newPos);
|
|
|
- //_slideOnTopDH->snapClient2Bounds();
|
|
|
+ _lastIterTime += fdt;
|
|
|
+ }
|
|
|
|
|
|
- if (!(newPos == _content->getPosition()))
|
|
|
- {
|
|
|
- _sliding = false;
|
|
|
- }
|
|
|
|
|
|
- Vector2 s = -_speed;
|
|
|
- s.normalizeTo(200);
|
|
|
- _speed = _speed + s * dt;
|
|
|
+ SlidingEvent sl(SlidingEvent::SLIDING);
|
|
|
+ sl.speed = _speed;
|
|
|
+ dispatchEvent(&sl);
|
|
|
+ _speed = sl.speed;
|
|
|
|
|
|
- if (_speed.dot(s) > 0.9)
|
|
|
- {
|
|
|
- _sliding = false;
|
|
|
+ if (_speed.sqlength() < 8)
|
|
|
+ {
|
|
|
+ _sliding = false;
|
|
|
+ SlidingEvent ev(SlidingEvent::END);
|
|
|
+ dispatchEvent(&ev);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if (!_sliding)
|
|
|
- {
|
|
|
- //slideDone();
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
void SlidingActor::handleEvent(Event *event)
|
|
|
- {
|
|
|
- bool touchEvent = event->type > _et_TouchFirst && event->type < _et_TouchLast;
|
|
|
- if (touchEvent && _holded)
|
|
|
- {
|
|
|
-
|
|
|
- // return;
|
|
|
- }
|
|
|
-
|
|
|
+ {
|
|
|
Actor::handleEvent(event);
|
|
|
}
|
|
|
|
|
|
void SlidingActor::_newEvent(Event *event)
|
|
|
{
|
|
|
TouchEvent *te = safeCast<TouchEvent*>(event);
|
|
|
+ timeMS tm = getTimeMS();
|
|
|
switch(te->type)
|
|
|
{
|
|
|
case TouchEvent::TOUCH_DOWN:
|
|
|
- _holded = event->target;
|
|
|
- _downPos = te->localPosition;
|
|
|
- _down = true;
|
|
|
+ {
|
|
|
+ _current = 0;
|
|
|
+ _lastIterTime = tm;
|
|
|
+
|
|
|
+ _prev[0].pos = _content->getPosition();
|
|
|
+ _prev[0].tm = tm;
|
|
|
+
|
|
|
+ for (int i = 1; i < NUM; ++i)
|
|
|
+ _prev[i].tm = 0;
|
|
|
+
|
|
|
+ _holded = event->target;
|
|
|
+ _downPos = te->localPosition;
|
|
|
+ _downTime = tm;
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case TouchEvent::TOUCH_UP:
|
|
|
{
|
|
|
- _movingY = _movingX = true;
|
|
|
+ if (_drag.getDragEnabled())
|
|
|
+ {
|
|
|
+ _downTime = 0;
|
|
|
+ Vector2 pos = _content->getPosition();
|
|
|
+
|
|
|
+ _holded = 0;
|
|
|
|
|
|
- _holded = 0;
|
|
|
- _down = false;
|
|
|
+ const iter *old = 0;
|
|
|
+ const iter *mid = 0;
|
|
|
+ const iter *last = _prev + _current;
|
|
|
|
|
|
- if (_snapSize.sqlength() < 0.000001 && _cbSlideDone)
|
|
|
- _cbSlideDone(0);
|
|
|
- }
|
|
|
+ for (int i = 1; i < NUM; ++i)
|
|
|
+ {
|
|
|
+ int n = (_current + NUM - i) % NUM;
|
|
|
+ if (_prev[n].tm)
|
|
|
+ last = _prev + n;
|
|
|
+ else
|
|
|
+ break;
|
|
|
+ if (!mid && (last->tm + 50 <= tm))
|
|
|
+ mid = last;
|
|
|
+ if (last->tm + 150 <= tm)
|
|
|
+ {
|
|
|
+ old = last;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!old)
|
|
|
+ old = last;
|
|
|
+ if (!mid)
|
|
|
+ mid = last;
|
|
|
+
|
|
|
+ Vector2 midpos = mid->pos;
|
|
|
+ Vector2 dir = pos - midpos;
|
|
|
+ if (dir.sqlength() < 10 * 10)
|
|
|
+ _speed = Vector2(0,0);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Vector2 dr = pos - old->pos;
|
|
|
+ Vector2 ns = (dr * 1000.0f) / (tm - old->tm);
|
|
|
+
|
|
|
+ /*
|
|
|
+ int d = tm - _downTime;
|
|
|
+ Vector2 dr2 = pos - _downPos;
|
|
|
+ Vector2 ts = dr2 / float(d) * 1000.0f;
|
|
|
+ ts.x = 0;
|
|
|
+
|
|
|
+ log::messageln("fs: %.2f %d ns: %.2f %d", ns.y, int(tm), ts.y, d);
|
|
|
+ */
|
|
|
+ //ns = ts;
|
|
|
+
|
|
|
+
|
|
|
+ if (_speed.dot(ns) < 0)
|
|
|
+ _speed = ns;
|
|
|
+ else
|
|
|
+ _speed += ns;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (!_sliding)
|
|
|
+ {
|
|
|
+ _sliding = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ SlidingEvent sd(SlidingEvent::BEGIN);
|
|
|
+ sd.speed = _speed;
|
|
|
+ dispatchEvent(&sd);
|
|
|
+ _speed = sd.speed;
|
|
|
+
|
|
|
+ _lastIterTime = tm;
|
|
|
+ }
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case TouchEvent::MOVE:
|
|
|
@@ -240,7 +312,7 @@ namespace oxygine
|
|
|
|
|
|
_content->setPressed(te->index);
|
|
|
_holded = 0;
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
break;
|
|
|
}
|