multithreading - Oval collision method never called - Java Swing -
i need calculate 2 ovals collision in java
swing
mini game.
i have jpanel
draws arraylist
of balls thread
's , player ball. in run()
method of non player balls check collision between player ball , balls thread
arraylist
.
the problem collision method never executed. it's not getting collision if
statement. never calls method.
ball.java:
public class ball extends thread { int x; int y; int velocity = 1; public int radius = 20; public boolean directionx = true; // true - right, false - left public boolean directiony = false; // true - up, false - down public static final int y_starting_position = 0; public static final int x_starting_position = 0; public ball() { switch (this.getstartingside()) { case 0: // left { this.directionx = true; this.directiony = true; this.x = this.getrandomheight(); this.y = this.getrandomwidth(); break; } case 1: // right { this.directionx = false; this.directiony = false; this.x = this.getrandomheight(); this.y = this.getrandomwidth(); break; } case 2: // top { this.directionx = true; this.directiony = false; this.x = this.getrandomwidth(); this.y = this.getrandomheight(); break; } case 3: // bottom { this.directionx = false; this.directiony = true; this.x = this.getrandomwidth(); this.y = this.getrandomheight(); break; } } } public int getx() { return this.x; } public void setx(int x) { this.x = x; } public int gety() { return this.y; } public void sety(int y) { this.y = y; } public void move() { if (this.directionx) // right { this.x += this.velocity; } else // left { this.x -= this.velocity; } if (this.directiony) // { this.y -= this.velocity; } else // down { this.y += this.velocity; } } @override public void run() { try { this.iscollision(); // never called thread.sleep(20); } catch (interruptedexception e) { e.printstacktrace(); } } /** * random number varies 0 screen width. * * @return random number. * */ public int getrandomwidth() { random random = new random(); return random.nextint((program.getpanelwidth() - 0) + 1) + 0; // minimum = 0,maximum = program.panelwidth } /** * random number varies 0 screen height. * * @return random number. * */ public int getrandomheight() { random random = new random(); return random.nextint((program.getpanelheight() - 0) + 1) + 0; // minimum = 0,maximum = program.panelheight } /** * starting side of ball. * * left - 0. * right - 1. * top - 2. * bottom - 3. * * @return * */ public int getstartingside() { random random = new random(); return random.nextint((4 - 0) + 1) + 0; // minimum = 0,maximum = 3 } public void iscollision() { system.out.println("ssssssssssssssss"); if (math.sqrt(math.pow(mypanel.playerx + mypanel.playerradius - this.getx() + this.radius,2) + math.pow(mypanel.playery + mypanel.playerradius - this.gety() + this.radius,2)) <= mypanel.playerradius + this.radius) // collision { system.exit(0); } } } // end of ball class
mypanel.java:
public class mypanel extends jpanel implements keylistener { private static final long serialversionuid = 1l; private static final color background_color = color.white; private static final color npc_balls_color = color.red; // player oval public static int playerradius = 35; public static int playerx; public static int playery; // true - first player position, false - otherwise private boolean playerposition = true; // array of balls threads public static arraylist<ball> balls = new arraylist<ball>(); public mypanel() { this.setbackground(mypanel.background_color); this.setfocusable(true); this.addkeylistener(this); new timer(10,new updateui()); } // drawing @override protected void paintcomponent(graphics g) { super.paintcomponent(g); final double panel_width = this.getwidth(); final double panel_height = this.getheight(); if (this.playerposition) { mypanel.playerx = (int)(panel_width / 2 - mypanel.playerradius); mypanel.playery = (int)(panel_height / 2 - mypanel.playerradius); this.playerposition = false; } // drawing player g.setcolor(color.black); g.filloval(playerx,playery, mypanel.playerradius * 2, mypanel.playerradius * 2); // drawing npc's balls g.setcolor(mypanel.npc_balls_color); (ball ball: mypanel.balls) // concurrentmodificationexception { if (ball.isalive()) { ball.start(); } ball.move(); repaint(); g.filloval(ball.getx(), ball.gety(), ball.radius * 2, ball.radius * 2); } } // keyboard listeners @override public void keypressed(keyevent e) { switch (e.getkeycode()) { case keyevent.vk_w: // { mypanel.playery -= 10; repaint(); break; } case keyevent.vk_s: // down { mypanel.playery += 10; repaint(); break; } case keyevent.vk_d: // right { mypanel.playerx += 10; repaint(); break; } case keyevent.vk_a: // left { mypanel.playerx -= 10; repaint(); break; } } } @override public void keyreleased(keyevent e) { } @override public void keytyped(keyevent e) { } public class updateui implements actionlistener { @override public void actionperformed(actionevent e) { repaint(); } } } // end of mypanel class
program.java:
public class program { private static int panelwidth; private static int panelheight; public static void main(string[] args) { myframe frame = new myframe(); program.panelwidth = frame.getwidth(); program.panelheight = frame.getheight(); // generate ball each 2 seconds while (true) { try { mypanel.balls.add(new ball()); thread.sleep(500); } catch (interruptedexception e) { e.printstacktrace(); } } } // end of main method public static int getpanelwidth() { return program.panelwidth; } public static int getpanelheight() { return program.panelheight; } }
the jframe
nothing special , adds jpanel
, so.
so iscollision()
method never called if it's on run()
method of thread
. how come?
you never started thread implemented ball
class.
the concurrentmodificationexception
due fact adding balls arraylist
nature thread-unsafe datastructure if don't synchronize externally. here adding in thread while iterating list in edt (event dispatch thread). either synchronize on list, or use thread-safe data structure (for iteration still may need lock full list).
have @ collections.synchronizedlist or copyonwritearraylist (the latter doesn't need synchronizing iteration).
however, synchronization on each insertion , each iteration seems inefficient me, because aiming game requires fast rendering , background processing. may sufficient basic game though.
as sidenote: better technique game use double buffering: render game graphics in background thread e.g. on bufferedimage, , when done, switch 2 buffers 1 drew displayed on screen, , other 1 can used again drawing next frame. might need synchronization checkpoint between frames. more advanced, if starting in java, wouldn't spend time on , keep things simple.
Comments
Post a Comment