I’m creating a video game, and when I call the repaint() method, the entire screen updates and flashes irregularly. I have slightly fixed that problem, by specifying what’s repainted (charRect, which is a Rectangle object) in this line of code: repaint(charRect.x, charRect.y, 20, 32); The entire screen stops flashing, but the character is incredibly glitchy. I just need help to get the animation from moving (a and d) and jumping (w) to run smoothly.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.lang.*;
import static java.lang.Math.*;
import static java.lang.System.out;
import java.util.Random.*;
import javax.swing.JApplet;
import java.awt.Graphics;
public class UltimaBlade extends JApplet implements KeyListener
{
public final int WIDTH = 900;
public final int HEIGHT = 650;
public int score = 0;
private boolean jumping = false;
private boolean moveRight = false;
private boolean moveLeft = false;
private boolean jumpRight = false;
private boolean jumpLeft = false;
private boolean moveRightWhileJumping = false;
private boolean moveLeftWhileJumping = false;
public JFrame JTitle = new JFrame("UltimaBlade");
Image characterImg = null;
Image blockImg1 = null;
Image floorImg1 = null;
Image wallImg1 = null;
JLabel scoreLabel = new JLabel("Score: " + score);
Rectangle charRect = new Rectangle(25, 450, 20, 32);
Rectangle blockRect1 = new Rectangle(25, 482, 30, 30);
Rectangle floorRect1 = new Rectangle(25, 482, 200, 1);CHANGE BACK TO 30
Rectangle wallRect1 = new Rectangle(55, 490, 1, 30);
//Rectangle tempGhost = new Rectangle(charRect.x, charRect.y, 20, 32);
public JMenuBar mb = new JMenuBar();
public JMenu menuFile = new JMenu("File");
public JMenuItem menuItemSave = new JMenuItem("Save");
public JMenuItem menuItemLoad = new JMenuItem("Load");
Container cont;
Runner runner;
public void init()
{
setSize(WIDTH, HEIGHT);
JTitle.setJMenuBar(mb);
menuFile.add(menuItemSave);
menuFile.add(menuItemLoad);
mb.add(menuFile);
JTitle.getContentPane().setLayout(new BorderLayout());
menuItemSave.addActionListener(new ListenMenuSave());
setJMenuBar(mb);
new UltimaBlade();
}
public UltimaBlade()
{
setLayout(null);
setSize(WIDTH, HEIGHT);
setVisible(true);
cont = getContentPane();
cont.setLayout(null);
addKeyListener(this);
cont.setBackground(Color.WHITE);
cont.add(scoreLabel);
scoreLabel.setBounds(50, 50, 100, 30);
scoreLabel.setForeground(Color.BLACK);
cont.setLayout(null);
repaint();
cont.validate();
runner = new Runner();
runner.start();
setContentPane(cont);
}
public class ListenMenuSave implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
new Save();
}
}
public void paint(Graphics g)
{
super.paint(g);
try
{
URL url1 = this.getClass().getResource("character.gif"); //Character
characterImg = Toolkit.getDefaultToolkit().getImage(url1);
URL url2 = this.getClass().getResource("block.gif"); //Block
blockImg1 = Toolkit.getDefaultToolkit().getImage(url2);
URL url3 = this.getClass().getResource("floor_line.gif"); //Floor Line
floorImg1 = Toolkit.getDefaultToolkit().getImage(url3);
URL url4 = this.getClass().getResource("wall_line.gif"); //Wall Line
wallImg1 = Toolkit.getDefaultToolkit().getImage(url4);
}
catch(Exception e)
{
}
g.drawImage(characterImg, charRect.x, charRect.y, this);
g.drawImage(floorImg1, floorRect1.x, floorRect1.y, this);
g.drawImage(blockImg1, blockRect1.x, blockRect1.y, this);
g.drawImage(wallImg1, wallRect1.x, wallRect1.y, this);
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyChar() == 'd' || e.getKeyChar() == 'D')
{
moveRight = true;
if(jumping)
moveRightWhileJumping = true;
}
if(e.getKeyChar() == 'a' || e.getKeyChar() == 'A')
{
moveLeft = true;
if(jumping)
moveLeftWhileJumping = true;
}
}
public void keyReleased(KeyEvent e)
{
if(e.getKeyChar() == 'd' || e.getKeyChar() == 'D')
{
moveRight = false;
if(!jumping)
moveRightWhileJumping = false;
}
if(e.getKeyChar() == 'a' || e.getKeyChar() == 'A')
{
moveLeft = false;
if(!jumping)
moveLeftWhileJumping = false;
}
}
public void keyTyped(KeyEvent e)
{
if(e.getKeyChar() == 'w' || e.getKeyChar() == 'W')
{
jumping = true;
}
}
public class Runner extends Thread// implements Runnable
{
public void run()
{
while(true)
{
try
{
int j = 5; //Beginning velocity
double t = 0;
double sum = j/5;
while(jumping)
{
repaint(charRect.x, charRect.y, 20, 32);
cont.validate();
int jump = (int)((-4.9 * ((t * t)/10)) + (j * t));
if(moveRightWhileJumping)
{
charRect.x = charRect.x + j; // Move Right while jumping.
if(charRect.intersects(wallRect1))
{
charRect.x = wallRect1.x - 21;
moveRightWhileJumping = false;
}
}
if(moveLeftWhileJumping)
{
charRect.x = charRect.x - j; //Move Left while jumping.
if(charRect.intersects(wallRect1))
{
charRect.x = wallRect1.x + 1;
moveLeftWhileJumping = false;
}
}
if(jump > 0)
{
charRect.y = charRect.y - Math.abs(jump);
if(charRect.intersects(floorRect1))
{
charRect.y = floorRect1.y - 32;
jumping = false;
moveRightWhileJumping = false;
moveLeftWhileJumping = false;
break;
}
}
else if(jump < 0)
{
charRect.y = charRect.y + Math.abs(jump);
if(charRect.intersects(floorRect1))
{
charRect.y = floorRect1.y - 32;
jumping = false;
moveRightWhileJumping = false;
moveLeftWhileJumping = false;
break;
}
}
else
{
if(charRect.intersects(floorRect1))
{
charRect.y = floorRect1.y - 32;
jumping = false;
moveRightWhileJumping = false;
moveLeftWhileJumping = false;
break;
}
}
t++;
Thread.sleep(30);
}
while(moveLeft)
{
repaint(charRect.x, charRect.y, 20, 32);
cont.validate();
charRect.x = charRect.x - j; //Move Left speed.
if(charRect.intersects(wallRect1))
{
charRect.x = wallRect1.x + 1;
}
if(charRect.intersects(floorRect1))
{
charRect.y = floorRect1.y - 32;
jumping = false;
moveRightWhileJumping = false;
moveLeftWhileJumping = false;
break;
}
t++;
Thread.sleep(30);
}
while(moveRight)
{
repaint(charRect.x, charRect.y, 20, 32);
cont.validate();
charRect.x = charRect.x + j; //Move Left speed.
if(charRect.intersects(wallRect1))
{
charRect.x = wallRect1.x + 1;
}
if(charRect.intersects(floorRect1))
{
charRect.y = floorRect1.y - 32;
jumping = false;
moveRightWhileJumping = false;
moveLeftWhileJumping = false;
break;
}
t++;
Thread.sleep(30);
}
}
catch(Exception e)
{
break;
}
}
}
}
}
One of your main problems is that you’re painting directly in the
paint(...)method JApplet itself rather in thepaintComponent(...)method of a JPanel or JCompnent that is held by the applet. If you do the latter, you gain the benefit of Swing’s default double buffering, and that can make all the difference. Also, you can repaint a smaller Rectangle of the GUI by using one of therepaint(...)overloads, but this is of secondary importance. First you should solve your lack of double buffering problem.Please start with this tutorial to learn the basics: Lesson: Performing Custom Painting
And then move on up to this article for more advanced information about drawing in Swing: Painting in AWT and Swing
Edit
Also, you should never read in files from within the
paint(...)orpaintComponent(...)methods as this will slow painting down and thereby reduce perceived responsiveness of your GUI several fold. Why not simply read in the files once and on applet startup, and then store their contents into a variable?