_Scyth_
|
 |
«
Posted
2013-10-29 12:16:40 » |
|
I'm making a space invaders-esk game and i have 3 rows of 11 aliens. I've down this by creating a multi-dimensional array of aliens As this is supposed to be an invasion the aliens need to move down the screen every so often, currently i'm using this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public void update() { alienTimer.schedule(new TimerTask(){
public void run() { moveAliens(); } }, 1000, 2000); }
private void moveAliens() { for(int i = (aliens.length -1); i > -1; i--) { for(int j = 10; j > -1; j--) { if(aliens[i][j] == null) { } else { aliens[i][j].moveDown(); } } } }
public void moveDown() { getPosition().y += 5; } |
but when i run the game the after the second delay all the aliens just move down the screen without stopping for the 2 second period. I've also tried scheduleAtFixedRate, but it had the same result. Anyone have any ideas, and whilst your here, how could i go about having different rows move in opposite directions left and right, eg row 1 would move left, hit the screen bounce then move right, row 2 would move right, it the screen bounce, then move left. Thanks for any help
|
|
|
|
Riven
|
 |
«
Reply #1 - Posted
2013-10-29 13:48:05 » |
|
With every call to update() (which happens at 60Hz or so) you schedule a new task.
So after 60 updates, you have scheduled 60 tasks that call moveAliens() after 2000ms.
After the initial 2000ms, every update/frame will effectively be calling moveAliens(), because the enormous amount of scheduled tasks.
What you need to do is call scheduleAtFixedRate and call that method only once, not for every update.
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
_Scyth_
|
 |
«
Reply #2 - Posted
2013-10-30 20:01:48 » |
|
That works wonders, now however, if the level changes i want the period variable to decrease so that there is less time between each movement, is there anyway to do that?
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Riven
|
 |
«
Reply #3 - Posted
2013-10-30 20:07:25 » |
|
Cancel the TimerTask and reschedule a new TimerTask. Keep in mind however that uses a new Thread behind the scenes, and you will run into all kinds of trouble due to concurrency issues. It's better (or... mandatory for non-experts) to handle all logic on the same thread.
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
_Scyth_
|
 |
«
Reply #4 - Posted
2013-10-30 20:12:42 » |
|
If there is only one timer will it cause an issue creating multiple timertasks? oh and in the timertask's run method, i will want to change the speed every 5 levels, so could i use 1 2 3 4
| if( level.getLevel() % 5 ) { this.cancel(); } |
then have a variable that is changed in the period parameter
|
|
|
|
Riven
|
 |
«
Reply #5 - Posted
2013-10-30 20:37:43 » |
|
The rendering and all other logic is happening on another thread, so yes, it will cause the weirdest bugs and crashes, if you let multiple threads manipulate the same objects.
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
_Scyth_
|
 |
«
Reply #6 - Posted
2013-10-30 20:40:17 » |
|
Is there a better way for me to handle the movement of the rows of aliens down the screen in a way so that i change the period between each movement?
|
|
|
|
SHC
|
 |
«
Reply #7 - Posted
2013-10-31 13:49:48 » |
|
I use my own timer class for these purposes. The idea is to move the aliens after counting the time. 1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class GTimer { public int elapsedTime;
public void update(long elapsedTime) { this.elapsedTime = elapsedTime; }
public void reset() { elapsedTime = 0; } } |
And use the timer like this. 1 2 3 4 5 6 7 8 9
| timer.update(elapsedTime);
if (timer.elapsedTime >= frequencyToMove) { moveAliensDown(); timer.reset(); frequencyToMove-=100; } |
Hope this helps.
|
|
|
|
_Scyth_
|
 |
«
Reply #8 - Posted
2013-11-01 15:01:08 » |
|
It does  Thanks a lot 
|
|
|
|
lcass
|
 |
«
Reply #9 - Posted
2013-11-02 08:03:34 » |
|
Question , how have you implemented that timer? the second part of the code could be placed in the main gameloop and call a function such as sectick();.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
_Scyth_
|
 |
«
Reply #10 - Posted
2013-11-02 15:53:12 » |
|
i havent put it in yet, im still trying to work out how to pass the elapsed time variable, im not sure whether system.currentTimeMilliseconds() will work or not
|
|
|
|
SHC
|
 |
«
Reply #11 - Posted
2013-11-02 16:10:18 » |
|
I use this method. 1 2 3 4
| public long getCurrentTime() { return (long)(System.nanoTime()/1000000); } |
Hope this helps.
|
|
|
|
_Scyth_
|
 |
«
Reply #12 - Posted
2013-11-03 16:19:22 » |
|
SHC do you just pass getCurrentTime() to the update() eg. update(getCurrentTime);?
|
|
|
|
Opiop
|
 |
«
Reply #13 - Posted
2013-11-03 16:24:00 » |
|
No, you should be passing the delta into the update method. The currentTime method literally gives you the current time. You should always use the delta when updating your graphics because its time it takes to change frames. You should be passing elapsedTime I believe.
|
|
|
|
SHC
|
 |
«
Reply #14 - Posted
2013-11-04 13:39:24 » |
|
SHC do you just pass getCurrentTime() to the update() eg. update(getCurrentTime);?
No, it's just a method to calculate the time. Just use the time difference between the frames or simply called, the delta time. I just posted it since you asked about the System.currentTimeMillis() method.
|
|
|
|
_Scyth_
|
 |
«
Reply #15 - Posted
2013-11-04 16:13:11 » |
|
My gameloop dosnt have an elapsed time, how will i do about getting that :/
|
|
|
|
SHC
|
 |
«
Reply #16 - Posted
2013-11-05 12:45:02 » |
|
My gameloop dosnt have an elapsed time, how will i do about getting that :/
Fixed time-step game loop? Then you can use as the elapsed time.
|
|
|
|
Riven
|
 |
«
Reply #17 - Posted
2013-11-05 16:32:54 » |
|
You mean 1.0 / UPDATES_PER_SECOND
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
_Scyth_
|
 |
«
Reply #18 - Posted
2013-11-05 22:22:03 » |
|
Err... I'm not too sure :S This is my game loop code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| final int TICKS_PER_SECOND = 30; final int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
long next_game_tick = System.currentTimeMillis(); long sleep_time = 0;
boolean game_is_running = true;
private class Logic extends Thread { public Logic() { start(); } public void run() { while( game_is_running ) { update(); invalidate(); next_game_tick += SKIP_TICKS; sleep_time = next_game_tick - System.currentTimeMillis(); if( sleep_time >= 0 ) { try { Thread.sleep(sleep_time); } catch(InterruptedException e) { e.printStackTrace(); } } else { } } } } |
|
|
|
|
SHC
|
 |
«
Reply #19 - Posted
2013-11-06 02:07:39 » |
|
Yes. You can pass to the update method and use it as elapsed time.
|
|
|
|
_Scyth_
|
 |
«
Reply #20 - Posted
2013-11-06 16:10:16 » |
|
Thanks for the help Really Appreciated 
|
|
|
|
_Scyth_
|
 |
«
Reply #21 - Posted
2013-11-06 18:29:37 » |
|
Using SKIP_TICKS doesnt work :s, if i pass next_game_tick it works but they move down the screen too fast.
|
|
|
|
SHC
|
 |
«
Reply #22 - Posted
2013-11-07 01:17:01 » |
|
Maybe something is wrong. Here's my game loop. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public final void run() { long now = getCurrentTime(); long step_size = 1000 / Global.STEPS_FOR_SECOND; long game_time = getCurrentTime();
int frames = 0; long lastFPSCount = getCurrentTime();
int updates = 0; long lastUPDCount = getCurrentTime();
int loops = 0;
while (running) { loops = 0; now = getCurrentTime();
while (now > game_time && loops < 2) { updateGame(1000 / Global.ACTUAL_STEPS_FOR_SECOND); game_time += step_size;
updates++; loops++;
if (now - lastUPDCount > 1000) { lastUPDCount = now; Global.ACTUAL_STEPS_FOR_SECOND = updates; updates = 0; } } displayGame();
frames++;
if (now - lastFPSCount > 1000) { lastFPSCount = now; Global.FRAMES_PER_SECOND = frames; frames = 0; } } }
|
It's similar to yours but it works for me.
|
|
|
|
_Scyth_
|
 |
«
Reply #23 - Posted
2013-11-07 21:30:56 » |
|
Nope, the aliens just move until they hit they bottom.
All i want is for them to move periodically, why does something so simple in concept turn out to be complicated? :/
Concept would be: 1. Move Down 2. Wait Duration Of Delay 3. Move Down
loop until game ends :S
|
|
|
|
|