the following code draws a square with two smaller square rotating inside it. whenever you click an arrow on the keyboard, the whole system will move in that direction. however i'm having some problems with the image tearing and at times skipping (its small but still there). i was wondering if anybody knew how i could fix these issues w/o massively altering the code.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import static java.awt.Color.*;
public class GUI extends JPanel implements ActionListener, KeyListener
{
int x, y, x1, y1, x2, y2, changeX, changeY, changeX2, changeY2;
JFrame frame;
Runtime r;
public static void main(String[] args)
{
new GUI();
}
public GUI()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e)
{
e.printStackTrace();
}
setSize(1020,770);
setBackground(WHITE);
setOpaque(true);
setVisible(true);
x = 0;
y = 0;
x1 = 0;
y1 = 0;
x2 = 0;
y2 = 0;
changeX=1;
changeY=0;
changeX2=1;
changeY2=0;
r = Runtime.getRuntime();
frame = new JFrame();
frame.setSize(1020,819);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(createMenuBar());
frame.validate();
frame.setBackground(WHITE);
frame.addKeyListener(this);
frame.setTitle("GUI");
frame.setContentPane(this);
frame.setVisible(true);
frame.createBufferStrategy(2);
Timer t = new Timer(100,this);
t.setActionCommand("Draw");
t.start();
repaint();
}
public JMenuBar createMenuBar()
{
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem save = new JMenuItem("Save");
save.setMnemonic(KeyEvent.VK_S);
save.setContentAreaFilled(false);
save.setOpaque(false);
save.addActionListener(this);
JMenuItem load = new JMenuItem("Load");
load.setMnemonic(KeyEvent.VK_L);
load.setContentAreaFilled(false);
load.setOpaque(false);
load.addActionListener(this);
JMenuItem quit = new JMenuItem("Quit");
quit.setMnemonic(KeyEvent.VK_Q);
quit.setContentAreaFilled(false);
quit.setOpaque(false);
quit.addActionListener(this);
fileMenu.add(save);
fileMenu.add(load);
fileMenu.addSeparator();
fileMenu.add(quit);
fileMenu.setContentAreaFilled(false);
fileMenu.setBorderPainted(false);
fileMenu.setOpaque(false);
JMenu editMenu = new JMenu("Edit");
JMenuItem undo = new JMenuItem("Undo");
undo.setMnemonic(KeyEvent.VK_U);
undo.setContentAreaFilled(false);
undo.setOpaque(false);
undo.addActionListener(this);
JMenuItem redo = new JMenuItem("Redo");
redo.setMnemonic(KeyEvent.VK_R);
redo.setContentAreaFilled(false);
redo.setOpaque(false);
redo.addActionListener(this);
editMenu.add(undo);
editMenu.add(redo);
editMenu.setContentAreaFilled(false);
editMenu.setBorderPainted(false);
editMenu.setOpaque(false);
JMenu helpMenu = new JMenu("Help");
JMenuItem controls = new JMenuItem("Controls");
controls.setMnemonic(KeyEvent.VK_C);
controls.setContentAreaFilled(false);
controls.setOpaque(false);
controls.addActionListener(this);
JMenuItem about = new JMenuItem("About");
about.setMnemonic(KeyEvent.VK_A);
about.setContentAreaFilled(false);
about.setOpaque(false);
about.addActionListener(this);
helpMenu.add(controls);
helpMenu.addSeparator();
helpMenu.add(about);
helpMenu.setContentAreaFilled(false);
helpMenu.setBorderPainted(false);
helpMenu.setOpaque(false);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);
return menuBar;
}
public void paintComponent(Graphics g)
{
g.clearRect(0, 0, 1020, 770);
g.setColor(BLACK);
g.fillRect(x,y,100,100);
g.setColor(RED);
g.fillRect(x1,y1,50,50);
g.setColor(BLUE);
g.fillRect(x2,y2,25,25);
g.dispose();
}
public void change()
{
if(x1>=x+50&&changeY==0&&changeX==1)
{
changeX=0;
changeY=1;
}
else if(y1>=y+50&&changeX==0&&changeY==1)
{
changeX=-1;
changeY=0;
}
else if(x1<=x&&changeX==-1&&changeY==0)
{
changeX=0;
changeY=-1;
}
else if(y1<=y&&changeY==-1&&changeX==0)
{
changeX=1;
changeY=0;
}
x1+=changeX*5;
y1+=changeY*5;
}
public void change2()
{
if(x2>=x1+25&&changeY2==0&&changeX2==1)
{
changeX2=0;
changeY2=1;
}
else if(y2>=y1+25&&changeX2==0&&changeY2==1)
{
changeX2=-1;
changeY2=0;
}
else if(x2<=x1&&changeX2==-1&&changeY2==0)
{
changeX2=0;
changeY2=-1;
}
else if(y2<=y1&&changeY2==-1&&changeX2==0)
{
changeX2=1;
changeY2=0;
}
x2+=changeX2*2;
y2+=changeY2*2;
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equalsIgnoreCase("Draw"))
{
r.runFinalization();
r.gc();
change();
change2();
repaint();
}
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_UP)
{
if(y-10>=0)
{
y-=10;
y1-=10;
y2-=10;
}
}
if(e.getKeyCode()==KeyEvent.VK_DOWN)
{
if(y+110<=getHeight())
{
y+=10;
y1+=10;
y2+=10;
}
}
if(e.getKeyCode()==KeyEvent.VK_LEFT)
{
if(x-10>=0)
{
x-=10;
x1-=10;
x2-=10;
}
}
if(e.getKeyCode()==KeyEvent.VK_RIGHT)
{
if(x+110<=getWidth())
{
x+=10;
x1+=10;
x2+=10;
}
}
repaint();
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
You are not constructing on the EDT. An instance of javax.swing.Timer makes this easy, as the action event handler executes on the EDT.
Addendum 1: You may decide you need double buffering, but first compare the code below to yours and see. If you go that route, you might look at this tutorial.
Addendum 2: The example below shows how to maintain an offscreen buffer, but it is sometimes easier to use the JPanel(boolean isDoubleBuffered) constructor for a similar effect.
import java.awt.event.KeyAdapter;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import static java.awt.Color.*;
/** #see http://stackoverflow.com/questions/2114455 */
public class GUI extends JPanel implements ActionListener {
int x, y, x1, y1, x2, y2, changeY, changeY2;
int changeX = 1; int changeX2 = 1;
Timer t = new Timer(100, this);
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new GUI(true).display();
}
});
}
public GUI(boolean doubleBuffered) {
super(doubleBuffered);
this.setPreferredSize(new Dimension(320, 240));
}
private void display() {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addKeyListener(new KeyListener());
frame.add(this);
frame.pack();
frame.setVisible(true);
t.start();
}
#Override
public void paintComponent(Graphics g) {
g.setColor(WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(BLACK);
g.fillRect(x, y, 100, 100);
g.setColor(RED);
g.fillRect(x1, y1, 50, 50);
g.setColor(BLUE);
g.fillRect(x2, y2, 25, 25);
}
public void change() {
if (x1 >= x + 50 && changeY == 0 && changeX == 1) {
changeX = 0;
changeY = 1;
} else if (y1 >= y + 50 && changeX == 0 && changeY == 1) {
changeX = -1;
changeY = 0;
} else if (x1 <= x && changeX == -1 && changeY == 0) {
changeX = 0;
changeY = -1;
} else if (y1 <= y && changeY == -1 && changeX == 0) {
changeX = 1;
changeY = 0;
}
x1 += changeX * 5;
y1 += changeY * 5;
}
public void change2() {
if (x2 >= x1 + 25 && changeY2 == 0 && changeX2 == 1) {
changeX2 = 0;
changeY2 = 1;
} else if (y2 >= y1 + 25 && changeX2 == 0 && changeY2 == 1) {
changeX2 = -1;
changeY2 = 0;
} else if (x2 <= x1 && changeX2 == -1 && changeY2 == 0) {
changeX2 = 0;
changeY2 = -1;
} else if (y2 <= y1 && changeY2 == -1 && changeX2 == 0) {
changeX2 = 1;
changeY2 = 0;
}
x2 += changeX2 * 2;
y2 += changeY2 * 2;
}
#Override
public void actionPerformed(ActionEvent e) {
change();
change2();
repaint();
}
private class KeyListener extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
int d = 5;
if (e.getKeyCode() == KeyEvent.VK_UP) {
if (y - d >= 0) {
y -= d;
y1 -= d;
y2 -= d;
}
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
if (y + 100 + d <= getHeight()) {
y += d;
y1 += d;
y2 += d;
}
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
if (x - d >= 0) {
x -= d;
x1 -= d;
x2 -= d;
}
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
if (x + 100 + d <= getWidth()) {
x += d;
x1 += d;
x2 += d;
}
}
}
}
}
I would take a look at double buffering. Basically, you draw to an offscreen graphics object and then draw the offscreen graphics object onto the JPanel's graphics object.
~Bolt
Related
I'm trying to make a Brick Breaker game where the ball which is initially on the paddle(referred to as BAR in the code below) is launched with a speed(approx 100) in some random direction, if it hits any brick on the screen the brick disappears and the ball changes direction accordingly.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.event.KeyEvent;
import java.awt.event.*;
public class Brick_Breaker extends Canvas implements KeyListener{
int BRICK_WIDTH=60,BRICK_HEIGHT=30,X=0,Y=0;
int BAR_X = 390,BAR_Y=560,BAR_WIDTH=120,BAR_HEIGHT=20,BAR_DX=10;
int BALL_X=440,BALL_Y=540,BALL_SIZE=20,BALL_DX=0,BALL_DY=0;
int LEFT_WALL=100,RIGHT_WALL=800,TOP_WALL=10;
boolean GAME_STATE=false;
int BAR_STATE=0;
static int[][] y = new int[10][5];
static int[][] x = new int[10][5];
static int[][] status = new int[10][5];
static Canvas canvas;
static JFrame frame;
#Override
public void keyReleased(KeyEvent ke){}
#Override
public void keyTyped(KeyEvent ke){}
public void STaRT(){
frame = new JFrame("My Drawing");
frame.addKeyListener(this);
canvas = new Brick_Breaker();
canvas.setSize(900, 600);
frame.add(canvas);
frame.pack();
frame.setVisible(true);
}
#Override
public void update(Graphics g){
BALL_X += BALL_DX;
BALL_Y += BALL_DY;
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
if(BALL_X>x[i][j]&&BALL_X<(x[i][j]+BRICK_WIDTH)&&BALL_Y<=y[i][j]+BAR_HEIGHT+BALL_SIZE && BALL_Y>y[i][j]&&BALL_DY<0){
BALL_DY=-BALL_DY;
status[i][j]-=1;
}else if(BALL_X>x[i][j]&&BALL_X<(x[i][j]+BRICK_WIDTH)&&BALL_Y>=y[i][j]-BALL_SIZE && BALL_Y<y[i][j]+BAR_HEIGHT&&BALL_DY>0){
BALL_DY=-BALL_DY;
status[i][j]-=1;
}else if(BALL_X+BALL_SIZE>=x[i][j]&&BALL_X<(x[i][j]+BRICK_WIDTH)&&BALL_Y>=y[i][j] && BALL_Y<y[i][j]+BAR_HEIGHT&&BALL_DY<0){
BALL_DX=-BALL_DX;
status[i][j]-=1;
}else if(BALL_X>x[i][j]&&BALL_X-BALL_SIZE<=(x[i][j]+BRICK_WIDTH)&&BALL_Y>=y[i][j] && BALL_Y<y[i][j]+BAR_HEIGHT&&BALL_DY<0){
BALL_DX=-BALL_DX;
status[i][j]-=1;
}else if(BALL_X-BALL_SIZE<LEFT_WALL||BALL_X+BALL_SIZE>RIGHT_WALL){
BALL_DX=-BALL_DX;
}else if(BALL_Y-BALL_SIZE<TOP_WALL){
BALL_DY=-BALL_DY;
}
}
}
BAR_X = BAR_X +BAR_STATE*BAR_DX;
repaint();
}
public static void main(String[] args) {
Brick_Breaker bb = new Brick_Breaker();
bb.STaRT();
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
x[i][j] = 300+60*j;
y[i][j] = 50+30*i;
status[i][j] = 1;
}
}
}
#Override
public void keyPressed(KeyEvent ke){
if(!GAME_STATE){
BALL_DX = (int)(100*Math.random());
BALL_DY = (int)(Math.sqrt(100*100-BALL_DX*BALL_DX));
GAME_STATE = true;
}else if(ke.getKeyCode() == KeyEvent.VK_LEFT){
BAR_STATE=-1;
}else if(ke.getKeyCode()==KeyEvent.VK_RIGHT){
BAR_STATE=1;
}
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.white);
g.drawLine(LEFT_WALL,600, LEFT_WALL, TOP_WALL);
g.drawLine(RIGHT_WALL, 600, RIGHT_WALL, TOP_WALL);
g.drawLine(LEFT_WALL,TOP_WALL,RIGHT_WALL,TOP_WALL);
g.fillRect(BAR_X,BAR_Y,BAR_WIDTH,BAR_HEIGHT);
g.setColor(Color.red);
g.fillOval(BALL_X, BALL_Y, BALL_SIZE, BALL_SIZE);
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
if(status[i][j]>0){
X = x[i][j];Y=y[i][j];
g.setColor(Color.white);
g.fillRect(X, Y, BRICK_WIDTH, BRICK_HEIGHT);
g.setColor(Color.red);
g.fillRect(X+3, Y+3, BRICK_WIDTH-6, BRICK_HEIGHT-6);
}
}
}
setBackground(Color.black);
}
}
Here the update function doesn't seem to update at all.
I'm not really sure on how the method works as well.
Any help would be appreciated
Canvas is a pretty low level component and one which I'd only consider using if I needed to use a BufferStrategy.
update is called as part of the paint phase and because you've overridden it without calling it's super implementation, you broke the paint workflow.
AWT and Swing generally employ a passive rendering system, this means that updates only occur when the system decides it needs to happen, so overriding update the way you have doesn't really make sense and isn't going to help you.
A better place to start is with a JPanel, the main reason is because it's double buffered and saves you hassles of trying to figure out how to eliminate flickering.
A good place to start is Performing Custom Painting and Painting in AWT and Swing to gain a better understanding of how painting works (and how you should work with it).
KeyListener is also a poor choice for input monitoring, seriously, just do some searching on SO for all the reasons why.
A better, and generally less problematic approach is to use key bindings as well.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
int BRICK_WIDTH = 60, BRICK_HEIGHT = 30, X = 0, Y = 0;
int BAR_X = 390, BAR_Y = 560, BAR_WIDTH = 120, BAR_HEIGHT = 20, BAR_DX = 1;
int BALL_X = 440, BALL_Y = 540, BALL_SIZE = 20, BALL_DX = 0, BALL_DY = 0;
int LEFT_WALL = 100, RIGHT_WALL = 800, TOP_WALL = 10;
boolean GAME_STATE = false;
int BAR_STATE = 0;
int[][] y = new int[10][5];
int[][] x = new int[10][5];
int[][] status = new int[10][5];
private Timer timer;
public TestPane() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
x[i][j] = 300 + 60 * j;
y[i][j] = 50 + 30 * i;
status[i][j] = 1;
}
}
BALL_DX = 0; //(int) (100 * Math.random());
BALL_DY = -1;//(int) (Math.sqrt(100 * 100 - BALL_DX * BALL_DX));
setBackground(Color.BLACK);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");
ActionMap am = getActionMap();
am.put("left", new KeyAction(this, -1));
am.put("right", new KeyAction(this, 1));
}
#Override
public void addNotify() {
super.addNotify(); //To change body of generated methods, choose Tools | Templates.
if (timer == null) {
timer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tick();
}
});
timer.start();
}
}
#Override
public void removeNotify() {
super.removeNotify();
if (timer != null) {
timer.stop();
timer = null;
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(900, 600);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.white);
g2d.drawLine(LEFT_WALL, 600, LEFT_WALL, TOP_WALL);
g2d.drawLine(RIGHT_WALL, 600, RIGHT_WALL, TOP_WALL);
g2d.drawLine(LEFT_WALL, TOP_WALL, RIGHT_WALL, TOP_WALL);
g2d.fillRect(BAR_X, BAR_Y, BAR_WIDTH, BAR_HEIGHT);
g2d.setColor(Color.red);
g2d.fillOval(BALL_X, BALL_Y, BALL_SIZE, BALL_SIZE);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
if (status[i][j] > 0) {
X = x[i][j];
Y = y[i][j];
g2d.setColor(Color.white);
g2d.fillRect(X, Y, BRICK_WIDTH, BRICK_HEIGHT);
g2d.setColor(Color.red);
g2d.fillRect(X + 3, Y + 3, BRICK_WIDTH - 6, BRICK_HEIGHT - 6);
}
}
}
g2d.dispose();
}
protected void tick() {
BALL_X += BALL_DX;
BALL_Y += BALL_DY;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
if (BALL_X > x[i][j] && BALL_X < (x[i][j] + BRICK_WIDTH) && BALL_Y <= y[i][j] + BAR_HEIGHT + BALL_SIZE && BALL_Y > y[i][j] && BALL_DY < 0) {
BALL_DY = -BALL_DY;
status[i][j] -= 1;
} else if (BALL_X > x[i][j] && BALL_X < (x[i][j] + BRICK_WIDTH) && BALL_Y >= y[i][j] - BALL_SIZE && BALL_Y < y[i][j] + BAR_HEIGHT && BALL_DY > 0) {
BALL_DY = -BALL_DY;
status[i][j] -= 1;
} else if (BALL_X + BALL_SIZE >= x[i][j] && BALL_X < (x[i][j] + BRICK_WIDTH) && BALL_Y >= y[i][j] && BALL_Y < y[i][j] + BAR_HEIGHT && BALL_DY < 0) {
BALL_DX = -BALL_DX;
status[i][j] -= 1;
} else if (BALL_X > x[i][j] && BALL_X - BALL_SIZE <= (x[i][j] + BRICK_WIDTH) && BALL_Y >= y[i][j] && BALL_Y < y[i][j] + BAR_HEIGHT && BALL_DY < 0) {
BALL_DX = -BALL_DX;
status[i][j] -= 1;
} else if (BALL_X - BALL_SIZE < LEFT_WALL || BALL_X + BALL_SIZE > RIGHT_WALL) {
BALL_DX = -BALL_DX;
} else if (BALL_Y - BALL_SIZE < TOP_WALL) {
BALL_DY = -BALL_DY;
}
}
}
BAR_X = BAR_X + BAR_STATE * BAR_DX;
repaint();
}
class KeyAction extends AbstractAction {
private TestPane source;
private int delta;
public KeyAction(TestPane source, int delta) {
this.source = source;
this.delta = delta;
}
#Override
public void actionPerformed(ActionEvent e) {
source.BAR_STATE = delta;
}
}
}
}
I've messed with delta values, because the ball and bar disappeared real quick
I am working in java with swing. I've created a ball which moves on the sides of the screen. What I want is to pause the animaion when I click on the frame. I am implementin MouseListener but to no avail.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Ball extends JFrame implements MouseListener
{
int x = 20;
int y = 20;
int rad = 20;
boolean temp1 = true;
boolean temp2 = true;
boolean temp3 = true;
Ball()
{
setSize(500, 500);
setVisible(true);
}
public void mouseClicked(MouseEvent me)
{
System.out.println("Hee");
temp3 = false;
}
public void mouseEntered(MouseEvent me){
temp3 = false;
}
public void mouseExited(MouseEvent me){
System.out.println("");
}
public void mouseReleased(MouseEvent me){
System.out.println("");
}
public void mousePressed(MouseEvent me){
System.out.println("");
}
void move()
{
if(x == rad && y == rad)
{
temp1 = temp2 = true;
}
if(x < (getWidth() - rad) && temp1 )
{
x = x + 1;
}
if( x == (getWidth() - rad) && y < getHeight() -rad)
{
x = getWidth() - rad;
y = y + 1;
}
if( y == getHeight() - rad && temp2 )
{
temp1 = false;
y = getHeight() - rad;
x = x - 1;
}
if( x == rad )
{
temp2 = false;
x = rad;
y = y -1;
}
try{
Thread.sleep(1);
}catch(Exception e)
{
}
}
public void paint(Graphics g)
{
super.paint(g);
g.fillOval(x, y, rad, rad);
}
public static void main(String[] args)
{
Ball b = new Ball();
while(b.temp3)
{
b.move();
b.repaint();
}
}
}
There are two fundamental problems with the code:
The loop in the main(..) method is blocking the Event Dispatch Thread.
The MouseListener is never added to the frame.
The code still has ways it should be changed, but here are both those problems fixed:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Ball extends JFrame implements MouseListener {
int x = 20;
int y = 20;
int rad = 20;
boolean temp1 = true;
boolean temp2 = true;
boolean temp3 = true;
Ball() {
setSize(500, 500);
setVisible(true);
// the correct way to animate a Swing GUI
ActionListener animationListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (temp3) {
move();
repaint();
}
}
};
Timer timer = new Timer(20, animationListener);
timer.start();
// add the listener to the frame!
this.addMouseListener(this);
}
public void mouseClicked(MouseEvent me) {
System.out.println("Hee");
temp3 = false;
}
public void mouseEntered(MouseEvent me) {
temp3 = false;
}
public void mouseExited(MouseEvent me) {
System.out.println("");
}
public void mouseReleased(MouseEvent me) {
System.out.println("");
}
public void mousePressed(MouseEvent me) {
System.out.println("");
}
void move() {
if (x == rad && y == rad) {
temp1 = temp2 = true;
}
if (x < (getWidth() - rad) && temp1) {
x = x + 1;
}
if (x == (getWidth() - rad) && y < getHeight() - rad) {
x = getWidth() - rad;
y = y + 1;
}
if (y == getHeight() - rad && temp2) {
temp1 = false;
y = getHeight() - rad;
x = x - 1;
}
if (x == rad) {
temp2 = false;
x = rad;
y = y - 1;
}
try {
Thread.sleep(1);
} catch (Exception e) {
}
}
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, rad, rad);
}
public static void main(String[] args) {
Ball b = new Ball();
}
}
I am making a multiplayer air hockey game as a project. When the ball falls my game stops and I want to restart the game, to count player scores. My question is how can I restart the game?
My code is:
package proje;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BallGame extends JPanel implements KeyListener, ActionListener,
Runnable {
static boolean right = false;
static boolean left = false;
static boolean right2 = false;
static boolean left2 = false;
int disk2x = 60;
int disk2y = 20;
int disk1x = 60;
int disk1y = 450;
public boolean intersects(Rectangle r, Rectangle p) {
int a;
int b;
int radiusR = (r.width / 2);
int radiusP = (p.width / 2);
double hip;
a = Math.abs((r.x) - (p.x));// x düzleminde yarıçapları farkı
b = Math.abs((r.y)) - ((p.y));// y düzleminde yarıçapları farkı
hip = Math.abs(Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)));
if (hip < radiusR + radiusP) {
return true;
} else
return false;
}
int ballx = 60;
int bally = 43;
Rectangle Ball = new Rectangle(ballx, bally, 20, 20);
Rectangle disk1 = new Rectangle(disk1x, disk1y, 56, 56);
Rectangle disk2 = new Rectangle(disk2x, disk2y, 56, 56);
Thread t;
BallGame() {
addKeyListener(this);
setFocusable(true);
t = new Thread(this);
t.start();
}
public static void main(String[] args) {
JFrame frame = new JFrame();
BallGame game = new BallGame();
frame.setSize(500, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(game);
frame.setLocationRelativeTo(null);// pencere ortada olsun diye
frame.setResizable(false);
frame.setVisible(true);
}
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillRect(0, 0, 500, 600);
g.setColor(Color.green);
g.fillRect(0, 0, 200, 7);
g.setColor(Color.green);
g.fillRect(300, 0, 200, 7);
g.setColor(Color.green);
g.fillRect(0, 566, 200, 7);
g.setColor(Color.green);
g.fillRect(300, 566, 200, 7);
g.setColor(Color.green);
g.fillRect(0, 0, 7, 600);
g.setColor(Color.green);
g.fillRect(489, 0, 7, 600);
g.setColor(Color.red);
g.fillOval(Ball.x, Ball.y, Ball.width, Ball.height);
g.setColor(Color.blue);
g.fillOval(disk1.x, disk1.y, disk1.width, disk1.height);
g.setColor(Color.black);
g.fillRect(500, 600, 500, 600);
g.setColor(Color.yellow);
g.fillOval(disk2.x, disk2.y, disk2.width, disk2.height);
}
int movex = -2;
int movey = -2;
boolean BallFall = false;
int count = 0;
public void run() {
while (BallFall == false) {
if (intersects(disk2, Ball)) {
movey = -movey;
}
repaint();
Ball.x += movex;
Ball.y += movey;
if (left2 == true) {
disk2.x -= 3;
right2 = false;
}
if (right2 == true) {
disk2.x += 3;
left2 = false;
}
if (left == true) {
disk1.x -= 3;
right = false;
}
if (right == true) {
disk1.x += 3;
left = false;
}
if (disk1.x <= 4) {
disk1.x = 4;
} else if (disk1.x >= 445) {
disk1.x = 445;
}
if (intersects(Ball, disk1)) {
movey = -movey;
}
if ((200 <= Ball.x) && (Ball.x <= 300) && (Ball.y <= 0)) {
BallFall = true;
}
if (Ball.x <= 0 || Ball.x + Ball.height >= 480) {
movex = -movex;
}
if (Ball.y <= 0) {
movey = -movey;
}
if ((Ball.y >= 560) && (Ball.x >= 300)) {
movey = -movey;
}
if ((Ball.y >= 560) && (Ball.x <= 200)) {
movey = -movey;
}
if ((200 <= Ball.x) && (Ball.x <= 300) && (Ball.y >= 600)) {
BallFall = true;
}
try {
Thread.sleep(8);
} catch (Exception ex) {
}
}
}
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT) {
left = true;
}
if (keyCode == KeyEvent.VK_RIGHT) {
right = true;
}
if (keyCode == KeyEvent.VK_A) {
left2 = true;
}
if (keyCode == KeyEvent.VK_D) {
right2 = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT) {
left = false;
}
if (keyCode == KeyEvent.VK_RIGHT) {
right = false;
}
if (keyCode == KeyEvent.VK_A) {
left2 = false;
}
if (keyCode == KeyEvent.VK_D) {
right2 = false;
}
}
#Override
public void keyTyped(KeyEvent arg0) {
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
I'm having some problems with my java applet...
MouseMotionListener works in eclipse applet viewer but not on browsers(I tried Chrome and Firefox and IE). In the game, I try to move a object using mouse.
The MouseMotionListener is in the initComponents method.
package tk.miloskostadinovski.game;
import java.applet.Applet;
import java.awt.Button;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.SwingUtilities;
public class Game extends Applet implements Runnable {
private static final long serialVersionUID = 1L;
// varibles
Thread thread;
boolean running = false;
Random random = new Random();
boolean pauseRunning = false;
int width = 600, height = 700;
int x = 350, y = 560;
int fruitSpeed = 2;
int points = 0;
int lives = 5;
int basketWH = 100;
int fruitWH = 70;
int aX = getRandNumbX(), aY = getRandNumbY();
int oX = getRandNumbX(), oY = getRandNumbY();
int sX = getRandNumbX(), sY = getRandNumbY();
int bX = getRandNumbX(), bY = getRandNumbY();
int hX = getRandNumbX(), hY = getRandNumbY();
int basketX = 350;
int basketY = 580;
private Image i;
private Graphics doubleG;
Image apple, orange, banana, straw, hamburger, background, basket, heart,
mellon;
public void init() {
initComponents();
setSize(width, height);
setLayout(null);
apple = getImage(getDocumentBase(), "pictures/apple.png");
orange = getImage(getDocumentBase(), "pictures/orange.png");
banana = getImage(getDocumentBase(), "pictures/banana.png");
straw = getImage(getDocumentBase(), "pictures/straw.gif");
hamburger = getImage(getDocumentBase(), "pictures/hamburger.png");
background = getImage(getDocumentBase(), "pictures/background.jpg");
basket = getImage(getDocumentBase(), "pictures/basket.png");
heart = getImage(getDocumentBase(), "pictures/heart.png");
mellon = getImage(getDocumentBase(), "pictures/mellon.png");
}
public void start() {
}
public void stop() {
running = false;
if (thread != null) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void destroy() {
}
public void run() {
pauseButton.setVisible(true);
while (running) {
while (pauseRunning) {
repaint();
}
fruitMoving();
repaint();
if (aY >= height) {
aY = getRandNumbY();
aX = getRandNumbX();
lives--;
}
if (oY >= height) {
oY = getRandNumbY();
oX = getRandNumbX();
lives--;
}
if (bY >= height) {
bY = getRandNumbY();
bX = getRandNumbX();
lives--;
}
if (sY >= height) {
sY = getRandNumbY();
sX = getRandNumbX();
lives--;
}
if (hY >= height) {
hY = getRandNumbY();
hX = getRandNumbX();
}
if (hY <= basketY + basketWH && hY >= basketY && hX >= basketX - 40
&& hX <= basketX + basketWH) {
lives--;
hY = getRandNumbY();
hX = getRandNumbX();
}
if (sY <= basketY + basketWH && sY >= basketY && sX >= basketX - 40
&& sX <= basketX + basketWH) {
points++;
sY = getRandNumbY();
sX = getRandNumbX();
}
if (bY <= basketY + basketWH && bY >= basketY && bX >= basketX - 40
&& bX <= basketX + basketWH) {
points++;
bY = getRandNumbY();
bX = getRandNumbX();
}
if (oY <= basketY + basketWH && oY >= basketY && oX >= basketX - 40
&& oX <= basketX + basketWH) {
points++;
oY = getRandNumbY();
oX = getRandNumbX();
}
if (aY <= basketY + basketWH && aY >= basketY && aX >= basketX - 40
&& aX <= basketX + basketWH) {
points++;
aY = getRandNumbY();
aX = getRandNumbX();
}
if (basketX >= width - basketWH) {
basketX = width - basketWH;
}
if (basketX <= 0) {
basketX = 0;
}
if (lives <= 0) {
tryAgain.setVisible(true);
while (true) {
if (tryAgain.isVisible() == false) {
aY = getRandNumbY();
aX = getRandNumbX();
oY = getRandNumbY();
oX = getRandNumbX();
sY = getRandNumbY();
sX = getRandNumbX();
bY = getRandNumbY();
bX = getRandNumbX();
hY = getRandNumbY();
hX = getRandNumbX();
lives = 5;
points = 0;
break;
}
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void paint(Graphics g) {
super.paintComponents(g);
g.drawImage(background, 0, 0, this);
g.drawImage(apple, aX, aY, this);
g.drawImage(orange, oX, oY, this);
g.drawImage(banana, bX, bY, this);
g.drawImage(straw, sX, sY, this);
g.drawImage(hamburger, hX, hY, this);
g.drawImage(basket, basketX, basketY, this);
g.drawImage(heart, 100, 10, this);
g.drawImage(mellon, 20, 10, this);
g.setFont(new Font("Seris", Font.PLAIN, 20));
g.drawString(lives + "", 125, 30);
g.drawString(points + "", 50, 30);
if (lives <= 0) {
g.setFont(new Font("Seris", Font.PLAIN, 30));
g.drawString("Game over", 220, 300);
}
if (pauseRunning) {
g.drawString("Game Paused", 220, 300);
}
}
#Override
public void update(Graphics g) {
if (i == null) {
i = createImage(this.getSize().width, this.getSize().height);
doubleG = i.getGraphics();
}
doubleG.setColor(getBackground());
doubleG.fillRect(0, 0, width, height);
doubleG.setColor(getForeground());
paint(doubleG);
g.drawImage(i, 0, 0, this);
}
public void initComponents() {
// startGame button, pointsBox, livesBox, pause button, game over, play
// again, resume game
setFocusable(true);
addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent evt) {
formMouseMoved(evt);
}
});
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
formKeyPressed(evt);
}
});
startGame = new Button("Start Game");
startGame.setFocusable(false);
startGame.setLocation(230, 300);
startGame.setSize(130, 40);
startGame.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startGameActionPerformed(e);
}
});
tryAgain = new Button("Try Again?");
tryAgain.setFocusable(false);
tryAgain.setLocation(230, 350);
tryAgain.setSize(130, 40);
tryAgain.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tryAgainActionPerformed(e);
}
});
tryAgain.setVisible(false);
pauseButton = new Button("Pause");
pauseButton.setFocusable(false);
pauseButton.setLocation(550, 10);
pauseButton.setSize(40, 25);
pauseButton.setVisible(false);
pauseButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pauseButtonActionPerformed(e);
}
});
add(startGame);
add(tryAgain);
add(pauseButton);
}
public void startGameActionPerformed(ActionEvent e) {
running = true;
thread = new Thread(this);
thread.start();
startGame.setVisible(false);
}
public void tryAgainActionPerformed(ActionEvent e) {
points = 0;
lives = 5;
tryAgain.setVisible(false);
}
public void pauseButtonActionPerformed(ActionEvent e) {
if (pauseRunning == false) {
pauseRunning = true;
} else {
pauseRunning = false;
}
}
public int getRandNumbX() {
return random.nextInt(520) + 10;
}
public int getRandNumbY() {
return (random.nextInt(+600) + 100) * -1;
}
public void fruitMoving() {
aY += fruitSpeed;
oY += fruitSpeed;
sY += fruitSpeed;
bY += fruitSpeed;
hY += fruitSpeed;
}
public void formMouseMoved(MouseEvent evt) {
PointerInfo a = MouseInfo.getPointerInfo();
Point point = new Point(a.getLocation());
SwingUtilities.convertPointFromScreen(point, evt.getComponent());
basketX = (int) point.getX() - 50;
repaint();
}
public void formKeyPressed(KeyEvent evt) {
if (pauseRunning == false) {
if (evt.getKeyCode() == KeyEvent.VK_RIGHT)
basketX += 20;
if (evt.getKeyCode() == KeyEvent.VK_LEFT)
basketX -= 20;
}
}
// Component declaration
Button startGame, tryAgain, pauseButton;
}
EDIT: This is an SSCCE to demonstrate my problem.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Main {
public static BufferedImage map, tileSand, tileSea;
public static void main(String[] args) {
map = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);
for(int x = 0; x < 50 ; x++){
for(int y = 0; y < 50 ; y++){
boolean colour = Math.random() < 0.5;
if (colour){
map.setRGB(x, y, -256);
} else {
map.setRGB(x, y, -16776961);
}
}
}
tileSand = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
Graphics g = tileSand.getGraphics();
g.setColor(Color.YELLOW);
g.fillRect(0, 0, 32, 32);
tileSea = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB);
g.setColor(Color.BLUE);
g = tileSea.getGraphics();
g.fillRect(0, 0, 32, 32);
Island test = new Main.Island();
test.start();
long start, sleep;
while(true) {
start = System.currentTimeMillis();
test.getCanvas().requestFocus();
test.getCanvas().repaint();
sleep = 15-(System.currentTimeMillis()-start);
try {
Thread.sleep(sleep > 0 ? sleep : 0);
} catch (InterruptedException e) {
}
}
}
static class Island implements Runnable {
private Tile[][] tiles;
private JFrame frame;
private JPanel panel;
private Thread logicThread;
private boolean running = false;
private boolean paused = false;
private Image image;
private Player player;
public Island() {
image = new BufferedImage(1027, 768, BufferedImage.TYPE_INT_ARGB);
player = new Player();
tiles = new Tile[map.getWidth()][map.getHeight()];
int rgb;
for(int x = 0; x < map.getWidth(); x++) {
for(int y = 0; y < map.getHeight(); y++) {
rgb = map.getRGB(x, y);
switch (rgb) {
case -16776961: tiles[x][y] = new Tile("sea");
break;
case -256: tiles[x][y] = new Tile("sand");
break;
}
}
}
makeMap();
makeFrame();
addBindings();
logicThread = new Thread(this);
}
public JPanel getCanvas() {
return panel;
}
public void start() {
running = true;
paused = false;
logicThread.start();
}
public void run() {
long sleep, before;
while(running){
before = System.currentTimeMillis();
player.move();
try {
sleep = 15-(System.currentTimeMillis()-before);
Thread.sleep(sleep > 0 ? sleep : 0);
} catch (InterruptedException ex) {
}
while(running && paused);
}
paused = false;
}
private void makeFrame() {
frame = new JFrame("Island");
panel = new JPanel(){
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, 1024, 768);
long xl, yl;
xl = player.getLocation().x-512;
yl = player.getLocation().y-384;
int x2, y2;
x2 = (int) Math.floor(xl / 32);
y2 = (int) Math.floor(yl / 32);
int xoffset, yoffset;
xoffset = (int) (xl % 32);
yoffset = (int) (yl % 32);
for(int x = x2; x < x2+40; x++) {
for(int y = y2; y < y2+40; y++) {
if (x < tiles.length && x > 0 && y < tiles[0].length && y > 0) {
g2d.drawImage(tiles[x][y].getContent(), (x-x2)*32 - xoffset, (y-y2)*32 - yoffset, null);
}
}
}
g.drawImage(image, 0, 0, null);
}
};
panel.setPreferredSize(new Dimension(1024, 768));
panel.setIgnoreRepaint(true);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
private void addBindings() {
InputMap inputMap = panel.getInputMap();
ActionMap actionMap = panel.getActionMap();
inputMap.put(KeyStroke.getKeyStroke("Q"),"hold-sprint");
actionMap.put("hold-sprint", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.sprint(true);
}
});
inputMap.put(KeyStroke.getKeyStroke("released Q"),"release-sprint");
actionMap.put("release-sprint", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.sprint(false);
}
});
inputMap.put(KeyStroke.getKeyStroke("RIGHT"),"hold-right");
actionMap.put("hold-right", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.right(true);
}
});
inputMap.put(KeyStroke.getKeyStroke("released RIGHT"),"release-right");
actionMap.put("release-right", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.right(false);
}
});
inputMap.put(KeyStroke.getKeyStroke("DOWN"),"hold-down");
actionMap.put("hold-down", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.down(true);
}
});
inputMap.put(KeyStroke.getKeyStroke("released DOWN"),"release-down");
actionMap.put("release-down", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.down(false);
}
});
inputMap.put(KeyStroke.getKeyStroke("LEFT"),"hold-left");
actionMap.put("hold-left", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.left(true);
}
});
inputMap.put(KeyStroke.getKeyStroke("released LEFT"),"release-left");
actionMap.put("release-left", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.left(false);
}
});
inputMap.put(KeyStroke.getKeyStroke("UP"),"hold-up");
actionMap.put("hold-up", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.up(true);
}
});
inputMap.put(KeyStroke.getKeyStroke("released UP"),"release-up");
actionMap.put("release-up", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
player.up(false);
}
});
}
private void makeMap() {
for(int x = 0; x < tiles.length; x++) {
for(int y = 0; y < tiles[0].length; y++) {
switch (tiles[x][y].getType()) {
case "sea": tiles[x][y].setContent(tileSea);
break;
case "sand": tiles[x][y].setContent(tileSand);
break;
}
}
}
}
}
static class Player{
private Point location;
private int xspeed, yspeed;
private boolean left, up, right, down, sprint;
public Player() {
location = new Point(0, 0);
left = false;
up = false;
right = false;
down = false;
sprint = false;
xspeed = yspeed = 0;
}
public void left(boolean state){
left = state;
}
public void up(boolean state){
up = state;
}
public void right(boolean state){
right = state;
}
public void down(boolean state){
down = state;
}
public void sprint(boolean state) {
sprint = state;
}
public void move() {
if (sprint) {
if (left) {
if(xspeed>-10)
xspeed--;
} if (right) {
if(xspeed<10)
xspeed++;
} if (up) {
if(yspeed>-10)
yspeed--;
} if (down) {
if(yspeed<10)
yspeed++;
}
} else {
if (left) {
if(xspeed>-5)
xspeed--;
} if (right) {
if(xspeed<5)
xspeed++;
} if (up) {
if(yspeed>-5)
yspeed--;
} if (down) {
if(yspeed<5)
yspeed++;
}
}
if (!sprint) {
if (xspeed > 5) {
xspeed--;
} if (xspeed < -5) {
xspeed++;
} if (yspeed > 5) {
yspeed--;
} if (yspeed < -5) {
yspeed++;
}
}
if (!left && !right) {
if (xspeed > 0) {
xspeed--;
} if (xspeed < 0) {
xspeed++;
}
} if (!up && !down) {
if (yspeed > 0) {
yspeed--;
} if (yspeed < 0) {
yspeed++;
}
}
location.x = location.x + xspeed;
location.y = location.y + yspeed;
}
public Point getLocation() {
return location;
}
}
static class Tile {
private String type;
private BufferedImage tile;
public Tile(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setContent(BufferedImage newTile) {
tile = newTile;
}
public BufferedImage getContent() {
return tile;
}
}
}
I have a JPanel with a modified paintComponent method. In this method I draw the relevant tiles from a 2d array to the screen based on the player location. I draw all my tiles to a BufferedImage and then I apply it to the screen at the end of the paint method. In theory this should not create tearing as I am double buffering? Here is the appropriate code, image is just a BufferedImage with the dimensions of the screen:
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, 1024, 768);
long xl, yl;
xl = player.getLocation().x-512;
yl = player.getLocation().y-384;
int x2, y2;
x2 = (int) Math.floor(xl / 32);
y2 = (int) Math.floor(yl / 32);
int xoffset, yoffset;
xoffset = (int) (xl % 32);
yoffset = (int) (yl % 32);
for(int x = x2; x < x2+40; x++) {
for(int y = y2; y < y2+40; y++) {
if (x < tiles.length && x > 0 && y < tiles[0].length && y > 0) {
g2d.drawImage(tiles[x][y].getContent(), (x-x2)*32 - xoffset, (y-y2)*32 - yoffset, null);
}
}
}
g.drawImage(image, 0, 0, null);
}
I think the tearing could possibly be caused by the player's location changing over the duration of the paint method causing the tiles not to match up, the faster the player goes the more obvious the effect is. However I get the players location at the start and store it in two longs, I was under the impression that longs are passed by value not reference so the player location should be constant whilst the method runs.
I am happy to provide more code :), and thanks in advance.
Just so if people find my question and wonder what I ended up doing to "fix" it, switch over to c++ and SDL or some other image library before you are to far into your project, it's simply better for this kind of thing.