I successfully made an arrow to move along a pre-defined path. Now i want to place some randomly moving object in the path and want to detect weather the arrow hits the object or not. The following is the code which i'm using for animation.
public void doAnimation(){
Matrix mxTransform=new Matrix();
PathMeasure pm=new PathMeasure(path,false);
float fSegmentLen = (float)((pm.getLength())/50);
if(iCurStep<=50){
pm.getMatrix(fSegmentLen * iCurStep, mxTransform,
PathMeasure.POSITION_MATRIX_FLAG + PathMeasure.TANGENT_MATRIX_FLAG);
canvas.drawBitmap(bt, mxTransform, null);
iCurStep++;
invalidate();
}
else{
iCurStep=0;
animate=0;
canvas.drawPoint((float)range-10,0f,forPoint);
}
}
The variable iCurStep is declared globally and the above function will be called inside the onDraw() method. I'm a beginner to android. So its very difficult for me to code. So I'm kindly requesting you to help me.
You can do this way as get the current position of the Arrow and moving objects.At any point of time, check its x-ordinates of Arrow intersects with x-coordinates of moving object.And similarly check for its y co-ordinates as well.
Hope this will help you.
Related
I have an Imageview with different number of touch points on them. It basically an app which is detecting the swipe between 2 touch points and not allowing the user to swipe any other point or in or out of other direction. It should constrict user to just swipe between two touch points.
Just take a look at following picture:
Now the user should start swiping from point 1 to point 2. if the swipe is not started from starting point 1, it should not color the path between point 1 and point 2.
But if the user successfully swipe between the point 1 and point 2 now swipe between point 2 to 3 should be enabled. Thus user should go through Point 1 to 2, Point 2 to 3 , Point 3 to 4 , point 4 to point 5 to complete round 1.
Please tell me how to achieve this functionality . I know about gestures, gesture overlay etc but none of them fits to my condition as they uses general touch events and gesture directions.
Please suggest me the way to achieve this and keep in mind I want to make this app to be able to run on all type of devices , so I can simply give the hard coded x,y values.
Edit : on Demand
I am posting the link of the app on play store who has same functionality , But I do not know How they are achieving this functionality .
https://play.google.com/store/apps/details?id=al.trigonom.writeletters
If each touch point can be created as individual views(e.g. ImageView), then you can create an inViewInBounds() function.
I used code from here to create code where I needed to detect finger press movement over multiple imageViews:
Rect outRect = new Rect();
int[] location = new int[2];
//Determine if a touch movement is currently over a given view.
private boolean inViewInBounds(View view, int x, int y){
view.getDrawingRect(outRect);
view.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect.contains(x, y);
}
To use this function, on a parent view to all those child touch points, set the Click and Touch Listeners:
//This might look redundant but is actually required: "The empty OnClickListener is required to keep OnTouchListener active until ACTION_UP"
parentView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {}
});
//All the work gets done in this function:
parentView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int)event.getRawX();
int y = (int)event.getRawY();
// ** myTouchPoint might be an array that you loop through here...
if ( inViewInBounds(myTouchPoint, x, y) ) doLogic(myTouchPoint);
return false;
}
});
The code above only shows detecting when one of your views are 'touched'.
if none are 'touched' but a view is 'active' (e.g. When a touch is detected, set a variable like: viewLastTouched = myTouchPoint) then you would call something like drawingLine(viewLastTouched, x, y) function - for whatever it needed to do to draw the line and/or detect boundaries etc.
They are not using android native java code to build this app.
The app is running with this code
import Runtime.MMFRuntime;
public class Main extends MMFRuntime {
}
This in turn is from https://github.com/ClickteamLLC/android/blob/master/docs/index.md
This is used to package apps / games written using - http://www.clickteam.com/clickteam-fusion-2-5
Good evening, quick question.
Im developing a top-down 2D platformer game in Unity3D. Here is a picture of the game.
I have pretty much everything worked out on a desktop, but when attempting to set up the controls for mobile, I can't seem to get it to work the way it should. All I need is to get the player to move in the direction of wherever the user touches the screen. With the current code im using, the player just rotates in 4 directions, up, down, left and right. He also moves a little, but never goes far from his spawn point.
Please take a look at my revised code:
public Camera camera;
public float movespeed = 0;
// Use this for initialization
void Start () {
movespeed = 2.75F;
}
// Update is called once per frame
void Update () {
if (Input.touchCount > 0) {
// The screen has been touched so store the touch
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) {
// If the finger is on the screen, move the object smoothly to the touch position
Vector3 touchPosition = camera.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, -13));
Quaternion rot = Quaternion.LookRotation(transform.position - touchPosition, Vector3.back);
transform.rotation = rot;
transform.eulerAngles = new Vector3 (0, 0, transform.eulerAngles.z);
rigidbody2D.angularVelocity = 0;
//float input = Input.GetAxis ("Vertical");
transform.position = Vector3.Lerp(transform.position, touchPosition, Time.deltaTime);
}
}
}
}
Any ideas on how I can get my player to move to the touched are of the screen? Any help would be much appreciated. Thanks in advance.
If I have understood correctly, you want your player game object to move towards the point on the screen that is being touched. I think it's probably best to describe the behavior of your code so that you can hopefully better understand what might be happening.
From the code posted, I can see one possible issue. Look again at this line:
Quaternion rot = Quaternion.LookRotation(transform.position - touchPosition, Vector3.back);
Here, you are asking Unity to calculate the unit quaternion that represents a rotation from the direction of Vector3.forward to the direction from of the player game object from the touch position. This probably isn't what you want. From the description of the problem, you want the game object to rotate to face the point on the screen being touched (rather than the opposite direction). You can either change the order of the subtraction operands or, preferably, use instead the Transform.LookAt method.
After this, you update the transform's rotation:
transform.rotation = rot;
That's fine, but note that you wouldn't need to do this when using Transform.LookAt.
You then set the transform's rotation again using in this line:
transform.eulerAngles = new Vector3 (0, 0, transform.eulerAngles.z);
I'm not entirely sure why you are doing this. If you only want one axis of rotation, you can use, for example:
transform.LookAt(new Vector3(touchPosition.x, touchPosition.y, transform.position.z))
This should rotate the player's transform around the z-axis to look in the direction of the point being touched.
Finally, you linearly interpolate the transform's position from its current position to the point being touched:
transform.position = Vector3.Lerp(transform.position, touchPosition, Time.deltaTime);
This isn't necessary. Instead, you should just move the player's transform forward. The player should be looking in the direction of the touched screen point. Hence, translating the player forward will move the player towards said screen point:
transform.position += transform.forward * speed * Time.deltaTime;
When the player is very close to the touched screen point it will overshoot and immediately rotate to look in the opposite direction. This will occur repeatedly. You should include some distance that specifies when the player is assumed to have reached the target point.
I make online map and try to add touchable paths/tracks (I change their color when user touches them). On one map I have 6-7 PathOverlays with added onDown event handling:
private class PathOverlayExtended extends PathOverlay
{
public PathOverlayExtended(int color, Context ctx, long trackId, HistoryDetailFragment currentFragment) {
super(color, ctx);
trackIndex = trackId;
fragment = currentFragment;
}
private long trackIndex;
private HistoryDetailFragment fragment;
#Override
public boolean onDown(final MotionEvent event, final MapView mapView) {
fragment.onRoadClicked(trackIndex);
return super.onDown(event,mapView);
}
}
Then I touch one path on screen, it catches event and proceeds through every path. Important: it always starts from the same path (the one added to the Olerlays at the end).
When I replace "return super.onDown(event,mapView)" with "return true", only the last path catches the event and this is not the one I touch (but the one added to the Overlays at the end).
How to check/distinct which Path I touched?
I implemented something similar for detecting a touch on filled Polygons.
It's using Android Regions.
The principle is to "put" the Path that has been drawn in a "Region":
region.setPath(mPath, new Region((int) bounds.left, (int) bounds.top, (int) bounds.right, (int) bounds.bottom));
Then you check if the touched point is in this region with:
region.contains(point.x, point.y);
No idea how this "contains" method is implemented, but it works, and seems quite efficient. Magic. I imagine it should also work for polylines.
You can look at the full code here:
http://code.google.com/p/osmbonuspack/source/browse/trunk/OSMBonusPack/src/org/osmdroid/bonuspack/overlays/Polygon.java
I couldn't find fine solution to my problem, so in the end, I decided to do it in the following way.
Firstly, I made my own PathOverlayExtended class which iherits PathOverlay. Then I added some variables - bounds of the path region (maximum and minimum latitude and longitude).
Secondly, I checkced if tap coordinates fits in theese bounds. That way, I get only those paths which can be understanded as related to my tap.
In the end, I checked distances from tap coordinates to every line segment and chose the smallest one. That's it.
I used viesturz's answer, which helped me very much:
https://code.google.com/p/osmdroid/issues/detail?id=36
Thanks for all answers!
I am attempting to translate an object depending on the touch position of the user.
The problem with it is, when I test it out, the object disappears as soon as I drag my finger on my phone screen. I am not entirely sure what's going on with it?
If somebody can guide me that would be great :)
Thanks
This is the Code:
#pragma strict
function Update () {
for (var touch : Touch in Input.touches)
{
if (touch.phase == TouchPhase.Moved) {
transform.Translate(0, touch.position.y, 0);
}
}
}
The problem is that you're moving the object by touch.position.y. This isn't a point inworld, it's a point on the touch screen. What you'll want to do is probably Camera.main.ScreenToWorldPoint(touch.position).y which will give you the position inworld for wherever you've touched.
Of course, Translate takes a vector indicating distance, not final destination, so simply sticking the above in it still won't work as you're intending.
Instead maybe try this:
Vector3 EndPos = Camera.main.ScreenToWorldPoint(touch.position);
float speed = 1f;
transform.position = Vector3.Lerp(transform.position, EndPos, speed * Time.deltaTime);
which should move the object towards your finger while at the same time keeping its movements smooth looking.
You'll want to ask this question at Unity's dedicated Questions/Answers site: http://answers.unity3d.com/index.html
There are very few people that come to stackoverflow for Unity specific question, unless they relate to Android/iOS specific features.
As for the cause of your problem, touch.position.y is define in screen space (pixels) where as transform.Translate is expecting world units (meters). You can convert between the two using the Camera.ScreenToWorldPoint() method, then creating a vector out of the camera position and screen world point. With this vector you can then either intersect some geometry in the scene or simply use it as a point in front of the camera.
http://docs.unity3d.com/Documentation/ScriptReference/Camera.ScreenToWorldPoint.html
How do I get the current translate position from a Canvas? I am trying to draw stuff where my coordinates are a mix of relative (to each other) and absolute (to canvas).
Lets say I want to do
canvas.translate(x1, y1);
canvas.drawSomething(0, 0); // will show up at (x1, y1), all good
// now i want to draw a point at x2,y2
canvas.translate(x2, y2);
canvas.drawSomething(0, 0); // will show up at (x1+x2, y1+y2)
// i could do
canvas.drawSomething(-x1, -y1);
// but i don't always know those coords
This works but is dirty:
private static Point getCurrentTranslate(Canvas canvas) {
float [] pos = new float [2];
canvas.getMatrix().mapPoints(pos);
return new Point((int)pos[0], (int)pos[1]);
}
...
Point p = getCurrentTranslate(canvas);
canvas.drawSomething(-p.x, -p.y);
The canvas has a getMatrix method, it has a setTranslate but no getTranslate. I don't want to use canvas.save() and canvas.restore() because the way I'm drawing things it's a little tricky (and probably messy ...)
Is there a cleaner way to get these current coordinates?
You need to reset the transformation matrix first. I'm not an android developer, looking at the android canvas docs, there is no reset matrix, but there is a setMatrix(android.graphics.Matrix). It says if the given matrix is null it will set the current matrix to the identity matrix, which is what you want. So I think you can reset your position (and scale and skew) with:
canvas.setMatrix(null);
It would also be possible to get the current translation through getMatrix. There is a mapVectors() method you could use for matrices to see where the point [0,0] would be mapped to, this would be your translation. But in your case I think resetting the matrix is best.