Java/Игра змейка/SnakeGame.java

Материал из Викиучебника

Перейти к: навигация, поиск
/************************************************************
 ** Title:  Игра змейка 
 ** Class:  SnakeGame
 ** Author: Oleg Imanilov
 **   Copyright (c) 2007 Oleg Imanilov.
 **   Permission is granted to copy, distribute and/or
 **   modify  this  document under  the  terms  of the
 **   GNU Free Documentation License
 ** Notes: Главный класс игры змейка
 ************************************************************/
package game.snake;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.geom.Area;
import java.io.*;

import javax.swing.JPanel;

public class SnakeGame extends JPanel {
  private static int wallStep = 10;

  private Shape walls1 = new Polygon();

  private Shape walls2 = new Polygon();

  private Shape walls3 = new Polygon();

  private Snake snake = new Snake(2, 2, wallStep);

  private Point food = new Point();

  private int points = 0;

  public SnakeGame() {
    super(true);
    Dimension d = getLevel("C:/sn1.dat");
    putFood();

    setPreferredSize(d);
    setMinimumSize(d);
    setMaximumSize(d);
    setSize(d);

    Thread th = new Thread(new Runnable() {
      public void run() {
        while (true) {
          gameCycle();
          try {
            Thread.sleep(500 - snake.getSpeed());
          } catch (InterruptedException e) {
          }
        }
      }
    });
    th.start();

  }

  private void putFood() {
    int x = 5;
    int y = 5;

    while (walls2.contains(x, y)) {
      x = (int) (wallStep * Math.floor(Math.random() * 40)) + 2;
      y = (int) (wallStep * Math.floor(Math.random() * 40)) + 2;
    }
    food.setLocation(x, y);
  }

  public Snake getSnake() {
    return snake;
  }

  private Dimension getLevel(String fileName) {
    int minX = 500, maxX = 0, minY = 500, maxY = 0;
    Area w1 = new Area();
    Area w2 = new Area();
    Area w3 = new Area();

    BufferedReader input = null;
    try {
      File file = new File(fileName);
      input = new BufferedReader(new FileReader(file));
      String line = null; //not declared within while loop

      int y = 0;
      while ((line = input.readLine()) != null) {
        for (int x = 0; x < line.length(); x++) {
          if (line.substring(x, x + 1).equals("1")) {
            minX = Math.min(minX, x * wallStep);
            maxX = Math.max(maxX, (x + 1) * wallStep + 4);
            minY = Math.min(minY, y * wallStep);
            maxY = Math.max(maxY, (y + 1) * wallStep + 4);

            w1.add(new Area(new Rectangle(x * wallStep, y * wallStep, wallStep, wallStep)));
            w2.add(new Area(new Rectangle(x * wallStep + 2, y * wallStep + 2, wallStep, wallStep)));
            w3.add(new Area(new Rectangle(x * wallStep + 4, y * wallStep + 4, wallStep, wallStep)));
          }
        }
        y++;
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        if (input != null) {
          input.close();
        }
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }

    walls1 = w1;
    walls2 = w2;
    walls3 = w3;

    Dimension d = new Dimension(maxX - minX, maxY - minY);
    return d;
  }

  public void gameCycle() {
    if (snake.getDirection() != Snake.DIR_POUSE) {
      setMessage(null);
    }
    Point p = snake.move();
    if (p.x - food.x == 0 && p.y - food.y == 0) {
      points++;
      snake.expand();
      putFood();
    }
    if (walls2.contains(p)) {
      if (snake.getDirection() != Snake.DIR_POUSE) {
        points -= 10;
      }
      snake.setDirection(Snake.DIR_POUSE);
      setMessage("Boom!");
    }
    this.repaint();
  }

  private String message = null;

  private void setMessage(String msg) {
    message = msg;
  }

  @Override
  public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g.create();

    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g2.setColor(Color.white);
    g2.fillRect(0, 0, getWidth(), getHeight());

    g2.setColor(Color.black);
    g2.fill(walls3);
    g2.setColor(Color.lightGray);
    g2.fill(walls1);
    g2.setColor(Color.gray);
    g2.fill(walls2);

    g2.setColor(Color.orange);
    g2.fillArc(food.x, food.y, wallStep, wallStep, 0, 360);
    g2.setColor(Color.red);
    g2.drawArc(food.x, food.y, wallStep, wallStep, 0, 360);

    snake.paint(g2);

    g2.setColor(Color.yellow);
    g2.drawString("Points: " + points, 2, 10);

    if (message != null) {
      g2.setColor(Color.red);
      g2.fillRect(150, 100, 100, 30);
      g2.setColor(Color.black);
      g2.drawRect(150, 100, 100, 30);
      g2.drawString(message, 160, 120);
    }
  }

  public void processKey(KeyEvent ev) {
    Snake snake = getSnake();
    switch (ev.getKeyCode()) {
    case KeyEvent.VK_RIGHT:
      snake.setDirection(Snake.DIR_RIGHT);
      break;
    case KeyEvent.VK_LEFT:
      snake.setDirection(Snake.DIR_LEFT);
      break;
    case KeyEvent.VK_DOWN:
      snake.setDirection(Snake.DIR_DOWN);
      break;
    case KeyEvent.VK_UP:
      snake.setDirection(Snake.DIR_UP);
      break;
    case KeyEvent.VK_ESCAPE:
      System.exit(0);
      break;
    }
  }

}