How to get direction from onDragUpdate - flame

How would you get a direction from onDragUpdate?
Vector2 dragDeltaPosition = Vector2(0, 0);
Vector2 dragDirectionVector = Vector2(0, 0);
#override
bool onDragStart(DragStartInfo info) {
dragDeltaPosition = info.eventPosition.game - position;
return false;
}
#override
bool onDragUpdate(DragUpdateInfo info) {
// double x = info.eventPosition.game.x - dragDeltaPosition.x;
// double y = info.eventPosition.game.y - dragDeltaPosition.y;
// double x = info.eventPosition.game.x - info.delta.game.x;
// double y = info.eventPosition.game.y - info.delta.game.y;
dragDirectionVector = Vector2(x, y);
}
Update: this kind of work:
double x = (info.eventPosition.game - position).x - dragDeltaPosition.x;
double y = (info.eventPosition.game - position).y - dragDeltaPosition.y;
Let me know if there is a better way. Thanks

You'll have to look on the delta, which is the vector from the last onDragUpdate to the current one.
#override
bool onDragUpdate(DragUpdateInfo info) {
// You can use info.delta.game.normalized here too if you don't care
// about the length of the directional vector.
dragDirectionVector = info.delta.game;
}

Related

Flutter canvas not rendering as expected

I am trying to render a grid with flutter canvas with Canvas.drawLine method.
Some lines are rendered semi-transparent and some are not even being rendered on the canvas.
class Background extends PositionComponent with HasGameRef<RokokoGame>{
Offset start = Offset.zero;
Offset end = Offset.zero;
// will be different across devices
late final double canvasX;
late final double canvasY;
final int cellSize = GameConfig.cellSize;
Background(this.canvasX, this.canvasY);
#override
Future<void>? onLoad() {
start = Offset(0, 0);
end = Offset(this.canvasX, this.canvasY);
}
#override
void render(Canvas canvas) {
canvas.drawRect(Rect.fromPoints(Offset.zero, end), Styles.white);
_drawVerticalLines(canvas);
_drawHorizontalLines(canvas);
}
void _drawVerticalLines(Canvas c) {
for (double x = start.dx; x <= end.dx; x += cellSize) {
c.drawLine(Offset(x, start.dy), Offset(x, end.dy), Styles.red);
}
}
void _drawHorizontalLines(Canvas c) {
for (double y = start.dy; y <= end.dy; y += cellSize) {
c.drawLine(Offset(start.dx, y), Offset(end.dx, y), Styles.blue);
}
}
}
So, i was able to solve the issue by applying some stroke width in my Styles class.
class Styles {
static Paint white = BasicPalette.white.paint();
static Paint blue = BasicPalette.blue.paint()..strokeWidth = 3;
static Paint red = BasicPalette.red.paint()..strokeWidth = 3;
}

PolygonShape created at different position

I'm trying to create a polygon at the center of the screen with a mouse joint, very simple.
A CircleShape works great. Also the mouse joint behaves strangely and I couldn't find a pattern.
All code is in the main file here. I kept the code to a minimum.
Vector2 vec2Median(List<Vector2> vecs) {
var sum = Vector2(0, 0);
for (final v in vecs) {
sum += v;
}
return sum / vecs.length.toDouble();
}
void main() {
final game = MyGame();
runApp(GameWidget(game: game));
}
class MyGame extends Forge2DGame with MultiTouchDragDetector, HasTappables {
MouseJoint? mouseJoint;
static late BodyComponent grabbedBody;
late Body groundBody;
MyGame() : super(gravity: Vector2(0, -10.0));
#override
Future<void> onLoad() async {
final boundaries = createBoundaries(this); //Adding boundries
boundaries.forEach(add);
groundBody = world.createBody(BodyDef());
final center = screenToWorld(camera.viewport.effectiveSize / 2);
final poly = Polygon([
center + Vector2(0, 0),
center + Vector2(0, 5),
center + Vector2(5, 0),
center + Vector2(5, 5)
], bodyType: BodyType.dynamic);
add(poly);
grabbedBody = poly;
}
#override
bool onDragUpdate(int pointerId, DragUpdateInfo details) {
final mouseJointDef = MouseJointDef()
..maxForce = 3000 * grabbedBody.body.mass * 10 //Not neccerly needed
..dampingRatio = 1
..frequencyHz = 5
..target.setFrom(grabbedBody.body.position)
..collideConnected = false //Maybe set to true
..bodyA = groundBody
..bodyB = grabbedBody.body;
mouseJoint ??= world.createJoint(mouseJointDef) as MouseJoint;
mouseJoint?.setTarget(details.eventPosition.game);
return false;
}
#override
bool onDragEnd(int pointerId, DragEndInfo details) {
if (mouseJoint == null) {
return true;
}
world.destroyJoint(mouseJoint!);
mouseJoint = null;
return false;
}
}
abstract class TappableBodyComponent extends BodyComponent with Tappable {
final Vector2 position;
final BodyType bodyType;
TappableBodyComponent(this.position, {this.bodyType = BodyType.dynamic});
#override
bool onTapDown(_) {
MyGame.grabbedBody = this;
return false;
}
Body tappableBCreateBody(Shape shape) {
final fixtureDef = FixtureDef(shape)
..restitution = 0.8
..density = 1.0
..friction = 0.4;
final bodyDef = BodyDef()
// To be able to determine object in collision
..userData = this
..angularDamping = 0.8
..position = position
..type = bodyType;
return world.createBody(bodyDef)..createFixture(fixtureDef);
}
}
class Polygon extends TappableBodyComponent {
final List<Vector2> vertecies;
Polygon(this.vertecies, {BodyType bodyType = BodyType.dynamic})
: super(vec2Median(vertecies), bodyType: bodyType);
#override
Body createBody() {
final shape = PolygonShape()..set(vertecies);
return tappableBCreateBody(shape);
}
}
tappableBCreateBody encapsulate Tappable and body creation methods, Polygon is the object I'm trying to create, vec2Median returns the center of the polygon (by vertices).
Thank you very much!
I think that you have to remove center from the vertices and only add that as the position of the BodyComponent instead, like you already do in the super call of your Polygon class.

Flutter polyline distance with google_maps_flutter plugin

Hi I am using the google_maps_flutter plug in and have gotten a polyline to show up on my map. What I would like to do is calculate the distance of the polyline length. My code is linked here and there is a snippet below. I do not want to use the Directions API. How do I calculate polyline distance and print to console? Thanks for reading.
class ShowMap extends StatefulWidget {
final double lat;
final double lng;
ShowMap({Key key, this.lat, this.lng}) : super(key: key);
#override
_ShowMapState createState() => _ShowMapState();
}
class _ShowMapState extends State<ShowMap> {
// Field
double lat, lng;
BitmapDescriptor policeIcon;
List<Marker> list = List();
List<String> listDocuments = List();
final Set<Polyline> _polyline = {};
GoogleMapController controller;
List<LatLng> latlngSegment1 = List();
List<LatLng> latlngSegment2 = List();
static LatLng _lat1 = LatLng(45.19, -121.59);
static LatLng _lat2 = LatLng(45.30, -122.20);
static LatLng _lat3 = LatLng(45.11, -122.61);
static LatLng _lat4 = LatLng(45.42, -122.62);
static LatLng _lat5 = LatLng(45.34, -122.32);
static LatLng _lat6 = LatLng(45.21, -122.2);
bool _myLocationButtonEnabled = true;
bool _myLocationEnabled = true;
// Method
#override
void initState() {
super.initState();
// findLatLng();
readDataFromFirebase();
setState(() {
lat = widget.lat;
lng = widget.lng;
latlngSegment1.add(_lat1);
latlngSegment1.add(_lat2);
latlngSegment1.add(_lat3);
latlngSegment1.add(_lat4);
//line segment 2
latlngSegment2.add(_lat4);
latlngSegment2.add(_lat5);
latlngSegment2.add(_lat6);
latlngSegment2.add(_lat1);
});
}
Let us say that you want to calculate the distance of polyline created by the points in latlngSegment1.
For that you need to calculate the distance between each consecutive LatLng points in latlngSegment1.
I would do it with something like this.
double calculateDistane(List<LatLng> polyline) {
double totalDistance = 0;
for (int i = 0; i < polyline.length; i++) {
if (i < polyline.length - 1) { // skip the last index
totalDistance += getStraightLineDistance(
polyline[i + 1].latitude,
polyline[i + 1].longitude,
polyline[i].latitude,
polyline[i].longitude);
}
}
return totalDistance;
}
double getStraightLineDistance(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2 - lat1);
var dLon = deg2rad(lon2 - lon1);
var a = math.sin(dLat / 2) * math.sin(dLat / 2) +
math.cos(deg2rad(lat1)) *
math.cos(deg2rad(lat2)) *
math.sin(dLon / 2) *
math.sin(dLon / 2);
var c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
var d = R * c; // Distance in km
return d * 1000; //in m
}
dynamic deg2rad(deg) {
return deg * (math.pi / 180);
}
Note: The getStraightLineDistance() function gives the straight line distance between two latlng points, which might not be the way someone reaches from point A to B.

Unity3D : How to hide touchscreen keyboard when i select inputfile and inputfield still focus

I've had this problem for a long time. I want to hide touchscreen keyboard when I select inputfile and inputfield still focus. I don't need touchscreen keyboard but I need carretpostion and focus on inputfield(application like calculator).
Thank you everyone for the answer. I solved the problem by custom inputfield. I disable touchscreen keyboard and get carretpostion by OnPointerUp .
code :
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class InputFieldWithOutKeyboard : InputField
{
protected override void Start()
{
keyboardType = (TouchScreenKeyboardType)(-1);
}
public override void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData)
{
base.OnPointerDown(eventData);
}
public override void OnPointerUp(PointerEventData eventData)
{
Vector2 mPos;
RectTransformUtility.ScreenPointToLocalPointInRectangle(textComponent.rectTransform, eventData.position, eventData.pressEventCamera, out mPos);
Vector2 cPos = GetLocalCaretPosition();
int pos = GetCharacterIndexFromPosition(mPos);
Debug.Log("pos = " + pos);
GameObject.FindWithTag("canvas").GetComponent<Calculator>().carretPostion = pos;
GameObject.FindWithTag("canvas").GetComponent<Calculator>().carretVector = mPos;
base.OnPointerUp(eventData);
}
public Vector2 GetLocalCaretPosition()
{
// if (isFocused)
// {
TextGenerator gen = m_TextComponent.cachedTextGenerator;
UICharInfo charInfo = gen.characters[caretPosition];
float x = (charInfo.cursorPos.x + charInfo.charWidth) / m_TextComponent.pixelsPerUnit;
float y = (charInfo.cursorPos.y) / m_TextComponent.pixelsPerUnit;
Debug.Log("x=" + x + "y=" + y);
return new Vector2(x, y);
// }
// else
// return new Vector2(0f, 0f);
}
private int GetCharacterIndexFromPosition(Vector2 pos)
{
TextGenerator gen = m_TextComponent.cachedTextGenerator;
if (gen.lineCount == 0)
return 0;
int line = GetUnclampedCharacterLineFromPosition(pos, gen);
if (line < 0)
return 0;
if (line >= gen.lineCount)
return gen.characterCountVisible;
int startCharIndex = gen.lines[line].startCharIdx;
int endCharIndex = GetLineEndPosition(gen, line);
for (int i = startCharIndex; i < endCharIndex; i++)
{
if (i >= gen.characterCountVisible)
break;
UICharInfo charInfo = gen.characters[i];
Vector2 charPos = charInfo.cursorPos / m_TextComponent.pixelsPerUnit;
float distToCharStart = pos.x - charPos.x;
float distToCharEnd = charPos.x + (charInfo.charWidth / m_TextComponent.pixelsPerUnit) - pos.x;
if (distToCharStart < distToCharEnd)
return i;
}
return endCharIndex;
}
private int GetUnclampedCharacterLineFromPosition(Vector2 pos, TextGenerator generator)
{
// transform y to local scale
float y = pos.y * m_TextComponent.pixelsPerUnit;
float lastBottomY = 0.0f;
for (int i = 0; i < generator.lineCount; ++i)
{
float topY = generator.lines[i].topY;
float bottomY = topY - generator.lines[i].height;
// pos is somewhere in the leading above this line
if (y > topY)
{
// determine which line we're closer to
float leading = topY - lastBottomY;
if (y > topY - 0.5f * leading)
return i - 1;
else
return i;
}
if (y > bottomY)
return i;
lastBottomY = bottomY;
}
// Position is after last line.
return generator.lineCount;
}
private static int GetLineEndPosition(TextGenerator gen, int line)
{
line = Mathf.Max(line, 0);
if (line + 1 < gen.lines.Count)
return gen.lines[line + 1].startCharIdx - 1;
return gen.characterCountVisible;
}
}
You can use something like this
TouchScreenKeyboard keyboard;
void Update()
{
if (keyboard != null)
{
if (Input.deviceOrientation == DeviceOrientation.FaceDown)
keyboard.active = false;
if (Input.deviceOrientation == DeviceOrientation.FaceUp)
keyboard.active = true;
}
}
it will retrieve the TouchScreenKeyboard and after that, you can active or deactive it as you want.

Sprite long click in andengine

I am using an animated sprite and want to perform some action on its long click events, but it is not working. Please help guys...
AnimatedSprite playBtn = new AnimatedSprite(MainActivity.CAMERA_WIDTH/2, MainActivity.CAMERA_HEIGHT - 100, activity.tTextureRegion3, activity.getVertexBufferObjectManager())
{
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y)
{
if (pSceneTouchEvent.isActionDown())
{
scoreInc = scoreInc + 10;
score.setText("Score: " + scoreInc);
width = width + 5;
progressRectangle();
return true;
}
return false;
};
};
this.registerTouchArea(playBtn);
this.setTouchAreaBindingOnActionDownEnabled(true);
I have used this
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float X, float Y)
{
switch(pSceneTouchEvent.getAction()) {
case TouchEvent.ACTION_MOVE:{ //Done my Work}
and it worked