Copy link to clipboard
Copied
I have a program that records the mouse position every 300 msec over an approximately 9 minute time period.
However, I need to know the mouse position ONLY when it is not the same as the previous moment (sometimes the user stops to talk. I don't want to record 5 minutes of the same mouse position)
Here's the original program
var drawTimer:Timer = new Timer(300, 500000);
drawTimer.addEventListener(TimerEvent.TIMER, timeSampler);
function timeSampler(evt:TimerEvent):void {
{ trace (+mouseX, "," +mouseY);
}
}
I tried creating a variable to capture the mouse position at a specific moment
var posMouseX:Number= mouseX;
var posMouseY:Number= mouseY;
and to add a conditional statement into the function
if ((mouseX != posMouseX) && (mouseY != posMouseY))
{ trace (+mouseX, "," +mouseY);}
but I am not doing this correctly because I either get all mouse moves or none
Can anyone suggest a better way to do this?
Thanks in advance
The above code can do what you're looking for
you'll get the values only when the mouse is moving, so there will not be duplicated values
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
function onMove(e:MouseEvent):void
{
trace(mouseX + ", " + mouseY);
// add your code here to record the values, for example:
// myArray.push(mouseX, mouseY);
}
as the timer still counting down and on complete it'll remove the stage event listener.
var drawTimer:Timer = new Timer(300, 500000);
drawTimer.
...Copy link to clipboard
Copied
use MouseEvent.MUSE_MOVE
var drawTimer:Timer = new Timer(300, 500000);
drawTimer.addEventListener(TimerEvent..TIMER_COMPLETE, timeSampler); // here you have to use TIMER_COMPLETE not TIMER cause TIMER will call the function each 300 msec means the mouse event listener will be removed after 300 msec only.
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
function onMove(e:MouseEvent):void
{
//trace (+mouseX, "," +mouseY); //in your code there's a comma after mouseX you have to remove it.
trace(mouseX + ", " + mouseY);
}
// on time complete remove the event listener
function timeSampler(evt:TimerEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
}
drawTimer.start();
Copy link to clipboard
Copied
Thank you.
I'm trying to follow the logic.
The software is trying to capture the effort to locate a hidden target by placing the mouse in the correct location.
As each mouse move is made, it is (1) traced into the output window and (2) uploaded into an Excel file to be looked at later (this is why the comma is present)
The timer samples his position every 300 msec
Sometimes, the person doing the task will stop to talk for 2 minutes.
But the software is sampling mouse position every 300 msec the whole time and the Excel file will contain a hundred repeats of the same mouse position.
So I don't need these duplicate values I want to get rid of them before they get put into the Excel matrix
But I don't want to stop the timer.
Once the person resumes the search, I still want to record the mouse moves
Thanks
Copy link to clipboard
Copied
The above code can do what you're looking for
you'll get the values only when the mouse is moving, so there will not be duplicated values
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
function onMove(e:MouseEvent):void
{
trace(mouseX + ", " + mouseY);
// add your code here to record the values, for example:
// myArray.push(mouseX, mouseY);
}
as the timer still counting down and on complete it'll remove the stage event listener.
var drawTimer:Timer = new Timer(300, 500000);
drawTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timeSampler);
function timeSampler(evt:TimerEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
}
drawTimer.start();
Copy link to clipboard
Copied
You're brilliant!
Thank you so much
I have one question, In the original code, I was sampling mouse position every 300 msec.
Does the new code also do this? It's hard to tell/
Thanks again immeasurably!
Copy link to clipboard
Copied
Thank you too, No it'll record on enter frame during the mouse move event..
But you can control it as in the following code:
Edit:
var mouseMoves: Array = [];
var recordingArray: Array = [];
var dataIndex: int = 0;
var drawTimer: Timer = new Timer(1000, 1); //your delay value is: 150000000 i used 1000 only..
drawTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timeSampler); // on complete time
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
function onMove(e: MouseEvent): void {
mouseMoves.push(mouseX, mouseY); // Now it's saving all the moves on enter frame inside the "mouseMoves" Array, (24 records of mouseX & mouseY each second) 24 is the frame rate per second (FPS).
}
function timeSampler(evt: TimerEvent): void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
trace("Enter Frame Records: " + mouseMoves);
trace(mouseMoves.length);
// on complete it'll record 2 values and ignore 6 values, inside the "recordingArray" using "dataIndex" variable and "for" loop statement.
for (var i: uint = 0; i < (mouseMoves.length / 8); i++)
{
//1000 msec / 300 msec = 3.3 | 24 fps / 3.3 = 7.2 , let's say 8, So we have saved 8 values each 300 msec in the "mouseMoves" array but we need 2 only
recordingArray.push(mouseMoves[dataIndex], mouseMoves[dataIndex + 1]); // record 2 values
dataIndex += 8; // ignore the next 6 values (jump to the next 300 msec records in the next loop)
}
trace("Recorded Values: " + recordingArray);
trace(recordingArray.length);
}
drawTimer.start();
Copy link to clipboard
Copied
HI. Thank you so much for your kindness . Sorry for the delay . On top of everything else, I forgot my login information
I tried your suggestion. Using the following code (which I found on the internet), I come close to what I need, b-u-t
var switcher:int = 0;
var posXa:Number = stage.mouseX;
var posYa:Number = stage.mouseY;
var posXb:Number = stage.mouseX;
var posYb:Number = stage.mouseY;
this.addEventListener(Event.ENTER_FRAME, checkMovement);
function checkMovement(e:Event):void {
{
if (switcher == 0)
{
posXa = stage.mouseX;
posYa = stage.mouseY;
switcher = 1;
}
else
{
posXb = stage.mouseX;
posYb = stage.mouseY;
switcher = 0;
}
if (posXa == posXb && posYa == posYb)
{
// trace("not moving");
}
else
{
trace("moving", mouseX, "," +mouseY, "time = ", +getTimer());
}
}}
This captures the mouse position into a form transferrable to an Excel matrix to graph which shows the search path for a square target
(below is a tiny sample of the data from the above program .
moving 153 ,353 time = 20797
moving 141 ,353 time = 20841
moving 137 ,345 time = 20881
In reality, a trial can last as long as 10 minutes, so the number of data points is potentially huge, unless I can use some strategy to record mouse position only about 3 times per sec. Nothing I;ve tried so far seems to work.
Do you know what to do? I'm trying to adapt your suggestion but don't know how
Copy link to clipboard
Copied
Hi, you can use this code:
var recordsArray:Array = [];
//totalMSEC: 10*60*1000 // 10 minutes, 600,000 msec
// totalMSEC /300 = 2000
var drawTimer:Timer = new Timer(300, 2000); // repeat it every 300 msec for 2000 times (total = 10 minutes)
drawTimer.addEventListener(TimerEvent.TIMER, _record);
// the timer function will run every 300 msec and it'll check if the current mouse position is already recorded or not, if it's in the same position of the last mouseY value saved in the array then it'll not record it again, that means the mouse is not moving..
function _record(e:TimerEvent):void
{
if (recordsArray[recordsArray.length-1] != mouseY)
{
recordsArray.push(mouseX, mouseY);
trace("moving: " + recordsArray[recordsArray.length-2] +", "+ recordsArray[recordsArray.length-1]);
}
}
drawTimer.start();
// we can add the records time if you want, but now I don't want to confuse you, try that code first
Copy link to clipboard
Copied
Thank you so much,
I added your code to the bottom of the program Dec 23 .6
It seems to be detecting mouse position less frequently (as I need), but gives two mouseY coordinates and not mouseX),
Do you know why
moving 353 ,674 time = 1051 // this is from the top part of the program. When the mouse is moving
moving 248 ,621 time = 1091
moving 233 ,608 time = 1131
moving 228 ,568 time = 1175
moving 227 ,529 time = 1215
moving: 529, 529 //this is from the part you added.
moving 224 ,511 time = 1258
moving 222 ,511 time = 1298
moving 208 ,517 time = 1342
moving 186 ,531 time = 1382
moving 171 ,553 time = 1423
moving 168 ,558 time = 1494
moving 193 ,606 time = 1506
moving: 606, 606 //this is from the part you added. So it gets one of the coordinates correct.
moving 220 ,614 time = 1550
moving 218 ,614 time = 1590
moving 206 ,612 time = 1634
moving 209 ,609 time = 1674
moving 205 ,601 time = 1714
moving 194 ,573 time = 1758
moving 175 ,528 time = 1798
moving 167 ,486 time = 1845
moving: 486, 486
moving 167 ,469 time = 1883
moving 172 ,459 time = 1926
moving 183 ,449 time = 1967
moving 200 ,445 time = 2006
moving 249 ,444 time = 2050
moving 296 ,453 time = 2092
moving 322 ,474 time = 2131
moving: 474, 474
Copy link to clipboard
Copied
Check the index number I think you're using the same index in trace() method:
trace("moving: " + recordsArray[recordsArray.length-2] +", "+ recordsArray[recordsArray.length-1]);// the first one is the second last record "mouseX", the second one is the last record "mouseY".
Copy link to clipboard
Copied
As you said you need about 3 records each second (if the mouse moving), if you want more you can change the timer delay and repeat properties:
//totalMSEC = 10*60*1000 // 10 minutes, 600,000 msec
// totalMSEC /100 = 6000 // 10 records per second for 10 minutes
var drawTimer:Timer = new Timer(100, 6000);
Copy link to clipboard
Copied
I also tried this with your code from the top
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
function onMove(e:MouseEvent):void
{
trace(mouseX + ", " + mouseY);
// add your code here to record the values, for example:
// myArray.push(mouseX, mouseY);
}
var recordsArray: Array = [];
//as the timer still counting down and on complete it'll remove the stage event listener.var recordsArray: Array = [];
var totalMSEC:Number = 10*60*1000; // 10 minutes, 600,000 msec
// totalMSEC /300 = 2000
var drawTimer:Timer = new Timer(400, 20000); // repeat it every 300 msec for 2000 times (total = 10 minutes)
drawTimer.addEventListener(TimerEvent.TIMER, _record);
//the timer function will check every 300 msec if the current mouse position has been recorded, it'll not record it
function _record(e:TimerEvent):void
{
if (recordsArray[recordsArray.length-1] != mouseY)
{
recordsArray.push(mouseX, mouseY);
trace("moving: " + recordsArray[recordsArray.length-1] +", "+ recordsArray[recordsArray.length-1], "time = ", +getTimer());
}
}
drawTimer.start();
The data looks like this
2, 334
9, 335
15, 337
20, 338
24, 339
29, 340
30, 340
30, 341
30, 342
moving: 342, 342 time = 839
33, 342
35, 341
38, 340
56, 336
86, 324
131, 305
154, 293
181, 278
189, 273
192, 272
200, 266
209, 262
216, 257
223, 251
229, 246
234, 241
239, 236
244, 231
247, 228
248, 227
249, 224
250, 223
250, 222
250, 221
248, 220
247, 219
246, 219
243, 219
238, 217
234, 216
232, 215
226, 214
222, 214
215, 214
210, 213
202, 213
194, 213
188, 213
181, 213
176, 213
170, 213
166, 213
165, 213
moving: 213, 213 time = 1218
163, 214
161, 215
158, 216
155, 217
153, 218
150, 220
146, 220
143, 221
139, 222
136, 222
132, 223
128, 223
125, 224
122, 224
117, 224
110, 224
103, 224
96, 224
90, 224
81, 223
80, 223
78, 221
76, 221
70, 218
65, 215
58, 211
51, 206
45, 202
40, 197
36, 192
32, 188
28, 182
24, 177
21, 172
18, 166
16, 161
moving: 161, 161 time = 1635
0, 113
2, 112
3, 112
4, 112
5, 112 (there are over 23 pages of numbers for a relatively brief trial, so I still need to cut the data down)
When plotted, it looks like this. I wrote my name (Joyce) which came out upsidedown. I guess the mouseY must be -mouseY
Copy link to clipboard
Copied
You're a genius! It works. I can't thank you enough. I wrote this upside down. Do you know how to turn mouseY into -mouseY
Do I do it here? recordsArray.push(mouseX, -mouseY); ?
Copy link to clipboard
Copied
Thank you too )
yes you can use -mouseY and it'll return a negative value, but also change the mouseY value in the if statement:
if (recordsArray[recordsArray.length-1] != -mouseY)
{
recordsArray.push(mouseX, -mouseY);
}
Copy link to clipboard
Copied
As you can use:
if (recordsArray[recordsArray.length-2] != mouseX || recordsArray[recordsArray.length-1] != -mouseY) // compare the mouse x & y with the last x & y records, if the mouse moved on x or y axis you'll get a new record
{
recordsArray.push(mouseX, -mouseY);
}