2013-06-26 2 views
0

Я пытаюсь создать простую шахматную игру, чтобы получить некоторый опыт работы с Java, но я застрял и нуждаюсь в совете о том, как реализовать несколько игроков в моей игре.Какой подход я должен предпринять, чтобы реализовать несколько игроков в простой пошаговой игре?

У меня есть класс под названием Player, который вызывается методом main для создания объекта Player со всеми свойствами. Следуя этой идее, я подумал, что добавление нескольких игроков будет таким же простым, как создание нескольких экземпляров Player, однако оказалось, что это довольно сложно, так как мне нужно получить доступ к переменным всех игроков из нескольких других классов, кроме тех, в которых он был создан, и я могу Невозможно найти простой способ сделать это.

Является ли мой подход правильным или лучше (проще и шире) способами, с точки зрения структуры кода и связывания различных классов, для реализации многопользовательской функциональности?

EDIT: класс

плеера с частными переменными:

public class Player { 

    private int playerID; 
    private String playerName; 
    ... 
} 

Это, как я инициализация несколько объектов игрока в зависимости от количества игроков в игре:

public static void createPlayers(int numberOfPlayers) { 
    if (numberOfPlayers == 2) { 
     Player playerOne = new Player(1); 
     Player playerTwo = new Player(2); 
    } else if (numberOfPlayers == 4) { 
     Player playerOne = new Player(1); 
     Player playerTwo = new Player(2); 
     Player playerThree = new Player(3); 
     Player playerFour = new Player(4); 
    } 
} 

Например У меня есть метод в классе Board, который печатает 2D-массив для консоли, и если он найдет playerID, скажем, PlayerOne, это shou ld напечатать его ID в заданном поле. Однако я не могу получить доступ к соответствующему способу доступа, потому что PlayerOne был инициализирован в main, а не в Board.

private static final int boardFieldEmpty = 0;  // 0 on a board represents empty field 
private static final int boardFieldChampion = 1; // 1 on a board represents a champion 
private static final int boardFieldBase = 2;  // 2 on a board represents a base 


// Initialise board and fill it with empty fields 
public Board(int boardRows, int boardColumns) { 
    boardSize = new int[boardRows][boardColumns]; 
    for (int r = 0; r < boardRows; r++) { 
     for (int c = 0; c < boardColumns; c++) { 
      boardSize[r][c] = boardFieldEmpty; 
     } 
    } 
} 


// Print a board on the screen 
public void printBoard() { 
    for (int r = 0; r < boardSize.length; r++) { 
     for (int c = 0; c < boardSize[0].length; c++) { 
      if (boardSize[r][c] == boardFieldEmpty) { 

       // Empty field found      
       System.out.print(" |_|"); 

      } else if (boardSize[r][c] == boardFieldChampion) { 

       // Champion field found 
       System.out.print(" |" + PlayerOne.getPlayerID + "|"); 

      } else if (boardSize[r][c] == boardFieldBase) { 

       // Base field found 
       System.out.print(" |X|");      
      } 
     } 
     System.out.println(); 
    } 
    System.out.println(); 
} 

EDIT 2: Учитывая мой код, как бы я должен изменить его для того, чтобы каждый экземпляр объекта проигрывателя доступны из разных классов?

+0

Можете ли вы изменить свой вопрос, включив в него некоторый код, особенно в том месте, где вы пытаетесь получить доступ к данным этого игрока? –

+0

После того, как вы отредактировали, ясно, что вам нужен шаблон Factory ... см. Мой ответ. – Renato

ответ

0

Посмотрите на API коллекций - он немного привыкает, но Google поможет.

Он содержит кучу классов, которые можно использовать для хранения нескольких экземпляров одного и того же класса.

Возможно, вам понравится ArrayList. Это позволит вам добавить к нему несколько объектов Player и получить к ним доступ по индексу. Если вы просто продолжаете увеличивать индекс до тех пор, пока не достигнете количества игроков, а затем установите его на ноль, вы будете иметь базовую модель поворота в действии.

+0

Я экспериментировал с инициализацией нескольких объектов Player, используя ArrayList, однако я чувствовал, что у меня не было контроля над наименованием каждого объекта, и мне было трудно обратиться к конкретному экземпляру Player позже в моем коде. Если мне не хватает чего-то тривиального. – Ninetou

+0

Хорошо, тогда может быть интересна Карта - она ​​позволяет вам снова хранить коллекцию объектов Player, но вы можете ссылаться на них по имени, а не по индексу. Возможно, немного сложнее, но не очень. – DaveH

0

Вы должны сделать это с помощью всего лишь одного Player, как вы уже упоминали.

Player p1 = new Player(); 
Player p2 = new Player(); 
p1.movePlayerUp(); 

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

Например, этот метод может быть в любом классе, и вы просто передаете ему плеер. Вы используете методы для получения и установки переменных объекта Player. Таким образом, обновления будут отображаться в объекте, на который вы вызываете movePlayerUp().

public void movePlayerUp() { 
    this.setY(this.getY() + 1); 
} 
0

У вас могут быть статические поля, которые будут использоваться всеми экземплярами ...Пример:

class Player { 
    String notSharedProp; 
    static String sharedProp; 
} 

При создании нового игрока, он будет иметь свой собственный «notSharedProp», но он будет использовать один и тот же «sharedProp», как все остальные игроки (именно поэтому вам не нужен экземпляр проигрывателя изменить «sharedProp»:

Player p1 = new Player() 
p1.notSharedProp = "John"; 

Player p2 = new Player() 
p2.notSharedProp = "Mary"; 

Player.sharedProp = "People"; 

// now both p1 and p2 have sharedProp set to "People" 
// but p1.notSharedProperty is "John" and p2.notSharedProp is "Mary" 

// now let's set ALL Player instances sharedProp to "Soldier" 
Player.sharedProp = "Soldier"; 

Если вы хотите, чтобы убедиться, что вы можете получить все игроки созданы, независимо от того, откуда, вы должны использовать шаблон фабрики:

public class PlayerFactory { 

    private final List<Player> allPlayers = new ArrayList<>(); 

    public static class Player { 
      private Player() {} // now no other classes can instantiate Player 
      /* write the player code */ 
    } 

    public static Player createPlayer() { 
      // create them 
      Player p = new Player(); 
      allPlayers.add(p); 
      return p; 
    } 

} 



public class AnotherClass { 

    void someMethod() { 
      Player p1 = PlayerFactory.createPlayer(); 
      Player p2 = PlayerFactory.createPlayer(); 
      // and so on... 

    } 
} 
+0

Не могли бы вы пояснить, какая разница делает этот подход в отличие от инициализации таких объектов ?: 'Список cars = new ArrayList (); for (int i = 0; i Ninetou

+0

В шаблоне фабрики ни один класс, отличный от самого завода, не может создать объект (Player в этом случае). Вы гарантируете, что сделаете конструктор Player закрытым.Это очень мощно и гарантирует, что вы всегда можете быть в безопасности, вы можете применить изменения в том, как вы создаете игроков только в одном месте ... вы даже можете решить вернуть определенный подкласс игрока в разных ситуациях ... – Renato

+0

http: //www.oodesign.com/factory-pattern.html – Renato

1

вы не показывают, как вы инициализируете (ака, что происходит, когда игрок добавляется, куда идут куски и кто принадлежит этим частям). Есть много способов сделать то, что вы хотите сделать, это просто зависит от многих вещей. В чем смысл вашей игры? Как чемпиона размещаются на борту? Есть ли чемпионы на одного игрока? Можно ли взять базу (ы)? Как вы побеждаете? и т. д. и т. д. Отслеживающие чемпионы можно было бы сделать через доску (в этом случае вы хотели бы следить за владельцем/игроком чемпиона), или вы могли бы отслеживать чемпионов через игроков (и иметь ArrayList игроков) в Класс Board, с которым вы проходите, и находите места чемпионов игроков, основанные на атрибуте row/colr чемпиона Champion. Это основано от идеи доска местоположение:

Это может быть хорошей идеей, чтобы создать класс под названием Кусок, который имеет следующее:

public class Piece { 
    private int type; 
    private Player owner; 
    public Piece(int type, Player owner){ 
     this.type = type; 
     this.owner = owner; 
    } 

    public int getType(){ 
     return type; 
    } 
    public Player getOwner(){ 
     return owner; 
    } 
} 

Затем, когда вы хотите инициализировать плату, создавать новые кусочки как:

private static final int boardFieldEmpty = 0;  // 0 on a board represents empty 
private static final int boardFieldChampion = 1; // 1 on a board represents a champion 
private static final int boardFieldBase = 2;  // 2 on a board represents a base 
private Piece[][] boardSize; 

    // Initialise board and fill it with empty fields 
    public Board(int boardRows, int boardColumns) { 
     boardSize = new Piece[boardRows][boardColumns]; 
     for (int r = 0; r < boardRows; r++) { 
      for (int c = 0; c < boardColumns; c++) { 
       boardSize[r][c] = new Piece(boardFieldEmpty, null); //the pieces will be empty, so no player owns those spots yet 
      } 
     } 

     // Diagnostic - report board size 
     System.out.println("Board consists of " + boardRows + " rows and " + boardColumns + "columns."); 
    } 


    // Print a board on the screen 
    public void printBoard() { 
    for (int r = 0; r < boardSize.length; r++) { 
     for (int c = 0; c < boardSize[0].length; c++) { 
      if (boardSize[r][c].getType() == boardFieldEmpty) { 

       // Empty field found      
       System.out.print(" |_|"); 

      } else if (boardSize[r][c].getType() == boardFieldChampion) { 

       // Champion field found 
       System.out.print(" |" + boardSize[r][c].getOwner().playerID + "|"); 

      } else if (boardSize[r][c].getType() == boardFieldBase) { 

       // Base field found 
       System.out.print(" |X|");      
      } 
     } 
     System.out.println(); 
    } 
    System.out.println(); 
} 

Это означает, что где бы вы инициализировать размещение частей для игрока, вы должны иметь что-то подобное для платы:

public void initializePlayerChampion(Player p, int row, int column){ 

     //loop through the board for wherever you want to add that players champion 
     //add them however you want 
     int champion = 1; //champion 
     boardSize[row][column] = new Piece(champion, p); //r and c determined by your loop 
    //try your printBoard after calling initializePlayerChampion(...) wherever you want to place your champions from your main method 
} 

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

boardSize[row][column] = new Piece(2, null); 

Если вы хотите базу, чтобы иметь потенциал, чтобы быть приняты в течение, просто расширить класс Кусочек как класс Base и добавьте метод setOwner(), который устанавливает владельца в зависимости от того, какой игрок его выиграл. Существуют более эффективные шаблоны проектирования, которые можно использовать для этого, но без каких-либо подробностей относительно того, что вы хотите сделать, трудно определить, что использовать.

+0

Я использовал базу только как контрольную точку, которая была графиком на простой сетке в консоли. Спасибо за эти предложения, они обязательно пригодится, когда я захочу сделать игру немного более сложной. – Ninetou

+0

Я отредактирую это снова через пару минут, я подумал о чем-то, что может улучшить вашу игру. – ARC