2016-11-19 5 views
-1

Я пытаюсь создать программу на Java, которая похожа на настольную игру. У меня есть gameTiles, в настоящее время только с одним цветом, когда я пытаюсь правильно подобрать макет. Я хочу, чтобы плитки появлялись примерно на полпути ширины окна и простирались на дно, возможно, где-нибудь от 9x9 или 11x11 различных фрагментов. Я попытался использовать макет сетки, чтобы они были близки друг к другу, не обязательно касаясь, но достаточно близко, чтобы выглядеть как настольная игра. Однако, независимо от того, что я пытаюсь сделать, плитки - это пространство, находящееся далеко друг от друга, и меняют форму при изменении размера окна. Я использую менеджер GridLayout, чтобы попытаться достичь этого. Вот мой код.grid layout с JPanels java

import java.awt.GridLayout; 
    import javax.swing.JFrame; 
    public class GameWindow extends JFrame { 

public GameWindow(String title){ 
    super(title); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setSize(1200,400); 
} 

/** 
* @param args 
*/ 
public static void main(String[] args) { 
    GameWindow gameWindow = new GameWindow("Game"); 
    gameWindow.setLayout(new GridLayout(0,2)); 
    GameTile greenTile = new GameTile(0,true,0,10); 
    GameTile greenTile2 = new GameTile(0,true,0,10); 
    gameWindow.add(greenTile); 
    gameWindow.add(greenTile2); 
    gameWindow.setVisible(true); 
} 
    } 

Это файл GameWindow.java. GameTile.java я до сих пор (который до сих пор в основном не закончен только для тестирования) выглядит следующим образом:

import java.awt.Color; 
    import java.awt.Graphics; 
    import java.awt.Image; 
    import java.io.File; 
    import java.io.IOException; 
    import javax.imageio.ImageIO; 
    import javax.swing.JPanel; 
    /** 
    * @author Zachary Parks 
    * 
    */ 
    public class GameTile extends JPanel { 
    private Color color; 
    private Color[] colors = {Color.BLUE, Color.YELLOW, Color.BLACK}; 
    private int score, multiplier,initialX,initialY; 
    private boolean positiveEffect; 

    public GameTile(int colorTile, boolean effect, int initX, int initY){ 
    color = colors[colorTile]; 
    score = getScore(color); 
    multiplier = getMultiplier(color); 
    positiveEffect = effect; 
    initialX = initX; 
    initialY = initY; 
    } 
    protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    Image image = null; 
    try { 
     image = ImageIO.read(new File("greentile.png")); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    g.drawImage(image,initialX,initialY,this); 
    } 

    private int getMultiplier(Color color2) { 
    return 0; 
    } 

    private int getScore(Color color2) { 
    return 0; 
    } 
    /** 
    * Method that returns the data from the tile in 
    * array of int. 0 index = added score, 1 index = tile effect score 
    * @return 
    */ 
    public int[] getData() { 
    int [] scoreData = null; 
    scoreData[0] = score*multiplier; 
    return null;  
    } 
    } 

Много кода все еще продолжается, как и свойство GameTile, все, что я пытаюсь в этот момент вы получаете плитки рядом друг с другом. Это то, что я получаю:

http://i.imgur.com/nXfrYSU.png

+0

Итак, что конкретно представляет собой ваш вопрос? Ваша батарея составляет 94%, подключите кабель? – brummfondel

+0

Не делайте ввода-вывода файлов в методе рисования. Изображение должно быть прочитано в конструкторе вашего класса. – camickr

+0

Вам действительно нужны эти панели и менеджер макетов? Если вы ищете простой доски, почему бы просто не рисовать и заполнять квадраты 9x9 или 11x11? – Arvind

ответ

2

Чтобы добавить плитки, как сетки. A tileSize переменная отлично подходит. Предположим, что изображение/плитка составляет 32 пикселя.

public static final tileSize = 32; 

С этим, мы можем теперь добавить плитки, используя для цикла:

for(int x = 0; x < SCREEN_WIDTH/GameTile.tileSize; x++) { // loop through as many tiles fit the x-axis. 
    for(int y = 0; y < SCREEN_HEIGHT/GameTile.tileSize; y++) { // do the same with y-axis 
     GameTile greenTile = new GameTile(0,true, x * GameTile.tileSize , y * GameTile.tileSize); 
     gameWindow.add(greenTile); 
    } 
} 

SCREEN_WIDTH и SCREEN_HEIGHT является размер вашего JFrame. Имейте в виду, что это происходит по всему экрану, вам нужна половина, но она легко настраивается.

Пожалуйста, отформатируйте свой код в следующий раз (вкладка), гораздо легче прочитать и помочь. Я настоятельно рекомендую переместить image = ImageIO.read(new File("greentile.png")); в конструктор, прямо сейчас вы загружаете изображение каждые частоты кадров для каждой игры, что приведет к снижению производительности.

Также нет JPanel для каждого GameTile. Вместо того, чтобы держать его в главном классе рисования и петли через все GameTiles используя ArrayList

public static ArrayList<GameTile> gameTiles = new ArrayList<GameTile>(); 

protected void paintComponent(Graphics g) { 
    for(int i = 0; i < gameTiles.size(); i++) { 
     gameTiles.get(i).draw(g); 
    } 

Таким образом, вместо добавления JPanel в JFrame для каждого gameTile, мы рисуем gameTiles по указанным координатам. Удачи!

Чтобы ответить на ваш вопрос в поле комментария: код будет выглядеть на эту

public class GameWindow extends JPanel { 

    public static ArrayList<GameTile> gameTiles = new ArrayList<GameTile>(); 

    public static void main(String[] args) { 
     new GameWindow(); 
    } 

    public GameWindow() { 

     JFrame frame = new JFrame();  
     frame.setSize(300, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(this); 
     frame.setVisible(true); 

     // add all the tiles (I just use x and y as parameters here) 
     gameTiles.add(new GameTile(10, 10)); 
     gameTiles.add(new GameTile(50, 10)); 

    } 

    public void paintComponent(Graphics g) { 

     for(int i = 0; i < gameTiles.size(); i++) { 
      gameTiles.get(i).draw(g); 
     } 

    } 

} 

А внутри класса GameTile, удалите extends JPanel. И переименуйте paintComponent как draw или что-то подобное.

+0

Я реализую ваш код, чтобы увидеть, как это будет выглядеть, но на строке (gameTiles.get (i) .draw (g); есть ошибка, когда у меня нет метода draw для класса gameTiles. извините за то, что вы такой noob, но GUI действительно меня пугает. – SkillaPop

+0

Вам нужно заменить свой метод paintComponent в классе GameTile с помощью draw (Graphics g). Вы можете вызвать метод, который вы хотите, рисовать, рисовать, рисовать, вверх – Squiddie

+0

Это то, что у меня есть (и я сожалею, что не знаю, как форматировать код на эти комментарии или в сообщении, как вы видели) \t [[protected void draw (Graphics g) { super.paintComponent (g); \t for (int i = 0; i SkillaPop

1

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

GridLayout расширяет каждую ячейку, чтобы заполнить пространство, доступное для компонента. Если у вас есть только две ячейки, каждая ячейка займет половину ширины кадра.

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

Что-то вроде:

JPanel tilePanel = new JPane(new GridLayout(0, 2, 5, 5)); 
tilePanel.add(new GameTile(...)); 
tilePanel.add(new GameTile(...)); 

JPanel wrapper = new JPanel(new GridBagLayout()); 
wrapper.add(tilePanel, new GridBagConstraints()); 

frame.add(wrapper, BorderLayout.CENTER); 

Приведенный выше код заставит плитки быть в центре кадра.

frame.add(wrapper, BorderLayout.LINE_END); 

Приведенное выше приведет к тому, что плитки будут отображаться справа от рамки, вертикально центрированной.