Well, thanks all you guys for the help and tips. Everything works fine and moving on with the creation.
By the way, speaking about JFrames container in Snake class, my way works fine as well:
EDIT: If anyone is interested in the result (but I guess not
), here is the code:
I used 3 images 10x10 for the apple, head and body.
import java.awt.Container;
import java.awt.Graphics;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Image;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.FontMetrics;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.ImageIcon;
import java.util.Random;
class Snake extends JFrame {
Snake(String title) {
setTitle(title);
setSize(310, 335);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Board b = new Board();
Container c = getContentPane();
c.setLayout(new BorderLayout());
c.add(b, BorderLayout.CENTER);
// Board b = new Board();
// b.setLayout(new BorderLayout());
// setContentPane(b);
}
public static void main(String args[ ]) {
new Snake("Snake game 2010 by Asido (c)");
}
}
class Board extends JPanel implements ActionListener {
private final int WIDTH = 302;
private final int HEIGHT = 309;
private final int DOT_SIZE = 10;
private final int ALL_DOTS_X = 30;
private final int ALL_DOTS_Y = 30;
private int x[ ] = new int[ALL_DOTS_X];
private int y[ ] = new int[ALL_DOTS_Y];
private int prevX[ ] = new int[ALL_DOTS_X * ALL_DOTS_Y];
private int prevY[ ] = new int[ALL_DOTS_X * ALL_DOTS_Y];
private int headX;
private int headY;
private int bodyX;
private int bodyY;
private int appleX;
private int appleY;
private int bodySize = 3;
private int delay = 300;
private int pausedDelay = 0;
int score = 0;
private boolean inGame = false;
private boolean left = true;
private boolean up = false;
private boolean right = false;
private boolean down = false;
private boolean appleStatus = false;
private Graphics g;
private Font hugeFont = new Font("Luxi Mono", Font.BOLD, 30);
private Font largeFont = new Font("Luxi Mono", Font.BOLD, 24);
private Font smallFont = new Font("Luxi Mono", Font.PLAIN, 14);
private Font tinyFont = new Font("Luxi Mono", Font.BOLD, 10);
private Random random = new Random();
private Timer timer;
private Image apple;
private Image head;
private Image body;
private Color backgroundColor = Color.BLACK;
private Color stringColor = Color.WHITE;
private MovementHandler movementHandler = new MovementHandler();
private RestartHandler restartHandler = new RestartHandler();
Board() {
setSize(WIDTH, HEIGHT);
setBackground(backgroundColor);
setFocusable(true);//kad KeyEventai veiktu ant JPanel
// images
ImageIcon appleIcon = new ImageIcon(getClass().getResource("apple.png"));
apple = appleIcon.getImage();
ImageIcon headIcon = new ImageIcon(getClass().getResource("head.png"));
head = headIcon.getImage();
ImageIcon bodyIcon = new ImageIcon(getClass().getResource("body.png"));
body = bodyIcon.getImage();
timer = new Timer(delay, this);
timer.start();
begining();
}
void locateApple() {
appleX = x[random.nextInt(30)];
appleY = y[random.nextInt(30)];
for(int i = 0; i < bodySize; i++) {
if((appleX == prevX[i] && appleY == prevY[i]) || (appleX == headX && appleY == headY))
locateApple();
}
}
void begining() {
inGame = true;
left = true;
right = false;
up = false;
down = false;
bodySize = 3;
score = 0;
addKeyListener(movementHandler);
for(int i = 0; i < (WIDTH / 10); i++)
x[i] = i * DOT_SIZE;
for(int i = 0; i < (HEIGHT / 10); i++)
y[i] = i * DOT_SIZE;
locateApple();
headX = x[((int)(ALL_DOTS_X / 2))];
headY = y[((int)(ALL_DOTS_Y / 2))];
for(int i = 0; i < bodySize; i++) {
prevX[i] = headX + i * DOT_SIZE;
prevY[i] = headY;
}
setTimerDelay(200);
}
void setTimerDelay(int delay) {
timer.setDelay(delay);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(inGame) {
if(!appleStatus) {
g.drawImage(apple, appleX, appleY, this);
}
g.setColor(stringColor);
g.setFont(tinyFont);
g.drawString("Score: " + score, 5, (HEIGHT - 1));
g.setColor(Color.DARK_GRAY);
g.drawLine(0, (HEIGHT - 10), WIDTH, (HEIGHT - 10));
g.drawImage(head, headX, headY, this);
for(int i = 0; i < bodySize; i++) {
bodyX = prevX[i];
bodyY = prevY[i];
g.drawImage(body, bodyX, bodyY, this);
}
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
else
gameOver(g);
}
void gameOver(Graphics g) {
String gameOverMessage = "Game Over";
String restartMessage = "Press 'R' to restart";
String scoreMessage = "Score: " + score;
inGame = false;
g.setFont(largeFont);
g.setColor(stringColor);
FontMetrics largeFM = g.getFontMetrics(largeFont);
g.drawString(gameOverMessage, ((WIDTH - largeFM.stringWidth(gameOverMessage)) / 2), (HEIGHT / 2));
removeKeyListener(movementHandler);
addKeyListener(restartHandler);
FontMetrics hugeFM = g.getFontMetrics(hugeFont);
g.setFont(hugeFont);
g.drawString(scoreMessage, ((WIDTH - hugeFM.stringWidth(scoreMessage)) / 2), (HEIGHT / 3 * 2));
g.setFont(smallFont);
g.drawString(restartMessage, 10, (HEIGHT - 20));
}
void restart() {
begining();
repaint();
}
void detectCollision() {
if(headX < 0 || headX > 290 || headY < 0 || headY > 290)
inGame = false;
if(bodySize > 3) {
for(int i = 0; i < bodySize; i++) {
if(headX == prevX[i] && headY == prevY[i])
inGame = false;
}
}
}
void checkApple() {
if(appleX == headX && appleY == headY) {
bodySize++;
score += 100;
locateApple();
switch(bodySize) {
case 10: setTimerDelay(190); break;
case 15: setTimerDelay(170); break;
case 20: setTimerDelay(150); break;
case 25: setTimerDelay(140); break;
case 30: setTimerDelay(130); break;
case 35: setTimerDelay(120); break;
}
}
}
public void actionPerformed(ActionEvent event) {
for(int i = bodySize; i >= 0; i--) {
if(i > 0) {
prevX[i] = prevX[i-1];
prevY[i] = prevY[i-1];
}
else {
prevX[i] = headX;
prevY[i] = headY;
}
}
if(up)
headY -= DOT_SIZE;
if(down)
headY += DOT_SIZE;
if(left)
headX -= DOT_SIZE;
if(right)
headX += DOT_SIZE;
detectCollision();
checkApple();
repaint();
}
private class MovementHandler implements KeyListener {
public void keyPressed(KeyEvent event) {
int keycode = event.getKeyCode();
if(keycode == KeyEvent.VK_UP && !down) {
up = true;
right = false;
left = false;
down = false;
}
if(keycode == KeyEvent.VK_LEFT && !right) {
left = true;
right = false;
up = false;
down = false;
}
if(keycode == KeyEvent.VK_RIGHT && !left) {
right = true;
left = false;
up = false;
down = false;
}
if(keycode == KeyEvent.VK_DOWN && !up) {
down = true;
up = false;
right = false;
left = false;
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
private class RestartHandler implements KeyListener {
public void keyPressed(KeyEvent event) {
int keycode = event.getKeyCode();
if(keycode == KeyEvent.VK_R)
restart();
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
}