How to spawn enemies periodically - java

I am attempting to create a game where enemies will spawn randomly and move towards a point on the screen. My problem is that the program waits for them to spawn and them starts moving them. I want them to start moving as they spawn and have a short break in between each one.
Here's the two main methods behind making them move:
public void newLevel() {
runOnUiThread(new Runnable(){
public void run() {
int i = 0;
while( i < 10){
addSpeks();
i++;
try {
Thread.sleep(2000);
}
catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
});
}
public void addSpeks() {
Spek newSpek = new Spek(this);
setRandomRegion();
newSpek.setX(spawnX);
newSpek.setY(spawnY);
relativeLayout.addView(newSpek);
spekList.add(newSpek);
newSpek.setOnClickListener(spekListener);
newSpek.animate().x(finalX).y(finalY).setDuration(8000);
}
Spek is a simple class which extends an ImageView and setRandomRegion() selects a random x, y coordinate on the border of the screen. I have a counter in the while loop for simplicity purposes but I would like to eventually move it to a conditional infinite loop where it only stops if you lose the game.
Thanks for any help and let me know if the problem needs more clarification.

You would have to re-run your thread when it finished, in Android it can be done like this:
First, create your Runnable:
private Runnable SpawnEnemies = new Runnable(){
public void run(){
//Your code here...
spawnHandler.postDelayed(2000, this);
}
};
Then, create a handler, which will be the class that runs the thread (or, well, runnable) and start your Runnable like this:
Handler spawnHandler = new Handler();
spawnHandler.post(new SpawnEnemies());
This will run every 2 seconds, you could also add a boolean or something simmilar to stop the loop manually.

your newLevel() method runs completely on the UI Thread, and Thread.sleep(2000); is making wait your UI Thread 2seconds each iteration. To add this sort of delay you can use an Handler:
Declare the Handler as member class
final Handler mHandler = new Handler();
int i = 0;
and change newLevel accordingly:
public void newLevel() {
mHandler.postDelayed(new Runnable(){
public void run() {
if (i > 10) {
mHandler.removeCallbacks(this);
return;
}
addSpeks();
i++;
mHandler.postDelayed(this, 2000);
}
}), 2000);
}
Another optmization would be to declare the Runnable instance as final member, in order to avoid its instationation every time newLevel is called. Check for typo

Related

Trying To Delay In Java Multiple Times

Need To Do One Animation, Sleep 1000 Then Do The Next Sleep 1000 And So On, Instead It Sleeps For The Entire Time Then Plays All Animations At Once. No Idea What Im Doing.
Tried Timers, Running The Animation Before The tread.sleep And Using A While Loop Instead Of A For.
private void playLaunchAnimation()
{
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.fadein);
for(int i=0; i < buttons.size();i++)
{
try {
Thread.sleep(1000);
buttons.get(i).startAnimation(animation);
} catch (Exception e){
/*
main declares that it throws InterruptedException. This is an exception that sleep throws when another thread interrupts the current thread while sleep is active. Since this application has not defined another thread to cause the interrupt, it doesn't bother to catch InterruptedException.
*/
}
}
}
Hi, Make sure this code helps you
public static void main(String[] args) throws Exception {
for(int i=0; i < 10;i++) {
try {
Thread.sleep(1000);
System.out.println(i);
if(i==9) {
i=0;
}
} catch (Exception e){
System.out.println("error");
}
}
}
(Answer assumes Android which wasn't entirely clear in OP.)
This is somewhat of a lazy way to do it - but maybe get you thinking. It would
be more interesting to have the handler invoke the next handler so only one handler is declared - but that would be a little more work.
private void playLaunchAnimation() {
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.fadein);
for(int i=0; i < buttons.size();i++)
{
// Create a handler on the UI thread to execute after a delay.
// The delay is a function of loop index.
//
// It may be necessary to declare buttons final - but your
// OP did not list where it is defined.
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
buttons.get(i).startAnimation(animation);
}
}, ((i+1)*1000));
}
}
References:
How to call a method after a delay in Android
Android basics: running code in the UI thread
It sounds like you are calling Thread.Sleep from the User Interface thread. This will ultimately result in the entire User Interface freezing up for the duration of the sleep. What you really want is to launch sleep from a background thread.
For example:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
for(int i=0; i < buttons.size();i++)
{
try {
Thread.sleep(1000);
activity.runOnUiThread(new Runnable() {
buttons.get(i).startAnimation(animation);
});
} catch (Exception e){}
}
});
Another way you could do this using post delay:
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
buttons.get(i).startAnimation(animation);
new android.os.Handler().postDelayed(this, 1000);
}
},
1000);

Java-Repositioning of object when timer increments

I have a JFrame with two buttons. One of the buttons when clicked moves (btnMove) the other button(shape) from the present position to another.I am using a thread as a timer to count in seconds but each time the counter increments, the button moves back to its original position.
public class FrameTh extends JFrame {
class count extends Thread {
public int p = 0;
public void run() {
for (int i = 1; i < 100; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println(e);
}
lblCounter.setText("Seconds: " + i);
}
}
}
count t1 = new count();
private void formWindowActivated(java.awt.event.WindowEvent evt) {
t1.start();
}
private void btnMoveActionPerformed(java.awt.event.ActionEvent evt) {
shape.setLocation(23, 44);
}
The core problem is you're fighting the layout management API, which when you call setText is causing the container to be invalidated and relayed out
You might consider using something like JLayeredPane, but remember, you become entirely responsible for the size and position of the component
The other problem you have is you're violating the single threaded nature of Swing, Swing is not thread safe, meaning you shouldn't update the ui from out of the Event Dispatching Thread.
To solve that particular problem you should use a Swing Timer instead of a thread, see How to use Swing Timers for more details

Count integer with Thread in Activity and update Canvas in View

I'm developing my first android game without xml files for layouts in eclipse. This is calling MyGameView.class(extends View) from MyGameActivity.class(extends View implements OnTouchListener)
MyGameView myView;
myView = new MyGameView(this);
myView.setOnTouchListener(this);
setContentView(myView);
Everytime, I touch (MotionEvent.ACTION_DOWN), I update the Canvas in MyGameView.class with the following code. This is the code I use to update MyGameView.class from MyGameActivity.class.
myView.invalidate();
Yes it works!But I got a serious problem now.I need to move Canvas in MyGameView.class by every 0.3 second.I use Thread to update but it forced stop!!!! I tried again and again and again! I failed!
public void runtime() {
i = 0;
Thread timer = new Thread(new Runnable() {
#Override
public void run() {
while (i<1500) {
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
if (right) {
i++;
//This is static int a from MyGameView.
MyGameView.a += 2;
myView.invalidate();
}
else {
i = 1500;
}
}
}
}
});
timer.start();
}
Updating Static int or boolean to MyGameView.class from MyGameActivity.class with myView.invaldate(); is working. But I can't control it with Thread! Is there something wrong with my Thread running code?
It's probably up to Thread because I can move +2 along X-axis to right everytime I press (MotionEvent.ACTION_DOWN).
//I can Move with this code but not with Thread!
case MotionEvent.ACTION_DOWN:
MyGameView.a += 2;
myView.invalidate();
break;
With Thread, it stops! Please give me a solution for this! In other words, I need to count with time without error and update canvas on every count!
Invalidate must be called from the UI thread. Try calling
postInvalidate()
instead.
See this for reference.

Run Handler Task in Android successively

atm i have a problem with my actual Android application.
For explanation:
At first i want to show a Text in a TextView Char by Char. This is my actual Code for this
tvIntro.setText("");
final Handler textHandler = new Handler();
for(int i=0; i<intro.length();i++){
final int finalCount = i;
textHandler.postDelayed(new Runnable() {
#Override
public void run() {
tvIntro.setText(tvIntro.getText() + (intro.charAt(finalCount)+""));
}
}, 150 * i);
}
After the whole text is displayed, i want to play a sound and continuously change the Color of the Screen for 5 Seconds. For this, my code is:
myBackground.setBackgroundColor(Color.RED);// set initial colour
final Thread blink = new Thread(new Runnable() {
public void run() {
while (getRunning()) {
try {
Thread.sleep(100);
if(start[0] !=1){
mp.start();
start[0] = 1;
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
updateColor(myBackground);
whichColor = !whichColor;
}
}
});
private void updateColor(final RelativeLayout myBackground) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (whichColor)
myBackground.setBackgroundColor(Color.RED);
else
myBackground.setBackgroundColor(Color.GREEN);
}
});
}
All the functions are working, but i want too finish the first handler, before the second handler is executed. Furthermore the Second handler should stop after x seconds.
I have some problems understanding how the handler and the Threads work.
Would be nice if someone of you have a solution for me.
To delay the performing of tasks until a specified thread (or threads) finishes, add this line immediately after the thread you wish to wait on:
myThread.join();
And then immediately follow it with the code you wish to run after it finishes.
For your second problem, you can set a variable to be the value (in milliseconds) for the amount of time you want to wait before ending the thread, and then decrease that value by 100 (or whatever amount you choose to tell it to sleep for) each time the code runs. Have a check for the value to be less than or equal to zero, and then if that condition returns true, end the thread with an interrupt. So basically:
long timeToRun = 5000, sleepTime = 100;
// Your code here...
Thread.sleep(sleepTime);
timeToRun -= sleepTime;
if(timeToRun <= 0) {
myThread.interrupt();
}
There are likely more graceful ways to accomplish this, but at the very least this should solve your problems.

How to implement a smoothly falling JLabel without using Timer, but Threads instead

Alright, so I have a null layout JPanel with a single JLabel in it. The JLabel is positioned at (0,0). What I'm trying to do is use a while loop in a new Thread to sleep the new Thread and then shift the JLabel 10px down by using SwingUtilities.invokeLater . The problem is that the UI gets updated in a laggy sort of way. It doesn't update every time it should, but skips lots of updates and shifts in big chunks. I know I can easily do it with Timer, but the point is understanding Threads better. Thanks in advance!
Code:
private void start(){
Updater up = new Updater();
up.start();
}
public void updatePosition(){
int y = label1.getLocation.y;
label.setBounds(0,y+10, 10,10);
}
private class Updater extends Thread{
public void run(){
while(!shouldQuit){
try{
Updater.sleep(100);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updatePosition();
}
});
}catch(Exception e){
System.out.println(e);
}
}
}
}
EDIT:
I got it to work by replacing the while loop with a call to a new Thread instance in the updatePosition() method, to settle things down a bit. And also, it wasn't only the Thread that was causing the problem, so I had to force the panel to re-layout it's subviews by calling revalidate() on it.
Here's how it looks (the fully working one):
private void start(){
new Updater().start();
}
public void updatePosition(){
int y = label1.getLocation.y;
label.setBounds(0,y+10, 10,10);
panel.revalidate();
if(!shouldQuit) new Updater().start();
}
private class Updater extends Thread{
public void run(){
try{
Updater.sleep(100);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
updatePosition();
}
});
}catch(Exception e){
System.out.println(e);
}
}
}
You should try to use visibility and GridLayout to maximize movement. You can use a int var to count threads and reciprocate that to the label. As well, you should be using your ability o create Updaters, more and smoother. Just do the start() mwthod while trolling for threads :-)
You could have something besides an infinity call to start. I think you've lost the inheritance from the class, itself. The object label1 must ave been lost in tbe fray. If that's not it, then I'm pretty sure I'm not really able to answer this one.

Categories