Главная страница
Навигация по странице:

  • 1 Описание правил игры «Лабиринт»

  • 2 Диаграмма классов и её описание

  • 3 Разработка основных алгоритмов

  • 4 Реализация и тестирование программы

  • Приложение А

  • Приложение B

  • Приложение C

  • Приложение D

  • Приложение E

  • Приложение F

  • курсовая игра в лабиринт на JAVA. курсовая. Содержание Введение 6 1 Описание правил игры Лабиринт 7 2 Диаграмма классов и её описание 8 3 Разработка основных алгоритмов 10 4 Реализация и тестирование


    Скачать 1.04 Mb.
    НазваниеСодержание Введение 6 1 Описание правил игры Лабиринт 7 2 Диаграмма классов и её описание 8 3 Разработка основных алгоритмов 10 4 Реализация и тестирование
    Анкоркурсовая игра в лабиринт на JAVA
    Дата25.10.2022
    Размер1.04 Mb.
    Формат файлаdocx
    Имя файлакурсовая.docx
    ТипРеферат
    #753951






    Содержание


    Введение 6

    1 Описание правил игры «Лабиринт» 7

    2 Диаграмма классов и её описание 8

    3 Разработка основных алгоритмов 10

    4 Реализация и тестирование программы  12

    Заключение 16

    Приложение А 17

    Приложение B 18

    Приложение C 19

    Приложение D 20

    Приложение E 22

    Приложение F 26


    Введение


    Лабиринт — жанр игр; игры данного жанра характеризуются тем, что успех игрока определяется в основном навигацией и ориентацией в лабиринте – структуре (обычно в двухмерном или трёхмерном пространстве), состоящей из запутанных путей к выходу. Ответ на вопрос, является ли что-то лабиринтом, относителен, но как правило имеется возможность различить, ставит ли предлагаемая комбинация комнат и коридоров необходимость решения задачи навигации в лабиринте.

    Целью курсовой работы является приобретение навыков по разработке

    программ на языке Java на примере создание игры «Лабиринт».

    Для реализации цели необходимо решить ряд задач:

    1) Описать правила игры

    2) Реализовать диаграмму классов

    3) Разработать основные алгоритмы

    4) Реализовать и протестировать программу

    1 Описание правил игры «Лабиринт»


    Первые лабиринтные игры не обладали большой сложностью. Так, для приключенческих игр размер представлял около полусотни локаций. Некоторое время предпринимались попытки увеличения их числа, но вскоре выяснилось, что такой подход не позволяет внести в игру чего-то особенно интересного, и обычной практикой стал объём игрового мира порядка сотни локаций. Вместо увеличения размера лабиринта начали применять другие решения. Например, выделять группу локаций в отдельные зоны, где игровой мир обретал свои общие свойства. Локации в такой зоне могут отличаться графически от других зон, это может быть однотипное описание в текстовых играх. Для первых лабиринтовых игр характерен вид сверху, когда карта мира объединялась с представлением, а сам лабиринт целиком помещался на экране.

    Основная задача классического лабиринта найти выход из структуры со сложной системой путей, управляя главным героем. Победой игрока считается успешный выход из лабиринта (если есть ограничение по времени, то успешный выход за определенное время).

    2 Диаграмма классов и её описание




    Рисунок 1 – диаграмма классов игры «Лабиринт»

    Абстрактный класс GameObject является родительским для классов Maze и Player и реализует интерфейс Serializable вместе с GameKeyAdapter и GameWindowAdapter. Эти классы являются вложенными для класса Game и расширяет свой абстрактный класс.

    Класс Game является классом-контейнером и расширяет класс JPanel, реализуя методы интерфейсов Serializable и KeyListener.

    Выполнение программы начинается в классе Main, в нём создаётся экземпляр класса-контейнера Game и вызываются его методы, отвечающие за загрузку игры, поэтому он в свою очередь является компонентом класса Main и находится в отношении композиции с ним.

    3 Разработка основных алгоритмов




    Рисунок 2 – общий алгоритм работы программы

    В классе Game создается файл game.save, в который впоследствии будет сохранена игра. Потом в этом же классе создается окно с помощью метода initWindow(), вызываются классы c методами для прослушивания адаптеров. Далее создается и инициализируется игра с помощью метода initGame()). Отрисовкой занимается метод paintComponent(Graphics g). Игра загружается.

    После загрузки пользователь видит поле с лабиринтом, игроком в левом верхнем углу, выходом в нижнем правом углу и таймером сверху.

    4 Реализация и тестирование программы 


    Средой программирования была выбрана программа IntelliJ IDEA. Так как главные действующие лица игры - игровые объекты, первым делом необходимо реализовать их, а также их родителя – абстрактный класс. 

    GameObject – абстрактный класс, являющийся родителем для классов игровых объектов. Методы draw(Graphics g) и update() переопределяются в классах-наследниках и отвечают за отрисовку и обновление состояния объектов.

    Класс Game реализует интерфейс Serializable, который отвечает за сериализацию.

    Класс Player имеет следующие поля xDir и yDir типа int, хранящие в себе направление движение игрока. Для поля xDir: (1) – движение игрока вправо, (-1) движение игрока влево. Для поля yDir: (1) – движение игрока вверх, (-1) движение игрока вниз.

    Player имеет метод setPlayerPos типа void, принимающий как параметры int  xDir и int yDir, он меняет значения соответствующих полей, отвечающих за  направление движение игрока в зависимости от принятых параметров. 

    За отображение игрока отвечает переопределённый метод draw(Graphics g). Он устанавливает цвет будущего шарика c помощью метода setColor класса Graphics который принимает значение поля цвета. Затем данный метод рисует прямоугольник с помощью метода класса Graphics – fillRect, принимающего координаты и размер из полей Player.

    За обновление состояние игрока отвечает переопределённый метод update(). 

    Класс Game будет наследоваться от класса JPanel, который является частью библиотеки javax.swing. Это позволит сделать Game контейнером для остальных игровых объектов не только с точки зрения проектирования кода, но и с точки зрения пользователя. По своей сути Game будет являться панелью – холстом, на котором будут отображаться, перемещаться и взаимодействовать игровые объекты. 

    Класс Game будет реализовывать интерфейс Serializable, который позволит реализовать сериализацию/десериализацию, и интерфейс KeyListener, с помощь переопределённых методов которого игра будет отслеживать нажатия игрока на клавиатуру. 

    Также в классе Game объявляются переменные игровых объектов и таймер. Помимо этого, объявляется переменная window типа JFrame, она будет представлять собой окно, в котором будет располагаться наша рабочая область – панель игры, и переменная game типа Game, благодаря которой мы сможем объявить в классе Game методы, ответственные за сериализацию. Но объявленная здесь переменная game инициализироваться не будет.  Инициализация класса контейнера будет происходить в классе Main. 

    Если игра завершена, на экране выводится текст об успешном выходе из лабиринта. 

    Полный текст программы предоставлен в Приложении.

    При запуске программы пользователь видит окно в начальном состоянии

    показанное на рисунке 3.



    Рисунок 3 – начало игры

    После того как пользователь дошел до выхода в нижнем правом углу игра

    заканчивается, и он видит окно предлагающее начать игру сначала, показанное

    на рисунке 4:



    Рисунок 4 – окно после победы

    При нажатии кнопки Enter пользователю снова предоставляется начальное

    состояние игры, но с новым лабиринтом.

    Заключение


    В результате выполнения курсовой работы была разработана игра «Выход из лабиринта» на языке программирования Java, были приобретены навыки по созданию подобных игр. Поставленную цель можно считать достигнутой. Также были успешно выполнены следующие задачи: 

    1) Были описаны правила игры; 

    2) Была построена и описана диаграмма классов; 

    3) Были разработаны основные алгоритмы; 

    4) Была реализована и протестирована программа.

    Приложение__C'>Приложение__B'>Приложение_А'>Приложение А


    Листинг файла «Main.java»

    public class Main {

    public static void main(String[] args) {

    Game game;

    try {

    //game = Game.loadGame(); // для создания файла saved.save

    game = Game.loadGame("saved.save");

    game.startGame();

    } catch (Exception e) { System.out.println(e.getMessage()); }

    }

    }

    Приложение B


    Листинг файла «GameObject.java»

    import java.awt.*;

    import java.io.Serializable;
    abstract public class GameObject implements Serializable {

    protected final Point pos;

    protected final int size;

    protected GameObject(int x, int y, int size) {

    this.pos = new Point(x, y);

    this.size = size;

    }

    public abstract void draw(Graphics graphics);

    public abstract void update();

    Приложение C


    Листинг файла «Player.java»

    import java.awt.*;

    public class Player extends GameObject {

    private int xPos;

    private int yPos;

    public Player(int x, int y, int size, int xPos, int yPos) {

    super(x, y, size);

    this.xPos = xPos;

    this.yPos = yPos;

    }

    public void setPlayerPos(int x, int y) {

    this.xPos = x;

    this.yPos = y;

    }

    public int getPosX() { return xPos; }

    public int getPosY() { return yPos; }

    @Override

    public void draw(Graphics g) {

    g.setColor(CellType.PLAYER.getColor());

    g.fillRect(xPos * size + pos.x, yPos * size + pos.y, size, size);

    }

    @Override

    public void update() { }

    }

    Приложение D


    Листинг файла «Maze.java»

    import java.awt.*;

    import java.util.*;
    public class Maze extends GameObject {

    private final int rows;

    private final int cols;

    private final CellType[][] maze;

    private final Random rand;
    public Maze(int x, int y, int size, int rows, int cols) {

    super(x, y, size);

    this.rows = rows;

    this.cols = cols;

    maze = new CellType[rows][cols];

    rand = new Random();

    clearMaze();

    }

    public void clearMaze() {

    for(int row = 0; row < rows; ++row)

    for(int col = 0; col < cols; ++col) {

    if(row == 0 || col == 0 || row == rows - 1 || col == cols - 1)

    maze[row][col] = CellType.WALL;

    else maze[row][col] = CellType.EMPTY;

    }

    }

    private void fillMazeWalls() {

    for(int row = 0; row < rows; ++row)

    for(int col = 0; col < cols; ++col)

    maze[row][col] = CellType.WALL;

    }

    public void randomGenerate() {

    fillMazeWalls();

    final LinkedList frontiers = new LinkedList<>();

    frontiers.add(new int[]{ 1, 1, 1, 1 });

    while (!frontiers.isEmpty()){

    final int[] f = frontiers.remove(rand.nextInt(frontiers.size()));

    int wallX = f[0], wallY = f[1];

    int x = f[2], y = f[3];

    if (maze[y][x] == CellType.WALL) {

    maze[wallY][wallX] = maze[y][x] = CellType.EMPTY;

    if (x - 2 > 0 && maze[y][x - 2] == CellType.WALL)

    frontiers.add(new int[]{ x - 1, y, x - 2, y });

    if (y - 2 > 0 && maze[y - 2][x] == CellType.WALL)

    frontiers.add(new int[]{ x, y - 1, x, y - 2});

    if (x + 2 < cols - 1 && maze[y][x + 2] == CellType.WALL)

    frontiers.add( new int[]{ x + 1, y, x + 2, y });

    if (y + 2 < rows - 1 && maze[y + 2][x] == CellType.WALL)

    frontiers.add( new int[]{ x, y + 1, x, y + 2 });

    }

    }

    }

    public CellType getType(int x, int y) {

    return maze[y][x];

    }

    @Override

    public void draw(Graphics g) {

    for(int row = 0; row < rows; ++row)

    for(int col = 0; col < cols; ++col) {

    g.setColor(maze[row][col].getColor());

    int x = col * size + pos.x;

    int y = row * size + pos.y;

    g.fillRect(x, y, size, size);

    }

    }

    @Override

    public void update() { }

    }

    Приложение E


    Листинг файла «Game.java»

    import javax.swing.*;

    import java.awt.*;

    import java.awt.event.*;

    import java.io.*;
    public class Game extends JPanel {

    public static final int MAZE_WIDTH = 21;

    public static final int MAZE_HEIGHT = 21;

    public static final int CELL_SIZE = 25;

    public static final int WINDOW_WIDTH = MAZE_WIDTH * CELL_SIZE;

    public static final int WINDOW_HEIGHT = MAZE_HEIGHT * CELL_SIZE;
    private static class GameWindowAdapter extends WindowAdapter implements Serializable {

    @Override public void windowClosing(WindowEvent e) {

    try {

    FileOutputStream outputStream = new FileOutputStream("saved.save");

    ObjectOutputStream objOutputStream = new ObjectOutputStream(outputStream);

    objOutputStream.writeObject(instance);

    objOutputStream.close();

    } catch(Exception ex) { }

    super.windowClosing(e);

    }

    }

    private class GameKeyAdapter extends KeyAdapter implements Serializable {

    @Override public void keyPressed(KeyEvent e) {

    if(e.getKeyCode() == KeyEvent.VK_ENTER)

    initGame();

    if(isWin) return;

    switch (e.getKeyCode()) {

    case KeyEvent.VK_RIGHT -> tryMove(1, 0);

    case KeyEvent.VK_LEFT -> tryMove(-1, 0);

    case KeyEvent.VK_UP -> tryMove(0, -1);

    case KeyEvent.VK_DOWN -> tryMove(0, 1);

    }

    }

    }
    private void tryMove(int xDir, int yDir) {

    int newX = player.getPosX() + xDir;

    int newY = player.getPosY() + yDir;

    if(newX > 0 && newX < MAZE_WIDTH - 1 &&

    newY > 0 && newY < MAZE_HEIGHT - 1 &&

    maze.getType(newX, newY) != CellType.WALL)

    player.setPlayerPos(newX, newY);

    if(newX == MAZE_WIDTH - 2 && newY == MAZE_HEIGHT - 2) {

    isWin = true;

    timer.stop();

    infoBox("Время прохождения: " + secondsPlay + " секунд.\nНажмите Enter для новой игры!", "Вы победили!");

    }

    }
    private final JFrame window;

    private static Game instance;
    private final Maze maze;

    private final Player player;

    private final Timer timer;

    private int secondsPlay;

    private boolean isWin;
    public Game() {

    window = new JFrame();

    initWindow();
    maze = new Maze(0, 0, CELL_SIZE, MAZE_WIDTH, MAZE_HEIGHT);

    player = new Player(0, 0, CELL_SIZE, 1, 1);

    timer = new Timer(1000, new AbstractAction() {

    public void actionPerformed(ActionEvent e) { secondsPlay++; }

    });
    initGame();

    window.setVisible(true);

    }
    private void initWindow() {

    this.setPreferredSize(newDimension(WINDOW_WIDTH, WINDOW_HEIGHT));

    window.add(this);

    window.pack();

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    window.addKeyListener(new GameKeyAdapter());

    window.addWindowListener(new GameWindowAdapter());

    window.setResizable(false);

    }

    private void initGame() {

    isWin = false;

    player.setPlayerPos(1, 1);

    maze.randomGenerate();

    secondsPlay = 0;

    timer.restart();

    }
    public static Game loadGame() {

    if(instance == null)

    instance = new Game();

    return instance;

    }

    public static Game loadGame(String saveFile) throws Exception {

    if(instance == null) {

    File file = new File(saveFile);

    if(!file.isFile() || !file.canRead())

    return loadGame();

    try {

    FileInputStream fileInputStream = new FileInputStream(saveFile);

    ObjectInputStream objInputStream = new ObjectInputStream(fileInputStream);

    instance = (Game) objInputStream.readObject();

    instance.window.setVisible(true);

    if(!instance.isWin)

    instance.timer.start();

    objInputStream.close();

    } catch (Exception ex) {

    throw new Exception("Ошибка при загрузке сохранения!");

    }

    }

    return instance;

    }
    public void startGame() {

    long lastTime = System.nanoTime();

    double ns = 1000000000 / 60D;

    double delta = 0;

    while(true) {

    long now = System.nanoTime();

    delta += (now - lastTime) / ns;

    lastTime = now;

    if(delta >= 1) {

    if(!isWin) {

    tick();

    repaint();

    }

    }

    }

    }

    private void tick() {

    window.setTitle("Time: " + secondsPlay + " seconds");

    maze.update();

    player.update();

    }

    @Override

    protected void paintComponent(Graphics g) {

    super.paintComponent(g);

    maze.draw(g);

    player.draw(g);

    }

    public void infoBox(String message, String title) {

    JOptionPane.showMessageDialog(null,message,title, JOptionPane.INFORMATION_MESSAGE);

    }

    }

    Приложение F


    Листинг файла «CellType.java»

    import java.awt.*;
    public enum CellType {

    EMPTY(Color.WHITE),

    WALL(Color.BLACK),

    PLAYER(Color.BLUE);
    private final Color color;

    CellType(Color color) {

    this.color = color;

    }

    public Color getColor() { return color; }

    }



    написать администратору сайта