Record time a key is held in Processing - time

I've searched on so many forums including this one and I can't see to find any answer for this. Many of the solutions given to me looked like this:
void keyPressed(){
if (key == 'e'){
t = millis();
}
}
void keyReleased(){
if (key == 'e'){
t = millis()-t;
println(t);
}
}
This is incorrect however because the keyPressed function continuously calls upon millis() when I hold a key. So when the key is released the recorded time prints a number close to zero!
How do I make keyPressed call millis() only once?

You could just use a boolean that tracks whether you've already set the value. Something like this:
boolean recorded = false;
void keyPressed(){
if (key == 'e' && !recorded){
t = millis();
recorded = true;
}
}

Related

Kinect Record Only When One Body/Skeleton Is in the Frame

I need to write a program that records the frames, but only when one skeleton/body is in the frame. I looked at the bodyCount method, but it always gives a value of 6 (useless). One thing I tried to do is shown below. This code basically shows the index at which the body being tracked is stored. But, I still can't figure out how to know if there is one or more bodies in the frame.
I would really appreciate any help.
Thanks in advance.
private void Reader_FrameArrived(object sender, BodyFrameArrivedEventArgs e){
using (BodyFrame bodyFrame=e.FrameReference.AquireFrame()){
if (bodyFrame!=null){
if(this.bodies==null){
this.bodies=new Body[bodyFrame.BodyCount];
}
body.Frame.GetAndRefreshBodyData(this.bodies)
for(int i=0; i<6;i++){
if(this.bodies[i].IsTracked){
Console.WriteLine("Tracked"+i)
}
}
}
}
}
Just check the IsTracked property of each body, and store the number of tracked skeleton in a single variable. If this number is equal to 1, there is just one single skeleton tracked, and you can start your recording.
private Body[] bodies = null;
[...]
private void Reader_FrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
bool dataReceived = false;
using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame())
{
if (bodyFrame != null)
{
if (this.bodies == null)
{
this.bodies = new Body[bodyFrame.BodyCount];
}
// The first time GetAndRefreshBodyData is called, Kinect will allocate each Body in the array.
// As long as those body objects are not disposed and not set to null in the array,
// those body objects will be re-used.
bodyFrame.GetAndRefreshBodyData(this.bodies);
dataReceived = true;
}
}
if (dataReceived)
{
int trackedBodyCount = 0;
for (int i=0; i<this.bodies.Length; ++i)
{
if(this.bodies[i].IsTracked) {
trackedBodyCount += 1;
}
}
if (trackedBodyCount == 1)
{
// One skeleton is tracked
}
}
}

Logic Error in Player Controls in Greenfoot

Recently, I've been using Greenfoot, and I wanted to make a simple top-down/bullet-hell shooter. Everything was going smoothly until I tried some of the movement. It's simple enough with good old "arrow keys to move, space to shoot", but the problems show up when I try to move diagonally up-left or down-right and shoot at the same time. I can only do one at a time. I noticed that the directions are related by their location in the else-if calls, but that got me no where. I've also tried moving the code around, replacing the fire() call in act; with the if check entirely, but nothing has changed it.
import greenfoot.*;
/**
* Write a description of class PlayerShip here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class PlayerShip extends SmoothMover
{
private int stepSize = 4;
private boolean tiltLeft = false;
private boolean tiltRight = false;
private int tiltFrame = 1;
private int flameFrame = 0;
private final int COOLDOWN = 20;
private int armsCool = 0;
public PlayerShip()
{
}
/**
* Act - do whatever the PlayerShip wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
setImage();
if(Greenfoot.isKeyDown("left") && Greenfoot.isKeyDown("right"))
{
tiltFrame = 1;
}
move();
fire();
armsCool ++;
}
public void setImage()
{
if(Greenfoot.isKeyDown("up"))
{
setLocation(getX(), getY() - stepSize - 2);
}
else if(Greenfoot.isKeyDown("down"))
{
setLocation(getX(), getY() + stepSize + 2);
}
if (Greenfoot.isKeyDown("left")) {
setLocation(getX() - stepSize, getY());
tiltLeft = true;
if(tiltFrame == 1)
{
setImage("LeftTilt1.png");
tiltFrame ++;
}
else if(tiltFrame == 2)
{
setImage("LeftTilt2.png");
tiltFrame++;
}
else if(tiltFrame == 3)
{
setImage("LeftTilt3.png");
tiltFrame++;
}
else
{
if(flameFrame == 1)
{
setImage("LeftTilt.png");
flameFrame --;
}
else
{
setImage("LeftTiltAlt.png");
flameFrame ++;
}
}
}
else if (Greenfoot.isKeyDown("right")) {
setLocation(getX() + stepSize,getY());
tiltRight = true;
if(tiltFrame == 1)
{
setImage("RightTilt1.png");
tiltFrame ++;
}
else if(tiltFrame == 2)
{
setImage("RightTilt2.png");
tiltFrame++;
}
else if(tiltFrame == 3)
{
setImage("RightTilt3.png");
tiltFrame++;
}
else
{
if(flameFrame == 1)
{
setImage("RightTilt.png");
flameFrame --;
}
else
{
setImage("RightTiltAlt.png");
flameFrame ++;
}
}
}
else
{
tiltFrame = 1;
tiltLeft = false;
tiltRight = false;
if(flameFrame == 1)
{
setImage("PlayerShip2.png");
flameFrame --;
}
else
{
setImage("PlayerShip.png");
flameFrame ++;
}
}
}
private void fire()
{
if(Greenfoot.isKeyDown("space") && (armsCool >= COOLDOWN))
{
getWorld().addObject(new PlayerBasicBullet(new Vector(12, 5), 251), this.getX(), this.getY());
Battleground.bulletsOnScreen ++;
armsCool = 0;
}
}
}
The move(); method and Vector class are separate and just for smoother movement. I can provide those too, but there shouldn't be anything in there that messes with the controls.
A slightly modified version of the code works fine on my machine. There's two possibilities that I can think of:
Your setImage calls (which I commented out, because I don't have those images) could be throwing an exception, in which case the fire() method wouldn't be reached. Seems unlikely, though, as this would happen even without diagonal movement, and you'd see an exception in the terminal. So, much more likely:
Your keyboard may not be able to register those particular three-key combinations. Three ways to test this:
a. Try this keyboard ghosting demo (click the keyboard at the top of the page) and see if it can register all the keys.
b. load the Asteroids scenario from the book examples and see if you can shoot bullets while accelerating and steering.
c. You could just change "space" in your code to, say, "x" and see if works with that key.
Otherwise, I'm at a loss, unless there is code elsewhere in the scenario causing a problem.

Override a variable on keyPressed()

I am trying to change the column header from a table using a variable name that changes using keyPressed() but it is not working.
String colSub;
Table dataTable;
void setup()
{
for(int k =0; k<dataTable.length; k++)
{
float xrate = dataTable.getFloat(k, colSub);
}
}
void draw()
{
rect(400,300,150,150);
}
void keyPressed()
{
if (key == '1')
{
colSub = "AVERAGE_ENGLISH";
}
if (key == '2')
{
colSub = "AVERAGE_MATHS";
}
}
Thanks in advance.
setup() only gets called once, at the beginning of your Processing program. In order to achieve whatever goal you may have, you should copy your code to the keyPressed() section, so everytime the key gets pressed the values get updated. Again your code doesn't do anything with xrate, but you would require to make your variable xrate global, so that setup() and keyPressed() can access this data.

Backspace while entering filename in JFileChooser makes directory go one level back

I am pretty new to Java Swing development and is encountering the following issue and not certain how to resolve it.
While providing a file name to save a file using JFileChooser, entering a backspace(in the filename field), makes a directory go up 1 level. This problem is encountered only on Windows and not on Linux.
Can somebody shed some light on why this may happening and an approach to fix this issue.
Thanks.
I had this problem too.
My solution - is to override the processKeyBinding method , and in the specific case stop the method , see below:
#Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
int condition, boolean pressed) {
if (KeyEvent.VK_BACK_SPACE == e.getKeyChar()){
if (jTextField!= null && jTextField.hasFocus())
return false;
}
return super.processKeyBinding (ks,e,condition,pressed);
}
the jTextField is the filename field that , was calculated in the contractor of my FileChooser class
the method to calculate is -
private Component getTextFieldInJFileChooser(Component [] c )
{
if (c == null)
return null;
for(Component k: c)
{
if( k instanceof JTextField) {
return k;
}
else if(k instanceof JPanel) {
JPanel jp=(JPanel)k;
Component jTextField = getTextFieldInJFileChooser(jp.getComponents());
if (jTextField != null)
return jTextField;
}
}
return null;
}
Success & Regards!

Algorithm to fire sequential keystrokes

I want to write an algorithm to sequentially press keys F1-F3. My form has these controls:
lblF1
textboxF1
lblF2
textboxF2
lblF3
textboxF3
btnStart
In textboxF1-textboxF3 the time in seconds is entered. This when the program is to press the hotkey. It is important that the program can't press two keys at once, for example F1 and F2. It may not press more than one key in a second. When I click on btnStart it calls Run().
This is how I tried to resolve this:
static int counterF1 = 9999;
static int counterF2 = 9999;
static int counterF3 = 9999;
public void Run()
{
counterF1 = 9999;
counterF2 = 9999;
counterF3 = 9999;
while (true)
{
Loop();
}
}
public void Loop()
{
bool used = false;
if (counterF1 >= (int)textboxF1.text)
{
counterF1 = PressKey(VK_F1);
used = true;
}
if (counterF2 >= (int)textboxF2.text)
{
counterF2 = PressKey(VK_F2);
used = true;
}
if (counterF3 >= (int)textboxF3.text)
{
counterF3 = PressKey(VK_F3);
used = true;
}
if (used == false)
{
IncrementCounters();
Delay(1000);
}
}
public double PressKey(uint key)
{
myPostMessageA(hWindow, WM_KEYDOWN, (uint)key, (uint)key);
IncrementCounters();
return 1; //return 1 because one second
}
public void IncrementCounters()
{
counterF1++;
counterF2++;
counterF3++;
}
But often it doesn't press any key (it is possible it is too late, but can't be an omission). Can you explain how to make an algorithm for this?
We will use a class KeyStroke that stores the necessary data for a special key:
public class KeyStroke
{
public int period { get; set; } // Period in which to hit key
public int next { get; set; } // ticks to the next hit of this key
public int VK { get; set; } //KeyCode
}
public List<KeyStroke> keys = new List<KeyStroke>();
An Initialize() method is needed to read the data from the text boxes and to init the simulation. We utilize a timer with the interval of one second to run the simulation. In my example, I don't read from textboxes, but use constant values. Add the input and error handling. If you use WPF, you can bind the KeyStroke objects to the textboxes.
void Init()
{
//Initialize keys with according periods from input
keys.Clear();
keys.Add(new KeyStroke() { VK = VK_F1, period = 1, next = 1 });
keys.Add(new KeyStroke() { VK = VK_F2, period = 10, next = 10 });
keys.Add(new KeyStroke() { VK = VK_F3, period = 5, next = 5 });
//sort keys by period (descending), in order to handle long period keys, too
keys.Sort((first, second) => second.period.CompareTo(first.period));
//Start the program
var t = new DispatcherTimer();
t.Interval = TimeSpan.FromSeconds(1);
t.Tick += new EventHandler(t_Tick);
t.Start();
}
The tick event is similar to yours:
void t_Tick(object sender, EventArgs e)
{
bool used = false;
foreach (var key in keys)
{
if (key.next <= 0 && !used)
{
PressKey(key.VK);
key.next = key.period;
used = true;
}
key.next--;
}
}

Resources