- Joined
- Aug 28, 2015
- Messages
- 213
I started creating a mouse control/helper system for my project that uses the mouse as input device heavily.
It is at this stage working but not fully polished.
you can check if a player presses a specific button, get the amount of multy clicks (double/tripperl/quadrupel... clicks), the mouse position a drag path of each button and the current mouse event.
Like always feedback ideas and suggestions are more than welcome.
Frotty
Chaosy
V.0.9b
Improved the code more. using castTo
Add more comments.
V.0.9
Streamlined the whole coda again more also separated the packages more clearly
added hot Docs
V.0.8b
Split the code in two packages:
-MouseUtils
-DragPath
cleaned up the onMouseEvent function:
-using a new mousebutton.toKey function to access the currentEvent via hashlist.
changed multiple if to switches.
using Players package(FrEntity) to initialize the tuple types for the playing players.
It is at this stage working but not fully polished.
you can check if a player presses a specific button, get the amount of multy clicks (double/tripperl/quadrupel... clicks), the mouse position a drag path of each button and the current mouse event.
Like always feedback ideas and suggestions are more than welcome.
Frotty
Chaosy
V.0.9b
Improved the code more. using castTo
Add more comments.
V.0.9
Streamlined the whole coda again more also separated the packages more clearly
added hot Docs
V.0.8b
Split the code in two packages:
-MouseUtils
-DragPath
cleaned up the onMouseEvent function:
-using a new mousebutton.toKey function to access the currentEvent via hashlist.
changed multiple if to switches.
using Players package(FrEntity) to initialize the tuple types for the playing players.
Wurst:
package DragPath
import MouseUtils
import ClosureEvents
import ClosureTimers
/**
This package helps with the managing of mouse clicks double and tripple clicks and drags.
This package saves the count how many times a button was multy clicked for each player
and safes the drag path the cursor moved across the map while holding one or more mouse buttons down.
*/
public constant MOUSE_PATH_POINT_DISTANCE = 1000 // the minimum distance the mouse has to move from its last path point to create a new point
public constant MOUSE_BUTTON_RESET_TIME = 0.2 // the maximum time between two clicks to count as multi click (in seconds)
public tuple clickStatus(int leftClicks, int rightClicks, int middleClicks, DragPath leftPath, DragPath rightPath, DragPath middlePath, real leftCD, real rightCD, real middleCD)
public clickStatus array clickStatuses
/**clickStatuses(Amount of LEFT multi clicks, Amount of RIGHT multi clicks, Amount of MIDDLE multi clicks, the path drawn on the map with pressed left button, the path drawn on the map with pressed right button, the path drawn on the map with pressed middle button, Game time the LEFT multi click reset cooldown started, Game time the RIGHT multi click reset cooldown started, Game time the MIDDLE multi click reset cooldown started)*/
public function player.getMouseClicks() returns clickStatus
return clickStatuses[this.getId()]
/**sets the multi click amount of the given mouse button to the given amount*/
public function player.setClickCounter(mousebuttontype wichButton, int count)
if wichButton == MOUSE_BUTTON_TYPE_LEFT
clickStatuses[this.getId()].leftClicks = count
else if wichButton == MOUSE_BUTTON_TYPE_RIGHT
clickStatuses[this.getId()].rightClicks = count
else if wichButton == MOUSE_BUTTON_TYPE_MIDDLE
clickStatuses[this.getId()].middleClicks = count
/**returns the amount of multi clicks of the given mouse button*/
public function player.getClickCounter(mousebuttontype wichButton) returns int
if wichButton == MOUSE_BUTTON_TYPE_LEFT
return clickStatuses[this.getId()].leftClicks
else if wichButton == MOUSE_BUTTON_TYPE_RIGHT
return clickStatuses[this.getId()].rightClicks
else if wichButton == MOUSE_BUTTON_TYPE_MIDDLE
return clickStatuses[this.getId()].middleClicks
return 0
/**Checks the distance between the last point and mouse position and adds a new DragPoint to the path if over MOUSE_PATH_POINT_DISTANCE*/
function mouseStatus.onMouseMoved(int playerId)
if this.left
clickStatuses[playerId].leftPath.addDragPoint(this.mousePosition)
if this.right
clickStatuses[playerId].rightPath.addDragPoint(this.mousePosition)
if this.middle
clickStatuses[playerId].middlePath.addDragPoint(this.mousePosition)
/**Increases the click counter and adds a new path for based on the currentEvent*/
function mouseStatus.onMousePressed(int playerId)
switch this.currentEvent
case MouseEvent.PRESSED_LEFT
clickStatuses[playerId].leftClicks ++
clickStatuses[playerId].leftPath = new DragPath(this.mousePosition)
case MouseEvent.PRESSED_RIGHT
clickStatuses[playerId].rightClicks ++
clickStatuses[playerId].rightPath = new DragPath(this.mousePosition)
case MouseEvent.PRESSED_MIDDLE
clickStatuses[playerId].middleClicks ++
clickStatuses[playerId].middlePath = new DragPath(this.mousePosition)
default
/**Checks if a new button release was done after this one*/
function clickStatus.isClicking(mousebuttontype wichButton) returns bool
let subtractedTime = getElapsedGameTime() - MOUSE_BUTTON_RESET_TIME
if wichButton == MOUSE_BUTTON_TYPE_LEFT
return this.leftCD <= subtractedTime
else if wichButton == MOUSE_BUTTON_TYPE_MIDDLE
return this.middleCD <= subtractedTime
else if wichButton == MOUSE_BUTTON_TYPE_RIGHT
return this.rightCD <= subtractedTime
return false
/**Destroys the path and starts the counter reset based on the currentEvent*/
function mouseStatus.onMouseReleased(int playerId)
DragPath currentPath = null
clickStatus clickStatus = clickStatuses[playerId]
switch this.currentEvent
case MouseEvent.RELEASED_LEFT
clickStatus.leftCD = getElapsedGameTime()
currentPath = clickStatus.leftPath
case MouseEvent.RELEASED_RIGHT
clickStatus.rightCD = getElapsedGameTime()
currentPath = clickStatus.rightPath
case MouseEvent.RELEASED_MIDDLE
clickStatus.middleCD = getElapsedGameTime()
currentPath = clickStatus.middlePath
default
clickStatuses[playerId] = clickStatus
doAfter(MOUSE_BUTTON_RESET_TIME)->
let buttonType = ConvertMouseButtonType((this.currentEvent castTo int) -3)
if not clickStatus.isClicking(buttonType)
playerFromIndex(playerId).setClickCounter(buttonType, 0)
if currentPath != null
currentPath.onButtonRelease(this.mousePosition)
destroy currentPath //destroys the Path after releasing atm.
class DragPoint
let pathPoint = ZERO3
construct(real x, real y, real z)
pathPoint = vec3(x, y, z)
construct(vec2 currentPosition, bool withTerrainZ)
pathPoint = withTerrainZ ? currentPosition.withTerrainZ() : currentPosition.toVec3()
construct(vec3 currentPosition)
pathPoint = currentPosition
function getVector() returns vec3
return pathPoint
/**The path drawn on the map*/
public class DragPath
vec2 oldMousePosition
LinkedList<DragPoint> path = new LinkedList<DragPoint>
construct(vec2 currentMousePosition)
path.add(new DragPoint(currentMousePosition, true))
this.oldMousePosition = currentMousePosition
/**returns true if a new point is set*/
function addDragPoint(vec2 currentMousePosition)
if currentMousePosition.distanceToSq(this.oldMousePosition) >= MOUSE_PATH_POINT_DISTANCE
path.add(new DragPoint(currentMousePosition, true))
this.oldMousePosition = currentMousePosition
/**Returns a LinkedList of DragPoints where you can iterate over*/
function getPath() returns LinkedList<DragPoint>
return this.path
/**Returns the specific DragPoint of index in the path*/
function getIndexDragPoint(int index) returns DragPoint
return path.get(index)
function onButtonRelease(vec2 currentMousePosition)
addDragPoint(currentMousePosition)
ondestroy
path.clear()
/**This Class manages the mouse input to path setup*/
class ClickListener extends MouseListener
override function onEvent(mouseStatus mouseStatus, int playerId)
if mouseStatus.currentEvent castTo int >= 7
mouseStatus.onMouseMoved(playerId)
else if mouseStatus.currentEvent castTo int >=4
mouseStatus.onMouseReleased(playerId)
else if mouseStatus.currentEvent castTo int >= 0
mouseStatus.onMousePressed(playerId)
init
doAfter(0.02)->
for p in ALL_PLAYERS
clickStatuses[p.getId()] = clickStatus(0, 0, 0, null, null, null, 0.00, 0.00, 0.00)
let mouseEvent = new ClickListener()
EventListener.add(EVENT_PLAYER_MOUSE_DOWN, () -> mouseEvent.onMouseEvent())
EventListener.add(EVENT_PLAYER_MOUSE_UP, () -> mouseEvent.onMouseEvent())
EventListener.add(EVENT_PLAYER_MOUSE_MOVE, () -> mouseEvent.onMouseEvent())
Wurst:
package MouseUtils
import ClosureEvents
import ClosureTimers
import public Players
import public GameTimer
/**
This Util helps to handle the mouse natives and gives acces to all mouse informations outside mouse trigger events
You can extend the functionallity by overriding the MouseEvents.onEvent function.
*/
public enum MouseEvent
STOPPED
PRESSED_LEFT
PRESSED_MIDDLE
PRESSED_RIGHT
RELEASED_LEFT
RELEASED_MIDDLE
RELEASED_RIGHT
DRAGGED_LEFT
DRAGGED_MIDDLE
DRAGGED_RIGHT
MOVED
public constant MOUSE_MOVE_RESET_TIME = 1.00 / 24.00 // the time after mouse movement to set current event to stop (in seconds)
/**mouseStatus(Most recent mouse event, Is the left button pressed, Is the right button pressed, Is the middle button pressed, Is the mouse moving, Current mouse pointer position on the map, Game time where the mouse started the move cooldown)*/
public function player.getMouseStatus() returns mouseStatus
return mouseStatuses[this.getId()]
/**returns the mouse position as vec2 on the map*/
public function player.getMousePosition() returns vec2
return mouseStatuses[this.getId()].mousePosition
/**The reversed function to ConvertMouseButtonType(i)*/
public function mousebuttontype.convertMouseButtonIndex() returns int
if this == MOUSE_BUTTON_TYPE_LEFT
return 1
if this == MOUSE_BUTTON_TYPE_MIDDLE
return 2
if this == MOUSE_BUTTON_TYPE_RIGHT
return 3
return 0
/**Shows the current Event in game*/
public function mouseStatus.printCurrentEvent()
Log.debug(MOUSE_EVENT_STRINGS[this.currentEvent castTo int])
public tuple mouseStatus(MouseEvent currentEvent, boolean left, boolean right, boolean middle, boolean move, vec2 mousePosition, real moveCD)
public mouseStatus array mouseStatuses
constant string array MOUSE_EVENT_STRINGS = [
"STOPPED",
"PRESSED_LEFT",
"PRESSED_MIDDLE",
"PRESSED_RIGHT",
"RELEASED_LEFT",
"RELEASED_MIDDLE",
"RELEASED_RIGHT",
"DRAGGED_LEFT",
"DRAGGED_MIDDLE",
"DRAGGED_RIGHT",
"MOVED"]
EventListener firstEventListener = null
public function addMouseListener(EventListener listener) returns EventListener
if firstEventListener != null
firstEventListener.prev = listener
listener.next = firstEventListener
firstEventListener = listener
return listener
public function removeMouseListener(EventListener listener)
if firstEventListener == listener
firstEventListener = null
destroy listener
/**Gives back the index of the EventList for this mousebutton*/
function mousebuttontype.toEventListIndex(eventid whichEvent ) returns int
var i = this.convertMouseButtonIndex()
if whichEvent == EVENT_PLAYER_MOUSE_UP
i += 3
return i
/**This Class is used to listen to mouse events and set the new values to the MouseStatuses*/
public class MouseListener
/**Overrite this function if you want to add more functionallity afterward*/
function onEvent(mouseStatus mouseStatus, int playerId)
function isMoving(real startTime) returns bool
return (getElapsedGameTime() - MOUSE_MOVE_RESET_TIME) <= startTime
function setMoveEvent(mouseStatus mouseStatus) returns MouseEvent
let eventindex = mouseStatus.currentEvent castTo int
if eventindex <= 3 and eventindex > 0
return (eventindex + 6) castTo MouseEvent
if eventindex <= 6
return MouseEvent.MOVED
return mouseStatus.currentEvent
/**This function is called from the EventListener if you want to add more functionallity to the system use the onEvent(mouseStatus, playerId) function*/
function onMouseEvent()
let triggerPlayer = GetTriggerPlayer()
let playerId = triggerPlayer.getId()
var mouseStatus = mouseStatuses[playerId]
let id = GetTriggerEventId()
mouseStatus.mousePosition = vec2(BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY())
if id == EVENT_PLAYER_MOUSE_MOVE
//prevent the event to fire inside a menu
if mouseStatus.mousePosition.x != 0 or mouseStatus.mousePosition.y != 0
mouseStatus.move = true
mouseStatus.currentEvent = setMoveEvent(mouseStatus)
mouseStatus.moveCD = getElapsedGameTime()
doAfter(MOUSE_MOVE_RESET_TIME) ->
if not isMoving(mouseStatus.moveCD)
mouseStatus.currentEvent = MouseEvent.STOPPED
else
let mb = BlzGetTriggerPlayerMouseButton()
mouseStatus.currentEvent = mb.toEventListIndex(id) castTo MouseEvent
if mb == MOUSE_BUTTON_TYPE_LEFT
mouseStatus.left = (id == EVENT_PLAYER_MOUSE_DOWN)
else if mb == MOUSE_BUTTON_TYPE_RIGHT
mouseStatus.right = (id == EVENT_PLAYER_MOUSE_DOWN)
else if mb == MOUSE_BUTTON_TYPE_MIDDLE
mouseStatus.middle = (id == EVENT_PLAYER_MOUSE_DOWN)
onEvent( mouseStatus, playerId)
mouseStatuses[playerId] = mouseStatus
var listener = firstEventListener
while listener != null
listener.onEvent()
listener = listener.next
init
doAfter(0.02) ->
for p in ALL_PLAYERS
mouseStatuses[p.getId()] = mouseStatus(MouseEvent.STOPPED, false, false, false, false, ZERO2, 0.00)
Last edited: