Skip to content

Instantly share code, notes, and snippets.

@jd-alexander
Last active July 19, 2019 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jd-alexander/b343cd8d67b108768d5eedff1bb7fef4 to your computer and use it in GitHub Desktop.
Save jd-alexander/b343cd8d67b108768d5eedff1bb7fef4 to your computer and use it in GitHub Desktop.
/**
I wrote this code recently for a Word Puzzle game I created and this particular class is responsible for processing the touch
events that occur when the user swipes on different words within the grid. It's suppose to detect the direction that the swipe
took place in so that it can utilize the direction to determine the coordinates between the start and end event of the touch
interaction so that it can highlight those letters. I found this code interesting because I had to use coordinate geometry
knowledge I learnt in college to solve the issues at hand and I learnt alot about how coordinates are represented on screens.
**/
class CoordinatesDirectionInteractor @Inject constructor() {
private var swipeDirection: SwipeDirection? = null
private var swipeType: SwipeType? = null
/**
This function is the main entry point for the component. It accepts a (x,y) coordinate of the start and end event and returns
direction (based on the compass) the swipe took place in and the type; whether it is diagonal,vertical or horizontal.
**/
fun detectSwipeDirection(startCoordinate: WordCoordinate, endCoordinate: WordCoordinate): Pair<SwipeDirection?, SwipeType?> {
return when {
areCoordinatesInSameRow(startCoordinate, endCoordinate) -> Pair(swipeDirection, swipeType)
areCoordinatesInSameColumn(startCoordinate, endCoordinate) -> Pair(swipeDirection, swipeType)
else -> {
calculateDiagonalCoordinates(startCoordinate, endCoordinate)
Pair(swipeDirection, swipeType)
}
}
}
/**
The logic behind this function is that I checked to see if the start and end coordinate or on the same y axis and if so that means
they are in the same row so from there the only thing I needed to know was if the movement was negative/positive on the x axis.
**/
private fun areCoordinatesInSameRow(startCoordinate: WordCoordinate, endCoordinate: WordCoordinate): Boolean {
if (startCoordinate.y != endCoordinate.y) return false
swipeType = Horizontal
if (startCoordinate.x < endCoordinate.x) {
swipeDirection = W.to(E)
} else if (startCoordinate.x > endCoordinate.x) {
swipeDirection = E.to(W)
}
return true
}
/**
This particular function does the opposite of the above and seeks to verify that the movement is on the y axis which means
the user swiped vertically so there would be change in the y axis either negatively or positively with the same x axis.
**/
private fun areCoordinatesInSameColumn(startCoordinate: WordCoordinate, endCoordinate: WordCoordinate): Boolean {
if (startCoordinate.x != endCoordinate.x)
return false
swipeType = Vertical
if (startCoordinate.y < endCoordinate.y) {
swipeDirection = N.to(S)
} else if (startCoordinate.y > endCoordinate.y) {
swipeDirection = S.to(N)
}
return true
}
/**
This function was the most interesting as the diagonals had to determined using formulas from coordinate geometry. Here I
needed to verify that the line between the two points are at a 45 degree angle to the horizontal (or that the two points
would be opposite vertices of a square). Below I accomplished this by calculating the difference between the two X and the difference
between the two Y values. If those differences are the same then I then attempt to determine the direction the swipe took place in
and then utilize the compass direction to make it easier to be inferred.
**/
private fun calculateDiagonalCoordinates(startCoordinate: WordCoordinate, endCoordinate: WordCoordinate): Boolean {
val diffX = Math.abs(startCoordinate.x - endCoordinate.x)
val diffY = Math.abs(startCoordinate.y - endCoordinate.y)
if (diffX == diffY && diffX != 0) {
swipeType = Diagonal
if (startCoordinate.x > endCoordinate.x && startCoordinate.y < endCoordinate.y) {
swipeDirection = NE.to(SW)
}
if (startCoordinate.x < endCoordinate.x && startCoordinate.y > endCoordinate.y) {
swipeDirection = SW.to(NE)
}
if (startCoordinate.x < endCoordinate.x && startCoordinate.y < endCoordinate.y) {
swipeDirection = NW.to(SE)
}
if (startCoordinate.x > endCoordinate.x && startCoordinate.y > endCoordinate.y) {
swipeDirection = SE.to(NW)
}
}
return true
}
fun Direction.to(value: Direction): SwipeDirection = SwipeDirection(this, value)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment