As part of a project I am currently working on we (a few fellow coding enthusiasts friends) we are trying to make a relatively simple game. The game was to consist of several smaller games that we would program separately and my job was to combine them together into a sorta frankensteined super game.
One of these mini games consists of a "transportation Simulator". Very similar to something like frogger; just a lane swerving minigame. My friend who programmed this has it running 14 swing workers to complete tasks like spawning oncoming cars, road animations and your car. The problem I am having is when I call this class all of the threads don't launch. Some don't activate till after others finish, and others will run behind others. I moved the swingworkers into an Execution Service, but still get similar results. Is there a cap on number of threads running simultaneously? Are swingworkers the wrong thing for the job? It is very confusing for me because I cannot see any consistency in the failed threads. There seems to be no reason why sometimes they launch and other times don't. Any suggestions?
This is the Constructor
travelGUI(Player playerIn) throws InterruptedException {
...
//player is a object that contains a variable for each GUI
//it is also a Parameter
player = playerIn;
player.mapGUI.setVisible(false);
player.mapGUI.dispose();
methodNewThread();//road display
carThread();//Used to update the car in the game
copShootThread();
copShootThread();//Used to set up the bullet shoot thread that shoots at the car
healthThread();
bulletThread();
copThread("1", 1, "1" + "p");
copThread("2", 2, "2" + "p");
copThread("3", 3, "3" + "p");
copThread("4", 4, "4" + "p");
//Creates the background animation for the road and the end conditions for the level
intComponents();
}
an example of one of the threads is
public static void healthThread() {//This thread is used to update the players health
SwingWorker<Void, String> he;
he = new SwingWorker<Void, String>() {
#Override
protected Void doInBackground() throws Exception {
//code to be run in the new thread
...
}
return null;
}
};
// he.execute();
executorService.submit(he);
}
Related
I'm working on a simple 2D text-base game. So, I have 2 Player class thats fighting in a Arena class. I want to use them at the same time and modify their (position, hp, etc...)
For example: when program is running, Player1 move to x,y position, Player2 move to x,y position and then they have new position in Arena at the same time.
What's the best way to do this?
Don't conflate game time with CPU time. Just because players move at the same game time doesn't mean you need to have CPU threads executing concurrently. You just need a logic loop that simulates simultaneous movement.
For example, loop over all the players and check that their actions don't conflict with each other. If two players want to move to the same location, show an error. Otherwise, loop over them a second time and move them all to their new locations. Then redraw the scene. Even though you're updating the players one at a time in the second loop, the screen won't show the movements until the entire scene is repainted.
For this you must use thread. Here is an example of this:
public static void main(String[] args) {
new Thread() {
public void run() {
method1();
}
}.start();
new Thread() {
public void run() {
method2();
}
}.start();
//etc
//or, as kingdamian42 pointed out, if you use java8, use this
new Thread(() -> method1()).start();
new Thread(() -> method2()).start();}
here method one and two will be you players move.
I'm working on a processing sketch here: https://github.com/davidcool/processing/tree/master/polyhedrons/polyhedrons_4
It's not very elegant code-wise but works fine. It renders rotating complex (meaning many faces) polyhedrons to the screen. Each time you click it adds 5 new rotating polyhedron objects... Once you have 20-25 objects it starts to bog down, meaning the frames/sec drop and it looks jumpy.
I've been reading about threading in Processing/Java. So I started to think maybe I could split the total number of objects out to each processing core. I saw this example in particular: http://www.camnewnham.com/threading-in-processing/
Before I dive into this goose chase, does anyone know if threading would help in terms of animation speed? When I run a sketch normally does it always just use one core for the draw loop? Can threading spread out the object animation rendering over "idle" cores?
Thanks!
The draw() function is always called by the same Thread. This same Thread also calls the mousePressed() and similar functions. In Processing this is called the Animation Thread- Java has a similar idea, called the EDT.
So you can't simply move your drawing to other threads. This will cause problems with the rendering- for example, the Animation Thread might be trying to draw the next frame, while your drawing threads are still trying to draw the previous frame. It's not going to work.
You could try to do your own multi-threaded off-screen buffering by having all your helper threads draw to a PGraphics instead of calling the Processing drawing methods directly. You'd then have to synchronize all of your drawing threads and only draw your PGraphics to the screen (using the Animation Thread) after all of those threads have finished.
This is not a particularly difficult job, but it does involve a pretty decent understanding of how threading works, which goes beyond the scope of most Processing sketches.
Also note that JavaScript doesn't have multiple threads, so anything you do with threading will not work in JavaScript mode.
Here's an example sketch that uses just the Animation Thread to draw 10000 random points every frame. I get about 7 FPS with it:
PGraphics sharedGraphics;
void setup(){
size(500, 500);
sharedGraphics = createGraphics(500, 500);
}
void draw(){
sharedGraphics.beginDraw();
sharedGraphics.background(0);
for(int i = 0; i < 10000; i++){
sharedGraphics.ellipse(random(500), random(500), 5, 5);
}
sharedGraphics.endDraw();
image(sharedGraphics, 0, 0);
println(frameRate);
}
And here is how you might use multiple Threads to render to a PGraphics:
PGraphics sharedGraphics;
void setup() {
size(500, 500);
sharedGraphics = createGraphics(500, 500);
}
void draw() {
ArrayList<Thread> threads = new ArrayList<Thread>();
sharedGraphics.beginDraw();
sharedGraphics.background(0);
for (int i = 0; i < 100; i++) {
Thread t = new DrawThread();
threads.add(t);
t.start();
}
for (Thread t : threads) {
try {
t.join();
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
sharedGraphics.endDraw();
image(sharedGraphics, 0, 0);
println(frameRate);
}
class DrawThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
sharedGraphics.ellipse(random(500), random(500), 5, 5);
}
}
}
However, the performance of that is even worse than the single-threaded model, and I get strange artifacts (some of the ellipses are filled, others are not) which suggests that PGraphics is not thread-safe. That might depend on the type of renderer you're using. You might then add some synchronization:
class DrawThread extends Thread {
public void run() {
for (int i = 0; i < 100; i++) {
synchronized(sharedGraphics) {
sharedGraphics.ellipse(random(500), random(500), 5, 5);
}
}
}
}
That works, but the performance of it is even worse, since you're still only accessing the PGraphics with one thread at a time, and you're doing a bunch of extra work every time draw() is called.
You might be able to fiddle around with it to make it work, but the end result is that it's probably not worth it.
"Some people, when confronted with a problem, think “I know, I'll use multithreading”. Nothhw tpe yawrve o oblems."
I am working on a school project that involves generating two separate Swing Canvas objects which animate Breadth/Depth-First Search Algorithms on cloned copies of a Matrix/Grid Data Structure I have designed.
I have created a few classes that help translate the Matrix/Grid into graphics, which are combined in a SearchAnimation class that acts a ViewController for managing the animations. In the image below, they appear on the right (not in the yellow background area). Each SearchAnimation object includes a JLabel, Canvas, and White Background.
Below is a screenshot of the layout:
The JFrame contains two instances of the SearchAnimation Class in the Application Controller Class (ICL.java). These animations must run concurrently. I have created separate Threads for each animation, passing it separate SearchAnimation objects:
public void setupDepthFirstPanel() {
// Create a new GridGraphic Panel
//canvasDepthFirst = new GridPanel(null, DEPTH_FIRST_LABEL);
mDepthAnimation = new SearchAnimation(null, SearchAnimationType.DEPTH_FIRST_ANIMATION);
mDepthThread = new Thread(mDepthAnimation, "Depth Thread");
}
public void setupBreadthFirstPanel() {
// Create a new GridGraphic Panel
//canvasBreadthFirst = new GridPanel(null, BREADTH_FIRST_LABEL);
mBreadthAnimation = new SearchAnimation(null, SearchAnimationType.BREADTH_FIRST_ANIMATION);
mBreadthThread = new Thread(mBreadthAnimation, "Breadth Thread");
}
I start the Threads in the ActionListener class that responds to the Click Event of the button that labeled "Label Components":
if ( source == labelComponents ) {
if (DEBUG && DEBUG_CLICK_LISTENER) System.out.println("\"Label Components\" Button Clicked!");
/*This is where the call for the labelBreadth and labelDepth of the
ICLLogic class is going to occur*/
// Run Animation
// Set Up Threads
System.out.println("ICL.ActionPerformed - Current Thread: " + Thread.currentThread());
//mBreadthThread = new Thread(mBreadthAnimation, "Breadth Animation");
//mDepthThread = new Thread(mDepthAnimation, "Depth Animation");
// Start Threads
mBreadthThread.start();
mDepthThread.start();
}
When the program runs and the "Label Components" button is clicked, only one of the graphics starts animating, but it seems as though both SearchAnimation Threads are running within a single JPanel/Canvas since the animation does not follow the logic of either algorithm.
Here is the implementation of the Runnable Interface within SearchAnimation:
// THREAD METHODS
/** Implementation of the Runnable interface for Multithreading of the
* SearchAnimation Class, which allows multiple SearchAnimations to run Concurrently.
* In this case, the Breadth & Depth-First SearchAnimations
*
*/
public void run() {
System.out.println("Thread Started - " + mAnimationType.toString());
// Run the Animation
step();
}
Which eventually calls determineSearchType() that switches on an Enum to pick the appropriate Algorithm:
public void determineSearchType(Pixel p) {
// Animate a single pixel movement, step depends on AnimationType
if (DEBUG && DEBUG_STEP_NEXT_PIXEL) { System.out.println("Determining Animation Type..."); }
switch (mAnimationType) {
case BREADTH_FIRST_ANIMATION:
if (DEBUG && DEBUG_STEP_NEXT_PIXEL) { System.out.println("Animation Type: Breadth-First"); }
// Begin Breadth-First Search
stepBreadthSearch(p);
break;
case DEPTH_FIRST_ANIMATION:
if (DEBUG && DEBUG_STEP_NEXT_PIXEL) { System.out.println("Animation Type: Depth-First"); }
// Begin Depth-First Search
stepDepthSearch(p);
//simpleDepthSearch(mCurrentPixel);
break;
}
}
When I alternate commenting them out, each Thread/Animation executes in its own JPanel/Canvas graphic and produces the expected results. I am pretty new to threading and I'm sure someone has an easy solution. Any ideas at how I can fix the issue that the animations won't animate simultaneously?
option1 :
to give another Thread chance to be executed. at the end of thread code, try yield() and see if you have some luck
Thread.currentThread().yield();
option2 :
add flag in your thread, to pause and continue the thread. the idea is
after thread 1 finish the step
- pause thread 1 - then start thread 2 - after thread 2 finish the step
- pause thread 2 - and continue thread 1 again.
I created a live wallpaper service using AndEngine library. On screen there are a number of bird Sprite objects that flying repeatedly from the left to right started in random y-coordinate (I'm using LoopEntityModifier and PathModifier for this, see my previous question if you're curious). The birds shouldn't start flying in same time, but there is a gap/interval about 3 seconds before another bird showed up from left most screen.
The question is what technique that I have to use to achieve that?
I had created array of Sprites to hold the bird sprites. The code is like this...
public class MyLiveWallpaperService extends BaseLiveWallpaperService {
private BirdSprite[] birdSprites; // BirdSprite is actually an extension class from AnimatedSprite
...
#Override
public Scene onLoadScene() {
...
birdSprites= new BirdSprite[4];
for (int i=0; i<4; ++i) {
birdSprites[i] = new BirdSprite(0, 0, birdTextureRegion);
scene.getChild(LAYER_FRONT).attachChild(birdSprites[i]);
}
}
}
The above code produces four birds that show-up on left screen in same time. I tried by adding Thread.sleep(3000) before calling attachChild, but it affects whole application. The live wallpapaper application become hanged for several seconds when started.
This is the solution I found by using TimerHandler:
scene.registerUpdateHandler(new TimerHandler(3, true, new ITimerCallback() {
#Override
public void onTimePassed(TimerHandler pTimerHandler) {
// your code here will be executed every 3 seconds (see 1st argument of TimerHandler)
...
scene.getChild(LAYER_FRONT).attachChild(birdSprites[i]);
}
}));
Please let me know if you have better solution.
I'm trying to implement a countdown timer into a pre-existing public class and I have a few questions.
An overview: I want to have a timer within a program that counts down from 60 (seconds) once the program is initialized.
If the timer reaches zero, the program quits.
If the user meets certain parameters within the 60 second time frame, the timer resets to 60, presents a new set of parameters, and begins the countdown again. It should be able to do this an infinite number of times, until the user fails to meet parameters within 60 seconds.
There will also be some sort of (TBD) GUI representation of the timer, most likely either numerical countdown or JProgressBar.
I'm semi-new (~3 months) to programming, self-taught, and still learning lots (so be gentle) :)
My questions are:
What is the best way to implement this?
I'm assuming this needs to run in a thread?
Will the timer be easily configurable? (not important, just interesting)
Thanks for your help. If you need to see code, I can find some.
EDIT: Just for some clarification/context:
This is for a timed racing video game I'm working on to develop my skills as a programmer. The idea is that a player has 60 seconds to complete a lap. If the player completes a successful lap, the timer resets to 60 seconds and the track changes to be slightly more difficult. The game runs until the player is unable to complete a lap in 60 seconds due to the difficulty. The game records the number of laps as a high score, and asks to player if they would like to try again.
If I were you, I'd use:
an AtomicInteger variable which would keep the current countdown value;
a timer thread that would wake up every 1s and decrementAndGet() the variable, comparing the result to zero and terminating the app if the result is zero;
(possibly) a thread that would also wake up every 1s to repaint the GUI -- the best approach here depends on your GUI framework.
Finally, whenever you need to reset the count back to 60s, you just call set(newValue) from any thread.
The timer thread's run() method could be as simple as:
for (;;) {
if (counter.decrementAndGet() <= 0) {
// TODO: exit the app
}
Thread.sleep(1000);
}
I think it's much easier to get this right than trying to manage multiple Timer objects.
The best way to impliment timer in your application is using some sheduler frameworks like Quartz
You could use java.util.Timer to schedule an execution of a method and then cancel it if the requirements is met.
Like this:
timer = new Timer();
timer.schedule(new Task(), 60 * 1000);
And then make a class like this to handle the timerschedule:
class Task extends TimerTask {
public void run() {
System.exit(0);
}
}
If the requirements is met, then do this to stop it from executing:
timer.cancel();
If you need to update your GUI better to use SwingWorker http://en.wikipedia.org/wiki/SwingWorker
I would write something like this:
SwingWorker<String, Integer> timer = new SwingWorker<String, Integer>() {
Integer timer=60;
#Override
protected String doInBackground() throws Exception {
//update guiModel
//label.setText(timer.toString());
while(timer>0){
Thread.sleep(1000);
timer--;
}
return null;
}
#Override
public void done(){
System.exit(0);
}
};
JButton restart = new JButton(){
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.cancel(true);
timer.execute();
}
});
}
};