I am beginner when it comes to java and I have come across with a problem that I haven't found a solution to just yet. The thing is that I have working methods for drawing an letter and also for rotating it - when I set rotation it works the way it should. However I would like to make this slightly more interactive, at school we were given the basic framework for that - I was able to create a button that when you click on it the letter's angle changes and the letter is redrawed correctly. But I would like to make it an animation, for example you click on the button and for 10 seconds (or until you press the button again) the letter will be rotating.
On the internet I found a way to perform an action after certain period of time, and I thought I will use this. I wanted to add an angle and redraw an image, after let's say 1 second, then it would repeat - I thought this would make it look like it is animated. But I was wrong. I tried so many ways to do this, the best thing was that after few seconds that I set I want the animation to go for, it changed an angle and redraw, unfortunately it was the final state and it didn't draw states in between to create an animation. And this latest code doesn't even do that, the program just freezes.
int animation = 0;
int steps = 0;
public void G_draw() {
graphic.clear();
if (animace==1)
{
animation();
}
letter('a', G_Color.G_cBlack, 2, 2);//drawing an letter
}
public void G_mousePressed(G_Button button, int x, int y) {
if (button.equals(G_Button.B_LEFT)&&x>700&&x<750&&y>500&&y<520){
animation=1;
G_draw();
}
}
public void animation() {
long start = System.currentTimeMillis();
long end = start + 2 * 1000;
while (System.currentTimeMillis() < end) {
}
langle+=30; // adding an angle
steps++;
G_repaint();
G_draw();
if (steps<4) animace();
}
instead of this
long start = System.currentTimeMillis();
long end = start + 2 * 1000;
while (System.currentTimeMillis() < end) {
}
use
Thread.sleep(# in milliseconds);
We can't see where you use langle
This line if (steps<4) animace(); only runs when animace<>1 otherwise it's skipped because animate()calls G_draw() calls animate and so on.
Related
i've made a java aplication that displays the current time as a digital clock, and i would like to make the file automatically run after the mouse isn't moved for 10 minutes.Does anyone have any ideas?
P.S. I'm new to StackOverflow and to coding as well at that, so forgive me if this is actualy a stupid question.
As per your comment, Java doesn't make .exe files. You would need to place your jar file into a special executable wrapper to accomplish that. Launch4j can do that for you.
You would want to run your application as a Service. This SO Thread can shed some additional light on that subject.
In your application:
Set your clock component so that it is non-visible. Create a TimerTask to monitor the System Mouse pointer location (x, y). Utilize the MouseInfo Class within the TimerTask's run() method to track the Mouse Pointer location. Keep track of the time from the mouse last movement. If 10 minutes has elapsed with no mouse movement then display your clock (make it visible). If you like, when the mouse is moved again make the clock non-visible again. Your code in relation to this might look something like this:
First declare and initialize four (4) Class Member Variables:
int mouseX = 0;
int mouseY = 0;
long timeOfLastMovement = 0L;
TimerTask mouseMonitorTask;
Somewhere in your Class copy/paste this method. Make the required changes as you see fit:
private void startMouseMonitoring() {
mouseMonitorTask = new TimerTask() {
#Override
public void run() {
PointerInfo info = MouseInfo.getPointerInfo();
Point pointerLocation = info.getLocation();
long currentTime = java.lang.System.currentTimeMillis();
//System.out.format("Mouse Location - X: %d, Y: %d\n", pointerLocation.x, pointerLocation.y);
float elapsedTime = (((currentTime - timeOfLastMovement) / 1000F) / 60);
if (pointerLocation.x == mouseX && pointerLocation.y == mouseY) {
// Check if 10 minutes has elapsed with no mouse movement
if (elapsedTime >= 10.0f) {
/* Make Clock Visible if it isn't already
or whatever else you want to do. */
if (clockIsNonVisible) {
// clock.setVisible(true);
}
}
}
else {
mouseX = pointerLocation.x;
mouseY = pointerLocation.y;
timeOfLastMovement = currentTime;
// Make clock non-visible if you like.
if (clockIsVisible) {
// clock.setVisible(false);
}
}
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
cancel();
e.printStackTrace();
}
}
};
Timer monitorTimer = new Timer("Timer");
long delay = 1000L; // Start Delay: 1 second
long period = 1000L; // Cycle every: 1 second
monitorTimer.scheduleAtFixedRate(mouseMonitorTask, delay, period);
}
Call the startMouseMonitoring() method and the ball is rolling. I'm sure you'll figure out the rest.
If you want to cancel the TimerTask and Mouse Monitoring then you can call the TimerTask#cancel() method:
mouseMonitorTask.cancel();
I'm using LibGDX and I want to know if it is possible to do a speech system where the text gets drawn letter by letter, or slowly, like a person speaking, instead of just appearing. Is this possible? Do I need to make a function to do it or does LibGDX or java have it built in??
Thanks,
Luke
I would recommend something similar to Sameera's comment, although a wait generally isn't a good idea for a game as it stops everything else, unless you do it in a separate thread.
Instead of waiting, perhaps use your delta times:
private float timeSinceLastLetter = 0f;
private static final float TIME_PER_LETTER = 100f;
public void render(float deltaTime) {
// do your other rendering
if(timeSinceLastLetter > TIME_PER_LETTER) {
timeSinceLastLetter = 0f;
// render your next letter here
} else {
timeSinceLastLetter += deltaTime;
}
}
There's plenty more details that need filling in, but that should give a rough idea
I'm creating java game (I'm a beginner with this for now) and I'd like to start with some kind of platform game.
I'd like to know how I can make the player jump (I know how to move him up and down), but I don't know how how to make him go back down after going up.
Here is my code:
public void keyPress() {
if (listener.arrowUp) {
Jump();
}
}
private void Jump() {
if(player.get(1).getPosY() > maxJump) {
player.get(1).moveY(-10);
} else if(player.get(1).getPosY() == maxJump) {
player.get(1).moveY(85);
}
}
So.. the player moves -10px upwards as long as i press 'w' and when he hits maxJump (which is 375 and players position at the start is 465) he "teleports" back to 465 instead of sliding back down like he does when going up.. It's really hard to explain this without a video, but i hope somebody understands and can help me with this.
This question gives a basic answer to yours. Now in your jump function, you have to set the vertical_speed only once and only call fall() every frame and add some moveY.
Here are two alternatives:
Option 1. Simulating some very simple physics. You add forces to your player, so pressing the up arrow will add a force that makes the player move upwards. Gravity is constantly applied and thus it will gradually cancel out the force you applied when the up arrow was pressed. Perhaps you only want to use forces in the vertical direction you do something like this:
// Each frame
if(notOnTheGround){
verticalVelocity -= GRAVITATIONAL_CONSTANT;
}
// When user jumps
vertivalVelocity += JUMP_FORCE;
Option 2. An alternative is to kind of animate the jumps using projectile motion.
// Each frame
if(isJumping){
verticalVelocity = initialVelocity*sin(angle) - g*animationTime;
animationTime += TIME_STEP;
}
// When user jumps
isJumping = true;
animationTime = 0;
initialVelocity = ... // calculate initial velocity
I'm making a "space-invaders style" game. You(the player) move left and right at the bottom of the screen. There will be one enemy in each window, and you have to move to the window and shoot.
I'm working on the enemies popping up system. The window in which an enemy is random and should change every 3 seconds. Here's my code for this:
int enemylocation = new Random().nextInt(2) +1;
if(enemylocation==1){
enemy1.setFilter(Image.FILTER_NEAREST);
enemy1.draw(200,170,s*10);
}
if(enemylocation==2){
enemy2.setFilter(Image.FILTER_NEAREST);
enemy2.draw(200,360,s*10);
}
Everything works, but the random number part is always picking a new number, so both windows are flickering. How can I delay the timer to change the value of enemylocation every 3 seconds and not constantly?
Thanks
I'd say the "right" way to do this is to have a game loop that ticks x times per second. You decide to change the value of the enemylocation every x ticks. If you tick 60 times per second, that means 3 seconds will be 60 * 3 = 180. That means you can change the enemylocation when tickNumber % 180 == 0
I am guessing you already have a gameloop with a timer since you are able to render, the flickering comes from enemylocation being set too often so the enemy is rendered all over the place. What I would do is to implement a cooldown. In pseudo-ish code (no IDE):
int enemySpawnRate = 3000;
int timeElapsed = enemySpawnRate+1; //Spawn the first time
void spawnEnemy(int delta) {
timeElapsed +=delta;
if(timeElapsed>enemySpawnRate) {
//spawn enemy as before, your code snippet
timeElapsed=0;
}
}
Where delta is the ammount of time that has passed since the previous run of your gameloop.
Note this depends entirely on you have a timerbased gameloop, if you don't and you are rendering on INPUT (eg render if key pressed) the code will be different, you would have to utilize a timertask or a swingtimer if you are using swing.
What's the simplest way to draw a line between two Point objects in a way
that will look like I am drawing that line in real time by hand?
For example:
Point a = new Point(5,20);
Point b = new Point(15,20);
How do I connect these points with a "moving" line?
In other words I want to make the user feel "motion" of some sort. Is there a simple way to do that?
Given two points, you can determine the equation of the line connecting them. The equation of a line is of the form y = mx + c, where m is the slope, and c is the y intercept.
So, given your two points (5,20) and (15,20), we first determine m.
m = (y2-y1)/(x2-x1)
= (20-20)/(15-5)
= (0)/10
= 0
Substituting into the equation for a straight line, we get y = 0x + c or y = c. Now that we know this, we simply need to know the points where y = c and 5<=x<=15. Simply draw each of these points in the normal way (look at this for the exact method) with a Thread.sleep() call in between drawing each point. In this case, you have only 11 points to draw, so it would make sense to draw 1 point every 100 ms. For details on Thread.sleep() see here.
EDIT: Since Thread.sleep() won't work on the EDT, look at javax.swing.Timer instead, as Uhlen suggested.
Following the answer by Chinmay Kanchi, you need to create a feeling of animation. As mentioned above in comments by Uhlen you should use Swing's Timer when working on EDT. To give you example of how to use Timer. Lets assume we have a panel and we want it to slide open on e.g. a button click, thus we need to animate it sliding open by increasing its size. Below is an example showing pretty much how you would use Timer to do the operations.
this.extendingTimer = new Timer(0, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//assume sliding is vertical
int value = maximumHeight;
//make sure the size will not be bigger then allowed maximum
if(currentExtensionSize + extensionRate >= value)
{
currentExtensionSize = value;
stopExtending();
}
else
currentExtensionSize += extensionRate;
setSize(new Dimension(maximumWidth, currentExtensionSize));
}
});
extendingTimer.setInitialDelay(0);
extendingTimer.setDelay(100);
extendingTimer.setRepeats(true);
int lineCount = 0; //global
// timer calls the below
xLocation = (*a)[a->size()-1] * timeSoFar / duration ;
if(xLocation > (*a)[lineCount+1]){
lineCount++;
}
double m = ((*b)[lineCount+1] - (*b)[lineCount])/((*a)[lineCount+1]-(*a)[lineCount]);
double yIntercept = (*b)[lineCount]-m*(*a)[lineCount];
yLocation = m * xLocation + yIntercept;
xLocation = (yLocation - yIntercept) / m;
this is in c++ and using vectors but its the theory we want. This allows for multiple lines not just one.