So, I am fairly new to java and android programming and I am having an issue coming up with the code for a project I am working on. Basically, there is a list of times, which I assume need to be stored as an array. Once the game has started, it needs to do one of two things:
If the user presses the screen within a few milliseconds of a time in the array, it will register as a hit and increase count.
If the user presses the screen outside of the "hit" time, it will register as a miss and reset count to 0.
Now, I have all the elements in place to make everything work (increasing count on screen press, etc). My issue is with the code to detect if the user pressed the screen on time or not. I have tried doing some searches, but I can't figure it out. Here is a small list of the times that are "good" hits:
0.25
0.84
1.03
1.60
2.3
2.6
2.9
These times can change a little and some can be removed if its not working correctly. The biggest issue I can think of is making sure that it starts the timer when the game starts so the times match up. The current timer starts at 100 and counts down 1 second at a time and when it reaches zero it takes the user to the game over screen. This of course can change if there is a better way to do it or a different way that it has to happen to make the screen press detection code work.
Any idea how to make this work?
Really, all you need to do is log the current system time at the time the game starts. Then, it's just:
long startTime = System.currentTimeMillis();
//...
System.currentTimeMillis() - startTime;
Then, to check if you're within the bounds set at any point in the array (which I will assume is an array of doubles):
public final static int THRESHOLD_MSEC = 100;
public boolean isHit(double time) {
int time = System.currentTimeMillis - startTime;
for(double d : array)
if(Math.abs(d-time) < THRESHOLD_MSEC) return true;
return false;
}
Then, elsewhere in your application, you can handle what happens when isHit returns either true or false. I'm not going to write that part for you. A point of note: a few milliseconds is nothing in comparison to human reflexes, and nobody will be able to make that time.
Related
I am a beginner in Java and am trying to practice my skills. I am trying to create a game that requires the player to hit a button repeatedly for a certain amount of time. I want to do something like this to generate a number of how many times a specific key, like the space bar, has been pressed in a specific time, for instance, 30 seconds
while(time!=0){
//amount of time
if (isPressing("w")){
buttonPressed ++;
}
//decrements amount of time
}
Ultimately once the time runs out I want to exit the loop and return the number of times the button has been pressed. I am unsure of how to actually accomplish this as the timers I have found are looped to repeat an action on an interval. Can anyone help give me some direction?
You can get the time in milliseconds with:
Following your example of 30 seconds,you would do something like this:
long time = System.currentTimeMillis();
while(System.currentTimeMillis() - time < 30000){//30000 is 30 seconds in milliseconds
if (isPressing("w")){
buttonPressed ++;
}
}
It would work by comparing the start time with the time after every iteration.
Iam new here, like week ago I started learning to program and Iam working on my text based strategic game in which I would like to make resources gather every x seconds passively.
basicaly my game is based on while (true) loop in which are switch cases and the game keeps waiting for keys to press to gather resources.
I would like the game to gather resources passively every x seconds.
example : every 10 seconds you will receive +1 wood.
I will welcome in help :)
Iam programming in java using NetBeansIDE
Just get the current time in every loop run with this
and check whether the 10 seconds passed since last time you gave +1 wood.
Note the time unit.
I am not sure how you are storing gathered resources, but if you could call a method to look it up based on when the game began. You could store the following variable as part of your game class:
private long startTime = System.currentTimeMillis();
And then get current resources by using the following method:
public int getWood() {
long diffMilliseconds = System.currentTimeMillis() - startTime;
int numSeconds = (int)diffMilliseconds / 1000;
int amtWood = numSeconds/10;
return amtWood + <any other wood gathering/calculating parameters>;
}
This does not account for using your wood. If you want a variable to update every ten seconds, you could use something like the solution here: Print "hello world" every X seconds. This solution uses the TimeTask class. Rather than printing, you could update a amtWood variable.
If there are no restrictions on what classes you can use, try Timer class available as part of Java Swing. You can also look at java.util.Timer class for scheduling your updates.
I am looking to move objects across a canvas or other component(s), but to do so without noticeable latency/delays. Now, to get it out of the way I am using double buffering with multiple layers (most of which only get drawn once). In my case I have a background that gets drawn once when the map generates, a mask layer (things behind the object), and a fringe layer (things in front of the object). The only thing that's actually getting re-drawn is the actual object moving around the screen.
That being said, I have also setup KeyListeners on this, and moved my object movement into a drawing and processing into separate threads (e.g. a thread dedicated to drawing the canvas, and a thread dedicated to processing the movement).
What I notice is that when I press a key to move the object (W,A,S,D) it will move a small amount (a single move action), followed by a slight delay, then move constantly until I stop pressing the keys.
Is there a better way to implement movement from the keyboards to reduce/eliminate delay?
-Edit-
I realized I could probably sum this up in a single statement: How to make controls for a game that feel responsive, without awkward delays/latency.
What operating system are you using? On linux / possibly mac, holding a key down performs several cycles which involve calling both the press and release methods constantly (You know how if you hold a key down in a text box, one character appears, then there's a delay, then several more appear rapidly? In linux, the operating system executes press, then release, really really fast.) In windows, however, the release method is never called until the key is actually released. (basically, it just keeps calling the press method really fast.)
A very ugly and hacky answer, but I hope it helps:
It is helpful to know the timing of these cycles. Typically, it goes something like this:
User presses and holds a button (say, the 'a' key). The 'a' key's press function is immediately called.
There is about a quarter to half second delay (often adjustable in system settings).
'a' key's release function is called
Few millisecond delay (between 2 and 10 ms by my testing)
Press function is called again
Slightly longer delay (Between 20 and 30 ms by my testing).
Repeat starting on third bullet point.
With this cycle in mind, it is theoretically possible (actually, completely possible. I've tested it.) to use timing to detect whether or not the user has actually released the key. Basically, if the key is released for more than 10 milliseconds (I'd go 15, just to be safe), then you know that the user has released the key.
This solution involves creating a boolean for each relevant key. Your KeyListeners, in turn, will do nothing more than set these booleans to true / false (maybe when they are pressed, they are set to true, and when they are released, they are set to false.)
Then, you create one more boolean for every key which will represent whether or not the keys are really being pressed. Create a thread which watches the first booleans (the ones controlled by the KeyListeners). Every time the first booleans are set to true, set the corresponding second boolean to true.
However, whenever the first booleans are set to false, wait 15 milliseconds, and check again. If they are still set to false, then set the corresponding second boolean to false. Why? If it's been 15 milliseconds and they are still false, then you know that the user has actually released the key.
KeyListener:
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode == 65){
aPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e){
if(e.getKeyCode == 65){
aPressed = false;
}
}
Separate Thread (calling it trueKeyListener)
boolean waiting = false;
long tWaitStart;
Runnable trueKeyListener = new Runnable(){
#Override
public void run(){
while(true){//Instead of true, use some variable, like running
if(aPressed){
aTruePressed = true;
}else if(!waiting){//not yet waiting for the 15 ms
waiting = true;
tWaitStart = System.nanoTime();
}else if(System.nanoTime() - tWaitStart >= 15000000){//waiting is over
waiting = false;
if(!aPressed){//a still isn't pressed
aTruePressed = false;
}
}
}
}
};
As far as I know, timing the booleans is the only way to make it work on any operating system. As I said, this shouldn't be (or at least wasn't when I last coded something like this) an issue on a Windows OS.
Edit: Finally, as I forgot to mention, you can create one more thread which watches the truePressed booleans and handles movement accordingly.
Secondly, just some advice, if there are several relevant keys in your application, I recommend using arrays of pressed booleans, truePressed booleans, waiting booleans, and tWaitStart longs for handling multiple keys in one for loop.
Second Edit: I have found this question which seems very similar to yours. I hope it helps.
Try calling right before repaint() inside your repaint loop.
Toolkit.getDefaultToolkit().sync()
To give some background information, I'm currently working on a Java coded pinball game. I'm keeping it in an MVC design model. It has a fairly realistic physics system that allows it to work collisions, gravity, friction etc. The system runs on a 20 FPS system right now.
The problem I'm having is that the physics loop that checks for collisions in the system works by running a method that using the current velocity of the ball calculates the time until the next collision. The most effective way for this to work would obviously be to keep running the check to account for the movement of the ball between checks to get it as accurate as possible, and if the time until collision is less than the time until the next check, then carry out the collision.
However, right now the system I am working with can only run the loop 20 times per second, which does not provide as accurate results as I would like, particularly during times of high acceleration, such as at ball launch.
The timer loop that I use is in the controller section of the MVC, and places a call to the physics section, located within the model. I can pass in the time remaining at the time the method is called in the controller, which the physics system can use, however I don't know how to run the loop multiple times while still tracking the remaining time before the next screen refresh?
Ideally I would like to run this at least 10 times per screen refresh. If anybody needs any more information please just ask.
Thanks for any help.
So the actual problem is that you do not know when the the collision will happen and when the next frame update is?
Shouldnt these be seperate running tasks? One thread that manages the collision detection and one that does the updating? each thread can run on its own interval (Timer.addTask(...)) and they should propebly be synchronized so colission/location updates are not performed when the render thread is executed.
Hope this answers your question.
Regards, Rob.
I'm trying to work up a basic text-based game as I'm learning Java. I'd like to be able to count rounds in the game as a means of managing the pacing of certain events. For instance, changing rooms could be limited to once per round (a second, in the test code.) A small creature might attack or change rooms at a higher rate, whereas a larger one might be more cumbersome. Good so far? Great.
So, I cooked this up and immediately realized that I'd be hitting a block each time the while loop waited for the player to input a command. Code:
private void startPlaying() {
//declare clock/round variables.
int lastRound = 0;
int currentRound = 0;
long lastTime = System.currentTimeMillis();
long currentTime;
while (player.getIsPlaying()){
//Clocking
currentTime = System.currentTimeMillis();
if ((lastTime + 1000) < currentTime) {
lastTime = currentTime;
lastRound = currentRound;
currentRound++;
System.out.println("Current round:\t" + currentRound + "\tCurrent time:\t" + currentTime); //EDIT:NOTE: This is just a test line to observe the loop.
}//end if (Clocking)
Command command = new Command();
String[] commandString = command.setAll(); //Array gets parsed elsewhere.
player.doCommand(commandString);
//Class Player extends Pawn extends Actor; Pawn has most command methods.
}
finishPlaying();
}//END STARTPLAYING()
So, here is my question:
Is there a way I could use a separate method to log time/rounds concurrent to the while loop presenting the player with a command prompt?
If not, is there a different way to make this a non-issue that I'm just not seeing/practiced in yet?
Take a look at Concurrency tutorial. With threads you can wait user input without stopping other processes (and make these other processes execute at the same time - not in parallel, but time-sharing).
It is called "game loop" which allows the game to run smoothly regardless of the input of the user.
The most straightforward solution - create 2 threads, frist will wait for user input and puts it into ConcurrentLinkedQueue with capacity 1. The second thread will run your game loop and takes user input from queue to process it if queue is not empty.
You can use any data structure you want to exchange data between 2 threads, it can be even volatile string variable. The only requirements read write access to this variable should be synchronized somehow.
A real-time text adventure? Sounds interesting. I wouldn't suggest trying to do concurrency for this particular problem, there are easier ways.
Normally you wouldn't mix blocking on input with time in seconds. Unless you have your heart set on this design, I'd suggest either.
1) Don't block on user input. Write your own input handling code by checking for key-presses each frame. Then you can just calculate the time difference between iterations. E.g. a monster moves 1 block second, so if the current loop iteration took 100ms then it moves 0.1 blocks. (store these values as floats internally, even if you draw on a text grid.
2) Increment game time in 'ticks' based on user input. This would be NetHack/Roguelike-style. Monsters can move so many blocks per tick, rather than per second.
Yes there is a way. You would need to put the "Round Counting" code in its own Thread, so it in not blocked by the user waiting to input data. The java.util.concurrency package can help with this.
Look at Java Doc the scheduleAtFixedRate() method will execute a runnable at fixed intervals. The "round counting" code would be moved to a class that implements the runnable interface. And this would be executed at the set time interval. This is reasonably advanced though.