How can i randomize delay of moving object - java

Recently i added that enemy shoots but unfortunately i cannot randomize delay of Shooting for every object.
Project 60 times in second :
update (all code here is connected to this part)
draw
sleep
Fragment of code :
Fragment of code.
public void createNewEnemyBullet(){
for(Enemy enemy: enemies){
EnemyBullet enemyBullet = new EnemyBullet(getResources());
randomShot = random.nextInt(60-40)+40;
System.out.println("Randomowy shot :"+ randomShot);
enemyBullet.x = (int) (((enemy.x+enemy.widthEnemy/2)-18)*screenRatioX);
enemyBullet.y= enemy.y+20;
enemyBullets.add(enemyBullet);
}
System.out.println("\n\n");
}
Screenshot of my result
enter image description here

Use Math.random(). It'll be your friend here. Compare (Math.random() <= epsilon) the output of random() with some number epsilon you want as your threshold for making an enemy shooting decision.
If enemyBullets is what the UI code uses to draw bullets, you may want to add a Thread.sleep(Math.random()) to add variable delay in adding them.

Solution for generating random delay of bullet is to change this delay when a enemy starship is shot.

Related

JAVA/Swing (Eclipse) : Program works step by step but not in normal execution

I have a job to do for school. There is a window where there are pigeons, and by clicking the mouse we place some food that pigeons have to eat. To make it simple, I use swing to paint some filled round for food and filled square for pigeons. Pigeons and Foods are Threads that have a PigeonShape or FoodShape object that are JPanels.
When I place my food, pigeons move in the right direction. The problem is that, because I use swing, I have to repaint the PigeonShape each time I change its positions. Here is the code in Pigeon.java :
The run() :
public void run(){
while(true){
try {
sleep(25);
this.observe(); //just to check what is the closest piece of Food, we don't care here
this.move();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
And the move() :
private void move(){
//If there is available food, the Pigeon has to move to it
if(this.closest != null){
/*
* some calculations for the move
* coordonates are stored in xPigeon et yPigeon that are integers
*/
//it makes the PigeonShape disappear because the background is white too
this.draw.setColor(Color.WHITE); //(1)
this.draw.repaint(); //(2)
//it changes coordinates of the Pigeon
//each time those functions are called, it call the same function for this.draw (the PigeonShape)
this.setPosX(xPigeon);
this.setPosY(yPigeon);
//it makes the PigeonShape reappear
this.draw.setColor(CURIOUS); //(3)
this.draw.repaint(); //(4)
}
}
(In the above code, this.draw is the object PigeonShape that represents this Pigeon, and CURIOUSis a private static Color equal to Color.GREEN)
The problem is that in normal execution, the PigeonShape moves, lines (3) et (4) are done but not (1) and (2). In the window, it keeps previous positions the Pigeon had :
(when the PigeonShape is green, it meens that it is curious, and when it is blue, it is asleep)
But when I debug step by step, lines (1) and (2) are correctly done and I don't have the trail of the move !
I don't understand why it works when debugging step by step but not in normal execution... Could you help me please ? Thank you !
it keeps previous positions the Pigeon had :
You need to invoke super.paintComponent(...) as the first statement when you override the paintComponent(...) method. This will clear the background before doing the custom painting.

Trying to animate a die roll in Java

I'm attempting to "animate" a die roll in Java. I currently have an icon (called "diceImage") set up that, when a button is clicked (called "diceRoll"), updates to a new random image of a die face. What I would like to do is have it change image (to a random die face) numerous times over a couple of seconds before stopping on a final image.
The problem I have is not with generating a random number, or rolling it numerous times, it's with the updating the image numerous times within a loop. The code below, which rolls the die 10 times is what I have so far:
private void diceRollActionPerformed(java.awt.event.ActionEvent evt) {
for (int i = 1; i <= 10; i++) {
rollDice();
pause(100);
}
}
This links to the following two methods (the first of which generates the random number, and sets the icon image):
private void rollDice() {
Random r = new Random();
int randomNumber = r.nextInt(6) + 1;
diceImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Game/Images/Dice " + randomNumber + ".png")));
}
The method below is "supposed" to pause the programme briefly between updating the image (this was taken from a programming course I was on where we had to animate an image of a car moving across the screen):
private void pause(int sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
System.exit(-1);
}
}
All this programme seems to do is pause and then print the final dice roll. It doesn't show any of the "intermediate" faces. Does anyone have any ideas on why this isn't working?
Any help is greatly appreciated.
This question is asked several times a day. If you sleep in the event dispatch thread, you're preventing it from doing its job: react to events and repaint the screen.
Your animation should be done in another thread. Read the tutorial about concurrency in Swing, and use a Swing Timer.
The pause() you are using is when u need to animate moving stuff like a car for example , but just changing the icon of a JLabel which is the dice here doesn't need pause ( unless you just want it to be delayed a bit) ...
but anyways , to solve your issue , you need to call repaint() on that JLabel or updateGraphics(). Setting the Icon for the JLabel doesn't make the new Icon get displayed , you just need to repaint() it .
of course like JB Nizet said , for the app not to hang you need to call repaint on a new Thread .Thought you have to learn how to use Thread well cuz it can be very tricky at times .
good luck

Create Java 2D gravity?

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

drawing random image libgdx

I am learning java game development with libgdx and have the following issue.
I have a Rectangle array which I iterate through and draw an image according to the position of the rectangle.
My Questions is how do I draw a random image every render but still keep drawing the same random image until it leaves the screen. currently it is drawing the same image but I would like know how to draw a different pipe image every iter.
Thank you
My Iterator
Iterator<Rectangle> upperIter = upperPipes.iterator();
while(upperIter.hasNext()) {
Rectangle upperpipe = upperIter.next();
upperpipe.x -= 8 * Gdx.graphics.getDeltaTime();
if(upperpipe.x < -32) upperIter.remove();
My draw method
public void drawPipes(){
batch.begin();
for(Rectangle upperPipe: Pipes.lowerPipes) {
batch.draw(Assets.pipeImg, upperPipe.x, upperPipe.y, upperPipe.width, upperPipe.height);
batch.end();
}
One great way to get repeatable random data is to use a Random object (java.util.Random is suitable for game usage), and provide it with a non-random seed. Each time you put in the seed and request the same sequence of number types+ranges, you will get the same (psuedo-)random numbers. When you want different numbers, just change the seed.
As an example:
Random rand = new Random(1234);
System.out.println(rand.nextInt()); // an int from Integer.MIN to Integer.MAX
System.out.println(rand.nextInt(100)); // an int from 0 to 100
Will always output the following, every single time.
-1517918040
33
But change the seed (in the constructor for Random), and the output values will change. rand.setSeed(seed) will reset the Random to start its sequence over.
You could use this to produce the same set of random numbers over and over while the rect is on screen.
However, a more direct and simple way would be to to just generate one random number for each rect when it is created, and store that number until it leaves:
public void drawPipes(){
for(int i = 0; i<Pipes.color.size; i++){
num = Pipes.color.get(i);
}
for(Rectangle bottomPipe: Pipes.lowerPipes) {
switch(num){
case 0:
batch.draw(Assets.redPipeImg, bottomPipe.x, bottomPipe.y, bottomPipe.width, bottomPipe.height);
break;
case 1:
batch.draw(Assets.yellowPipeImg, bottomPipe.x, bottomPipe.y, bottomPipe.width, bottomPipe.height);
break;
}
}
}
SOLVED!!
I created a custom pipe class and just created an array of pipes, each new pipe object that went into the array took a random image.
I iterated through the array, and called the draw method on each pipe object.
Simple and it works perfect

Java Game Dev: How to put a timer around this code?

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.

Categories