Hi I'm studying the basics of java threads,
but I'd like to get some help because I don't understand the examples in the book.
https://imgur.com/a/pcdOq2n
In this example, when the user presses any key,
the yellow bar is filled with magenta and the bar's magenta is
reduced by a thread.
But the part I don't understand is if you press the key for a long time while bar is full,
the magenta of the bar does not reduce immediately when the key is released
when I checked. the fill() function was running for a certain time even when the key was released.
I want to know, why if the bar is full and the key is pressed for a long time,
the fill() function works for a certain time even when the key is released
and the bar does not reduce immediately.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class MyLabel extends JLabel {
private int barSize = 0;
private int maxBarSize;
public MyLabel(int maxBarSize) {
this.maxBarSize = maxBarSize;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.MAGENTA);
int width = (int) ( ( (double)( getWidth() ) )/maxBarSize *barSize );
if (width == 0) return;
g.fillRect(0, 0, width, this.getHeight());
}
synchronized void fill() {
if (barSize == maxBarSize) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
return;
}
}
barSize++;
repaint();
notify();
}
synchronized void consume() {
if (barSize == 0) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
return;
}
}
System.out.println("consume");
barSize--;
repaint();
notify();
}
}
class ComsumerThread extends Thread {
private MyLabel bar;
public ComsumerThread(MyLabel bar) {
this.bar = bar;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(true) {
try {
sleep(100);
bar.consume();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
return;
}
}
}
}
public class TabAndThreadEx extends JFrame {
private MyLabel bar = new MyLabel(100);
public TabAndThreadEx(String title) {
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(null);
bar.setBackground(Color.orange);
bar.setOpaque(true);
bar.setLocation(20, 50);
bar.setSize(300, 20);
c.add(bar);
c.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
bar.fill();
}
});
setSize(350, 200);
setVisible(true);
c.setFocusable(true);
c.requestFocus();
ComsumerThread th = new ComsumerThread(bar);
th.start();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new TabAndThreadEx("Quickly press any key to fill the bar");
}
}
Related
I am writing a breakout Game and everything is working fine except one little thing.
I have a ball object which extends from thread and RepainterThread which can either implement Runnable or extends Thread which calls the paint method which re-renders the game field with bricks, a paddle, and a Ball
I have a Singelton GameController which connects all things.
I have a GameState with an isActive boolean to decide if the game should be paused or not.
I start the game and I can play and the program behaves as it should.
The Frame gets drawn the ball moves the bricks break when the ball hits everything fine.
Then I pause the game via a Button where I set is Active to false.
The Ball stops as it should. Then I hit the continue Button and isActive is again true. The ball object starts running again and the running method of Repainter Thread is allso triggered but the Swing Frame Freezes completely.
I tried various things these are my nearest approaches i have.
I spent days on it please help
public class Ball extends MovingObject {
private double hSpeed; // Horizontal velocity
private double vSpeed; // Vertical velocity
public Ball() {
this.color = Color.MAGENTA;
this.height = GameSettings.ballSize;
this.width = GameSettings.ballSize;
this.position = new Point2D.Double(GameSettings.defaultBallX, GameSettings.defaultBallY);
this.hSpeed = GameSettings.ballHSpeed;
this.vSpeed = GameSettings.ballYSpeed;
}
public Ball(Ball ball) {
color = ball.color;
height = ball.height;
width = ball.width;
position = ball.position;
hSpeed = ball.hSpeed;
vSpeed = ball.vSpeed;
}
public double getHSpeed() {
return this.hSpeed;
}
public double getVSpeed() {
return this.vSpeed;
}
public void run() {
try {
while (GameController.getInstance().getGameState().isActive()) {
System.out.println("Ich run im Ball");
Thread.sleep(10);
this.meetingWall();
this.meetingBrick();
this.position.setLocation(this.getPosition().getX() + this.hSpeed,
this.getPosition().getY() + this.vSpeed);
if (this.meetingPaddle()) {
this.newDirection();
}
if (this.out()) {
GameController.getInstance().stopGame();
this.stopThread();
}
this.position = this.getPosition();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void stopThread() {
GameController.getInstance().getGameState().setActive(false);
}
public void startThreadAgain() {
this.run();
}
#Override
public synchronized void start() {
this.position.setLocation(GameSettings.defaultBallX, GameSettings.defaultBallY);
super.start();
}
class GamePanel extends JPanel {
private static final long serialVersionUID = 1L;
private final Color backgroundColor = Color.BLACK;
GameState gameState = GameController.getInstance().getGameState();
public GamePanel() {
super();
this.addKeyListener(new KeyListener() {
// Dieser KeyListener soll auf Inputs der Pfeiltasten nach links
// <- und rechts -> hoeren und eine entsprechende Bewegung des
// Schlaegers erwirken, aber nur, wenn das Spiel nicht
// pausiert/gestoppt ist.
public void keyPressed(KeyEvent keyEvent) {
if (gameState.isActive()) {// gameState.isActive()
if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
gameState.getPaddle().setPositionRigth();
}
if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
gameState.getPaddle().setPositionLeft();
}
}
}
public void keyReleased(KeyEvent keyEvent) {
// TODO
}
public void keyTyped(KeyEvent arg0) {
}
});
}
public void paint(Graphics g) {
Graphics2D graphics2D = (Graphics2D) g;
graphics2D.setColor(this.backgroundColor);
graphics2D.fillRect(0, 0, this.getWidth(), this.getHeight());
for (int i = 0; i < gameState.getBricks().length; i++) {
for (int j = 0; j < gameState.getBricks()[i].length; j++) {
if ((gameState.getBricks()[i][j] != null)) {
graphics2D.setColor(gameState.getBricks()[i][j].getColor());
graphics2D.fillRect(
(i * GameSettings.brickWidth) + (i + 1) * (GameSettings.spaceAroundBrick + 1),
(j * GameSettings.brickHeight) + (j + 1) * GameSettings.spaceAroundBrick,
GameSettings.brickWidth, GameSettings.brickHeight);
}
scoreLabel.setText(this.gameState.getScore() + "");
gameState.getPaddle().draw(graphics2D);
gameState.getBall().draw(graphics2D);
}
}
}
}
// First Approach
private class RepainterThread implements Runnable {
public RepainterThread() {
System.out.println("RepainThreadCOntructor");
}
private void updateGUI() {
System.out.println("before invoke later");
System.out.println("repaint");
getGamePanel().requestFocus();
getGamePanel().repaint();
}
#Override
public void run() {
System.out.println("Repainter run");
System.out.println(GameController.getInstance().getGameState().isActive());
while (GameController.getInstance().getGameState().isActive()) {
System.out.println("inside while");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updateGUI();
}
}
}
// Second Approach
private class RepainterThread implements Runnable {
public RepainterThread() {
System.out.println("RepainThreadCOntructor");
}
private void updateGUI(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println("repaint");
getGamePanel().requestFocus();
getGamePanel().repaint();
}
});
}
#Override
public void run() {
System.out.println("Repainter run");
System.out.println(GameController.getInstance().getGameState().isActive());
while (GameController.getInstance().getGameState().isActive()) {
System.out.println("inside while");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updateGUI();
}
}
}
Frame should no longer freeze
please help
This is kind of a wild guess, but since according to your description the program works correctly until you pause and unpause it, the problem likely lies with the startThreadAgain method:
public void startThreadAgain() {
this.run();
}
Your code does not show how you call this method, but in that method you just call this.run(), i.e. you call the run method as a regular, blocking method, while probably still in the UI thread. Instead, you should call start() to start a proper new thread executing the run method.
public void startThreadAgain() {
super.start(); // not this start, otherwise it resets the ball's location
}
I'm going to create a JPanel Howto, which is rendering 6 images in order and then add the back button to go back to title.
I'm trying check if it call paintComponent method in class howto or not. And it doesn't so the value i is still 0 and end up stuck in loop
Here's my Howto class
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JPanel;
import Audio.HitSound;
import Graphic.DrawingUtility;
public class Howto extends JPanel implements Runnable{
private JButton back;
private static int i;
public Howto(){
this.setPreferredSize(new Dimension(800, 600));
this.setLayout(null);
repaint();
HitSound h = new HitSound();
i=0;
this.setVisible(true);
}
public void run() {
// TODO Auto-generated method stub
try {
while(i<6)
{
GameManager.frame.repaint();
Thread.sleep(10);
System.out.println("i: " + i);
}
} catch (Exception e) {
// TODO: handle exception
Thread.interrupted();
}
}
public void paintComponent(Graphics g){
if(GameManager.thread.isAlive()){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(DrawingUtility.getHowto(i), 0, 0, 800, 600,null);
i++;
}
}
}
and this what in my GameManager class
public static void startThread() {
thread = new Thread(howto);
thread.start();
}
public static void runHowto() {
howto = new Howto();
howto.setVisible(true);
frame.switchScene(howto);
howto.repaint();
startThread();
while (thread.isAlive()) {
//frame.repaint();
}
if (!thread.isAlive()) {
JButton back = new JButton();
back.setBorderPainted(false);
back.setContentAreaFilled(false);
back.setFocusPainted(false);
back.setOpaque(false);
back.setBounds(640, 446, 132, 132);
back.addMouseListener(new MouseListener() {
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
HitSound h = new HitSound();
h.play(3);
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
GameManager.goToTitle();
}
});
}
but when I call runHowto(); it's still looping and i == 0 and not increase i
So I think it's may have problem with paintComponent and repaint method
So please help me fixing it Thanks in advance :)
The while (thread.isAlive()) loop blocks the AWT Event Dispatch Thread (EDT).
You need to return to the event dispatch loop from runHowto. Have your Howto task to post back to the EDT with java.awt.EventQueue.invokeLater to construct your back button and presumably add it to a panel.
I have an application where onMouseDown starts drawing a line and the line is drawn when onMouseUp. The problem I have is that when I move my mouse the previous lines stays. How can I do it to work normally and when the line is drawn, the previous are deleted?
To get it more clear I'm posting a screanshots:
And here is my code:
public class MainClass {
private static Point fp;
private static Point lp;
public static void main(String[] args) {
// TODO Auto-generated method stub
Display d = new Display();
Shell shell = new Shell(d);
shell.setLayout(new FillLayout());
Canvas c = new Canvas(shell, SWT.NONE);
c.setSize(100, 100);
c.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
shell.open();
createPaintListener(c);
createMouseListener(c);
createMoveListener(c);
while(!shell.isDisposed()) {
if(!d.readAndDispatch()) {
d.sleep();
}
}
d.dispose();
}
private static void createMoveListener(final Canvas c) {
// TODO Auto-generated method stub
c.addMouseMoveListener(new MouseMoveListener() {
#Override
public void mouseMove(MouseEvent e) {
// TODO Auto-generated method stub
if (fp != null) {
GC gc = new GC(c);
if(lp != null) {
gc.setXORMode(true);
gc.drawLine(fp.x, fp.y, lp.x, lp.y);
lp = new Point(e.x, e.y);
gc.drawLine(fp.x, fp.y, lp.x, lp.y);
}else {
lp = new Point(e.x, e.y);
}
gc.dispose();
}
}
});
}
private static void createMouseListener(final Canvas c) {
c.addMouseListener(new MouseListener() {
#Override
public void mouseDoubleClick(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseDown(MouseEvent e) {
// TODO Auto-generated method stub
if (fp == null) {
fp = new Point(e.x, e.y);
} else {
}
}
#Override
public void mouseUp(MouseEvent e) {
// TODO Auto-generated method stub
GC gc = new GC(c);
gc.drawLine(fp.x, fp.y, e.x, e.y);
gc.dispose();
fp = null;
}
});
}
private static void createPaintListener(Canvas c) {
c.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
// TODO Auto-generated method stub
}
});
}
}
Remove all the drawing code from the mouse listeners. The drawing should only occur inside paint(). Even though you keep newing up a GC() in the mouse listeners, internally, they all point to the same memory buffer that gets output to the screen, so you're drawing a new line every time the mouse moves, on top of the old buffer. In paint(), you're getting the an empty buffer to start with.
private static void createPaintListener(Canvas c) {
c.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent e) {
e.gc.drawLine(fp.x, fp.y, lp.x, lp.y);
}
});
}
i am trying to make a simple reaction test in java.
when the screen turns green i press space witch is supposed to change te boolean "clicked into false and stop the loop that measures time.
in reality the key listner does nothing.
am i adding the keay listener to the right compnent( jpanel panel)?
is there any other problems?
import java.awt.Color;
import java.awt.RenderingHints.Key;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
public class mainCheck {
// //////////////////////////////////////
public static void timeKeeper() {
boolean clicked=false;
long time = 10000;
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
panel.setBackground(Color.GREEN);
while (time > 0 && !clicked) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
time--;
}
panel.setBackground(Color.gray);
long time2= 10000-time;
JLabel x = new JLabel("" +time2+"");
panel.add(x);
}
// //////////////////////////////////////
static boolean clicked;
JFrame frame;
static JPanel panel;
public mainCheck() {
frame = new JFrame();
panel = new JPanel();
clicked = false;
Handler handler = new Handler();
frame.addKeyListener(handler);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
// //////////////////////////////////////
public static void main(String[] args) {
mainCheck f = new mainCheck();
panel.getActionMap();
f.timeKeeper();
}
// //////////////////////////////////////
public class Handler implements KeyListener {
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
clicked = false;
System.out.println("space pressed");
}
}
}
}
do not use Thread.sleep(5000); block Event Dispatch Thread and during sleep you can lost all events to the already visible Swing GUI
use Swing Timer instead
Thread.sleep(1); could be proper delay for space enviroment, non_human, very short period attacking latency in Native OS (8-14miliseconds, depends of Native OS)
JLabel x = new JLabel("" +time2+""); and panel.add(x); in AWT/Swing isn't any notifiers that some, any, part of JComponents are removed or added, have to notify used LayoutManager (JPanel has FlowLayout in API) by using methods revalidate and repaint, e.g.
.
JLabel x = new JLabel("" +time2+"");
panel.add(x);
panel.revalidate();
panel.repaint();
Swing GUI should be created on Initial Thread
don't to use KeyListener use KeyBindings instead, otherwise you (are focus hunter) would need to set panel.seFocusable(true);
The problem is that you "e.getKeyCode()" always is "0" so
change for "e.getKeyChar()" and "(char)32"
the other problem is in that you put clicked = false and must be
"true"
And the last problem you have is in "timeKeeper()" you have to erase "boolean" because it is already declarated
Bad
public static void timeKeeper() {
boolean clicked=false
....}
Good
public static void timeKeeper() {
clicked=false
....}
This is the correct code:
import java.awt.Color;
import java.awt.event.*;
import javax.swing.*;
public class mainCheck {
// //////////////////////////////////////
public static void timeKeeper() {
clicked=false;
long time = 10000;
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
panel.setBackground(Color.GREEN);
while (time > 0 && !clicked) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
time--;
}
panel.setBackground(Color.gray);
long time2= 10000-time;
JLabel x = new JLabel("" +time2+"");
panel.add(x);
}
// //////////////////////////////////////
static boolean clicked;
JFrame frame;
static JPanel panel;
Handler handler = new Handler();
public mainCheck() {
frame = new JFrame();
panel = new JPanel();
clicked = false;
frame.addKeyListener(handler);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
// //////////////////////////////////////
public static void main(String[] args) {
mainCheck f = new mainCheck();
panel.getActionMap();
f.timeKeeper();
}
// //////////////////////////////////////
public class Handler implements KeyListener {
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == (char)32) {
clicked = true;
System.out.println("space pressed");
}
}
}
}
It's a really bad idea to use Thread.sleep() to decrement the time value.
Use a Timer object instead:
public void myTimer(){
Timer myTimer = new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
//Stuff to do
}
});
}
Where delay is the amount of time you delay the timer. You start the timer with myTimer.start();
the cut code: This is the code, I cant get rid of the line rendering the tank2, it works fine when I switch the client that is sending data to this server. This is the server side of the game I am making:-
package dataEx;
import java.applet.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import javax.imageio.ImageIO;
public class test extends Applet implements Runnable, ActionListener,MouseListener, MouseMotionListener,Serializable
{
dataToExchange xc;
public static Image makeColorTransparent(Image im, final Color color)
{
ImageFilter filter = new RGBImageFilter()
{
public int markerRGB = color.getRGB() | 0xFF000000; //color to make transparent
public final int filterRGB(int x, int y, int rgb)
{
if ( ( rgb | 0xFF000000 ) == markerRGB )
{
// Mark the alpha bits as zero - transparent
return 0x00FFFFFF & rgb;
}
else
{
// nothing to do
return rgb;
}
}
};
ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(ip);
}
private Image dbImage;
private Graphics dbg;
ServerSocket server;
Socket connection;
dataToExchange data_recv=null;
Thread t;
int frameNumber=0;
int speed=5,block_front=0,block_end=0;
int fire=0,tankSpeed=0,pressing=0;
int topnose_x1,topnose_x2,topnose_y1,topnose_y2;
int bck_x=-500;
int init_x=500,tank_y=500;
int hand_x,hand_y,mouth_x,mouth_y;
double theta =0.785,angle;
int moveWithBck=0,glass_x=500;
Boolean shoot=false;
Image cannon[]=new Image[6];
Image glass,glass_t;
Image background;
//String[] tankSeq=new String[6];
ObjectInputStream input;
ObjectOutputStream output;
public void init()
{
setCursor (Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
try
{
connect();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
setSize(1350,640);
setBackground( Color.white);
cannon[0]=getImage (getCodeBase (), "1.png");
cannon[1]=getImage (getCodeBase (), "2.png");
cannon[2]=getImage (getCodeBase (), "3.png");
cannon[3]=getImage (getCodeBase (), "4.png");
cannon[4]=getImage (getCodeBase (), "5.png");
cannon[5]=getImage (getCodeBase (), "6.png");
glass = getImage (getCodeBase (), "glass.png");
glass_t = makeColorTransparent(glass, Color.red);
background = getImage (getCodeBase (), "wall2.jpg");
}
private void connect() throws ClassNotFoundException
{
int portNumber=1232;
server = null;
try
{
server=new ServerSocket(portNumber,1);
while(true)
{
System.out.println("wainting for clients");
connection=server.accept();
input=new ObjectInputStream(connection.getInputStream());
output= new ObjectOutputStream(connection.getOutputStream());
String message=(String)input.readObject();
System.out.println("message "+message);
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void start()
{
Thread t = null;
t = new Thread( this );
t.start();
try {
SendTheChange();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void update (Graphics g) //overriding the update for double buffering
{
// initialize buffer
dbImage = createImage (this.getSize().width, this.getSize().height);
dbg = dbImage.getGraphics ();
// clear screen in background
dbg.setColor (getBackground());
dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
// draw elements in background
dbg.setColor (getForeground());
paint (dbg);
// draw image on the screen
g.drawImage (dbImage, 0, 0, this);
}
void drawTank(Graphics g) throws MalformedURLException, IOException
{
int tank_x=tankSpeed+init_x;
if(frameNumber<5)
{
if(pressing==1)
frameNumber=frameNumber+1;
}
else
frameNumber=0;
Image tank= ImageIO.read(new URL(getCodeBase(), "1.png"));
Image tank2 = makeColorTransparent(tank, new Color(0).white);
**g.drawImage (tank2, tank_x,tank_y, this)**; //I just cant get rid of this line
g.drawImage (cannon[frameNumber], tank_x,tank_y, this);
topnose_x1=tank_x+100;
topnose_x2=tank_x+150;
topnose_y1= tank_y+65;
topnose_y2=tank_y+50;
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(7));
double base,height;
base=hand_x-topnose_x1;
height=topnose_y1-hand_y;
if(base<2)
{
base=2;
}
if(height<4)
{
height=4;
}
double tantheta=height/base;
theta=-Math.atan(tantheta);
topnose_x2=(int) (53*Math.cos(theta)+topnose_x1);
topnose_y2=(int) (53*Math.sin(theta)+topnose_y1);
g2.drawLine(topnose_x1,topnose_y1 , topnose_x2, topnose_y2);
g2.drawLine(topnose_x1+5,topnose_y1+4 , topnose_x2+2, topnose_y2+1);
g2.drawLine(topnose_x1+10, topnose_y1+5, topnose_x2+4, topnose_y2+2);
pressing=0;
}
void drawBackground(Graphics g)
{
g.drawImage (background,bck_x,0, this);
}
public void paint( Graphics g)
{
drawBackground(g);
try {
drawTank(g);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run()
{
while (true)
{
try {
recieveChanges();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}{
// repaint the applet
repaint();
try
{
Thread.sleep (20);
}
catch (InterruptedException ex)
{
}
}
}
}
private void recieveChanges() throws IOException, ClassNotFoundException
{
data_recv=(dataToExchange)input.readObject();
//System.out.println("ds"+data_recv.xOffsetTank);
}
int checkBckRange()
{
int p_bck_x = 0;
if(bck_x<0)
{
p_bck_x=bck_x*-1;
block_front=0;
}
else
{
block_front=1;
}
//if(bck_x+bck_length>)
return p_bck_x;
}
private void SendTheChange() throws IOException
{
dataToExchange data=new dataToExchange() ;
int p_bck_x=checkBckRange();
int offset=p_bck_x+init_x;
data.frameIndex=frameNumber;
data.xOffsetTank=offset;
output.writeObject(data);
output.flush();
}
public boolean mouseMove (Event e, int x, int y)
{
hand_x=x;
hand_y=y;
return false;
}
public boolean mouseDrag (Event e, int x, int y)
{
hand_x=x;
hand_y=y;
return false;
}
public boolean mouseDown (Event e, int x, int y)
{
if(shoot==false)
{
shoot=true;
mouth_x=topnose_x1;
mouth_y=topnose_y1-2;
moveWithBck=0;
angle=-theta;
//System.out.println(x+" "+y+"\n");
}
return true;
}
public boolean keyDown(Event e, int key)
{
// user presses left cursor key
if (key == 'a'&& block_front==0)
{
bck_x=bck_x+speed;
moveWithBck=moveWithBck+speed;
pressing=1;
}
// user presses right cursor key
else if (key == 'd')
{
bck_x=bck_x-speed;
moveWithBck=moveWithBck-speed;
pressing=1;
}
else if (key == 'w')
{
tank_y=tank_y-200;
}
else if (key == 's')
{
tank_y=tank_y-200;
}
try {
SendTheChange();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return true;
}
#Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
Doing this in a paint method looks like a very bad idea to me:
tank= ImageIO.read(new URL(getCodeBase(), "1.png"));
You should do that once when your applet starts up. I wonder whether it's just spending all its time reading images...