I'm trying to use the systemLock() to lock the device when the getSpeed() returns a value greater than 20 m/s.
public void locationUpdated(LocationProvider provider, Location location)
{
if(location.isValid())
{
float speed = location.getSpeed();
// Information to be displayed on the device
StringBuffer sb = new StringBuffer();
sb.append("\n");
sb.append("Speed : ");
sb.append(speed);
sb.append(" m/s");
if(speed < 20){
appMan = ApplicationManager.getApplicationManager();
appMan.lockSystem(true);
}else{
}
MyApp.this.updateLocationScreen(sb.toString());
}
}
I have a RichTextField and I can use the .settext() successfully in the if/else statement to change the RichTextField's text so I must be using the lockSystem() wrong.
Edit
if(speed > 20 || Double.isNaN(speed)){
requestForeground();
appMan = ApplicationManager.getApplicationManager();
appMan.lockSystem(true);
}else{
}
The first thing that comes to the eyes is:
to lock the device when the getSpeed() returns a value greater than 20 m/s.
and
if (speed < 20) {
appMan = ApplicationManager.getApplicationManager();
appMan.lockSystem(true);
}
From the docs on Location
public float getSpeed()
Returns:
the current ground speed in m/s for
the terminal or Float.NaN if the speed is not known
In Java, any comparison against Float.NaN will return false, so your lock screen code block won't execute if your device is returning NaN as the speed. You might want to add Double.isNaN(speed) to your condition.
Related
i'm trying to make this interaction with keyboard for movement using some sprites and i got stuck with two situations.
1) The character movement is not going acording to the animation itself (it only begin moving after one second or so while it's already being animated). What i really want it to do is, to move without a "initial acceleration feeling" that i get because of this problem
2) I can't think of a way to make the character face the position it should be facing when the key is released. I'll post the code here, but since it need images to work correctly and is not so small i made a skecth available at this link if you want to check it out: https://www.openprocessing.org/sketch/439572
PImage[] reverseRun = new PImage [16];
PImage[] zeroArray = new PImage [16];
void setup(){
size(800,600);
//Right Facing
for(int i = 0; i < zeroArray.length; i++){
zeroArray[i] = loadImage (i + ".png");
zeroArray[i].resize(155,155);
}
//Left Facing
for( int z = 0; z < reverseRun.length; z++){
reverseRun[z] = loadImage ( "mirror" + z + ".png");
reverseRun[z].resize(155,155);
}
}
void draw(){
frameRate(15);
background(255);
imageMode(CENTER);
if(x > width+10){
x = 0;
} else if (x < - 10){
x = width;}
if (i >= zeroArray.length){
i = 3;} //looping to generate constant motiion
if ( z >= reverseRun.length){
z = 3;} //looping to generate constant motiion
if (isRight) {
image(zeroArray[i], x, 300);
i++;
} //going through the images at the array
else if (isLeft) {
image(reverseRun[z],x,300);
z++;
} going through the images at the array
else if(!isRight){
image(zeroArray[i], x, 300);
i = 0; } //"stoped" sprite
}
}
//movement
float x = 300;
float y = 300;
float i = 0;
float z = 0;
float speed = 25;
boolean isLeft, isRight, isUp, isDown;
void keyPressed() {
setMove(keyCode, true);
if (isLeft ){
x -= speed;
}
if(isRight){
x += speed;
}
}
void keyReleased() {
setMove(keyCode, false);
}
boolean setMove(int k, boolean b) {
switch (k) {
case UP:
return isUp = b;
case DOWN:
return isDown = b;
case LEFT:
return isLeft = b;
case RIGHT:
return isRight = b;
default:
return b; }
}
The movement problem is caused by your operating system setting a delay between key presses. Try this out by going to a text editor and holding down a key. You'll notice that a character shows up immediately, followed by a delay, followed by the character repeating until you release the key.
That delay is also happening between calls to the keyPressed() function. And since you're moving the character (by modifying the x variable) inside the keyPressed() function, you're seeing a delay in the movement.
The solution to this problem is to check which key is pressed instead of relying solely on the keyPressed() function. You could use the keyCode variable inside the draw() function, or you could keep track of which key is pressed using a set of boolean variables.
Note that you're actually already doing that with the isLeft and isRight variables. But you're only checking them in the keyPressed() function, which defeats the purpose of them because of the problem I outlined above.
In other words, move this block from the keyPressed() function so it's inside the draw() function instead:
if (isLeft ){
x -= speed;
}
if(isRight){
x += speed;
}
As for knowing which way to face when the character is not moving, you could do that using another boolean value that keeps track of which direction you're facing.
Side note: you should really try to properly indent your code, as right now it's pretty hard to read.
Shameless self-promotion: I wrote a tutorial on user input in Processing available here.
So I am playing with IOKit and getting input from my PS3 controller. It works and I can read the state of every button and both sticks. Sort of. I only get an integer value of 0 or 1 from the triggers and the dpad. When I test the controller on http://html5gamepad.com/ I see a float value from 0-1 on both. Does anybody know how to get the analog values?
My input value callback looks like:
inputCallback(void * context, IOReturn result, void * sender, IOHIDValueRef valueRef)
{
if (IOHIDValueGetLength(valueRef) > 2) {
return;
}
IOHIDElementRef element = IOHIDValueGetElement(valueRef);
if (CFGetTypeID(element) != IOHIDElementGetTypeID()) {
return;
}
int usagePage = IOHIDElementGetUsagePage(element);
int usage = IOHIDElementGetUsage(element);
CFIndex value = IOHIDValueGetIntegerValue(valueRef);
switch (usagePage)
...
I am on OS X 10.10.
Thanks
I'm new to processing and trying to make a very simple program where i have an arduino that produces a seriel input (according to an analogue read value). The idea is a Processing window will open with a block color shown for 30 seconds. In this time all the readings from the arduino will be summed and averaged - creating an average for that color.
After 30 seconds the colour will change and a new average (for the next color) will start being calculated. This is the code i have started to write (for now focusing on just one 30 second period of green).
I realise there are likely problems with the reading/summing and averaging (i havent researched these yet so i'll put that to one side) - but my main question is why isn't the background green? When i run this program i expect the background to be green for 30 seconds - where as what happens is it is white for 30 seconds then changes to green. Can't figure out why! Thanks for any help!
import processing.serial.*;
Serial myPort;
float gsrAverage;
float greenAverage;
int gsrValue;
int greenTotal = 0;
int greenCount = 1;
int timeSinceStart = 0;
int timeAtStart;
int count=0;
color green = color(118,236,0);
void setup () {
size(900, 450);
// List all the available serial ports
//println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
}
void draw () {
while (timeSinceStart < 30000) {
background(green);
greenTotal = greenTotal + gsrValue;
greenCount = greenCount + 1;
delay(500);
timeSinceStart = millis()-timeAtStart;
//println(timeSinceStart); for de bugging
}
greenAverage = greenTotal/greenCount;
//println(greenAverage); for de bugging
}
void serialEvent (Serial myPort) {
int inByte=myPort.read();
//0-255
gsrValue=inByte;
}
What I like to do for timers, is use IF statements and use millis() or a constantly updated variable 'm' right inside the condition:
int timeSinceStart;
int m;
void setup(){
timeSinceStart = millis(); // initialize here so it only happens once
}
void draw(){
m = millis(); // constantly update the variable
if(timeSinceStart + 30000 < m){
greenAverage = greenTotal/greenCount; // or whatever is outside while loop
timeSinceStart = millis();
}
//Anything that went inside the while loop can go here, or above the IF
}
This makes it so around every 30 seconds, the background will change once, and you just re-update the timeSinceStart variable in there too. This way, it will only update when you want it to update and not constantly update and break the code.
I tend not to use while loops in processing as they usually cause headaches. Hope my example helps.
May have found a way round this using an IF statement. I perhaps looked over the fact the draw function is itself a loop, so i was able to use a variation of
if (timeSinceStart < 5000) {
background(green);
}
within draw.
When dealing with timed events in Processing you should not use while loops inside the draw() function. The draw() function itself is a while loop which updates the "screen" each frame.
So, what you should do is create a timer and let it do a switch for you inside the draw() function. In your case, if you want to start with a green screen, you do that in the setup() function, and then create a method for altering according to a timer in your draw() function.
This is a suggestion on how you could solve your particular problem. Just change the cycle variable according to your need. In your case it would be 30000.
boolean isGreen = true;
int startTime = 0;
int lastTime = 0;
int cycle = 1000; //the cycle you need
void setup() {
size(200, 200);
background(0, 255, 0); //green
}
void draw() {
startTime = millis();
if (startTime > lastTime + cycle) {
if (isGreen) {
background(255); //white
isGreen = !isGreen;
} else {
background(0, 255, 0); //green
isGreen = !isGreen;
}
lastTime = millis();
}
}
so I am having trouble with being able to have a proper TOTAL guess counter. my code needs to be basic so please dont offer me advice for doing anything you think is not trivial. currently, my code plays a game, then asks the user if they want to play again and its a simple Y or N. if yes, another games plays and if no then then game ends and it reports the results of every game played such: the total games, guesses per game, and the best game (reports game that had lowest guess count). my issues are being able to accurately count ALL THE GUESSES from every game. I am able to report results and track the total games played correctly but i cant figure out how to report a result that tracks the guesses per game, adds them all up, finds the smallest one.
import java.util.*;
public class Guess2{
// The range for what numbers the correct answer is allowed to be.
public static final int MAX = 2;
// Main method that calls the other methods for the game to run properly.
public static void main (String [] args) {
Scanner console = new Scanner(System.in);
introduction();
int userGuess = game(console);
int numGames = 1;
System.out.print("Do you want to play again? ");
String putYesNo = console.next();
while (putYesNo.equalsIgnoreCase("y")) {
System.out.println();
game(console);
numGames++;
System.out.print("Do you want to play again? ");
putYesNo = console.next();
}
if (putYesNo.equalsIgnoreCase("n")) {
System.out.println();
finalScores(console,totalGuess,numGames);
}
}
// Method to play the guessing game using the input from the console(parameter) via the user playing the game.
public static int game(Scanner console){
Random answer = new Random();
int correct = answer.nextInt(MAX) + 1;
System.out.println("I'm thinking of a number between 1 and " + MAX + "...");
int userGuess = 0; // This is used to prime the while loop.
int numGuess = 0; // This is used to start the count at 1.
int totalGuess = 0;
while (userGuess != correct){
System.out.print("Your guess? ");
userGuess = console.nextInt();
if (userGuess > correct){
System.out.println("It's lower.");
} else if (userGuess < correct){
System.out.println("It's higher.");
}
numGuess++;
}
if (userGuess == correct && numGuess == 1){
System.out.println("You got it right in 1 guess");
} else if (userGuess == correct && numGuess != 1){
System.out.println("You got it right in " + numGuess + " guesses");
}
totalGuess =+ numGuess;
return totalGuess; // This Returns the number of total guesses for this single game.
}
/* Method used to report the Users' final statistics of the game(s).
Uses information from the user input via the console,
the sum of guesses used for every game, and the total number of games played. */
public static void finalScores(Scanner console, int totalGuesses, int numGames){
System.out.println("Overall results:");
System.out.println(" total games = " + numGames);
System.out.println(" total guesses = " + totalGuesses);
System.out.println(" guesses/game = " + iLoveRounding(1.0*totalGuesses/numGames));
System.out.println(" best game = " );
}
// Method that introduces the User to the Game.
public static void introduction() {
System.out.println("This program allows you to play a guessing game.");
System.out.println("I will think of a number between 1 and");
System.out.println(MAX + " and will allow you to guess until");
System.out.println("you get it. For each guess, I will tell you");
System.out.println("whether the right answer is higher or lower");
System.out.println("than your guess.");
System.out.println();
}
/* Method used to round the "guessing/game" ratio to 1 decimal place.
The return value of this method returns the ratio in decimal form with only 1 didgit, so
The scores method can report it properly. */
public static double iLoveRounding(double round){
return Math.round(round * 10.0) / 10.0;
}
}
You could look into making an integer ArrayList to hold all of the guesses per game. Then, when you are printing the results, you could first print out the whole ArrayList to represent the guesses per game, then call 'Collections.sort(yourArrayList)', which will sort the ArrayList from lowest to highest, then print out the first element of the ArrayList.
I'd recommend the integer ArrayList over a simple integer array, since the array will require you to define the size beforehand. An ArrayList can be dynamic, and you can change the size according to the number of times the user plays the game.
Im needing to use local variables but when i use them for a timer (decreases time until conditions are met) it doesnt work
for (int i = 0; i < Weapons.Count; i++)
{
if (Weapons[i].ItemType == 6)
{
if (standard.IsKeyDown(Keys.G))
{
Cannons.Add(new CannonFire(this));
}
}
else if (Weapons[i].ItemType == 7)
{
float Recharge = Weapons[i].Laser.Rate;
Recharge -= (float)gametime.ElapsedGameTime.Seconds;
if (standard.IsKeyDown(Keys.G) && Recharge < 0)
{
laser.Add(new LaserFire(this, new Vector3(Weapons[i].Laser.range, 1, 1) ));
Recharge = Weapons[i].Laser.Rate;
}
}
}
other relevant code is where im getting the rate from
public class LaserItem
{
float Damage;
float Range;
float Last;
float RechargeRate;
public float damage
{
get { return Damage; }
set { Damage = value; }
}
public float Rate
{
get { return RechargeRate; }
set { RechargeRate = value; }
}
public float Life
{
get { return Last; }
set { Last = value; }
}
it works without the timer but i cant have it like that because i dont want 300 lasers to be built every time someone hits the key. as far as i can tell the timer is set to the laser rate every frame so it never reaches 0 (this section it in the update function)
for this piece of code its fine but when i need it in a loop i have to use local variables;
From what I can understand, what you are doing in the code is that you're creating a new local variable with the value set to the recharge rate of the laser every single update, firing it when the time from the last update is longer than the recharge rate - this would occur only on a very slow update.
Taking into account the automatic Update (the main loop one) calling of XNA, what would help you is setting some class variable for the Weapon, e.g. RemainingRecharge and when you fire, set it to the recharge rate and substract the elapsed time every update until it reaches zero or less. The only difference from your code is that the recharge is moved to the class instance and thus preserved between updates.
Recharge isn't a reference or a pointer; it's a copy (as float and double are immutable types). So, assigning a value to Recharge at the end of the if() block does absolutely nothing. (I'd bet that it even gets removed by the compiler).
Try this:
else if (Weapons[i].ItemType == 7)
{
float recharge = Weapons[i].Laser.Rate;
recharge -= (float)gametime.ElapsedGameTime.Seconds;
if (standard.IsKeyDown(Keys.G) && recharge < 0)
{
laser.Add(new LaserFire(this, new Vector3(Weapons[i].Laser.range, 1,1)));
/// changed the the next line:
Weapons[i].Laster.Rate = recharge;
}
}
i figured it out, XNA has a TimeSpan thing you can use its easier to work with and you can tell it if it reaches a number reset and do what you want