2014-10-31 4 views
0

Я воссоздаю классическую игру змеи. Я уже закончил кодирование змеи. Теперь мне нужно сделать код стены (которые должны быть расположены по краям рамки).Возможно ли в javax.swing пользователю два художника в одном кадре?

Как художник змеи «перекрашивает» каждые 30 миллисекунд, я думал, что было бы не очень эффективно позволить этому художнику также рисовать стены, так как стены остаются на одном и том же месте в течение всей игры, так что это не Действительно, необходимо перерисовать стены каждые 30 миллисекунд.

Таким образом, мне было интересно, возможно ли иметь две художники в моей игре, которая перекрашивает змею каждые 30 миллисекунд, и одну, которая рисует только один раз (она рисует стены в начале игры)? Как мне это сделать?

Это наиболее важные части кода, связанного с вопросом (полный код можно найти ниже этого):

//this is in the main class 
public Snake(){ 
    painter = new Painter(this); 
    this.add(painter, BorderLayout.CENTER); 
    this.setSize(500, 500); 
    this.setResizable(false); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.setVisible(true); 
    this.addKeyListener(this); 
    this.requestFocusInWindow(); 
    timer = new Timer(30, this); 
    startGame(); 
} 

    public void startGame(){ 
    snakeList = new LinkedList<Point>(); 
    snakeList.addFirst(new Point(10, 10)); 
    snakeSegments(3); 
    setFood(30, 30); 
    movementX = 0; 
    movementY = 0; 
    timer.start(); //timer triggers gameUpdate(); 
} 

public void gameUpdate(){ 
    snakeMove(movementX, movementY); 
    snakeInstructor(); 
    snakeEat(); 
    snakeCollision(); 
    painter.repaint(); 
} 

-

// this is in the painter class 
@Override 
protected void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    g.setColor(Color.BLACK); 
    g.fillRect(0, 0, 500, 500); 
    paintSnake(g); 
    paintFood(g); 
} 

Это полный код:

import java.awt.*; 
import java.util.*; 
import java.awt.event.*; 
import javax.swing.JFrame; 
import javax.swing.Timer; 

public class Snake extends JFrame implements KeyListener, ActionListener{ 
Painter painter; 
LinkedList<Point> snakeList; 
Timer timer; 
Point foodLocation; 
int direction; 
int snakeSize; 
int movementX, movementY; 

public static void main(String[] arg){ 
    new Snake(); 
} 

public Snake(){ 
    painter = new Painter(this); 
    this.add(painter, BorderLayout.CENTER); 
    this.setSize(500, 500); 
    this.setResizable(false); 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.setVisible(true); 
    this.addKeyListener(this); 
    this.requestFocusInWindow(); 
    timer = new Timer(30, this); 
    startGame(); 
} 

public void startGame(){ 
    snakeList = new LinkedList<Point>(); 
    snakeList.addFirst(new Point(10, 10)); 
    snakeSegments(3); 
    setFood(30, 30); 
    movementX = 0; 
    movementY = 0; 
    timer.start(); 
} 

public void gameUpdate(){ 
    snakeMove(movementX, movementY); 
    snakeInstructor(); 
    snakeEat(); 
    snakeCollision(); 
    painter.repaint(); 
} 

public void snakeCollision(){ 
    for(int i = 4; i < getSnakeSize(); i++){ 
     if(getFirst().equals(snakeList.get(i))){ 
      gameOver(); 
     } 
    } 
} 

public void gameOver(){ 
    timer.stop(); 
} 

public void snakeEat(){ 
    if(getFirst().equals(getFood())){ 
     newFood(); 
     setSnakeSize(); 
     snakeSegments(4); 
    } 
} 

public void snakeSegments(int i){ 
    snakeSize = i; 
    while(snakeSize > 0){ 
     snakeList.addLast(new Point(getLast())); 
     snakeSize--; 
    } 
} 

public void snakeInstructor(){ 
    int currentDirection = getDirection(); 
    if (currentDirection == 1){ 
     snakeMove(-1, 0); 
    } else if (currentDirection == 2){ 
     snakeMove(1, 0); 
    } else if (currentDirection == 3){ 
     snakeMove(0, -1); 
    } else if (currentDirection == 4){ 
     snakeMove(0, 1); 
    }  
} 

public void snakeMove(int directionX, int directionY){ 
    snakeList.getFirst().x = snakeList.getFirst().x + directionX; 
    snakeList.getFirst().y = snakeList.getFirst().y + directionY; 
    for(int i = getSnakeSize()-1; i >=1; i--) { 
     snakeList.get(i).setLocation(snakeList.get(i-1)); 
    } 
} 

public void newFood(){ 
    Random generator = new Random(); 
    int x = generator.nextInt(49); 
    int y = generator.nextInt(47); 
    setFood(x, y); 
} 

public void setFood(int x, int y){ 
    foodLocation = new Point(x, y); 
} 

public Point getFood(){ 
    return foodLocation; 
} 

public void setDirection(int newDirection){ 
    direction = newDirection; 
} 

public int getDirection(){ 
    return direction; 
} 

Point getFirst(){ 
    return snakeList.getFirst(); 
} 

Point getLast(){ 
    return snakeList.getLast(); 
} 

Point get(int i){ 
    return snakeList.get(i); 
} 

public void addFirst(Point p){ 
    snakeList.addFirst(p); 
} 

public void addLast(Point p){ 
    snakeList.addLast(p); 
} 

public int getSnakeSize(){ 
    return snakeList.size(); 
} 

public void setSnakeSize(){ 
    snakeSize = getSnakeSize() + 1; 
} 

@Override 
public void actionPerformed(ActionEvent event) { 
    gameUpdate(); 
} 

@Override public void keyReleased(KeyEvent e){ } 
@Override public void keyTyped(KeyEvent e){ } 
@Override public void keyPressed(KeyEvent e){ 
    int key = e.getKeyCode(); 
    if((key == KeyEvent.VK_LEFT) && direction != 2){ 
     setDirection(1); 
    } else if ((key == KeyEvent.VK_RIGHT) && direction != 1){ 
     setDirection(2); 
    } else if ((key == KeyEvent.VK_UP) && direction != 4){ 
     setDirection(3); 
    } else if ((key == KeyEvent.VK_DOWN) && direction != 3){ 
     setDirection(4); 
    } else if (key == KeyEvent.VK_SPACE){ 
     startGame(); 
    } 
} 

} 

-

import java.awt.*; 
import java.util.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class Painter extends JPanel{ 
Snake snake; 
public Painter(Snake snake){ 
    this.snake = snake; 
} 

@Override 
protected void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    g.setColor(Color.BLACK); 
    g.fillRect(0, 0, 500, 500); 
    paintSnake(g); 
    paintFood(g); 
} 

public void paintSnake(Graphics g){ 
    for(int i = 0; i < snake.getSnakeSize(); i++){ 
     g.setColor(Color.WHITE); 
     Point p = snake.snakeList.get(i); 
     g.fillRect(p.x*10, p.y*10, 10, 10); 
    } 
} 

public void paintFood(Graphics g){ 
    Point p = snake.getFood(); 
    g.setColor(Color.RED); 
    g.fillRect(p.x*10, p.y*10, 10, 10); 
} 

} 
+0

Чтобы лучше помочь, отправьте сообщение [MCVE] (http://stackoverflow.com/help/mcve) (минимальный полный проверяемый пример). –

ответ

2

Да и нет ...

Вы могли бы сделать Painter прозрачным и наложить змею на вершине стены, но призыв к g.fillRect(0, 0, 500, 500); бы сделать это излишним, так как она заполняет весь компонент с током цвет ...

Видел как метод paintComponent для обоих художников будет называться каждый раз, когда вы хотите обновить интерфейс, это также бессмысленно.

Лучшим решением было бы сделать карту BufferedImage и нарисовать ее внутри painter, прежде чем рисовать змею.

+0

Спасибо, я посмотрю на буферизованные изображения. – Ken

+1

Вы должны использовать «BufferedImage», где контент не изменяется или не изменяется часто, вы также можете использовать несколько «BufferedImage's» для создания «слоев» для разных эффектов, но это зависит от вас;) – MadProgrammer

Смежные вопросы