Get position of a child according to the screen, not according to the parent, in AndEngine - entity

I am working on AndEngine GLES2
I have an entity in the scene which have almost 24 children (Sprites) attached to it in different positions.I have made a function which moves the entity from one position to another.Whenever i try to get position of children it returns me the same position as it was in the beginning because it returns the position according to the parent(Entity).As you can see in the example below.
Entity myEntity = new Entity();
for(int i = 0; i < arraylist.size();i++)
{
myEntity.attachChild(arraylist.get(i));
}
Log.i("MyLog","Y Position of one child "+arraylist.get(4).getY());//Assume it 231
Log.i("MyLog","Y Position of Entity "+myEntity.getY());//Assume it 0
myEntity.setPosition(0,200);
Log.i("MyLog","Y Position of one child "+arraylist.get(4).getY());//it will return 231
It will return the same position as it was in the beginning. I want to get the position of this child according to the screen. I want it to be 431 now as it has moved 200 pixels down on the screen.

To do this you should use the convertLocalToSceneCoordinates(final float pX, final float pY) function for example:
myEntity.convertLocalToSceneCoordinates(arrayList.get(4).getX(),arrayList.get(4).getY()) which will return a float array that has a x and y position according to the scene the entity is attached to.

Related

Cards Stack swipe - add card in the back after swiping (removing) top card

I use this library: https://github.com/yuyakaido/CardStackView. It's like Tinder-like swiping cards left-right and it's based on RecyclerView.
This library has the following settings: cardStackLayoutManager.setVisibleCount(3) - that means that the number of visible cards at any time is MAXed to 3 cards.
Suppose I have an array with 5 elements, and then I load everything to my adapter.
On the screen, I'll see 3 cards - holding the first three elements from the array.
The Problem is that when I swipe the top card, (deleting it from the stack), then I have two cards left, but I'm expecting a new card appear at the bottom with the 4th element from the array, but it never happens unless I remove the first element from an array and then call: notifyDataSetChanged() which reloads the entire stack, adapter (and it comes up with blinking, flashing, etc.)
All I need is to load the NEXT element from the array in the new card at the bottom.
I figured this out. First, in Adapter, since I'm dealing with only 3 preloaded cards in stock at any time, I do this:
int countCards;
SwipeAdapter(ArrayList<String> userIDArr, Context ctx)
{
this.userIDArr2 = userIDArr;
.......
if (userIDArr2.size() >= 3) {
countCards = 3;
} else {
countCards = userIDArr2.size();
}
.......
this.ctx = ctx;
}
#Override
public int getItemCount() {
return countCards;
}
... that's provided that the total array userIDArr.size() might be more than 3 but getItemCount can only be MAX 3 or less (if the array size is less than 3).
Then, in an Activity that deals with an adapter, when I swipe the card whichever way, I remove index 0 (top card) from the array and then call notifyItemRemoved:
userIDArr.remove(0);
if (userIDArr.size() > 2) {
swipeAdapter.notifyItemRemoved(0);
}
NOTICE that notifyItemRemoved is only called when the array still has 3 or more items left.
Works perfectly smooth.

How to convert a tile layer into an object for depth sorting relative to the player?

I'm essentially making a Stardew Valley clone, using tile sets and tile layers to draw the background of each room. I have a 'Parent Depth Object'. Each child of this object (NPC's, crops) has its depth sorted relative to the player object to appear in front or behind the player. This works fine.
I have 'ground items' (barrels, rocks etc.) drawn to a single tile layer in each room. I want the player to be able to appear behind or in front of these too. Is there any way I can make this whole layer act as if it was a single object so I can add it to my Parent Depth Object, or do I have to create a separate object for each ground item?
My 'depthSorter' object creates a Data Structure, adds each instance to it and loops through, sorting the depth of each relative to the player.
/// #description DSGridGetInst/Add/Sort/Loop
// get number of instances of parentDepthObject, save in variable instNum / resize grid
var instNum = instance_number(parentDepthObject);
var dGrid = dsDepthGrid;
ds_grid_resize(dGrid, 2, instNum);
// add instances to grid / have all of them run this code
var yy = 0; with(parentDepthObject)
{
dGrid[# 0, yy] = id;
dGrid[# 1, yy] = y;
yy += 1;
}
// sort the grid in ascending order (lowest y value at top)
ds_grid_sort(dGrid, 1, true);
// loop through the grid and draw all the instances
var inst; yy = 0; repeat(instNum)
{
// pull out an ID
inst = dGrid[# 0, yy];
// draw yourself
with(inst)
{
event_perform(ev_draw, 0);
}
yy += 1;
}
I'd personally recommend to use these items you want to get behind as objects, rather than tiles. Tiles can't contain a script themselves. So that gets more tricky to use them the way you want.
However, you don't need to create a new object for each 'ground item'.
Instead, you can make an object called 'ground item', and change the sprite / related code to that object.
For example, when selecting an object in a room, you can use 'Creation Code' to add code that's unique for that object. That way, you can change the sprites of the ground item to it's unique id.
Another example is to make an object that's a child of the parent 'ground object'. So each object has it's own sprite, but reuses the object from 'ground object'

how to verify view is scrollable in mobile application (Automation)

Anyone knows automation script to verify a view (homePage/Browse) is scrollable or not. i can use ScrollTo(id) which is at the bottom of the page. But it is not a correct method to do, as test case passes if that element present in 1st page
Basically You cannot. You could try to cast the view to ScrollView class however any custom view can implement scroll.
Get the coordinates of any particular element like button etc unique element.
Swipe using driver.swipe() to 100 or more pixels.
And get the coordinates of that element again and check whether x or y coordinates changed or not.
This will let you know whether it is a single page application or more to scroll.
Basically there is no API to check the view is scrollable or not but if you still require this then you can do work around
#Test
public void testVerticalScroll()
{
//Try to Scroll till the 15th row
driver.scrollTo("List item:15");
//Assert that the 1st row is not visible.
Assert.assertFalse( driver.findElement(By.name("List item:01")).isDiaplyes())
//Assert that the 15th row is not visible.
Assert.assertTrue( driver.findElement(By.name("List item:15")).isDiaplyes())
}
You can consider the last visible element as "YourText" But this is
just a workaround that needs to be customized for each page.
Here we are using swipe until we find the element. In this case, the last visible element indicates the margin of the page.
Dimension dimensions = driver.manage().window().getSize();
Double screenHeightStart = dimensions.getHeight() * 0.5;
int scrollStart = screenHeightStart.intValue();
System.out.println("s="+scrollStart);
Double screenHeightEnd = dimensions.getHeight() * 0.2;
int scrollEnd = screenHeightEnd.intValue();
for (int i = 0; i < dimensions.getHeight(); i++) {
driver.swipe(0,scrollStart,0,scrollEnd,2000);
if (driver.findElement(By.name("YourText")).size()>0)
exit;
}
driver.findElement(By.name("YourText")).click();
There is a way to check it. You have to find a layer that you will target for example:
MobileElement scrollableLayer= driver.findElementById("elementID");
Then you will extract attribute value "scrollable" of that element like this:
String scrollableState = scrollableLayer.getAttribute("scrollable");
And then you can check if the String value is true or false.
if (scrollableState.equals("true")){System.out.println("it's scrolable"); }else{System.out.println("it's not scrolable");}
Or you can do whatever you want with it :)

constrain proportions while resizing images

I implemented drag and drop of images and now i want to constrain proportions of images while resizing.
/**
* Variable: constrainChildrenOnResize
*
* Specifies if children should be constrained according to the <constrainChildren>
* switch if cells are resized (including via <foldCells>). Default is false for
* backwards compatiblity.
*/
mxGraph.prototype.constrainChildrenOnResize = false;
i set this to true but its not working :s
What API/property i need for this functionality..
constrainChildrenOnResize is responsible for positioning and size of the children of resized cell. It means that children should keep their position relatively to the parent-cell.
In your case I would suggest to extend mxVertexHandler using union method. In this example you can see how to implement min-width/min-height restrictions. Using this example you are able to write your own rules for constrain.
Here is my simple solution:
var vertexHandlerUnion = mxVertexHandler.prototype.union;
mxVertexHandler.prototype.union = function (bounds) {
var result = vertexHandlerUnion.apply(this, arguments);
var coff = bounds.width / bounds.height
result.width = result.height * coff;
return result;
};
So this function is called every time you move mouse during dragging the resizer.
bounds - object, always same and represent old geometry of the cell (before resizing)
result - object, represents new values, which are going to be applied. Between this line ad return statement you can place any code you need to modify result.
In my simple example I just get the initial relation between width and height of the cell (coff) and then set new width by multiplying coff and new height. It will work if you drag corner or top/bottom. In real project this logic should be slightly extended, or you should make visible only corner handlers.
By the way, this code will work for all resizable cells on your graph. If you want to apply it only to images or some other kind of cells - you can put condition and check the cell type before recalculating. You can get current cell or its state via this.state.cell or this.state inside of union function.
For example only for vertecies:
... ...
var result = vertexHandlerUnion.apply(this, arguments);
if (this.state.cell.isVertex()) {
//calculations here
}
return result;

flash cc createjs hittest works without hit

the rect should be alpha=0.1 once the circle touches the rect . but if statement not working . it becomes 0.1 opacity without hitting
/* js
var circle = new lib.mycircle();
stage.addChild(circle);
var rect = new lib.myrect();
stage.addChild(rect);
rect.x=200;
rect.y=300;
circle.addEventListener('mousedown', downF);
function downF(e) {
stage.addEventListener('stagemousemove', moveF);
stage.addEventListener('stagemouseup', upF);
};
function upF(e) {
stage.removeAllEventListeners();
}
function moveF(e) {
circle.x = stage.mouseX;
circle.y = stage.mouseY;
}
if(circle.hitTest(rect))
{
rect.alpha = 0.1;
}
stage.update();
*/
The way you have used hitTest is incorrect. The hitTest method does not check object to object. It takes an x and y coordinate, and determines if that point in its own coordinate system has a filled pixel.
I modified your example to make it more correct, though it doesn't actually do what you are expecting:
circle.addEventListener('pressmove', moveF);
function moveF(e) {
circle.x = stage.mouseX;
circle.y = stage.mouseY;
if (rect.hitTest(circle.x, circle.y)) {
rect.alpha = 0.1;
} else {
rect.alpha = 1;
}
stage.update();
}
Key points:
Reintroduced the pressmove. It works fine.
Moved the circle update above the hitTest check. Otherwise you are checking where it was last time
Moved the stage update to last. It should be the last thing you update. Note however that you can remove it completely, because you have a Ticker listener on the stage in your HTML file, which constantly updates the stage.
Added the else statement to turn the alpha back to 1 if the hitTest fails.
Then, the most important point is that I changed the hitTest to be on the rectangle instead. This essentially says: "Is there a filled pixel at the supplied x and y position inside the rectangle?" Since the rectangle bounds are -49.4, -37.9, 99, 76, this will be true when the circle's coordinates are within those ranges - which is just when it is at the top left of the canvas. If you replace your code with mine, you can see this behaviour.
So, to get it working more like you want, you can do a few things.
Transform your coordinates. Use localToGlobal, or just cheat and use localToLocal. This takes [0,0] in the circle, and converts that coordinate to the rectangle's coordinate space.
Example:
var p = rect.localToLocal(0, 0, circle);
if (rect.hitTest(p.x, p.y)) {
rect.alpha = 0.1;
} else {
rect.alpha = 1;
}
Don't use hitTest. Use getObjectsUnderPoint, pass the circle's x/y coordinate, and check if the rectangle is in the returned list.
Hope that helps. As I mentioned in a comment above, you can not do full shape collision, just point collision (a single point on an object).