import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class main extends Applet implements KeyListener{
public int x = 0;
public int y = 0;
public void init(){
setBackground(Color.CYAN);
addKeyListener(this);
}
public void paint( Graphics g){
g.setColor(Color.BLUE);
g.fillRect(x, y, 10, 10);
g.setColor(Color.BLACK);
g.drawRect(x, y, 10, 10);
g.drawRect(x+1, y+1, 8, 8);
}
public void keyTyped(KeyEvent input){
char key = input.getKeyChar();
while (key == 'd'){
repaint();
if (x < 600){
x = (x + 5);
try {
Thread.sleep(25);
} catch (InterruptedException e){}
}else{
break;
}
}
}
public void keyPressed(KeyEvent input){
}
public void keyReleased(KeyEvent input){
}
}
Repaint problemsI'm trying to make "Snake" using a java applet but whene
Page 1 of 1
13 Replies - 698 Views - Last Post: 21 June 2009 - 05:09 PM
Replies To: Repaint problems
#2
Re: Repaint problems
Posted 17 June 2009 - 11:32 AM
you need to put you question in a post please it got cut off
#3
Re: Repaint problems
Posted 17 June 2009 - 01:18 PM
Yeah, and post your code between the code tags. [code*] and [/code*] without the *.
#4
Re: Repaint problems
Posted 17 June 2009 - 04:43 PM
Please go back and edit your post

Help us to help you
And what is your question ?
Help us to help you
And what is your question ?
#5
Re: Repaint problems
Posted 17 June 2009 - 08:42 PM
I was wondering how i could get the image to move by a set amount of pixels(which now is supposed to be 5) instead of making one big leap to the if statement in the loop which is what is happening now.
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class main extends Applet implements KeyListener{
public int x = 0;
public int y = 0;
public void init(){
setBackground(Color.CYAN);
addKeyListener(this);
}
public void paint( Graphics g){
g.setColor(Color.BLUE);
g.fillRect(x, y, 10, 10);
g.setColor(Color.BLACK);
g.drawRect(x, y, 10, 10);
g.drawRect(x+1, y+1, 8, 8);
}
public void keyTyped(KeyEvent input){
char key = input.getKeyChar();
while (key == 'd'){
repaint();
if (x < 600){
x = (x + 5);
try {
Thread.sleep(25);
} catch (InterruptedException e){}
}else{
break;
}
}
}
public void keyPressed(KeyEvent input){
}
public void keyReleased(KeyEvent input){
}
}
#6
Re: Repaint problems
Posted 17 June 2009 - 08:59 PM
Good you learned how to use the
tags
this can't work
this can't work... sorry
the thread that will do the repaint() is the same that fired the call to your keyTyped() method
so basically making that thread to sleep, just delayed the time the repaint() will be able to call back your paint() method
this can't work
public void keyTyped(KeyEvent input){
char key = input.getKeyChar();
while (key == 'd'){
repaint();
if (x < 600){
x = (x + 5);
try {
Thread.sleep(25);
} catch (InterruptedException e){}
}else{
break;
this can't work... sorry
the thread that will do the repaint() is the same that fired the call to your keyTyped() method
so basically making that thread to sleep, just delayed the time the repaint() will be able to call back your paint() method
This post has been edited by pbl: 17 June 2009 - 09:01 PM
#7
Re: Repaint problems
Posted 17 June 2009 - 09:48 PM
So how would i go about getting it to work??
#8
Re: Repaint problems
Posted 17 June 2009 - 10:01 PM
Don't want to preach for my parish but..
go there
http://www.dreaminco...topic110346.htm
and see how, in the last post, I made a thread that refresh the Snake position in a different thread than the one used to do the repaint stuff
If you need more explanation on how this code works ... just ask but I forced myself to put a lot a comments
go there
http://www.dreaminco...topic110346.htm
and see how, in the last post, I made a thread that refresh the Snake position in a different thread than the one used to do the repaint stuff
If you need more explanation on how this code works ... just ask but I forced myself to put a lot a comments
#9
Re: Repaint problems
Posted 17 June 2009 - 10:08 PM
The main class (Snake) that extends JFrame implements Runnable so it has a run() method that updates the Snake position that is independant of all MouseListener (in your cas KeyListener) that can be activated/fired
#10
Re: Repaint problems
Posted 17 June 2009 - 10:24 PM
Ok, but lets say for purposes other than snake... could you explain what to do instead of having it the way it is?
#11
Re: Repaint problems
Posted 18 June 2009 - 01:55 AM
For convenience, here is the code so you both don't have to jump between threads. 
And the nicer version:
@pbl - you should make this a tutorial. and definitely add a difficulty bar, because it's too easy now lol (i play a lot of video games) or make it so the snake speeds up every time he eats an apple.
import javax.swing.*;
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.util.*;
public class Snake extends JFrame implements Runnable, ActionListener {
// number of squares in the grid, size of each of them
private static final int SIZE = 25, WIDTH = 20;
// the labels for displaying the snake and its foods
private SnakeLabel[][] label = new SnakeLabel[SIZE][SIZE];
// arrayList containing all of the snake position (Labels)
private SnakeList snakeList = new SnakeList();
// the label displaying if I am running or not and the size of the snake
private JLabel statusLabel = new JLabel();
// random number generator to find a new spot for a new food when I eat one
private Random random = new Random();
// if I am in a pause state or not
boolean pause = false;
// the button to switch from pause to not pause
private JButton pauseResume = new JButton("Pause");
// which direction I am running and where is my head
private int directionX = 0, directionY = -1, headX, headY;
Snake() {
super("Snake Game");
// to hold all the labels
JPanel panel = new JPanel(new GridLayout(SIZE, SIZE, 1, 1));
panel.setBackground(Color.BLUE);
panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
// create all the JLabel
for(int j = 0; j < SIZE; j++) {
for(int i = 0; i < SIZE; i++) {
label[i][j] = new SnakeLabel(i, j);
panel.add(label[i][j]);
}
}
// add the 4 foods
initFood();
// the snake in the middle of everything initial size 8
headX = SIZE / 2;
headY = (SIZE / 2) - 4;
// declare these label as holding the snake
// registering them in the arrayList
for(int i = 0; i < 8; i++)
snakeList.addLabel(label[headX][headY + i]);
add(panel, BorderLayout.CENTER);
// label if I am running well and size of the snake
statusLabel.setHorizontalAlignment(SwingConstants.CENTER);
add(statusLabel, BorderLayout.NORTH);
// listener so the pause button will work
pauseResume.addActionListener(this);
add(pauseResume, BorderLayout.SOUTH);
// general JFrame stuff its size and visible
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(SIZE * WIDTH, SIZE * WIDTH);
setVisible(true);
Thread thread = new Thread(this);
thread.start();
}
// to put the initial 4 food labels in 1/4 of the grid
private void initFood() {
// north/west at 1/4 of the grid
int x = SIZE / 4;
int y = x;
label[x][y].setFood(true);
// north east so x is the same delta from the end
x = SIZE - x;
label[x][y].setFood(true);
// south/west
y = x;
x = SIZE / 4;
label[x][y].setFood(true);
// south east
x = y;
label[x][y].setFood(true);
}
// run as a thread to move the snake
public void run() {
for(;;) {
// wait according to snake length... determine an empiric way
try {
Thread.sleep(10000L / snakeList.size());
}
catch(Exception e) {}
// if the "Pause" button was pushed go to next turn
if(pause)
continue;
// update snake head position
headX += directionX;
headY += directionY;
// check if we are going out of bound
if(headX < 0 || headX >= SIZE || headY < 0 || headY >= SIZE) {
statusLabel.setText("Out of bound... length: " + snakeList.size());
return;
}
// check if we are eating ourself
if(label[headX][headY].isSnake) {
statusLabel.setText("You eat yourself... length: " + snakeList.size());
return;
}
// if we hit food
if(label[headX][headY].isFood) {
snakeList.updateHead(); // without updating tail
// found new place for food
for(;;) {
int x = random.nextInt(SIZE);
int y = random.nextInt(SIZE);
// start again if new random place is already in the snake or is already food
if(label[x][y].isFood)
continue;
if(label[x][y].isSnake)
continue;
// ok good dpot not used yet/// declare it as food
label[x][y].setFood(true);
break;
}
}
else {
snakeList.updateTail(); // first if I pass on my back
snakeList.updateHead();
}
statusLabel.setText("Running... snake length: " + snakeList.size());
}
}
// called when the pause/resume button is hit
public void actionPerformed(ActionEvent e) {
// change the state
pause = !pause;
// updtae button text accordingly
if(pause)
pauseResume.setText("Resume");
else
pauseResume.setText("Pause");
}
// to run the whole damned thing
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Snake();
}
});
}
// arrtay list that contains the position taken by the snake
class SnakeList extends ArrayList<SnakeLabel> {
// for initial build when we install the snake first positions
boolean addLabel(SnakeLabel sl) {
sl.setSnake(true);
return super.add(sl);
}
// remove (make free) the tail of the snake
void updateTail() {
SnakeLabel sl = remove(size() - 1);
sl.setSnake(false);
}
// to update the head to new position
void updateHead() {
label[headX][headY].setSnake(true);
add(0, label[headX][headY]);
}
}
// extends JLabel to keep coordinate X and Y and have a mouseListener if cliked
class SnakeLabel extends JLabel implements MouseListener{
private int x, y;
// init not food not snake
boolean isFood = false;
boolean isSnake = false;
// constructor
SnakeLabel(int x, int y) {
super("");
// save my coordinates
this.x = x; this.y = y;
// opaque because I use background to represent myself
setOpaque(true);
// so I will react if I am cleicked
addMouseListener(this);
// default color
setBackground(Color.WHITE);
}
// declares me as a food case or not
void setFood(boolean state) {
isFood = state;
// change color accordingly
if(state)
setBackground(Color.RED);
else
setBackground(Color.WHITE);
}
// declares me as part of the snake or not
void setSnake(boolean state) {
isSnake = state;
// change my color accordingly
if(state) {
setBackground(Color.BLUE);
isFood = false; // slot availabel again if I just eat it for later use
}
else {
setBackground(Color.WHITE);
}
}
// ok click on me
public void mouseClicked(MouseEvent e) {
// so am I going vertically or horitonaly
if(directionX == 0) {
// if clicked to my left
if(x < headX) {
// update the way I am going
directionX = -1;
directionY = 0;
}
else if(x > headX) { // is it to my rioght ?
directionX = +1;
directionY = 0;
}
}
else { // OK I am moving horizontaly
if(y < headY) { // to my left
directionY = -1;
directionX = 0;
}
if(y > headY) { // to my right ?
directionY = +1;
directionX = 0;
}
}
}
// do not react to those
public void mouseEntered(MouseEvent arg0) {
}
public void mouseExited(MouseEvent arg0) {
}
public void mousePressed(MouseEvent arg0) {
}
public void mouseReleased(MouseEvent arg0) {
}
}
}
And the nicer version:
import javax.swing.*;
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.util.*;
public class Snake extends JFrame implements Runnable, ActionListener {
private static final long serialVersionUID = 123654L; // just to avoid compile warning
// number of squares in the grid, size of each of them
private static final int SIZE = 25, WIDTH = 20;
// the labels for displaying the snake and its foods
private SnakeLabel[][] label = new SnakeLabel[SIZE][SIZE];
// arrayList containing all of the snake position (Labels)
private SnakeList snakeList = new SnakeList();
// the label displaying if I am running or not and the size of the snake
private JLabel statusLabel = new JLabel("Initializing");
// random number generator to find a new spot for a new food when I eat one
private Random random = new Random();
// if I am in a pause state or not
boolean pause = false;
// the button to switch from pause to not pause
private JButton pauseResume = new JButton("Pause");
// which direction I am running and where is my head
private int directionX = 0, directionY = -1, headX, headY;
// the refresh rate
private long refreshRate;
Snake() {
super("Snake Game");
// to hold all the labels with a gap of 1 pixel
JPanel panel = new JPanel(new GridLayout(SIZE, SIZE, 1, 1));
// the same color as the Snake so the back will show a continuos snake
panel.setBackground(Color.BLUE);
panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
// create all the JLabels
initLabels(panel);
// add the 4 foods
initFood();
// init the snake the length of a quarter of our size
initSnake(SIZE / 4);
add(panel, BorderLayout.CENTER);
// label if I am running well and size of the snake
statusLabel.setHorizontalAlignment(SwingConstants.CENTER);
statusLabel.setOpaque(true);
statusLabel.setBackground(Color.YELLOW);
add(statusLabel, BorderLayout.NORTH);
// listener so the pause button will work
pauseResume.setForeground(Color.RED);
pauseResume.addActionListener(this);
add(pauseResume, BorderLayout.SOUTH);
// general JFrame stuff its size and visible
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(SIZE * WIDTH - 5, SIZE * WIDTH - 5);
setVisible(true);
// start the thread that move the snakes
Thread thread = new Thread(this);
thread.start();
}
// to initialize the labels filling the grid
// this method is called only once
private void initLabels(JPanel p) {
for(int j = 0; j < SIZE; j++) {
for(int i = 0; i < SIZE; i++) {
label[i][j] = new SnakeLabel(i, j);
p.add(label[i][j]);
}
}
}
// to put the initial 4 food labels in 1/4 of the grid
// this method will be called only once
private void initFood() {
// north/west at 1/4 of the grid
int x = SIZE / 4;
int y = x;
label[x][y].setFood(true);
// north east so x is the same delta from the end
x = SIZE - x;
label[x][y].setFood(true);
// south/west
y = x;
x = SIZE / 4;
label[x][y].setFood(true);
// south east
x = y;
label[x][y].setFood(true);
}
// to position the snake at the beginning of game
private void initSnake(int length) {
// the snake in the middle of everything initial size of length
headX = SIZE / 2;
headY = (SIZE / 2) - (length / 2);
// declare these label as holding the snake
// registering them in the arrayList
for(int i = headY; i < headY + length; i++)
snakeList.addLabel(label[headX][i]);
// set the color for the first time
snakeList.updateColor();
}
// run as a thread to move the snake
public void run() {
for(;;) {
// wait according to snake length... determine an empiric way
refreshRate = 5000L / (snakeList.size() / 2);
// manage to have at least a minimum refresh rate
if(refreshRate < 10L)
refreshRate = 10L;
try {
Thread.sleep(refreshRate);
}
catch(Exception e) {}
// if the "Pause" button was pushed go to next turn
if(pause)
continue;
// update snake head position
headX += directionX;
headY += directionY;
// check if we are going out of bound
if(headX < 0 || headX >= SIZE || headY < 0 || headY >= SIZE) {
statusLabel.setText("Out of bound... length: " + snakeList.size());
return;
}
// check if we are eating ourself
if(label[headX][headY].isSnake) {
statusLabel.setText("You eat yourself... length: " + snakeList.size());
return;
}
// if we hit food
if(label[headX][headY].isFood) {
snakeList.updateHead(); // without updating tail
// found new place for food
for(;;) {
int x = random.nextInt(SIZE);
int y = random.nextInt(SIZE);
// start again if new random place is already in the snake or is already food
if(label[x][y].isFood)
continue;
if(label[x][y].isSnake)
continue;
// ok good dpot not used yet/// declare it as food
label[x][y].setFood(true);
break;
}
}
else {
snakeList.updateTail(); // first if I pass on my back
snakeList.updateHead();
}
statusLabel.setText("Running... snake length: " + snakeList.size()
+ " Refresh Rate: " + refreshRate + "/1000 sec");
}
}
// called when the pause/resume button is hit
public void actionPerformed(ActionEvent e) {
// change the state
pause = !pause;
// updtae button text accordingly
if(pause)
pauseResume.setText("Resume");
else
pauseResume.setText("Pause");
}
// to run the whole damned thing
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Snake();
}
});
}
// array list that contains the position taken by the snake
private class SnakeList extends ArrayList<SnakeLabel> {
private static final long serialVersionUID = 654321L; // to avoid compile warning
// the 2 colours of the snake
private Color[] snakeColor = {new Color(0, 0, 255), new Color(75, 75, 255)};
// for initial build when we install the snake first positions
private boolean addLabel(SnakeLabel sl) {
// flag the SnakeLabel as being part of the Snake
sl.setSnake(true);
// call father's method to add an object into the arrayList
return add(sl);
}
// remove (make free) the tail of the snake
private void updateTail() {
SnakeLabel sl = remove(size() - 1);
sl.setSnake(false);
}
// to update the head to new position
private void updateHead() {
// declare it as part of the snake
label[headX][headY].setSnake(true);
// add it to the head of the snake
add(0, label[headX][headY]);
// switch colors
updateColor();
}
// to put 2 colours in the snake
private void updateColor() {
int len = size();
// the head in black
get(0).setBackground(Color.BLACK);
// variation of blue for the others
for(int i = 1; i < len; i++) {
get(i).setBackground(snakeColor[i % snakeColor.length]);
}
}
} // end of inner class SnakeList
// specialized JLabel to keep coordinate X and Y and have a mouseListener if cliked
private class SnakeLabel extends JLabel implements MouseListener{
private static final long serialVersionUID = 123456L; // to avoid compile warning
// my coordinates on the Grid so the mouseListener can know where I am situate
private int x, y;
// init not food and not snake
boolean isFood = false; // not a food case
boolean isSnake = false; // not part of the snake
// constructor
SnakeLabel(int x, int y) {
super("");
// save my coordinates
this.x = x; this.y = y;
// opaque because I use background to represent myself
setOpaque(true);
// so I will react if I am cleicked
addMouseListener(this);
// default color
setBackground(Color.WHITE);
}
// declares me as a food case or not
private void setFood(boolean state) {
isFood = state;
// change color accordingly
if(state)
setBackground(Color.RED); // food color
else
setBackground(Color.WHITE); // regular color
}
// declares me as part of the snake or not
private void setSnake(boolean state) {
isSnake = state;
// change my color accordingly
if(state) {
setFood(false); // make it available again as food slot
setBackground(Color.BLUE);
}
else {
setBackground(Color.WHITE);
}
}
// ok click on me I just chek for the Pressed event to react faster
// (important when the snake goes very fast)
public void mousePressed(MouseEvent e) {
// so am I going vertically or horitonaly
if(directionX == 0) {
// if clicked on my same X nothing to do
if(x == headX)
return;
directionY = 0; // stop updating Y
// if clicked to my left
if(x < headX) {
// update the way I am going
directionX = -1;
}
else { // so to my rioght
directionX = +1;
}
}
else { // OK I am moving horizontaly
if(y == headY)
return;
directionX = 0;
if(y < headY) { // to my left
directionY = -1;
}
else { // to my right
directionY = +1;
}
}
}
// do not react to those but as I implement MouseListener have have to implement these
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mouseClicked(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
} // end inner class SnakeLabel
}
@pbl - you should make this a tutorial. and definitely add a difficulty bar, because it's too easy now lol (i play a lot of video games) or make it so the snake speeds up every time he eats an apple.
This post has been edited by 333OnlyHalfEvil: 18 June 2009 - 02:04 AM
#12
Re: Repaint problems
Posted 18 June 2009 - 05:15 AM
333OnlyHalfEvil, on 18 Jun, 2009 - 12:55 AM, said:
@pbl - you should make this a tutorial. and definitely add a difficulty bar, because it's too easy now lol (i play a lot of video games) or make it so the snake speeds up every time he eats an apple.
It is
// wait according to snake length... determine an empiric way
refreshRate = 5000L / (snakeList.size() / 2);
// manage to have at least a minimum refresh rate
if(refreshRate < 10L)
refreshRate = 10L;
try {
Thread.sleep(refreshRate);
}
catch(Exception e) {}
just change it to gp faster if you want
#13
Re: Repaint problems
Posted 18 June 2009 - 05:21 AM
chicken2057, on 17 Jun, 2009 - 09:24 PM, said:
Ok, but lets say for purposes other than snake... could you explain what to do instead of having it the way it is?
For any purposes
sleepting in an action event method is NOT a good idea at all and if you do not exit from it as soon as possible nothing else will be done (like repaint) until you exit it
so:
public void actionPerformed(ActionEvent e) {
...
...
repaint();
...
Thread.sleep()
...
} <--- the paint() won't be call until this method exits
#14
Re: Repaint problems
Posted 21 June 2009 - 05:09 PM
so how should i go about having the repaint and sleep both work within the loop?(I'm pretty new at this java stuff... just to explain the questions)
Page 1 of 1
|
|

New Topic/Question
Reply




MultiQuote




|