Obtaining drag rectangle in isValidDropTarget - mxgraph

In mxgraph,a cell must be dragged onto another cell (its parent), but the location should be restricted. In particular, I want to avoid that cells dragged into the parent overlap each other.
I have overriden isValidDropTarget() and wrote my own version.
Here I want to check for the droptarget, if the area that is to be occupied by the cell to be dropped is free/not occupied by some other cell.
It is possible to find the coordinates and height/width of the cells in the parent, but I need to have to coordinates of the cell to be included. Specifically, I want to have the coordinates of the dragging rectangle

In isValidDropTarget() function you should have access to event from which you can get x,y poistion, and convert it to position on diagram, there is even helper for that:
convertPoint():
Converts the specified point (x, y) using the offset of the specified container and returns a new mxPoint with the result.
var pt = mxUtils.convertPoint(graph.container,
mxEvent.getClientX(evt), mxEvent.getClientY(evt));

Related

Flash Games: Make a world continuous, circular

I am writing now a flash game and I run into a an issue. I have a map for the game which is defined as a 2-D array, where each element represents a component of the map. The player is always in the center of the map.
The problem is when the player reaches one end of the map. Now it is empty space. I want that the player instead of seeing the empty space, to see another end of the map and in this way, the map will loo like it goes around.
So for example if the player goes to right he will eventually start seeing the the left side of the map and the world will look continuous.
Does anyone knows how to implement this functionality?
You could make the array 2 times and put the first one behind the second one again and than the second one behind the first etc etc..
It's done here with 2 pictures, just use the arrays instead:
//The speed of the scroll movement.
var scrollSpeed:uint = 2;
//This adds two instances of the movie clip onto the stage.
var s1:ScrollBg = new ScrollBg();
var s2:ScrollBg = new ScrollBg();
addChild(s1);
addChild(s2);
//This positions the second movieclip next to the first one.
s1.x = 0;
s2.x = s1.width;
//Adds an event listener to the stage.
stage.addEventListener(Event.ENTER_FRAME, moveScroll);
//This function moves both the images to left. If the first and second
//images goes pass the left stage boundary then it gets moved to
//the other side of the stage.
function moveScroll(e:Event):void{
s1.x -= scrollSpeed;
s2.x -= scrollSpeed;
if(s1.x < -s1.width){
s1.x = s1.width;
}else if(s2.x < -s2.width){
s2.x = s2.width;
}
}
You simply check if your player is about to get off the "right" or "left" edge of the map, and position him at the other edge. To draw a circular map, you can use the following technique: if you are about to draw a column of a number that exceeds the map's width, decrease that number by width and draw the column at resultant index; and if you are about to draw a column at index below zero, add width and draw the column at resultant index. If you are in troubles of making a hitcheck at continuous map's borders, you can employ the same trick to find neighbors. (The "circular array" is a pretty basic algorithmic problem, and is resolved in many ways already)
You have a few options here. You can do the pac-man style of just making your character pop up on the other side of the screen, but that would require you to abandon the cool bit of the character being in the middle at all times.
On to the real suggestions:
If you're not implementing your array as one solid object (i.e. making it draw individual collumns/rows at a time) then this is a no-brainer. Just have a function that returns the index of the next collumn/row, within certain bounds. Like, if your array is 40 elements wide, when it tries to draw element 41, subtract the size of the array, and make it draw element 1 instead.
If your array is one solid object (like if you drew it onto a stage object and are just manipulating that) and it's not very big, you could probably get away with drawing a total of four of them, and just having a new one cover up any whitespace that's about to appear. Like, as you approach the right edge of the first array, the second array moves to the right of it for a lawless transition.
If your array is a solid object and is very big, perhaps you could make eight buffer objects (one per edge and one per corner) that hold approximately half a screen's worth of the array. That way as you approach the right edge, you see the left edge, but then when you cross into the buffer zone, you could teleport the player to the corresponding position on the left of the array, which has the buffer for the right size. To the player, nothing has changed, but now they're on the other side of the world.

Numbering the Panels in a canvas according to its position from left to right

i am having a canvas which contains panels that are created dynamicaly.That panels are draggable.So that an user can drag any panel and keep it anywhere in the canvas.
My requirement is when we click a button ,we have to change the panel numbers according to its position,that is from left to right.
How to find out where the panel is present in canvas and number them in ascending order according to its position.
One way to do it would be to add the panels to an Array as they are created. Then, when the button is clicked, you can do a sort on the array by x property:
panelArray.sortOn("x", Array.Numeric);
Once the array has been sorted, you can loop over it and adjust the panel numbers based on their position in the array.

How do I select a set of grid cells along a given angle quickly?

I have set up a grid class that contains theoretical cells.
I have a method collectCells() which accepts a starting point, radians and distance as arguments. I want this method to return an Array containing all the cells that are along a given angle and that are within the specified distance from the starting point, e.g.
The easiest way for me to do this is just loop through all the pixels in the given direction and pick cells up as I go, something like:
for(var i:int = 0; i<distance; i++)
{
startPoint.x += Math.cos(radians);
startPoint.y += Math.sin(radians);
if( start point falls within uncollected cell) collect cell;
}
This is obviously really poor, as the loop will be as long as the distance I specify - extremely slow.
I tried something different, creating a nextCell() method which accepts the last collected cell and radians. The method threw a point 25 pixels in the direction specified by radians, collected the resulting cell and then started over from that cell for a given amount of cells.
I didn't really think about this approach clearly enough, and once done realized that I had a problem, being that the actual path I'm testing gets broken each time the next cell is sought, e.g.
Where the green dotted line is the desired path, and the blue lines are the paths that make up each nextCell() call because the check is made from the centre of each cell.
What is the correct way to efficiently collect the cells in a given direction over a specified distance (pixels)?
Or you could use Bresenham's line drawing algorithm. Because literally you are trying to draw a pixel width line but with huge pixels.

as3: Making an animation

I am playing with animation in AS3 and flex4, and I've come into a problem. My application is a game board (like a chess board), where each field is a border container added to some position.
Also I am adding a child element (shape), to this container on mouse click. What I want to achieve is to be able to move shapes smoothly from one field to another. But it appears that the shape goes behind the neighbor field this way http://screencast.com/t/iZ3DCdobs.
I believe this happens because shape is a child of specific border container, and to make it visible over every other container, I would need to use layers somehow....
I would be happy if anybody could suggest a solution
Yes you're right on that. You should add the movable objects to a different layer.
As there are no typical layers in AS, you could try to drop the fields in one sprite and any other objects to a different an than place them on each other, so that when you will move a object it won't go behind other objects.
If you place both sprites in the same position you will still have accurate x,y positions between movable objects and fields.
You have two options:
First one is to have different layers for your DisplayObjects: as an example, the bottom layer would hold all the boards, and the upper layer would hold all the pieces.
Second option is to manipulate the index of the objects with swapChildren(), swapChildrenAt(), and setChildIndex(). So to bring a MovieClip to the topmost front, you would do MovieClip(parent).setChildIndex(this, 0);
If the situation is that always the shape object gets hidden behind the next ( right side ) grid container, the I suggest you create your grid in reverse.
Suppose you are creating a chess grid. that is a 8x8 grid. Normally you would create your grid using 2 for loops, looping from 0 to 8 with say the x and y points starting at 0,0 for the first grid and going on till the end. What I suggest you to do is to create from 8,8 to 0,0.
Display objects in flash are stacked on top of each other based on their child index.
For example: If you create two objects. Rectangle and Circle as follows
var rect:Rectangle = new Rectangle();
this.addChild(rect);
var circ:Circle = new Circle();
this.addChild(circ);
The circle will always be on top of the rectangle in this scenario because the circle was added after the rectangle to the display list.
So if you reverse the order of creation of your grid, the right grid cell will be added to the display list first and so the grid cells to the left will always be on top of the right ones. Hence, the problem that you are facing will not occur.

check occupied grid-elements

I created a visual grid of sprites which are stored in an Array1.
Some of those sprites got an image placed on it.
Now I would like to drag another image on an empty grid-element.
Special case:
Several images are dragged at the same time for being placed.
Therefore a drag-container holds also an Array2 of those dragged images.
As soon as the mouse goes up, the images of Array2 should be placed on empty grid elements of Array1.
My question: How do I check if a sprite of Array1 is occupied or not?
While several images have been dragged, every image should be placed one grid-element below the previous(y-axis down). In this process it could happen that you place an image on an empty grid-element, but because several are placed below each other the next grid-element could be occupied and therefore the currently placed image should be placed to the next free grid-element.
Let's make a boolean array (let's cal it boolarr), containing true on i-th place if i-th Sprite of a grid already has an image. otherwise boolarr[i] is false. You should store boolarr in grid class, and change it each time images are added.
So, here's possible solution. We drop several images on i-th place. Let's find n next free spries
function getFreeSprites(n: int, i: position) {
var result = [];
while (result.length < n) {
if (!boolarr[i]) result.push(i);
i++;
}
return result;
}
array returned by the function will contain indexes of next n free sprites, after that you can attach images to them.
Hope that helps!