Модераторы: Rickert

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разработка игры "Территория" (Точки), Java, с нуля 
:(
    Опции темы
Qawra
Дата 31.12.2008, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



есть кнопка , есть класс  для выбора игроком цвета
Код

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

class ColorChooser extends JFrame implements ActionListener 
{
  private Player player;
  
  public void actionPerformed(ActionEvent e) {
    // Args are parent component, title, initial color
    Color color
      = JColorChooser.showDialog(this,"Choose your color",
                                                  player.getColor());
    if (color != null) {
      player.setColor(color);
    }
  }
}
 и есть класс игрок .
При нажатии кнопки должен выходить диалог выбора цвета  для игрока .
Я думала что достаточно при нажатии кнопки 
Код

if(e.getSource().equals(firstPlayerButton))
{ Player  first = new Player(1); 
}

 создать  игрока из конструктора класса Игрок  который уже выберет себе цвет но не знаю как этот конструктор прописать  что-бы он выбирал цвет .
Мой конструктор видимо в принципе ошибочный.Он ничего не выбирает поэтому я его здесь и не отображаю . 

PM MAIL   Вверх
Rpahut
Дата 31.12.2008, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Если цвет выбирается в момент создания игрока, то:
Код

class ColorChooser extends JFrame implements ActionListener 
{
  // private Player player; // класс работает с Цветом, а не с Игроком
  // private Color color; // сохранять цвет, впрочем, тоже не обязательно
  
  // просим пользователя выбрать цвет...
  public Color ShowChooser(Color defaultColor) {
    // ...и возвращаем его
    return JColorChooser.showDialog(this, "Choose your color",  defaultColor);
  }
}


В конструкторе класса Игрок:
Код

  // ОБЯЗАТЕЛЬНО нужно сначала назначить игроку какой-то уникальный цвет
  // иначе после отказа пользователя выбрать цвет, игрок будет рисоваться черным
  // (?) насчет черного не уверен, но ничего хорошего точно не выйдет
  ColorChooser cchooser;
  Color tmpcolor = cchooser.ShowChooser(color); // параметр color - цвет игрока по умолчанию
  if(tmpcolor != null) color = tmpcolor; // меняем цвет, только если получили обратно не-null


Добавлено @ 18:59
Если цвет хочется менять во время игры, то:
1. Создаем кнопки или пункты меню "Поменять цвет Игрока1" "Поменять цвет Игрока2"
2. Клеим их к основному окну
3. В класс Игрок добавляем метод смены цвета:
Код

public void ChangeColor() {
  ColorChooser cchooser;
  Color tmpcolor = cchooser.ShowChooser(color); // параметр color - текущий цвет игрока
  if(tmpcolor != null) color = tmpcolor; // меняем цвет, только если получили обратно не-null
}

4. В основном окне отслеживаем нажатие кнопок (или выбор пункта меню) и вызываем метод ChangeColor() соответствующего игрока.


ЗЫ
С Праздником!

Это сообщение отредактировал(а) Rpahut - 31.12.2008, 19:03
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 1.1.2009, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



C Наступившим ...и ещё с наступающими !
получился у меня такой синтакс на кнопке
Код

if (e.getSource().equals(firstPlayerButton)) 
    {  
         Color playerColor  = Color.blue;
          Player first= new Player(1);
      }


такой ColorChooser
Код

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

class ColorChooser extends JFrame implements ActionListener 
{
  
 
  public Color ShowChooser(Color defaultColor) {
      
    return JColorChooser.showDialog(this, "Choose your color",  defaultColor);
  }
  
   public void actionPerformed(ActionEvent e) {
    
  }
}



проблема сейчас с игроком
Код

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

public class Player 
 {
  private Color playerColor;
  private  ColorChooser cchooser;
  private int orderOfPlayers ;
  
  public Player(int orderOfPlayers) // constructor 
  {    
      this.orderOfPlayers=orderOfPlayers;
      
     
     this.playerColor = this.cchooser.ShowChooser(Color playerColor ); 
                                                  
     if(tmpcolor != null) 
     playercolor = tmpcolor;                     
                                           

    }
 }



на строчке
 this.playerColor = this.cchooser.ShowChooser(Color playerColor ); 
компайлер ругается что ему нужна ещё  ")" 
Я пробовала различные варианты написания , но ему всё равно нужна ещё одна скобка.
PM MAIL   Вверх
Rpahut
Дата 1.1.2009, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Код

... .ShowChooser(playerColor);


И еще:

Код

if (e.getSource().equals(firstPlayerButton)) 
    {  
          Player first= new Player(1, Color.blue); // передаем цвет
      }

Код

public Player(int orderOfPlayers, Color color) // constructor 
  {    
      this.orderOfPlayers=orderOfPlayers;
      this.playerColor=color; // принимаем цвет

      // кстати, переменную playerColor удобнее назвать просто color
      // потому как  переменная color класса Player может означать только цвет игрока
      // уточнять что это именно playerColor не требуется
      // можно сэкономить несколько букв =Ъ
      
      // не забываем - возвращаемый цвет сначала кладем во временную переменную
      Color tmpcolor = this.cchooser.ShowChooser(playerColor);
      // слово this в предыдущей строчке можно убрать
      if(tmpcolor != null) playerСolor = tmpcolor;
      /* Или без временной переменной, тогда вот так:
      playerColor = cchooser.ShowChooser(Color playerColor );
      if(playerColor==null) playerColor = color; // если не выбран цвет - присваиваем цвет по умолчанию
      */
      /*
      Или - еще лучше - вставить эту проверку в метод ShowChooser(). Т.е. если showDialog возвращает
      null, ShowChooser() должен вернуть defaultColor.
      Тогда здесь можно будет просто написать
      playerColor = cchooser.ShowChooser(playerColor );
      */
    }

--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 3.1.2009, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



почему-то компайлер хочет ещё одну круглую скобку. Видимо ему что-то другое не нравится в этом варианте конструктора 
Код

 public Player(int orderOfPlayers,Color color ) 
  {    
      this.orderOfPlayers=orderOfPlayers;
      this.playerColor = color; 
      
      playerColor = cchooser.ShowChooser(Color playerColor );
      if(playerColor==null)
      {playerColor = color;
        }
}

но пишет он что нужна ещё одна круглая скобка в строчке playerColor = cchooser.ShowChooser(Color playerColor );
Я уже видела   "лишнии" с моей точки зрения  круглые скобки в примерах с Java кодом , но как и почему их ставят - не знаю. Они бывают не парные !!! и откуда они берутся не понятно . В данном случае я попробовала поставить лишнию скобку - компайлер  всё равно пишет что скобки не хватает .Значит дело не в ней а в чём то другом ...
PM MAIL   Вверх
Rpahut
Дата 3.1.2009, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Ваша ошибка тут:
playerColor = cchooser.ShowChooser( smile Color smile  playerColor);

Цитата

Я уже видела   "лишнии" с моей точки зрения  круглые скобки в примерах с Java кодом

Скобки, кавычки и прочие знаки, используемые для отделения части текста, всегда парные - одна указывает начало куска, вторая конец.
При большом нагромождении скобок бывает трудно определить на глаз, все ли в коде правильно. Небольшие куски кода часто пишутся "из головы" и не проверяются на корректность - так что там могут быть и ошибки.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 4.1.2009, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Вы правы .. Это конечно объест класса Color но в данном случае он используется как аргумент ... Перестраховалась я  smile 
Теперь всё скомпилировалось но при нажатии на кнопку компайлер как ни странно  находит кучу exceptions типа java.lang.NullPointerException .
Код

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Player.<init>(Player.java:16)
    at Window.mouseClicked(Window.java:65)
    at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
    at java.awt.Component.processMouseEvent(Component.java:6044)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    at java.awt.Component.processEvent(Component.java:5806)
    at java.awt.Container.processEvent(Container.java:2058)
    at java.awt.Component.dispatchEventImpl(Component.java:4413)
    at java.awt.Container.dispatchEventImpl(Container.java:2116)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3995)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
    at java.awt.Container.dispatchEventImpl(Container.java:2102)
    at java.awt.Window.dispatchEventImpl(Window.java:2440)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Player.<init>(Player.java:16)
    at Window.mouseClicked(Window.java:62)
    at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
    at java.awt.Component.processMouseEvent(Component.java:6044)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    at java.awt.Component.processEvent(Component.java:5806)
    at java.awt.Container.processEvent(Container.java:2058)
    at java.awt.Component.dispatchEventImpl(Component.java:4413)
    at java.awt.Container.dispatchEventImpl(Container.java:2116)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3995)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
    at java.awt.Container.dispatchEventImpl(Container.java:2102)
    at java.awt.Window.dispatchEventImpl(Window.java:2440)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Player.<init>(Player.java:16)
    at Window.mouseClicked(Window.java:65)
    at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
    at java.awt.Component.processMouseEvent(Component.java:6044)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    at java.awt.Component.processEvent(Component.java:5806)
    at java.awt.Container.processEvent(Container.java:2058)
    at java.awt.Component.dispatchEventImpl(Component.java:4413)
    at java.awt.Container.dispatchEventImpl(Container.java:2116)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3995)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
    at java.awt.Container.dispatchEventImpl(Container.java:2102)
    at java.awt.Window.dispatchEventImpl(Window.java:2440)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Player.<init>(Player.java:16)
    at Window.mouseClicked(Window.java:62)
    at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
    at java.awt.Component.processMouseEvent(Component.java:6044)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    at java.awt.Component.processEvent(Component.java:5806)
    at java.awt.Container.processEvent(Container.java:2058)
    at java.awt.Component.dispatchEventImpl(Component.java:4413)
    at java.awt.Container.dispatchEventImpl(Container.java:2116)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3995)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
    at java.awt.Container.dispatchEventImpl(Container.java:2102)
    at java.awt.Window.dispatchEventImpl(Window.java:2440)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)


 Нам показывали exceptions которые возникают при вводе данных . А  здесь мы пока ещё ничего не  вводили .. Я что-то неправильно импортировала ?
PM MAIL   Вверх
arilou
Дата 5.1.2009, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 6
Всего: 61



Видимо ошибка вот тут

Цитата

  at Player.<init>(Player.java:16)


т.е. в 16 строке в файле Player.java. Судя по всему, член класса

Цитата

private  ColorChooser cchooser;


нигде не инициализируется, т.е. ему ничего не присваивается, поэтому происходит java.lang.NullPointerException smile 


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Qawra
Дата 5.1.2009, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



private  ColorChooser cchooser  был инициализирован но ему действительно ничего не присваивалось
Код

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

public class Player 
 {
  private Color playerColor;
  private  ColorChooser cchooser;
  private int orderOfPlayers ;
  
  public Player(int orderOfPlayers,Color color ) // constructor 
  {    
      this.orderOfPlayers=orderOfPlayers;
      this.playerColor = color; 
      
      playerColor = cchooser.ShowChooser( playerColor );
      if(playerColor==null)
      {playerColor = color;
        }
    }
 }
 
Надо   было  видимо создать обьект класса 
ColorChooser cchooser = new ColorChooser (); Только что ему присваивать как цвет если сразу у двух игроков есть предустановленные цвета  . .. null видимо ..

Ничего присваивать оказалось не нужно .Просто оставить пустые  скобочки и всё работает ! 

Это сообщение отредактировал(а) Qawra - 5.1.2009, 13:55
PM MAIL   Вверх
arilou
Дата 5.1.2009, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 6
Всего: 61



Qawra, 
Цитата

нигде не инициализируется


это и значит, что "ничего не присваивалось"  smile по крайней мере, в твоем коде я не нашел.
Цитата(Qawra @  5.1.2009,  13:50 Найти цитируемый пост)
Ничего присваивать оказалось не нужно .Просто оставить пустые  скобочки и всё работает ! 

ничего не понял, ну да ладно.

Цитата

  if(playerColor==null)
      {playerColor = color;
        }


также, вызывает сомнение этот код. Что ты им хотела сказать? 


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Rpahut
Дата 5.1.2009, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата(arilou @ 5.1.2009,  15:48)
Цитата

  if(playerColor==null)
      {playerColor = color;
        }


также, вызывает сомнение этот код. Что ты им хотела сказать?

Здесь если cchooser.ShowChooser(playerColor) возвращает null, игроку присваивается цвет по умолчанию.

Код

java.lang.NullPointerException

И это при том, что в яве указателей нету smile ...

ColorChooser не нужно делать членом класса, потому как после выполнения конструктора класса Player он уже не будет нужен.
Лучше создать его там где он используется:
Код

  public Player(int orderOfPlayers,Color color ) // constructor 
  {    
      this.orderOfPlayers=orderOfPlayers;
      //this.playerColor = color; 
      
      ColorChooser cchooser = new ColorChooser(); //<----
      playerColor = cchooser.ShowChooser(color);
      if(playerColor==null)
      {playerColor = color;
        }
    }

--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 5.1.2009, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



 да.. так оно тоже работает . А когда мы отключаем 
//this.playerColor = color;  то как  быть с  цветом для игрока заданным по умолчанию ? Мы ведь с ним теперь не работаем в конструкторе .
Я правда не могу это сейчас практически проверить .
Попробовать нарисовать точки без выбора цвета игрока  пока нечем .Нужен отдельный класс Points где точки будут рисоваться по очереди цветами игроков и только в углах клеток решётки . Вызывается решётка кодом на кнопке 
Код

if (e.getSource().equals(startButton)) 
    {new Grids("Points", 800, 800, 20, 20).setVisible(true);

есть по умолчанию  два цвета для игроков red и blue  . Но ведь если игрок не станет выбирать цвет то он не запустит  конструктор и цвета по умолчанию тоже не будет .. Хотелось бы написать 
Код

public void mouseClicked(MouseEvent e) {
    if (e.getSource().equals(startButton)) 
    {new Grids("Points", 800, 800, 20, 20).setVisible(true);
       Player first= new Player(1, Color.blue); 
       Player second = new Player(2,Color.red);  

    } else if (e.getSource().equals(firstPlayerButton)) 
    {  Player first= new Player(1, Color.blue);
              
    } else if (e.getSource().equals(secondPlayerButton)) 
    {  Player second = new Player(2,Color.red);  
   } 
  }   
 Но тогда игроку никогда не выбрать себе цвет smile
Как при нажатии кнопки старт проверить что были нажаты firstPlayerButton и
secondPlayerButton ? 
PM MAIL   Вверх
Rpahut
Дата 5.1.2009, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

А когда мы отключаем 
//this.playerColor = color;  то как  быть с  цветом для игрока заданным по умолчанию ?


Цвет по умолчанию мы передаем в ColorChooser:
playerColor = cchooser.ShowChooser(color);
так что либо пользователь изменит и выберет цвет - тогда его мы присвоим игроку,
либо пользователь откажется от выбора - тогда срабатывает проверка на null и цвет по умолчанию записывается в playerColor.

Конструктор вызывается автоматически при создании экземпляра объекта.
Код

Player first= new Player(1, Color.blue);
// создается новый экземпляр Player
// сам собой вызывается метод Player() этого экземпляра

Вручную конструкторы вызывать не стоит. Они существуют для инициализации объектов при создании - в случае класса Player для инициализации его переменных playerColor и orderOfPlayers.

Цитата

Хотелось бы написать...

Так у вас при нажатии кнопки Старт создаются оба игрока, т.е. для каждого из них будет выполнен конструктор, а значит два раза на экране появится ColorChooser с предложением поменять цвет. Вполне приемлимый вариант, только firstPlayerButton и secondPlayerButton в таком случае можно убрать.

Если вы желаете выбирать цвет для игроков перед началом игры, нужно:
1. При нажатии кнопок firstPlayerButton и secondPlayerButton показывать ColorChooser, запоминать выбранный цвет.
2. При нажатии кнопки Start создавать Игроков и передавать им (их конструкторам) цвета.
3. В конструкторе класса Player в таком случае ColorChooser показывать не нужно, просто записываем полученный цвет в playerColor.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 6.1.2009, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



что бы изменить код на кнопках мне пришлось дополнительно  декларировать в этом классе  две переменные 
Код
private Color playerColor;
  private  ColorChooser cchooser = new ColorChooser ();
 Код на кнопках теперь выглядит так 
Код

if (e.getSource().equals(startButton)) 
    {new Grids("Points", 800, 800, 20, 20).setVisible(true);
        Player first= new Player(1, playerColor);
        Player second = new Player(2,playerColor);  
        
    } else if (e.getSource().equals(firstPlayerButton)) 
    {  playerColor = cchooser.ShowChooser( playerColor );
      if(playerColor==null)
      {playerColor = Color.blue;
        }
              
    } else if (e.getSource().equals(secondPlayerButton)) 
    { playerColor = cchooser.ShowChooser( playerColor );
      if(playerColor==null)
      {playerColor = Color.red;
        }  
    } 
    }

Класс  Player совсем укоротился и выглядит так 
Код

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

public class Player 
 {
  private Color playerColor;
  private int orderOfPlayers ;
  
  public Player(int orderOfPlayers,Color color ) // constructor 
  {    
      this.orderOfPlayers=orderOfPlayers;
      this.playerColor = color;   
    }
 }



переменную private Color playerColor; пришлось прописать дважды в двух разных классах , иначе не компелировалось . А что будет если игрок сразу нажмёт кнопку старт ? У него не будет предустановленного цвета ? Может быть приравнять в начале класса private Color playerColor = Color.white ;
и на кнопке старт сделать проверку playerColor.Если он всё ещё white значит игроки отказываются выбирать цвет и мы им назначим цвет по умолчанию прямо здесь на кнопке старт ... сейчас  пытаюсь сообразить как построить класс Points  что-бы проверить каким цветом будет рисоваться .
Пока только сам процесс рисования скомпоновался. 
Код

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;

class DrawablePoint extends Component{

    private Color playerColor;
    private int radius =6;

    DrawablePoint(Color playerColor, int radius) {
        this.playerColor = playerColor ;
        this.radius = radius;
    }

    private void   drawCircle(int x, int y, int radius, Graphics g)
    {
    g.drawOval(x - radius, y - radius, radius*2, radius*2);
   }

    public int getRadius() {
        return radius;
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }
}


Там самый ужас что надо ставить точки только в углах решётки . Причем нужен небольшой зазор в координатах иначе человек должен будет " целится"
в определённый пиксель..
Решётка в двух классах выглядит так 
Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends Canvas {

    int rows;
    int cols;

    GridsCanvas(int r, int c) {
        rows = r;
        cols = c;
    }

    public void paint(Graphics g) {
        int i;
        int width = getSize().width;
        int height = getSize().height;
        // draw the rows
        int rowHt = height / (rows);
        for (i = 0; i < rows; i++)
            g.drawLine(0, i * rowHt, width, i * rowHt);
        // draw the columns
        int rowWid = width / (cols);
        for (i = 0; i < cols; i++)
            g.drawLine(i * rowWid, 0, i * rowWid, height);
    }
}

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class Grids extends Frame {

    Grids(String title, int w, int h, int rows, int cols) // constractor
    {
        setTitle(title);
        // Now create a Canvas and add it to the Frame.
        GridsCanvas canvas = new GridsCanvas(rows, cols);
        canvas.setSize(w, h);

        add(canvas);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Exit " + getTitle() + "?", "Confirm exit", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.OK_OPTION) {
                    System.exit(0);
                }
            }
        });
        pack();

        //Set this windown in the center
        setLocationRelativeTo(null);

        // Set it not resizable
        setResizable(false);
    }    
}



Это сообщение отредактировал(а) Qawra - 6.1.2009, 16:37
PM MAIL   Вверх
Qawra
Дата 6.1.2009, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Извините что вопрос про решётку не выделила в отдельную тему   smile

Это сообщение отредактировал(а) Qawra - 6.1.2009, 16:43
PM MAIL   Вверх
arilou
Дата 6.1.2009, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 6
Всего: 61



Qawra, я переименую тему в "Разработка игры "Территория", обащайтесь на здоровье.


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Rpahut
Дата 6.1.2009, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Да уж с темами кавардак...

Давайте что-ли сначала выбор цвета добьем.
Итак, мы желаем чтобы пользователь мог выбрать цвета игроков, до того как будут созданы сами игроки. Поскольку игроков еще нет, сохранить цвет в них мы не можем, стало быть нам понадобятся переменные для хранения цвета, и их нужно будет две, потому что игроков двое и каждый из них должен иметь свой цвет. Одной переменной playerColor тут не обойтись.

Цитата

А что будет если игрок сразу нажмёт кнопку старт ? У него не будет предустановленного цвета ?

Да. Сам по себе он не появится. 

Цитата

Может быть приравнять в начале класса private Color playerColor = Color.white 

Вначале - это в конструкторе. И, если у нас будет две переменные, можно будет в каждую из них положить свой цвет - например красный и синий. Потом, когда создаем игроков, передаем каждому его цвет. И ничего уже проверять не нужно будет - независимо от того, станет пользователь менять цвет или нет, игроки все равно будут разноцветные.

Дополнительно, хотя и не обязательно:
1. Вставьте проверку на null в метод ShowChooser():
Код

public Color ShowChooser(Color defaultColor) {
    Color choosedColor = JColorChooser.showDialog(this, "Choose your color",  defaultColor);
    if(choosedColor==null) return defaultColor;
    return choosedColor;
}

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

2. private  ColorChooser cchooser = new ColorChooser ();
Не нужно делать ColorChooser членом класса. Он не хранит внутри никаких данных, которые были бы нужны классу, и его можно создать когда он понадобится, например в методе где обрабатываются кнопки, а после использования выкинуть и забыть.

Так, что еще...

Цитата

Класс  Player совсем укоротился и выглядит так 

Тут зависит от того, как будет игра построена, но хранить orderOfPlayers внутри класса Игрок скорее всего не понадобится. Как раз должен быть вышестоящий класс, заведующий порядком ходов. В любом случае у нас уже есть переменные first и second, ясно что first это first, а second соответственно second.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Rpahut
Дата 7.1.2009, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Теперь решетка.
Ну, помимо размера тут нам понадобится еще знать размер клетки. Вместо того чтобы самим считать и указывать размер Grids, мы дадим ему количество клеток по горизонтали и вертикали, плюс размер клетки. Тогда размер канваса можно будет посчитать:
width = rows*cellSize; и height = cols*cellSize;
Переменные width и height удобно сделать членами класса GridsCanvas и вычислять их значения в конструкторе. После вычисления размеров конструктор GridsCanvas должен сам вызывать SetSize(). 

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

Касательно явы - возможно придется в GridCanvas переделать метод getPreferredSize() для того чтобы pack() сработал правильно. Еще хорошо бы вокруг канваса оставить пустое пространство, иначе крайние точки окажутся на самом краю окна и тыкать в них будет неудобно.

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

Дальше - т.к. каждый объект должен заниматься своим делом, расположение точек на канвасе мы оставим канвасу, а рисование точек - точкам. Поэтому класс Точка не будет знать свои координаты на канвасе. Вместо этого Точка будет рисовать всегда в координате [0, 0]
Код

// например
g.drawOval(-radius, -radius, radius*2, radius*2);

но!
Перед тем как просить точку нарисоваться, канвас будет вызывать Graphics.translate():
Код

// например
g.translate(pointPosX, pointPosY);

так что когда точка станет рисовать Oval, координаты [0, 0] будут именно там, где должна отобразиться точка.
В принцип работы translate() можно не вникать. Главное это после отрисовки точки вернуть все как было:
Код

g.translate(-pointPosX, -pointPosY);

иначе [0, 0] будет сдвигаться все дальше и дальше по мере рисования точек и улетит совсем. Не говоря уже о том, что точки будут появляться совсем не там где нам нужно.

Все вместе:
Если в классе Точка есть
Код

public void paint(Graphics g) {
  g.drawOval(-radius, -radius, radius*2, radius*2);
}

тогда в GridsCanvas.paint() пишем так:
Код

// рисуем сетку - опционально

// делаем цикл по всем точкам {
// вычисляем координаты точки на канвасе - pointPosX и pointPosY
g.translate(pointPosX, pointPosY);
currentPoint.paint(g);
g.translate(-pointPosX, -pointPosY);
// конец цикла по всем точкам }


Как считать координаты точки, зависит от того, как мы их храним. Я делал двумерный массив Точек размером [rows][cols], в цикле рисования поля у меня были переменные x и y, соответсвенно координаты точки [x][y] = [x*cellSize, y*cellSize].
Точки создаются все сразу, при создании игрового поля, и существуют уже до того как игроки их поставят. Вобще игроки у нас не ставят точки, они их просто помечают как свои... Точка, если она не помечена, либо не рисуется совсем, либо рисуется с меньшим радиусом, либо как-нибудь так рисуется чтобы ее можно было отличить от помеченной - ну это потом можно будет метод paint() точки дорабатывать по мере надобности.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 7.1.2009, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



По порядку  и старательно :
1.  рисуем две независимые переменные хранящие предустановленный цвет игроков.
Код

private Color secondDefautColor= Color.red;
  private  ColorChooser cchooser = new ColorChooser (); 

на кнопках теперь будет 
Код

if (e.getSource().equals(startButton)) 
    {new Grids("Points", 800, 800, 20, 20).setVisible(true);
        Player first= new Player(1, firstDefaultColor);
        Player second = new Player(2,secondDefaultColor);  
     
    } else if (e.getSource().equals(firstPlayerButton)) 
    {  fistPlayerColor = cchooser.ChangeColor( firstDefaultColor  );
                
    } else if (e.getSource().equals(secondPlayerButton)) 
    { secondPlayerColor = cchooser.ChangeColor(secondDefaultColor  );       
    } 
 а вот с Color Chooser теперь непонятно..Что передавать в качестве аргумента если переменные хранящие цвет теперь имеют разные названия ?
Код

public Color ChangeColor(Color ?"?"?) {
    Color choosedColor = JColorChooser.showDialog(this, "Choose your color",  ?"?"?);
    if(choosedColor==null) return ?????;
    return choosedColor;
 получается нам нужна ещё одна переменная хранящая цвет или мы можем прописать метод дважды ChangeColor1 и ChangeColor2 ? smile

2 . без строчки private  ColorChooser cchooser = new ColorChooser (); не компелируется ( не может найти cchooser )

3.  В конструкторе Player опять проблема с именем переменной хранящей цвет .
Код

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

public class Player 
 {
  private Color playerColor;
  
  public Player(Color ???? ) // constructor 
  {    
      this.????? = ????;   
    }
 }
 делать второй конструктор как то неудобно .Значит надо подумать о переменной хранящей цвет ..Не избежать её !

PM MAIL   Вверх
Qawra
Дата 7.1.2009, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



 с решёткой .....я рассматриваю свой GridsCanvas и его конструктор 
Код

class GridsCanvas extends Canvas {

    int rows;
    int cols;

    GridsCanvas(int r, int c) {
        rows = r;
        cols = c;
    }

    public void paint(Graphics g) {
        int i;
        int width = getSize().width;
        int height = getSize().height;
        // draw the rows
        int rowHt = height / (rows);
        for (i = 0; i < rows; i++)
            g.drawLine(0, i * rowHt, width, i * rowHt);
        // draw the columns
        int rowWid = width / (cols);
        for (i = 0; i < cols; i++)
            g.drawLine(i * rowWid, 0, i * rowWid, height);
    }
}
 получается что метод public void paint(Graphics g) надо вызвать внутри конструктора . Там же вызвать метод SetSize(). Его видимо надо найти в sun tutorials .
О методе  getPreferredSize() я не знала я просто хотела наложить решётку на новую JFrame . Надеюсь то тогда целиться в точки будет удобнее .

Начиная с фразы "Клетки чертятся по точкам, а не точки в углах клеток. Вообще сетку мы рисуем для красоты, работать все будет и без нее."
я впала в процесс осмысления который видимо затянется до утра ...
Завтра я постараюсь нарисовать что я поняла smile 



PM MAIL   Вверх
Rpahut
Дата 7.1.2009, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

с Color Chooser теперь непонятно..Что передавать в качестве аргумента если переменные хранящие цвет теперь имеют разные названия ?

Ну, вернемся к основам...
cchooser.ChangeColor(firstDefaultColor);
Когда мы вызываем метод, мы передаем ему аргументы. В данном случае у нас вписана переменная firstDefaultColor, в которой хранится Color.blue. Фишка в том, что мы не передаем саму переменную, мы не можем никак передать переменную - мы передаем значение которое хранится в переменной. Т.е. ChangeColor(firstDefaultColor) это то же самое что ChangeColor(СинийЦвет).

Внутри метода мы принимаем параметр
public Color ChangeColor(Color ?"?"?) {
не важно как он называется здесь, Ява просто засунет в эту переменную значение, которое мы передали(СинийЦвет). И Ява не запутается что куда класть, потому что метод принимает цвет, и мы передаем цвет, и там это первый параметр(и единственный), и тут первый параметр... Короче, компилятор ориентируется по типу и порядку аргументов, а не по их имени. Для самого метода этот параметр вообще выглядит как переменная, в которой как-то сам собой оказался синий цвет.
Программисту в отличии от компилятора проще ориентироваться по имени. Удобно называть параметр defaultColor, потому что это и есть по сути цвет по умолчанию, хотя вы можете выбрать название на свой вкус.


Цитата

2 . без строчки private  ColorChooser cchooser = new ColorChooser (); не компелируется ( не может найти cchooser )

А попробуйте сами его найти smile 
Его надо создать. Кажется, я писал об этом. Всякий объект перед тем как его можно будет использовать, должен быть создан. Но не нужно вписывать его как член класса, а нужно его прямо там создать где он используется, в методе где обрабатываются нажатия кнопок. Потому что он используется только там, потому что не хранит никакой нужной нам информации; нет никакой причины делать его членом класса. Вы же не выписываете все используемые в классе переменные в члены класса.

Цитата

3.  В конструкторе Player опять проблема...

А вот и нет. Тут то же что и с ChangeColor() - имя менять не нужно. Будет работать как есть.

Все. Когда с выбором цвета будет покончено, тогда перейдем к игровому полю.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 8.1.2009, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Я решилась оставить только две переменные хранящие цвет 
Код

private Color firstDefautColor= Color.blue;
  private Color secondDefautColor= Color.red;


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

if (e.getSource().equals(startButton)) 
    {
        new Grids("Points", 800, 800, 20, 20).setVisible(true);
        //Vector points = (Point) GridCanvas
       Player first= new Player(  firstDefautColor);
       Player second = new Player( secondDefautColor);  
     
  } else if (e.getSource().equals(firstPlayerButton)) 
    { firstDefautColor = cchooser.ChangeColor( firstDefautColor  );
          
    } else if (e.getSource().equals(secondPlayerButton)) 
    { 
       secondDefautColor = cchooser.ChangeColor( secondDefautColor  );
    } 
 то есть цвет либо останется либо измениться но он всё равно будет ..
При выборе цвета у меня получилось 
Код

{
Color choosedColor = JColorChooser.showDialog(this, "Choose your color",  firstDefautColor);
    if(choosedColor==null)
    {   firstDefautColor=choosedColor;
        return  firstDefautColor;
    }return  firstDefautColor;
}
 не знаю как это будет работать . Идея была оставить игроку одно название цвета независимо от того сам он его выбрал или цвет был задан  по умолчанию.  Смущают правда  два идентичных return ... 
Конструктор для игрока предполагает  дополнительную переменную playerColor
Код

 public Player(Color firstDefautColor ) // constructor 
  {    
      this.playerColor = firstDefautColor;   
    }
 Что мы с ней потом  будем делать ? 



PM MAIL   Вверх
Rpahut
Дата 9.1.2009, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

не знаю как это будет работать.


Работать это будет очень интересно:
Код

если(выбранныйЦвет==пустой) { // если пользователь отказался выбрать:
  цветПоУмолчанию = выбранныйЦвет; // т.е. цветПоУмолчанию = пустой;
  вернуть цветПоУмолчанию; // т.е. вернуть пустой(цвет)
}
// иначе, если пользователь выбрал цвет:
вернуть цветПоУмолчанию; // т.е. вернуть цвет, переданный в метод, не меняя его


Нам же нужно, чтобы возвращался:
1. цвет выбранный пользователем, если он его выбрал; 
2. а если не выбрал - то цвет по умолчанию (нам обязательно нужно вернуть обратно какой-то цвет, ради этого и существует метод; если пользователь не хочет выбирать цвет, нам придется вернуть цвет по умолчанию - потому что другого у нас просто нет).
Записываем это дело по-русски:
Код

если(пользователь выбрал цвет) {
  вернуть выбранный цвет;
}
иначе {
  вернуть цвет по умолчанию;
}


дальше переводим:
Код

если(выбранныйЦвет!=пустой) { // если выбранный цвет не пустой
  вернуть выбранныйЦвет;
}
иначе { // если выбранный цвет - пустой
  вернуть цветПоУмолчанию;
}


а теперь просто записываем то же самое на Яве:
Код

if(choosedColor!=null) { // если(выбранныйЦвет!=пустой) {
  return choosedColor; // вернуть выбранныйЦвет;
}
else { // иначе {
  return defaultColor; // вернуть цветПоУмолчанию;
}

============================================
Цитата

Идея была оставить игроку одно название цвета независимо от того сам он его выбрал или цвет был задан  по умолчанию.

Не надо так париться с именами. 
Когда мы возвращаем значение, мы возвращаем значение, т.е. то, что лежит внутри переменной. Мы пишем имя переменной, чтобы Ява знала, из какой переменной взять значение. Сама переменная не передается и не возвращается.
Код

// например:
int SomeMethod() {
  ...
  return myVariable; // Значение выдергивается из переменной с именем myVariable
}
...
int myOtherVariable = SomeMethod(); // ...и засовывается в переменную с именем myOtherVariable 
//=================================




//=================================
int integerVariable = 10; // засовываем в переменную с именем integerVariable значение 10
AnotherMethod(integerVariable); // из переменной integerVariable выдергивается значение 10
...
void AnotherMethod(int xz) { // ...и засовывается в переменную с именем xz
  ...
}


Или вот еще пример:
Код

// прекрасно работает:
Color choosedColor = showDialog(this, "Choose your color",  firstDefautColor);
// работает ничуть не хуже:
Color anyOtherName = showDialog(this, "Choose your color",  firstDefautColor);

А ведь внутри метода showDialog тоже есть строчка
return ...;
И мы даже не знаем, какое там имя используется. Нам и не нужно этого знать. Достаточно того что мы знаем какого типа значение возвращает метод - так мы можем создать подходящую переменную чтобы в нее положить значение:
Код

// showDialog() возвращает Color
Color anyNameYouLike;
anyNameYouLike = chooseColor(тут типа параметры);



Вобщем смысл всего этого:
1. Когда пишете какой-нибудь метод, позаботьтесь о том чтобы он делал то, что от него требуется. Определите, какая информация ему потребуется для работы - это и будут входные параметры. Как вы их назовете не важно, главное чтобы вы сами не путались в них.
2. Когда вызываете метод, передавайте значения, которые требуются ему для работы. Не важно как называются переменные, в которых эти значения лежат.
3. Если вы хотите чтобы метод возвращал вам что-то, нужна переменная соответствующего типа. С любым именем.
4. Перепишите метод ChangeColor(). Переименуйте параметр конструктора класса Игрок из firstDefautColor в color; конструктор будет работать и так, но у препода могут возникнуть вопросы.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 9.1.2009, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Спасибо за такой подробный перевод с Java на русский .
 В рамках нашего курса , программированию посвящено  только два часа в неделю поэтому многие вещи просто  не досказаны. Например, нам говорили то что компайлер различает конструкторы только по типу аргументов , но примеры всегда были с одинаковыми названиями этих самых аргументов в конструкторе  и  как членов класса ... 
Теперь у меня получилось  так : 
Код

 public Color ChangeColor(  Color firstDefautColor) 
  {
     Color choosedColor = JColorChooser.showDialog(this, "Choose your color",  firstDefautColor);
    if(choosedColor!=null)
    {    return  choosedColor;
    }return  firstDefautColor;
  }
  и 
Код

 private Color color;
  
  public Player(Color color ) // constructor 
  {    
      this.color = color;   
    }
 

Для того что бы начать рисовать точки нам нужно их предварительно создать и сохранить ещё до начала игры.  Это правда что хранить их лучше в Vector  а не в Array ? О векторах мы знаем только то что это dynamic array (мы проходили это в топике data structures). Теоретически ,  если  точки это обьекты то когда они созданы память под них уже выделена . Количество их во время игры тоже не измениться ... Какой выигрыш от использования векторов ? Мы ещё ни разу не обращались к ним на программировании . 


PM MAIL   Вверх
Rpahut
Дата 9.1.2009, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Какой выигрыш от использования векторов ?

Можно написать с использованием векторов, но реальной причины для этого я не вижу. Вектора понадобятся нам позже, а точки поля мы будем хранить в двумерном массиве.
Массив этот должен быть членом класса Поле (или GridCanvas? или полем у вас будет другой класс?). Пара слов об инициализации массива:
если массив мы определим так
Код

private int rows;
private int cols;
private DrawablePoint points[rows][cols]; // <------
...

то у нас ничего не получится, потому что, во-первых, эта строчка выполнится до конструктора класса Поле, а значит в переменных rows и cols будут еще лежать нули(получится points[0][0], массив нулевого размера). Во-вторых, никаких Точек эта строчка не создает, независимо от размеров, а создает она массив. Мы определили массив, мы его и получили, и ничего больше.

Поэтому мы напишем так:
Код

private DrawablePoint points[][]; // размер пока неизвестен; просто двумерный массив

и в конструкторе класса Поле:
Код

...
points = new DrawablePoint[rows][cols]; // сейчас размер известен и массиву можно придать размер
for(int y=0; y<cols; y++) {
  for(int x=0; x<rows; x++) {
    // цикл по всем элементам массива
    points[x][y] = new DrawablePoint(типа параметры); /* <--- Вот тут
    собственно и создаются Точки. Запихиваем их по одной в
    каждый элемент массива.
    */
  }
}


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

Когда точки созданы, можно попробовать их отрисовать. Так как DrawablePoint у нас extends Component, то по идее можно добавлять точки к GridsCanvas(метод add()) и они будут автоматически перерисовываться при перерисовке самого поля(т.е. автоматически будет вызываться метод paint() точек). Вот этого я делать не пробовал, вобще это больше по яве - а значит не совсем ко мне. У меня метод paint после нескольких попыток стал вызываться, но точек все равно не видно  smile 
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Rpahut
Дата 9.1.2009, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Ладно.
Раз уж мы используем SWING для GUI, давайте обойдемся без класса Component (он из AWT). Поле наше будет extends JPanel, точка вообще ничего не extends.
У поля должен быть метод void paintComponent(Graphics g); в нем нужно разместить код рисования сетки + в цикле для каждой Точки из массива вызывать метод paint(g). Разумеется в классе Точка нужно написать метод paint(Graphics g).
Дальше возможны два варианта - 
1. Если в классе Точка хранятся ее координаты, в методе Точка.paint() можно просто рисовать овал на этих координатах.
2. Если в классе Точка нет координат - тогда использовать метод translate() как я писал раньше.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 9.1.2009, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Работать с полем я хотела в отдельном классе потому что иначе я запутаюсь smile
Назовём его BattleField .
Код

 public int rows;
  public int cols;
  были уже инициализированы в GridCanvas
Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends Canvas {

   public  int rows;
    public int cols;

    GridsCanvas(int r, int c) {
        rows = r;
        cols = c;
    }

    public void paint(Graphics g) {
        int i;
        int width = getSize().width;
        int height = getSize().height;
        // draw the rows
        int rowHt = height / (rows);
        for (i = 0; i < rows; i++)
            g.drawLine(0, i * rowHt, width, i * rowHt);
        // draw the columns
        int rowWid = width / (cols);
        for (i = 0; i < cols; i++)
            g.drawLine(i * rowWid, 0, i * rowWid, height);
    }
}
 и использовались в Grids
Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class Grids extends Frame {

    Grids(String title, int w, int h, int rows, int cols) // constractor
    {
        setTitle(title);
        // Now create a Canvas and add it to the Frame.
        GridsCanvas canvas = new GridsCanvas(rows, cols);
        canvas.setSize(w, h);

        add(canvas);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Exit " + getTitle() + "?", "Confirm exit", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.OK_OPTION) {
                    System.exit(0);
                }
            }
        });
        pack();

        //Set this windown in the center
        setLocationRelativeTo(null);

        // Set it not resizable
        setResizable(false);
    }    
}
 Поэтому я надеюсь  мы можем их просто использовать в новом классе 

Код

public class BattleField
 {   private DrawablePoint points[][];

      public BattleField ( int rows , int cols ) // конструктор 
    {
       makePoints(rows,cols);  // вызываем метод
     }

     public void makePoints (int rows , int cols)
  {  points = new DrawablePoint[rows][cols];
      for(int y=0; y<cols; y++)
          {for(int x=0; x<rows; x++) 
             {
               points[x][y] = new DrawablePoint(int x, int y);
              }
           }
        }
    }
 Я правильно поняла что параметрами для заранее созданной точки могут быть только координаты ? У неё ведь ещё  нет владельца . Да и рисовать её нам пока не надо . Я краем уха в лаборатории  слышала smile 
что когда рисуется решётка и точки  - результат зависит от  порядка  действий . Решётка может  зарисовывать точки . А что ещё  мы будем делать в конструкторе поля ?

Добавлено @ 23:39
класс Точка в наброске пока выглядит так 
Код

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;

public class DrawablePoint
 {  
    public Color color ;
    public int radius =6;
    
    DrawablePoint(Color color) 
    {
        this.color = color ;
    }

    private void   drawCircle(int x, int y, int radius, Graphics g)
    {
    g.drawOval(x - radius, y - radius, radius*2, radius*2);
   } 
 
пришлось снова прописать public Color color ;  потому что со словом this. иначе не компелируется

Это сообщение отредактировал(а) Qawra - 9.1.2009, 23:45
PM MAIL   Вверх
Rpahut
Дата 10.1.2009, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Переделайте
1:
Код

class GridsCanvas extends Canvas { // в SWING нет класса Canvas
// поменять на 
class GridsCanvas extends JPanel { // зато есть JPanel; на ней можно рисовать


2:
Код

public class Grids extends Frame { // в SWING нет класса Frame
.....
public class Grids extends JFrame { // но есть JFrame


3:
Код

public void paint(Graphics g) { // это в классе GridsCanvas
....
public void paintComponent(Graphics g) { // в SWING нужно переопределять этот метод


Имеет смысл все-таки объединить классы GridsCanvas и BattleField. Два класса там во всяком случае не нужны.
Чтобы вы не путались, попробую обрисовать как это все должно выглядеть:
GridsCanvas(или BattleField) будет создавать, хранить точки и рисовать их на экран
Grids будет окном игры; окно нужно чтобы GridsCanvas можно было отобразить на экране

В классе Grids в качестве члена класса вписываем GridsCanvas. В конструкторе Grids, когда известны размеры поля, создаем(инициализируем, передаем размеры) GridsCanvas.
В классе GridsCanvas в члены класса вписываем массив points[][], в конструкторе инициализируем этот массив, точно так, как это сейчас сделано в BattleField.
Теперь чтобы создать поле в окне со всеми точками достаточно создать Grids с правильными параметрами; когда создается Grids, будет создан и GridsCanvas, а он в свою очередь создаст точки.
Касательно параметров конструктора Grids:
Код

Grids(String title, int w, int h, int rows, int cols)

title - не нужен; заголовок каждый раз будет тот же(или нет?), можно вписать в конструктор:
Код

setTitle("Фараонище");

w, h - не нужны; размер окна должен вычисляться в зависимости от размера поля
rows, cols - это все что нам нужно

=======================
Когда Ява решит отобразить окно, она вызовет метод GridsCanvas.paintComponent(); этот метод должен рисовать игровое поле. Пока он рисует только сетку, но должен еще и рисовать все точки на поле. Чтобы точки могли рисоваться, во-первых у них должен быть метод paint(Graphics g), во-вторых этот метод должен рисовать точку(при помощи drawOval() скорее всего), и наконец нужно чтобы при рисовании поля вызывался этот метод у каждой точки. Т.е. в GridsCanvas.paintComponent() нужно добавить цикл, в котором для каждой точки вызывается paint(g).

Цитата

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

Да. Но если уж вы передаете координаты "points[x][y] = new DrawablePoint(x, y);", то конструктор точки должен принимать координаты - "DrawablePoint(int xcoord, int ycoord)" - и сохранять их внутри класса.

Кстати, мы работать теперь будем с двумя разными координатными системами - у нас есть координаты точки на поле, и координаты точки на экране. Координаты на поле [3][2] означают точку в третьем столбце и второй строчке. Координаты на экране будут другими, потому что нам нужно расстояние между точками. Расстояние между точками это размер клетки, cellSize; тогда экранные координаты точки:
xscreen = xfield * cellSize;
yscreen = yfield * cellSize;

Можно в GridsCanvas добавить private-метод для перевода координат на поле в экранные:
Код

private int field2screen(int value) {
  return value*cellSize; /* int cellSize должен быть членом класса
  и в нем должен лежать размер клетки */
}

Использовать его можно например так:
Код

// создаем точку и передаем ей экранные координаты
points[x][y] = new DrawablePoint(field2screen(x), field2screen(y));


============================
Тока сейчас заметил - у вас опять написаны параметры вместе с типом!
Код

... = new DrawablePoint(int x, int y);

============================
По возможности вносите изменения небольшими кусками и компилируйте код - Ява покажет где у вас ошибки.
В помощь - поправленный класс Grids:
Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Grids extends JFrame {
    GridsCanvas canvas; // canvas теперь член класса

    Grids(int rows, int cols) // constructor
    {

        canvas = new GridsCanvas(rows, cols, 20); /* !! передаем дополнительно cellSize
        Размер можно менять по вкусу */

        // канвас должен сам set свой size:
        // canvas.setSize(rows*cellSize , cols*cellSize);
        add(canvas);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Exit " + getTitle() + "?", "Confirm exit", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.OK_OPTION) {
                    System.exit(0);
                }
            }
        });

        pack();
        setTitle("Фараонище");
        setLocationRelativeTo(null);
        setResizable(false);
        // без этого окна не будет:
        setVisible(true);
    }    
}


Это сообщение отредактировал(а) Rpahut - 10.1.2009, 22:46
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 11.1.2009, 00:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Когда я поменяла в class GridsCanvas extends Canvas на extends  JPanel решётка перестала выходить нормально. Появляется  окошко очень узкое и нерастягивающееся. Так что Canvas я пока оставила .Природа его не известна но на решётку он действует положительно .
Пытаюсь изменить свой класс Grid но пока от этого становиться только хуже. Окошко выходит но решётки на нём нет .
w, h  я пока хочу оставить потому окошко будет иметь постоянные размеры. У нас в школе разрешение мониторов  компьютером 800/600 и  я не  буду вводить функцию изменения размеров поля . Оно и так занимает весь экран .
Параметры у меня действительно написаны вместе с типом потому что иначе не комперировалось 
Код

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;

class DrawablePoint //extends Component
{

    private Color color;
    public  int radius = 6;
    public int x;
    public int y;
    
    DrawablePoint(Color color) 
    {
        this.color = color ;
    }

    private void   drawCircle (  x,   y,  radius, Graphics g)
    {
    g.drawOval(x - radius, y - radius, radius*2, radius*2);
   }   
}

в строчке private void   drawCircle (  x,   y,  radius, Graphics g) компайлер требует идентифаер ..
PM MAIL   Вверх
Rpahut
Дата 11.1.2009, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Появляется  окошко очень узкое и нерастягивающееся.

Ну нерастягивающееся оно потому что в коде так написано.
А что касается размера, то когда вы в Grids вызываете pack(), Ява спрашивает у GridsCanvas через метод getPreferredSize(), какой бы ей хотелось иметь размер. Чтобы Ява знала, какой нам нужен размер, сначала надо вызвать setPreferredSize() с указанным размером.
Так же нужно вызвать setVisible(true) в конструкторе GridsCanvas, потому как по умолчанию элементы спрятаны и отображаться не будут.

Цитата

Пытаюсь изменить свой класс Grid но пока от этого становиться только хуже. 

Пока GridsCanvas не будет правильно оформлен, окно будет пустым или очень маленьким, это нормально; главное чтобы оно отображалось на экране и нормально закрывалось при нажатии [Х]. Это будет озачать что Grids работает.

Цитата

w, h  я пока хочу оставить потому окошко будет иметь постоянные размеры.

Если размер постоянный, то передавать его через параметры совсем уж не нужно. Можно просто вписать его в класс. То же самое касается количества точек - если настройки не будет, все можно вписывать внутрь класса Grids. 

Цитата

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

Вот такое у меня хоть убейте не компилируется:
Код

    private void   drawCircle (  x,   y,  radius, Graphics g)
    {
     ...
    }

В заголовке метода типы должны указываться. Без них никак. Я уже писал о том что типы нужны компилятору.
Я имел ввиду кусок, в котором инициализируется массив точек:
Код

points[x][y] = new DrawablePoint(int x, int y); // ы?..

Разве BlueJ не ругается на эту строчку?
======================================

ОК, давайте по порядку.
Класс Grids
Можно скопировать код который я выкладывал. Если конструктор Grids не принимает параметров-размеров, скобки у него оставляем пустыми, но добавляем в него переменные:
Код

class Grids extends JFrame {
    GridsCanvas canvas;

public Grids() // constructor
    {
        int rows = 35; // желаемый размер поля
        int cols = 35;
        int cellSize = 15; // желаемый размер клетки
....

Тут у нас гадкая неопределенность - мы можем либо задать размер окна, размер клетки и вычислить сколько точек поместится в окне; либо мы можем задать опять размер окна, желаемое количество клеток, и из них посчитать размер клетки. Второй вариант мне не нравится, потому как размер клетки все-таки важнее количества точек, от него зависит насколько удобно будет тыкать в точки и как они будут выглядеть. Поэтому я прикинул и вписал клетку размером 15 пикселей и поле размером 35х35 клеток, потом если что эти цифры можно будет поменять.
Что еще нужно обязательно сделать в конструкторе - это создать GridsCanvas, передать ему размеры поля и клетки, добавить его...; все это есть в коде. 


Класс GridsCanvas
Обязательно extends JPanel, иначе работать не будет.
int rows, cols и cellSize делаем членами класса, мы будем часто пользоваться ими. В конструкторе помещаем в эти переменные конкретные значения, которые конструктор принимает как параметры.
Обязательно вызываем в конструкторе setVisible(true) и setPreferredSize(new Dimension(panelWidth, panelHeight)), иначе панель либо не будет отображаться совсем, либо будет слишком маленькой. Вместо panelWidth и panelHeight естественно нужно указать размер панели достаточный чтобы вместить все точки:
panelWidth = cols*cellSize;
panelHeight = rows*cellSize;

Еще один метод, необходимый в GridsCanvas - это
Код

void paintComponent(Graphics g) {
  // здесь рисование сетки и прочего
  // пока можно просто рисование сетки, прочее добавим позже
  ...
}


Класс DrawablePoint
Цитата

в строчке private void   drawCircle (  x,   y,  radius, Graphics g) компайлер требует идентифаер ..

Код

// вот так
private void drawCircle (int x, int y, int radius, Graphics g)


Еще нужно добавить метод
Код

public void paint(Graphics g, int x, int y) {
  int pointRadius = 3;
  drawCircle(x, y, pointRadius, g);
  // сейчас мы его не используем, но позже будем
}

Когда все это заработает, в метод GridsCanvas.paintComponent() можно будет добавить цикл, перебирающий все точки и вызывающий для каждой ее метод paint() - так наши точки будут рисоваться на экран.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 11.1.2009, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Эту строчку я не могу найти  smile 
Код

points[x][y] = new DrawablePoint(int x, int y); // ы?..

Судя по всему я её успела отредактировать как
Код

 points = new DrawablePoint[rows][cols];

Класс Grids я скомпелировала так 
Код

import javax.swing.*;
import java.awt.Dimension;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Grids extends JFrame {
    GridsCanvas canvas; 
     public int rows=20;
     public int cols=20;
     public int sellSize=20 ;
    
    Grids() // constructor
    {
        canvas = new GridsCanvas(rows, cols, sellSize); 
      
        canvas.setSize(rows*sellSize , cols*sellSize);
        add(canvas);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Exit " + getTitle() + "?", "Confirm exit", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.OK_OPTION) {
                    System.exit(0);
                }
            }
        });
        pack();
        setTitle("Points");
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    } 
    }


Где-то закралась ошибка потому что окошко выходит без решётки и не по центру экрана . Закрывается нормально но есть Terminal window с текстом
Код

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: adding a window to a container
    at java.awt.Container.addImpl(Container.java:1022)
    at java.awt.Container.add(Container.java:935)
    at javax.swing.JFrame.addImpl(JFrame.java:545)
    at java.awt.Container.add(Container.java:352)
    at Grids.<init>(Grids.java:18)
    at Window.mouseClicked(Window.java:74)
    at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253)
    at java.awt.Component.processMouseEvent(Component.java:6044)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    at java.awt.Component.processEvent(Component.java:5806)
    at java.awt.Container.processEvent(Container.java:2058)
    at java.awt.Component.dispatchEventImpl(Component.java:4413)
    at java.awt.Container.dispatchEventImpl(Container.java:2116)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3995)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
    at java.awt.Container.dispatchEventImpl(Container.java:2102)
    at java.awt.Window.dispatchEventImpl(Window.java:2440)
    at java.awt.Component.dispatchEvent(Component.java:4243)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)


На кнопке старт я изменила вызов конструктора с  new Grids("Points", 800, 800, 20, 20).setVisible(true);    на new Grids( );

DrawablePoints выглядят теперь так 
Код

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;

class DrawablePoint //extends Component
{

    private Color color;
    public  int radius = 6;
    public int x;
    public int y;
    
    DrawablePoint(Color color) 
    {
        this.color = color ;
    }

    private void   drawCircle (int  x,int   y,  int radius, Graphics g)
    {
    g.drawOval(x - radius, y - radius, radius*2, radius*2);
   }  
   
   public void paint(Graphics g, int x, int y) {
  int pointRadius = 3;
  drawCircle(x, y, pointRadius, g);
  }
}

И остался ещё класс BattleField который нам не нужен но там прописан метод
Код

public void makePoints (int rows , int cols)
  {  points = new DrawablePoint[rows][cols];
      for(int y=0; y<cols; y++)
          {for(int x=0; x<rows; x++) 
             {
 который теперь надо вызывать прописать в GridCanvas/

PM MAIL   Вверх
Rpahut
Дата 12.1.2009, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Эту строчку я не могу найти  smile 

Эта плоха. Быть она должна.
Цитата

Судя по всему я её успела отредактировать как
points = new DrawablePoint[rows][cols];

Вот после этой строчки у вас был там цикл инициализации массива в котором я видел ошибку... Если вы ее уже поправили - тогда ладно.

Цитата

Класс Grids я скомпелировала так 

Одно замечание:
canvas.setSize(rows*sellSize , cols*sellSize);
можно убрать. Для JPanel размер устанавливается через setPreferredSize(), и делать это нужно в конструкторе GridsCanvas.

Цитата

Где-то закралась ошибка
java.lang.IllegalArgumentException: adding a window to a container

Видимо ему не нравится extends класса GridsCanvas. Пока там не будет extends JPanel ошибка так и останется.

Цитата

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

Норм. 

Метод makePoints() нужно перенести из BattleField в GridsCanvas. Класс BattleField можно после этого убрать совсем.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 12.1.2009, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Нашла ! Эта строчка была в классе BattleField который мы уже не используем .Там мы инициализировали массив точек в методе  makePoints
Код

 public void makePoints ( int rows , int cols)
  {  points = new DrawablePoint[rows][cols];
      for(int y=0; y<cols; y++)
          {for(int x=0; x<rows; x++) 
             { points[x][y] = new DrawablePoint( x,  y);  
              }
 Теперь мы  уже не можем это делать потому что класс DrawablePoint  в настоящий момент не содержит такого конструктора . Там теперь конструктор 
Код

 DrawablePoint(Color color) 
    {
        this.color = color ;
    }
 

нужно видимо ввести  соординаты x,y как аргументы  , либо  сделать два разных конструктора DrawablePoint  . Один только с цветом а второй только с координатами .

class GridsCanvas extends JFrame  было ещё вчера .. Сегодня ошибка повторилась . 
"adding a window to a container" может означать что мы добавляем add(canvas); неправильно с точки зрения компайлера ..?


PM MAIL   Вверх
Rpahut
Дата 12.1.2009, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

class GridsCanvas extends JFrame  было ещё вчера

extends JPanel. JFrame - это окно, нельзя добавить окно в окно.

Конструктор точки пусть остается как есть. Цикл инициализации массива нужно модифицировать - передавать точке вместо координат цвет. Кроме того x и y мы будем передавать точке во время отрисовки.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 12.1.2009, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



C extends JPanel всё получилось замечательно.Сообщение о ошибке изчезло и решётка вышла нормально . 
PM MAIL   Вверх
Rpahut
Дата 13.1.2009, 04:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Ну вот, дальше собственно берем цикл
Код

for(int y=0; y<cols; y++) {
  for(int x=0; x<rows; x++) {
    points[x][y].paint(g, x*cellSize, y*cellSize); // вызываем метод paint() каждой точки
  }
}

и вставляем его в GridsCanvas в метод paintComponent(). Точки должны рисоваться цветом, который вы передаете им при создании.
И не удивляйтесь если точки окажутся неправильно расположены на сетке.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 13.1.2009, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Я изменила цикл инициализации массива 
Код

public void makePoints ( int rows , int cols)
      {  points = new DrawablePoint[rows][cols];
          for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) 
             {  points[x][y] = new DrawablePoint( color);  
              }
  и вызвала paint() для каждой точки 
 на строчке 
Код
             points[x][y].paint(g, x*cellSize, y*cellSize);  
 компайлер не может найти переменную cellSize которая является public членом того же класса. ..
Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends JPanel{

     public int rows=20;
     public int cols=20;
     public int sellSize=20 ;
     private Color color;
    
     private DrawablePoint points[][]; 
         
    GridsCanvas(int r, int c,int sellSize) {
        this.rows = r;
        this.cols = c;
        this.sellSize=sellSize;
        setVisible(true);
        setPreferredSize(new Dimension(800, 800));
    }

    public void paintComponent(Graphics g) {
        int i;
        int width = getSize().width;
        int height = getSize().height;
        // draw the rows
        int rowHt = height / (rows);
        for (i = 0; i < rows; i++)
            g.drawLine(0, i * rowHt, width, i * rowHt);
        // draw the columns
        int rowWid = width / (cols);
        for (i = 0; i < cols; i++)
            g.drawLine(i * rowWid, 0, i * rowWid, height);
            
        for(int y=0; y<cols; y++) {
          for(int x=0; x<rows; x++) {
             points[x][y].paint(g, x*cellSize, y*cellSize);  // вызываем метод paint() каждой точки
               }
              }
             }
    
     public void makePoints ( int rows , int cols)
      {  points = new DrawablePoint[rows][cols];
          for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) 
             {  points[x][y] = new DrawablePoint( color);  
              }
       }
   }
}

 

Это сообщение отредактировал(а) Qawra - 13.1.2009, 18:34
PM MAIL   Вверх
arilou
Дата 13.1.2009, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Великий МунаБудвин
****


Профиль
Группа: Экс. модератор
Сообщений: 2646
Регистрация: 15.7.2004
Где: город-герой Минск

Репутация: 6
Всего: 61



Qawra, 
[
Цитата

  public int sellSize=20 ;


опечатка. должно быть cellSize


--------------------
user posted imageuser posted image
PM WWW ICQ   Вверх
Rpahut
Дата 13.1.2009, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Угу.
И переменные rowHt и rowWid в методе paintComponent() это тот же cellSize, так что от них можно избавиться.
Код

// эти строчки можно выкинуть
        int width = getSize().width;
        int height = getSize().height;
        ...
        int rowHt = height / (rows);
        ...
        int rowWid = width / (cols);

В остальных местах где эти переменные используются меняем их на cellSize.

Кстати, переменные-члены класса у нас везде должны быть private, потому что пользуется ими только сам класс. Да и вообще разумно спрятать переменные класса от остальной программы.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 13.1.2009, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Если отключить 
Код

int rowHt = height / (rows);
int rowWid = width / (cols);
 то надо как-то модифицировать  paintComponent потому что
без них ничего нарисовать в данный момент нельзя.
Код

// draw the rows
       
        for (i = 0; i < rows; i++)
            g.drawLine(0, i * rowHt, width, i * rowHt);
        // draw the columns
        
        for (i = 0; i < cols; i++)
            g.drawLine(i * rowWid, 0, i * rowWid, height);
  
PM MAIL   Вверх
Rpahut
Дата 14.1.2009, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Код

g.drawLine(0, i * cellSize, width, i * cellSize);

и дальше в том же духе
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 14.1.2009, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



скомпелировалось так 
Код

 public void paintComponent(Graphics g) {
        int i;
        
        for (i = 0; i < rows; i++)
            g.drawLine(0, i * cellSize, i * cellSize,rows);
        
        for (i = 0; i < cols; i++)
            g.drawLine(i * cellSize, 0, i * cellSize,cols);
            
        for(int y=0; y<cols; y++) {
          for(int x=0; x<rows; x++) {
             points[x][y].paint(g, x*cellSize, y*cellSize);  
               }
              }
             }
 без rows и cols в аргументах drawLine не компелировалось поэтому я их там прописала. Как вы и предупреждали  рисует косые линии  там где предполагается решётка. Есть сообщение о NullPointerException в 34 строкe:
Код

  points[x][y].paint(g, x*cellSize, y*cellSize);  
 Array у нас инициализирован как private  член класса 
Код

private DrawablePoint points[][]; 
 
PM MAIL   Вверх
Rpahut
Дата 15.1.2009, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Как вы и предупреждали  рисует косые линии

Вот этого я не ожидал  smile 

Цитата

без rows и cols в аргументах drawLine не компелировалось поэтому я их там прописала.

А почему именно их?

Давайте разберемся:
Лини рисуются при помощи drawLine() + Линии рисуются неправильно = Неправильно используется метод drawLine()

drawLine() принимает четыре аргумента:
drawLine(x1, y1, x2, y2)
x1 и y1 это координаты начала линии, x2 и y2 - координаты ее конца. Нам, чтобы начертить сетку, нужно нарисовать вертикальные и горизонтальные линии на поле
Код

// чертим горизонтальные линии, строки
for (i = 0; i < rows; i++)
  g.drawLine(???);
// чертим вертикальные линии, колонки
for (i = 0; i < cols; i++)
  g.drawLine(???);

У горизонтальных линий y1 и y2 должны быть одинаковые, иначе они не будут горизонтальными. Вообще любая точка на горизонтальной прямой имеет ту же координату Y. У вертикальных линий должны быть одинаковые x1 и x2.
Дальше - первую горизонтальную линию нам надо начертить в самом верху поля, все остальные - ниже предыдущей на cellSize. Т.е. координата Y кратна cellSize и равна cellSize*номерСтроки; у нас в цикле уже есть переменная i которая считает строки и содержит номер текущей строки. Записываем:
Код

drawLine(x?, cellSize*i, x?, cellSize*i) // одинаковые Y для начала и конца линии

Теперь x1 и x2. Каждая линия должна идти от одного края поля до другого, для этого один икс должен быть равен нулю(у левого края поля x=0), а другой равен ширине поля (т.е. cols*cellSize); вписываем иксы:
Код

drawLine(0, cellSize*i, cols*cellSize, cellSize*i) // вот так линии не будут косыми


Аналогично для вертикальных линий:
X начала и конца каждой линии одинаковый.
X кратен cellSize и равен cellSize*номерСтолбца (вместо номера столбца опять используем переменную i).
Y начала линии - ноль.
Y конца линии - расстояние от верха до низа поля = высота поля = количествоСтрок*cellSize

===========================
Цитата

Есть сообщение о NullPointerException

В этой строке:
Код

points[x][y].paint(g, x*cellSize, y*cellSize);

такое исключение может возникнуть, только если points[x][y] не содержит точки.
Скорее всего что-то случилось с циклом инициализации массива points.
Вообще с этим массивом мы много чего делаем, напомню самые важные моменты:
Код

private DrawablePoint points[][]; /* объявление; "у нас будет двумерный массив с именем points
  в котром будут храниться DrawablePoint" */
...
points = new DrawablePoint[cols][rows]; /* создание; "points-это двумерный массив DrawablePoints
  размером cols-на-rows" */
...
points[x][y] = new DrawablePoint(); /* инициализация; создаем и раскладываем DrawablePoints в
  ячейки массива*/

Когда мы создаем массив, в его ячейки раскладывается значение null. Если не инициализировать массив, null так там и останется. Если после этого попытаться что-то сделать с элементом в массиве, например
Код

points[x][y].paint()

возникает NullPointerException.

Когда инициализация у вас будет работать как надо, на экране сразу появятся точки.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 15.1.2009, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Зашла в интернет утром перед школой и убегаю ..В школе попробую переделать . У меня часовой пояс на два часа раньше чем московкий .Поэтому я иногда не успеваю smile
PM MAIL   Вверх
Qawra
Дата 15.1.2009, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Решётка теперь рисуется нормально.
Цикл инициализации массива points ...
Мне кажется чего - то нехватает в классе  DrawablePoint ..
Но начнём по порядку :
В классе GridsCanvas если мы инициализируем как член класса 
Код

private DrawablePoint points[][] ; // array to hold all possible  points
 а затем указываем его размер 
Код

 points [][]= new DrawablePoint[cols][rows];
 компайлер на этой строчке требует идентифайер . Если сделать всё в одну строчку 
Код

private DrawablePoint points[][] = new DrawablePoint[cols][rows]; 
 то это компелируется и мы переходим к созданию и раскладыванию точек по ячейкам .У нас есть для этого  метод makePoints но конструктору к которому он нас отсылает 
Код

 DrawablePoint(Color color) 
    {
        this.color = color ;    
    }
 нужен аргумент color.
Если мы передадим цвет при создании точек (не знаю правда какой реально  это цвет с точки зрения компайлера ..наверно firstPlayerColor..) то сообщение об ошибке изчезает 

Код

public void makePoints ( int rows , int cols)
      {  for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) 
             {  points[x][y] = new DrawablePoint( color);       
           }      
    

Осталась нарисовать точки...Для этого нам нужны аргументы. В классе  DrawablePoint у нас прописано почему- то даже два метода
Код

 public void   drawCircle (int  x,int   y,  int radius, Graphics g)
    {
    g.drawOval(x - radius, y - radius, radius*2, radius*2);
   }  
   
   public void paint(Graphics g, int x, int y) 
   {
    int pointRadius = 6;
    drawCircle(x, y, pointRadius, g);
  }

 
когда я пытаюсь нарисовать точки как 
Код

points[x][y].drawCircle(x, y, 6, g);
 класс компелируется но при запуске программы выходит NullPointerException на этой строчке. Я думаю  нам надо переделать метод для рисования . Может быть проблема в Graphics g ..
PM MAIL   Вверх
Rpahut
Дата 15.1.2009, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

points [][]= new DrawablePoint[cols][rows];
 компайлер на этой строчке требует идентифайер

Эту строчку можно было хотя бы скопировать у меня. Зачем там квадратные скобки (points [][]... smile )?? Мы просто должны указать имя переменной, в которую хотим положить new DrawablePoint[cols][rows]:
Код

points = new DrawablePoint[cols][rows];

У BlueJ конечно кривые сообщения об ошибках, но если он ругается на эту строчку, значит ошибку стоит искать именно в ней. Зачем исправлять объявление массива, к которому у Явы нет никаких претензий?

Цитата

Если сделать всё в одну строчку 
private DrawablePoint points[][] = new DrawablePoint[cols][rows]; 

...то массив будет нулевого размера, потому что эта строка выполняется до конструктора класса, и в переменных cols и rows еще лежат нули. Дальше вы еще пытаетесь с этим массивом что-то делать - отсюда и все ошибки.
Так делать не надо!

Цитата

В классе  DrawablePoint у нас прописано почему- то даже два метода

Метод drawCircle() вы добавили сами ;). Пусть он пока остается, только сделайте его private. Для отрисовки точки используйте ее метод paint().

Цитата

при запуске программы выходит NullPointerException на этой строчке

Читайте все что я пишу внимательнее. Мы по несколько раз на одни и те же грабли наступаем.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 16.1.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Я поняла ..у меня даже точки прорисовались ...правда они пока выглядят пустыми кружками .Надо наверно одновременно с рисованием вызывать метод закрашивающий кружки . Цвет у них по умолчанию чёрный.
Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends JPanel{

     public int rows=20;
     public int cols=20;
     public int cellSize=30 ;
     private Color color;
     private DrawablePoint points[][]; // array to hold all possible  points
     
       
    GridsCanvas(int r, int c,int cellSize) {
        this.rows = r;
        this.cols = c;
        this.cellSize=cellSize;
        setVisible(true);
        setPreferredSize(new Dimension(600, 600));
        points = new DrawablePoint[cols][rows];
        makePoints(rows,cols);
    }

    public void paintComponent(Graphics g) {
        for (int i = 0; i < rows; i++)
            g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);
        
          for (int j = 0; j < cols; j++)
             g.drawLine(j * cellSize, rows*cellSize,  j * cellSize,0);
            
        for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {
             points[x][y].drawCircle(x*cellSize, y*cellSize, g);  
          }
         }
     }
     
     public void makePoints ( int rows , int cols)
      {  for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) 
             {  points[x][y] = new DrawablePoint( color);  
               
           }      
       }
   }
}
 сначала они прорисовались на самом краю решётки , там где координаты x=0 и y=0 . Но потом я для симметрии приравняла начальные x и y к 1 и точки встали симметрично , не касаясь краёв решётки .  Можно наверно даже так оставить ( не накладывать решётку на новую JFrame ).

Попыталась я закрасить кружочки добавив строчку 
Код

g.fillOval(getX() - 6, getY() - 6, 6 * 2, 6 * 2);
 скомпелировалось , но видимого результата от неё нет  .
пытаюсь добавить MouseListener к решётке 
Код

 canvas.addMouseListener(new MouseAdapter(){
          
            public void mouseClicked(MouseEvent e) {
                GridsCanvas canvas = (GridsCanvas) e.getSource();
                Point clickPoint = e.getPoint();
                DrawablePoint drawablePoint = new DrawablePoint(Color.RED);
                drawablePoint.setLocation(clickPoint);
                canvas.add(drawablePoint);
                canvas.repaint();
            }
       });

 компайлер не может найти метод setLocation ..Туманно пока представляю что ему надо в этом случае импортировать  или  имплементировать . Всё что можно было представить я уже импортировала  smile
Код

import java.awt.*;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.geom.Point2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;

public class Grids extends JFrame  implements Serializable , MouseListener {
    
     GridsCanvas canvas; 
     public int rows=20;
     public int cols=20;
     public int sellSize=30 ;
    
    Grids() // constructor
    {
        canvas = new GridsCanvas(rows, cols, sellSize); 
        add(canvas);
      
        addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Would you like to play new game  ?", "Options ", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.YES_OPTION) {
                    new Grids( );
                } else {  // this.System.exit();     
                }
            }
        });
        
        canvas.addMouseListener(new MouseAdapter(){
          
            public void mouseClicked(MouseEvent e) {
                GridsCanvas canvas = (GridsCanvas) e.getSource();
                Point clickPoint = e.getPoint();
                DrawablePoint drawablePoint = new DrawablePoint(Color.RED);
                drawablePoint.setLocation(clickPoint);
                canvas.add(drawablePoint);
                canvas.repaint();
            }
       });
        pack();
        setTitle("Points");
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    } 
    
   public void mouseEntered(MouseEvent e){
  }
  public void mouseExited(MouseEvent e) {
  }
  public void mousePressed(MouseEvent e) {
  }
  public void mouseReleased(MouseEvent e) {
  }
   public void mouseClicked(MouseEvent e) {
  
    }
}

 почему-то он не видит public void mouseClicked который прописан в кострукторе . Поэтому мне пришлось прописать public void mouseClicked ещё раз  в конце класса  .

 

Это сообщение отредактировал(а) Qawra - 17.1.2009, 00:24
PM MAIL   Вверх
Rpahut
Дата 17.1.2009, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Я поняла ..у меня даже точки прорисовались

Это замечательно! smile Можно двигаться дальше.

Рекомендации по движению дальше:
1. Сначала прочитайте, не вникая сильно, что я тут понаписал, постарайтесь уловить суть идеи.
2. Начните читать с начала, подробнее разбирая каждый пункт. Вносите изменения в код по мере продвижения.
3. Добавляйте в свой код комментарии, особенно касательно новых для вас вещей - так лучше усваивается.
4. Спрашивайте, если что непонятно.

______________________________________
Так, мы убедились что GridsCanvas и точки рисуются, так что пока отложим доработки (мы еще доработаем рисование сетки и точки). Есть более важная весчь - это обработка мыши, чтобы можно было щелкать по точкам.
Для того чтобы ловить события мыши, мы добавим implements MouseListener в класс Grids, и в него же впишем метод:
Код

public void mouseClicked(MouseEvent e) {
}


Пояснение:
implements MouseListener значит что класс, к которому это приписано, желает получать сообщения о том, что происходит с мышью.
Ява будет передавать классу сообщения о мыши, но чтобы их получать, в классе должны иметься определенные методы:
public void mouseEntered(MouseEvent e) // вызывается, когда мышка входит в пределы действия компонента
public void mouseExited(MouseEvent e) // наоборот
public void mouseDragged(MouseEvent e) // кнопка нажата и мышка двигается
public void mouseClicked(MouseEvent e) // пользователь щелкнул кнопкой мыши
Все эти методы должны присутствовать в классе Grids, иначе Ява не станет с ним работать; но нас интересует только где пользователь щелкнет кнопкой, поэтому мы впишем код только в mouseClicked(), а остальные методы оставим пустыми.

Еще нужно указать, какой именно компонент нас интересует. Для этого в конструктор Grids вставляем:
Код

canvas.addMouseListener(this); /* ЭТОТ класс хочет знать что происходит
                                                       с мышкой в пределах компонента CANVAS */


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

boolean firstPlayerMove; // объявление и создание переменной

а в конструкторе Grids присваиваем ей значение:
Код

firstPlayerMove = true; // инициализация переменной

Теперь чтобы узнать чей ход можно написать
Код

if(firstPlayerMove) {
  // ходит первый игрок
}
else {
  // ходит второй игрок
}

По ходу игры значение этой переменной будет меняться, и соответственно будут "переключаться" игроки - один ходит, второй отдыхает.

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

public boolean mouseWasClicked(int x, int y, Color playerColor) { // принимает координаты щелчка и цвет игрока который щелкнул

Класс GridsCanvas уже может рассчитать в какую точку попал щелчок(если вообще попал) и передать цвет этой точке. Но, опять, чтобы точка могла принять цвет, у нее должен быть метод по типу такого:
Код

public boolean setNewColor(Color newColor) { // метод принимает новый цвет
  color = newColor; // и меняет цвет точки на него
  return true;
}

Как рассчитать, в какую Точку попадают координаты щелчка:
если чтобы определить экранные координаты точки, мы умножали ее координаты-на-поле на cellSize
то здесь нам нужно наоборот, определить координаты-на-поле, поэтому делим экранные координаты на cellSize

--------------отступление--------------------
Настоятельно рекомендую поместить код преобразования координат экран->поле и поле->экран в отдельные методы класса GridsCanvas:
Код

int screen2field(int coord) { // screen to field
  return coord/cellSize;
}
...
int field2screen(int coord) { // field to screen
  return coord*cellSize;
}

Код

// использование:
// вместо например
points[x][y].drawCircle(x*cellSize, y*cellSize, g);
// стоит писать
points[x][y].drawCircle(field2screen(x), field2screen(y), g);

Это важно, потому что дальше код преобразования координат у нас поменяется немного, может быть несколько раз, и вам придется либо везде менять x*cellSize на новую формулу, либо можно будет просто подправить метод field2screen().
--------------------------------------------------

Так...
Метод DrawablePoint.setNewColor() я выше описал, теперь GridsCanvas.mouseWasClicked().
Код

public boolean mouseWasClicked(int x, int y, Color playerColor) {
  int pointX = screen2field(x); // считаем какая точка кликнута
  int pointY = screen2field(y);

  points[pointX][pointY].setNewColor(playerColor); // установить новый цвет - цвет игрока который кликнул
  repaint(); /* Очень важная штука, хотя я и забыл ее упомянуть.
                       Сообщаем Яве что поле надо перерисовать.
                       Она нужна чтоб вызвался метод paintComponent(),
                        без нее мы не увидим что точка поменяла цвет.*/
  return true;
}

Довольно просто.
Можете потом пощелкать в окне в стороне от сетки и посмотреть что получится =)

Теперь метод mouseClicked(), с которого все и началось.
Код

public void mouseClicked(MouseEvent e) {
  Player currentPlayer;
  int screenX = e.getX(); // получаем координаты щелчка
  int screenY = e.getY();

  // определяем игрока который щелкнул
  if(firstPlayerMove) currentPlayer = first;
  else currentPlayer = second;

  // сообщаем канвасу, кто и где щелкнул
  // canvas.mouseWasClicked(screenX, screenY, currentPlayer); // а-а-а косяк
  canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor());
}

Тут, как видно, нам еще нехватает метода Player.getColor(), который возвращал бы цвет игрока, но его я думаю вы напишете без подсказок.

--------------------------------------------
И все вместе с высоты птичьего полета:
1. Пользователь щелкает в окне
2. Ява вызывает Canvas.mouseClicked()
3. mouseClicked() передает информацию в GridsCanvas.mouseWasClicked()
4. mouseWasClicked() устанавливает новый цвет точки

PS Да чуть не забыл - в DrawablePoint.paint() нужно вставить строчку g.setColor(color); чтобы кружок рисовался цветом точки!!!

Это сообщение отредактировал(а) Rpahut - 17.1.2009, 00:38
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 17.1.2009, 01:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



в Grids пришлось прописать как членов класса  две переменные Player first  и Player second 
Код

public Player first;
 public Player second;
 
которые  создаются при нажатии на кнопки в стартовом окошке
Код

 public void mouseClicked(MouseEvent e) {
    if (e.getSource().equals(startButton)) 
    {
        new Grids( );
        stopSound();
        this.setVisible(false);
       Player first= new Player(  firstDefautColor);
       Player second = new Player( secondDefautColor);  
     
    } else if (e.getSource().equals(firstPlayerButton)) 
    { firstDefautColor = cchooser.ChangeColor( firstDefautColor  );
          
    } else if (e.getSource().equals(secondPlayerButton)) 
    { 
       secondDefautColor = cchooser.ChangeColor( secondDefautColor  );
    } 
    }
 

Я создала метод setNewColor в классе DrawablePoint .
Но " пощелкать в окне в стороне от сетки " мне не удалось .У меня там   пока только решётка и ничего больше нет  smile
Класс Player скомпелировался 
Код

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

public class Player 
 {
  private Color color;
  private Color firstPlayerColor;
  private Color secondPlayerColor;
  public Player first;
  public Player second;
  
  public Player(Color color ) // constructor 
  {    
      this.color = color;   
    }
    
    public Color getColor (Player currentPlayer )
    { if ( currentPlayer == first)
        {return firstPlayerColor;
        }
         else return secondPlayerColor;
        }
    }
 В методе getColor я передаю аргумент currentPlayer что-бы вернуть цвет игрока .Тут возникает проблема с Grids. mouseClicked который собственно и использует этот метод. canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor(currentPlayer )) ; компелируется но вызывает ошибку NullPointerException  когда я щёлкаю мышкой по решётке  . В классе Grids 
Код

import java.awt.*;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.geom.Point2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;

public class Grids extends JFrame  implements Serializable , MouseListener {
    
     GridsCanvas canvas; 
     public int rows=20;
     public int cols=20;
     public int sellSize=30 ;
     boolean firstPlayerMove;
     boolean secondPlayerMove;
     public Player first;
      public Player second;
    
    Grids() // constructor
    {   firstPlayerMove = true;
        secondPlayerMove = true;
        
        canvas = new GridsCanvas(rows, cols, sellSize); 
        add(canvas);
        
        canvas.addMouseListener(this);
      
        addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Would you like to play new game  ?", "Options ", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.YES_OPTION) {
                    new Grids( );
                } else {  // this.System.exit();     
                }
            }
        }); 
        pack();
        setTitle("Points");
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    } 
   /*if(firstPlayerMove) {
                // first player turn 
         }
           else {
               // second player turn
          } 
          
          */
   public void mouseEntered(MouseEvent e){
  }
  public void mouseExited(MouseEvent e) {
  }
  public void mouseDragged(MouseEvent e){
    }
  public void mousePressed(MouseEvent e) {
  }
  public void mouseReleased(MouseEvent e) {
  }
   public void mouseClicked(MouseEvent e) {
       Player currentPlayer;
       int screenX = e.getX(); // gets coordinate of the click
       int screenY = e.getY();
     
     if(firstPlayerMove) currentPlayer = first;
       else currentPlayer = second;
       
     canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor(currentPlayer )) ;
  
    }
}




Сначала я поместила 
Код

if(firstPlayerMove) {
  // ходит первый игрок
}
else {
  // ходит второй игрок
}
 но теперь думаю они должны быть частью отдельного метода .Поэтому я их из конструктора убрала и не знаю что с ними делать .




Это сообщение отредактировал(а) Qawra - 17.1.2009, 16:16
PM MAIL   Вверх
Rpahut
Дата 17.1.2009, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

в Grids пришлось прописать как членов класса  две переменные Player first  и Player second 

Блин какая путаница с классами.
Я как-то позабыл, что игроки у нас создаются в стартовом окне.
Ну ничего, это можно поправить - вы правильно прописали игроков, осталось только убрать эти переменные из стартового окна. А то так у нас четверо игроков - двое прописаны там и двое тут.
Еще нужно немного исправить программу. Привожу код:
Код

// в стартовом окне
public void mouseClicked(MouseEvent e) {
    if (e.getSource().equals(startButton)) 
    {
        new Grids(firstDefaultColor, secondDefaultColor); // <-- отправляем цвета в конструктор Grids
        stopSound();
        this.setVisible(false);
       // Player first= new Player(  firstDefautColor);
       // Player second = new Player( secondDefautColor);
    }
....

Код

// в классе Grids
Grids(Color defaultColorOne, Color defaultColorTwo) // constructor
{
     first = new Player(defaultColorOne); // игроки теперь создаются тут
     second = new Player(defaultColorTwo);
....

Когда это добавите, ошибка nullPointerException должна пропасть.

________________________________
Цитата

Класс Player скомпелировался 

Ну, Player.getColor() на самом деле гораздо проще:
Код

public Color getColor ()
{ 
  return color; // нам только нужно чтобы игрок сказал какой его цвет
  // и все
}

Смысл именно в том чтобы получить от игрока его цвет.
first.getColor() - возвращает цвет первого игрока
second.getColor() - возвращает цвет второго игрока
currentPlayer.getColor() - возвращает цвет того игрока, который сейчас ходит

_______________________________
Цитата

Сначала я поместила 
if(firstPlayerMove) {
  // ходит первый игрок
}
else {
  // ходит второй игрок
}
но теперь думаю они должны быть частью отдельного метода .Поэтому я их из конструктора убрала и не знаю что с ними делать .

=) Эти строки используются в Grids.mouseClicked(), немного в другом виде правда. Отдельно я их писал в качестве примера.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 17.1.2009, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



В Grids.mouseClicked(MouseEvent e) мы создаём обьект currentPlayer который 
видимо будет использоваться только в этом  классе . Могу я его обьявить private или даже наверно  "protected  ?  
Код

public void mouseClicked(MouseEvent e) {
       private Player currentPlayer;
       int screenX = e.getX(); // gets coordinate of the click
       int screenY = e.getY();
     
       if(firstPlayerMove) 
           currentPlayer = first;
       else currentPlayer = second;
    
     canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor( )) ;
  
    }
 в этом же классе у нас обьявляются две переменные 
Код

 private boolean firstPlayerMove;
 private boolean secondPlayerMove;
 которые потом будут использоваться в конструкторе Grids . Я сделала их private .Если что мы их переделаем на public.
Какой идентифаер присвоить  firstDefautColor и
  secondDefautColor пока не знаю . Они у нас появляются в стартовом окошке как private 
Код

private Color firstDefautColor= Color.blue;
 private Color secondDefautColor= Color.red;
 при нажатии на кнопку мы предлагаем сменить цвет 
Код

firstDefautColor = cchooser.ChangeColor( firstDefautColor  );
 затем мы используем  эти переменные в Grids при создании игроков 
Код

 first = new Player(firstDefautColor); // creating a Players
 second = new Player(secondDefautColor);
 но когда в Grids я предлагаю игрокам начать новую игру 
Код

addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Would you like to play new game  ?", "Options ", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.YES_OPTION) {
                    new Grids( firstDefautColor,  secondDefautColor);
                } else {  // this.System.exit();     
                }
            }
 компайлер пишет что " local variable firstDefautColor is accessed from within inner class ; need to be  declared final ". Я пробовала прописать public  и это не помогло . Компайлер хочет именно " final ". В   этом  случае мы видимо не сможем менять цвет  игрока ...

Запустила я программу полюбоваться на решётку ...
Если кликнуть то часть точек меняет цвет на цвет игрока smile
Там правда прорисовывается  лишняя точка в левом верхнем углу с координатами (0,0) которой там теоретически быть не должно . Мы рисуем точки начиная с x=1 , y=1
Код

 for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {
             points[x][y].drawCircle(field2screen(x), field2screen(y), g); 
             g.fillOval(getX() - 6, getY() - 6, 6 * 2, 6 * 2);

 Точка эта тоже способна менять цвет на цвет игрока. Причём делает она это при первом же шелчке мышки на решётке ! 


PM MAIL   Вверх
Rpahut
Дата 18.1.2009, 00:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

В Grids.mouseClicked(MouseEvent e) мы создаём обьект currentPlayer который 
видимо будет использоваться только в этом  классе . Могу я его обьявить private или даже наверно  "protected  ?

А зачем?.
И объект мы не создаем, нет никакого new Player(). Мы создаем переменную, и создаем мы ее внутри метода, так что за пределами метода ее "видно" не будет.
private и protected приписывается членам класса чтобы обозначить, возможен ли к ним доступ из других классов или нет. К переменным метода из за его пределов нельзя добраться независимо от того хотите вы этого или нет.

Цитата

"Would you like to play new game  ?"

Так новую игру начать в любом случае не выйдет. Нужно стартовое окно setVisible(true) а Grids закрыть. Советую на это забить сейчас.

Цитата

 for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {
             points[x][y].drawCircle(field2screen(x), field2screen(y), g); 
             g.fillOval(getX() - 6, getY() - 6, 6 * 2, 6 * 2);

g.fillOval(getX() - 6, getY() - 6, 6 * 2, 6 * 2); - А вот здесь что у вас???
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 18.1.2009, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Это я пробовала сама кружочки закрасить smile 
Без этого тоже работает так что я это уже отключила.
Точнее я это перенесла в метод 
Код

 public void   drawCircle (int  x,int   y,  Graphics g)
    {   g.setColor(color);
        g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
    }  
 
может быть это и вызывало лишнию точку потому что теперь её ужё нет . 

PM MAIL   Вверх
Qawra
Дата 21.1.2009, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Теперь я думаю можно скрыть точки которые мы создали и попытаться нарисовать точки за игроков .В GridsCanvas я отключаю пока 
Код

 //points[x][y].drawCircle(field2screen(x), field2screen(y), g);   
  и пытаюсь проследить логику программы .
Когда мы нажимаем кнопку старт у нас запускается конструктор Grids
Код

new Grids(firstDefautColor, secondDefautColor );
 что бы игра продолжалась конструктор должен вызвать метод принимающий команды от мышки .Если я вызываю         mouseClicked (MouseEvent e); в конструкторе  то это не компелируется .Пишет что нехватает ")" 
Метод Grids.mouseClicked я попыталась изменить что-бы начать рисовать точки по очереди цветами игроков .  Даже не целюсь в углы решётки.Просто пытаюсь передать цвет и ход .
Код

public void mouseClicked(MouseEvent e) {
       
       Player currentPlayer;
       
       int screenX = e.getX(); // gets coordinate of the click
       int screenY = e.getY();
     
       if(firstPlayerMove) 
          { currentPlayer = first;
            Point clickPoint = e.getPoint();
            DrawablePoint newPoint = new DrawablePoint( currentPlayer.getColor( ));
            newPoint.drawCircle ( screenX, screenY,Graphics  g);
            canvas.add(newPoint);
            canvas.repaint();
            firstPlayerMove=false;
            secondPlayerMove=true;
            //mouseClicked(); Тут я пытаюсь вызвать метод снова .Но не получается
             
        }
       if (secondPlayerMove)
       {
         currentPlayer = second;
          Point clickPoint = e.getPoint();
          DrawablePoint newPoint = new DrawablePoint( currentPlayer.getColor( ));
          newPoint.drawCircle (screenX, screenY, Graphics g);
          canvas.add(newPoint);
          canvas.repaint();
          secondPlayerMove=false;
          firstPlayerMove=true;
          
        }
     
   
      canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor( )) ;
       
    }

 Это наверно неправильно что всё происходит в одном методе mouseClicked . Но неправильно не  только это .... На строчке            newPoint.drawCircle ( screenX, screenY, Graphics g); нехватает ")"  



Это сообщение отредактировал(а) Qawra - 21.1.2009, 21:56
PM MAIL   Вверх
Rpahut
Дата 22.1.2009, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Теперь я думаю можно скрыть точки которые мы создали и попытаться нарисовать точки за игроков .В GridsCanvas я отключаю пока

Вообще говоря у нас программа, если она правильно работает, уже должна менять цвет точки на цвет игрока при щелчке. Так что отключать и менять ничего не надо. Другое дело что у нас не передается ход от одного игрока другому.

Логика программы такая:  пока пользователь ничего не делает, в нашей программе ничего не происходит. Тут то же что и в настоящих точках, на листочке - пока вы не поставите точку, игра никуда не продвинется. Как только происходит щелчок - запускается метод mouseClicked() и все остальные, в которых наш код и выполняет всю работу, а потом программа снова засыпает до следующего щелчка.
Как я раньше и писал:
Цитата

И все вместе с высоты птичьего полета:
1. Пользователь щелкает в окне
2. Ява вызывает Canvas.mouseClicked()
3. mouseClicked() передает информацию в GridsCanvas.mouseWasClicked()
4. mouseWasClicked() устанавливает новый цвет точки



Цитата

что бы игра продолжалась конструктор должен вызвать метод принимающий команды от мышки.Если я вызываю         mouseClicked (MouseEvent e); в конструкторе  то это не компелируется .

Не компилируется потому что у вас опять тип переменной вместе с параметром вписан - видно это ваши самые любимые грабли  smile ...

Этот метод вызывает сама Ява - каждый раз когда mouse clicked. Нам этого делать не нужно! Да и в MouseEvent наша программа тогда  должна перед этим вписать координаты щелчка, которого еще небыло - как вы собирались заставить это работать?...

У нас в Grids.mouseClicked был кусок такой:
Код

  // определяем игрока который щелкнул
  if(firstPlayerMove) currentPlayer = first;
  else currentPlayer = second;

Чтобы игроки ходили по очереди, нужно его подправить немного:
Код

  // определяем игрока который щелкнул
  if(firstPlayerMove) {
    currentPlayer = first;
    firstPlayerMove = false; // в следующий раз будет ход второго игрока
  }
  else {
    currentPlayer = second;
    firstPlayerMove = true; // ход второго игрока; следующий ход - первого
  }

Переменную secondPlayerMove выкиньте вообще и забудьте. У нас если fistPlayerMove равно true - значит сейчас ход первого игрока; если fistPlayerMove равно false - значит ход не первого игрока - это то есть второго. Если не ходит первый, значит однозначно ходит второй - у нас их всего двое.

-----
Можно посмотреть весь код - классы Grids, GridsCanvas, DrawablePoint и Player?
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 23.1.2009, 00:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Методом проб и ошибок я нашла чего не хватало для рисования точек при щелчке мышкой .Точки у нас уже созданы и при щелчке они меняют цвет ,но если их создать не прорисовывая , то щелчки по пустой решётке ни к какому эфекту не приводят .
В методе mouseWasClicked вместо repaint(); нужен был points[pointX][pointY].drawCircle(x,y,this.getGraphics());
Код

 public boolean mouseWasClicked(int x, int y, Color playerColor) 
         { // accepts coordinates and the playerColor of the Mouse click
        int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);

          points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color
          //repaint(); 
          points[pointX][pointY].drawCircle(x,y,this.getGraphics());
          return true;  
        }
 теперь если даже на пустой решётке рисуются точки . Правда они рисуются не в углах решетки а там где мышка кликнет . Ход игроков передаётся нормально .
Любимые мои грабли засели в подсознании . 
Я слишком много и быстро прочитала  о Java . Когда обьём информации превысил определённый уровень - детали перестали цеплятся сознанием и стали формироваться  образы в которых переменные были прописаны вместе с параметрами ...
Наверно это с сайта sun  на котором  я каждый день читала структуры классов  что бы нарисовать  GUI .
Особенно трудно  когда  я за компьютером в школе потому что  русский язык там не отображается .В результате  я не могу прочитать в текстовом файле то что вы мне рекомендуете сделать и действую как получается  . И получаются грабли smile
Код

import java.awt.*;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.geom.Point2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;

public class Grids extends JFrame  implements Serializable , MouseListener {
    
     GridsCanvas canvas; 
     public int rows=20;
     public int cols=20;
     public int sellSize=30 ;
     private boolean firstPlayerMove;
     public Player first;
     public Player second;
     
     
    
    Grids(Color firstDefautColor, Color secondDefautColor) // constructor
    {   
        first = new Player(firstDefautColor); // creating a Players
        second = new Player(secondDefautColor);
        firstPlayerMove = true;

        
        canvas = new GridsCanvas(rows, cols, sellSize); 
        add(canvas);
        
        canvas.addMouseListener(this);
      
        addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Would you like to stop the game  ?", "Options ", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.YES_OPTION) {
                } else {    
                }
            }
        }); 
        pack();
        setTitle("Points");
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
        
    } 
   
  public void mouseEntered(MouseEvent e){
  }
  public void mouseExited(MouseEvent e) {
  }
  public void mouseDragged(MouseEvent e){
    }
  public void mousePressed(MouseEvent e) {
  }
  public void mouseReleased(MouseEvent e) {
  }
  public void mouseClicked(MouseEvent e) {
    
       Player currentPlayer;
  
       int screenX = e.getX(); // gets coordinate of the click
       int screenY = e.getY();
     
   
      if(firstPlayerMove) {
       currentPlayer = first;
       firstPlayerMove = false; 
       }
      else {
       currentPlayer = second;
       firstPlayerMove = true; 
      }
      canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor( )) ;
       
    }
}

==============================
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends JPanel{

     public int rows=20;
     public int cols=20;
     public int cellSize=30 ;
     private Color color;
     private DrawablePoint points[][]; // array to hold all possible  points
     
       
    GridsCanvas(int r, int c,int cellSize) {
        this.rows = r;
        this.cols = c;
        this.cellSize=cellSize;
        setVisible(true);
        setPreferredSize(new Dimension(600, 600));
        points = new DrawablePoint[cols][rows];
        makePoints(rows,cols);
    }

    public void paintComponent(Graphics g) {
        for (int i = 0; i < rows; i++)
            g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);
        
          for (int j = 0; j < cols; j++)
             g.drawLine(j * cellSize, rows*cellSize,  j * cellSize,0);
            
        for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {
             //points[x][y].drawCircle(field2screen(x), field2screen(y), g);   
          }
         }
     }
     
     public void makePoints ( int rows , int cols)
      {  for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) 
             {  points[x][y] = new DrawablePoint( color);  
               
            }      
          }
         }
     public boolean mouseWasClicked(int x, int y, Color playerColor) 
         { // accepts coordinates and the playerColor of the Mouse click
        int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);

          points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color
    
          points[pointX][pointY].drawCircle(x,y,this.getGraphics());
          return true;  
        }
   
     int screen2field(int coord) { // screen to field convert coordinates
       return coord/cellSize;
      }

     int field2screen(int coord) { // field to screen  convert coordinates
       return coord*cellSize;
    }
  }
  
=================================
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;

class DrawablePoint //extends Component
{

    private Color color;
    public  int radius;
    public int x;
    public int y;
    
    
    
    DrawablePoint(Color color) 
    {
        this.color = color ;
        radius = 6;
        
    }
    public void   drawCircle (int  x,int   y,  Graphics g)
    {   g.setColor(color);
        g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
    }  
    
    public boolean setNewColor(Color playerColor) { // accepts new color
        color = playerColor; // changes color
     return true;
   }
   
   
}
=============================
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Player 
 {
  private Color color;
  
  public Player first;
  public Player second;
  
  public Player(Color color ) // constructor 
  {    
      this.color = color;   
    }
    
    public Color getColor ( )
    { return color;
        }
    }

 




PM MAIL   Вверх
Rpahut
Дата 23.1.2009, 02:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Боюсь что все то же самое, но не на русском, я написать не смогу. No vy mozhete perevesti russkij tekst v translit na etoj stranice smile  Верный способ сломать глаза.

Ладно.
Цитата

Точки у нас уже созданы и при щелчке они меняют цвет ,но если их создать не прорисовывая , то щелчки по пустой решётке ни к какому эфекту не приводят .

Точки в любом случае меняют цвет, но этого естественно не видно, если у вас отключена отрисовка. 
Я так понял вы хотите чтобы пока точка не поставлена ее небыло видно? Для этого достаточно подправить метод DrawablePoint.paint().

Я как-то помнится советовал вам использовать DrawablePoint.paint() вместо drawCircle() - потому что drawCircle(), очевидно, рисует круг и ничего больше, а paint() отображает Точку, и отображает в том виде, в каком нам хочется. У меня например не рисуется сетка на поле - вместо этого непоставленные точки отображаются в виде пустых кружков светло-серого цвета. Поставленные точки закрашиваются цветом игрока. Вы можете сделать как вам больше нравится - например не рисовать "пустые" точки совсем - но paint() все равно должен вызываться для каждой точки.

В метод paint() можно добавить условие, проверяющее поставлена точка или нет, и в зависимости от результата менять код рисования точки. Я пробежался по коду и сдается мне что у ваших точек color==null когда они не поставлены - это можно использовать:
Код

public void drawCircle(int x, int y, Graphics g) {
  g.setColor(color); // use current point color

  if(color==null) {
    // do not draw circle
  }
  else {
    drawCircle(x, y, g); // do draw circle
  }
}

И не надо ломать голову - просто вызываете paint(), а точка уже сама решит, рисоваться ей или нет. Объектно-ориентированное "разделяй и властвуй" в самой наглядной его форме.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 23.1.2009, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



В транслите я не только глаза сломаю но и мозги могу вывихнуть .
Русский конечно лучше ... cегодня на свой ноут самодельные русские буквы приклеила smile

Я уже пробовала использовать paint() , но у меня по какой-то причине не рисовалось и я этот метод удалила . Потом я использовала drawCircle и он рисовал пустые кружочки . Затем я заменила в самом методе drawCircle на fillOval и всё чудно прорисовалось. То есть мои точки немного овальные получились но не пустыми. Название метода drawCircle осталось по инерции. Сам метод рисует овальные цветные точки .Нужно ли его менять в интересах логики игры или можно оставить ? 
У меня решётка прорисовывается но точки ставятся где угодно ( даже друг на друга можно ставить ) . Для того что-бы они могли ставиться только в углах решётки нужно видимо  подкорректировать методы работающие с координатами
Код

      int screen2field(int coord) { // screen to field convert coordinates
       return coord/cellSize;
      }

     int field2screen(int coord) { // field to screen  convert coordinates
       return coord*cellSize;

эти методы используются в mouseWasClicked
Код

public boolean mouseWasClicked(int x, int y, Color playerColor) 
         { // accepts coordinates and the playerColor of the Mouse click
         int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);

          points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color
    
          points[pointX][pointY].drawCircle(x,y,this.getGraphics());
          return true;  
        }
не знаю как этого добиться но нужно сделать небольшой зазор в координатах углов клетки . Приходит в голову использовать % 
но думаю что это не будет  работать во всех возможных случаях . Могут быть OutOfBoundary Exceptions...
 

PM MAIL   Вверх
Rpahut
Дата 24.1.2009, 03:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Ну для начала - в предыдущем сообщении я приводил код, там метод подразумевался именно paint(); я сам запутался и не то название написал.

Игре абсолютно безразлично, как называются методы (кроме спец. случаев, вроде mouseClicked); но принято давать методам(и классам и переменным) имена, отражающие их назначение - с расчетом на то, что кто-то помимо программиста будет читать код, или вы сами, скажем через годик, откроете исходники и попытаетесь в них разобраться.
Пока метод drawCircle() рисует только круг - можно называть его так. Но - опять то о чем я говорил, и немного забегая вперед - рисование точки это не просто рисование круга. По меньшей мере там:
1. не рисуется ничего, если точка не поставлена
2. рисуется круг, если точка поставлена
3. когда точка захвачена (внутри замкнутого контура), это тоже влияет на внешний вид точки
Все вместе это нужно называть более общим словом - вроде paint() или display().

Дальше - все что нужно для рисования точек у нас уже есть. Если вас не устраивает, как рисуется точка, то вы меняете код в методе paint() (или drawCircle()) - потому что именно этот метод определяет, как рисуется точка.

Может показаться не очень логичным, что paint() нужно вызывать даже для точек, которые не должны быть видны.
Код

// GridsCanvas.paintComponent()
...
        for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {
             points[x][y].paint(field2screen(x), field2screen(y), g);   // call for EACH point
          }
         }
...

Но класс GridsCanvas, в котором у нас рисуются точки, не может решать, какую точку рисовать, а какую нет - у нас происходит "разделение труда" между классами, и GridsCanvas(второе имя Field) отвечает за то чтобы каждая точка рисовалась на положенном ей месте на поле. Точка не может решать, на каком месте ей нарисоваться, но она может решать рисоваться ли ей вообще.

======================================
Смысл Объектно-Ориентированного программирования
в том, что программа разделяется на объекты-классы, каждый из которых занят своим делом.

Когда вы пишете код класса DrawablePoint, вам не нужно держать в голове код остальных классов. Можно вообще забыть на время что есть еще какие-то классы - потому что все нужное точке она хранит внутри себя:
Код

// class DrawablePoint
private Color color; // у класса есть color
...
public void paint(int x, int y, Graphics g) { // у класса есть x, y и g
  g.setColor(color); // используем color
  if(color==null) {
  }
  else {
    drawCircle(x, y, g); // используем x, y и g
  }
}
...


То же с классом GridsCanvas:
Код

// class GridsCanvas
   private Point points[][];
   private int rows, cols;
   private int cellSize;
...
     /* Заметьте, все используемые переменные - свои.
     Мы не залезаем в другие классы и можем вообще
     ничего о них не знать. */
     public void paintComponent(Graphics g) {
        for (int i = 0; i < rows; i++)
            g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);
        
          for (int j = 0; j < cols; j++)
             g.drawLine(j * cellSize, rows*cellSize,  j * cellSize,0);
            
        for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {
             /* Классу так же совершенно безразлично, что
             происходит в методах других классов. Его
             задача - передать параметры. Так что передаем и не ломаем голову.*/
             points[x][y].paint(field2screen(x), field2screen(y), g);
          }
         }
     }
...


Чо-то опять длинновато получилось... smile Все, на сегодня хватит.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 24.1.2009, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Методы я разделила . Теперь они выглядят так 
Код

class GridsCanvas extends JPanel{

     public int rows=20;
     public int cols=20;
     public int cellSize=30 ;
     private Color color;
     private DrawablePoint points[][]; // array to hold all possible  points
     
       
    GridsCanvas(int r, int c,int cellSize) {
        this.rows = r;
        this.cols = c;
        this.cellSize=cellSize;
        setVisible(true);
        setPreferredSize(new Dimension(600, 600));
        points = new DrawablePoint[cols][rows];
        makePoints(rows,cols);
    }

    public void paintComponent(Graphics g) {
        for (int i = 0; i < rows; i++)
            g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);
        
          for (int j = 0; j < cols; j++)
             g.drawLine(j * cellSize, rows*cellSize,  j * cellSize,0);
            
        for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {
              
              points[x][y].paint(field2screen(x), field2screen(y), g);   // call for EACH point
          }
         }
     }
     
     public void makePoints ( int rows , int cols)
      {  for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) 
             {  points[x][y] = new DrawablePoint( color);  
               
            }      
          }
         }
     public boolean mouseWasClicked(int x, int y, Color playerColor) 
         { // accepts coordinates and the playerColor of the Mouse click
         int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);

          points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color
    
          points[pointX][pointY].paint(x,y,this.getGraphics());
          return true;  
        }
   
     int screen2field(int coord) { // screen to field convert coordinates
       return coord/cellSize;
      }

     int field2screen(int coord) { // field to screen  convert coordinates
       return coord*cellSize;
    }
  }
  
=====================
class DrawablePoint 
{
    private Color color;
    public  int radius;
    public int x;
    public int y;
    
    DrawablePoint(Color color) 
    {
        this.color = color ;
        radius = 6;
        
    }
    public void   paint (int  x,int   y,  Graphics g)
    {   g.setColor(color);
        
     if(color==null) {
    }
     else {
      drawCircle(x, y, g); // pass  x, y и g  to the  drawCircle
    }  
 }
    public void   drawCircle (int  x,int   y,  Graphics g)
    {   g.setColor(color);
         g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
    }  
    public boolean setNewColor(Color playerColor) { // accepts new color
        color = playerColor; // changes color
     return true;
   }  
}
 между методами paint и drawCircle теперь установленно " разделение труда " 
smile
PM MAIL   Вверх
Rpahut
Дата 25.1.2009, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Погонял немного нашу программку.
На данный момент есть следующие недочеты:
1. Точка закрашивается при щелчке в клетку справа-внизу от нее. Пришла пора править screen2field():
Код

     private int screen2field(int coord) { // screen to field convert coordinates
       return (coord+cellSize/2) /cellSize; // shift by half cell
      }


2. Точка перекрашивается даже если она уже занята другим игроком. Чтобы этого не происходило, нужно добавить проверку в setNewColor()
Код

// метод теперь возвращает false если точка уже занята
    public boolean setNewColor(Color playerColor) { // accepts new color
        if(color!=null) // color is changed already
           return false; // do nothing and return false

        color = playerColor; // changes color
     return true;
   }

3. Ход все равно передается следующему игроку, даже если предыдущий щелкнул в занятую точку. Мы используем значение, возвращаемое setNewColor(), чтобы определить, удалось ли игроку поставить точку или нет, и передадим ход только если удалось:
Код

// здесь просто возвращаем значение
     public boolean mouseWasClicked(int x, int y, Color playerColor) { // accepts coordinates and the playerColor of the Mouse click
        int pointX = screen2field(x); // count which point was clicked
        int pointY = screen2field(y);
        return points[pointX][pointY].setNewColor(playerColor); // return value returned by setNewColor()
    
        //return true;  
      }

Код

// здесь используем значение
  public void mouseClicked(MouseEvent e) {
    
       Player currentPlayer;
  
       int screenX = e.getX(); // gets coordinate of the click
       int screenY = e.getY();
     
   
       if(firstPlayerMove) {
         currentPlayer = first;
         // firstPlayerMove = false; 
       }
       else {
         currentPlayer = second;
         // firstPlayerMove = true; 
       }

       if( canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor( )) ) {
         // если цвет успешно сменен -
         // передаем ход следующему игроку
         firstPlayerMove = !firstPlayerMove;
       }
       
  }


4. При закрытии окна появляется диалог "Would you like to stop the game  ?", но окно закрывается независимо от того would я like или нет. Может оставить одну кнопку Yes? smile 
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 26.1.2009, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Точки которые созданы заранее и хранятся в массиве у меня на решётке не видны .А точки создаваемые при щелчке мышкой рисуются там где мышкой щёлкнули..даже  друг на друге .
Я попробовала изменить screen2field но пока поведение точек не изменилось.Может быть надо поправить и field2screen  что бы был эффект попадания в углы решётки ? 
После введения проверки в setNewColor() точки перестали перекрашивать друг друга но при неполном перекрывании новая точка того же цвета всё-таки рисуется. Если щёлкать мышкой и чуть чуть смещать курсор можно нарисовать линию из частично перекрывающихся точек одного цвета.  

В mouseWasClicked мне пришлось оставить points[pointX][pointY].paint(x,y,this.getGraphics()); потому что без него  точки не рисуются .
Код

public boolean mouseWasClicked(int x, int y, Color playerColor) 
         { // accepts coordinates and the playerColor of the Mouse click
         int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);
          points[pointX][pointY].paint(x,y,this.getGraphics());
          return points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color
        }

видимых изменений это не принесло потому что мы не смогли привязать координаты новых точек к координатам точек в массиве. Наши точки пока гуляют сами по себе smile
mouseClicked скомпелировался нормально .
Кнопочку я попыталась убрать изменив ту часть кода где она мне встретилась 
Код

public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Would you like to stop the game  ?", "Options ", JOptionPane.YES_OPTION);
                if (exitCode == JOptionPane.YES_OPTION) {
                } else {    
                }
 всё скомпелировалось но и кнопочка тоже осталась..Странно однако .
Хотя это пустяк по сравнению с точками "гуляющими" по решётке .



PM MAIL   Вверх
Rpahut
Дата 26.1.2009, 02:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

В mouseWasClicked мне пришлось оставить points[pointX][pointY].paint(x,y,this.getGraphics()); потому что без него  точки не рисуются .

ТАМ они и не должны рисоваться. У вас есть метод paintComponent() в котором происходит(ну, должна происходить) отрисовка.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 26.1.2009, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



paintComponent() происходит отрисовка точек которые заранее созданы в  массиве и самой решётки .Мы не определяем их цвет .
Код

 public void paintComponent(Graphics g) {
        for (int i = 0; i < rows; i++)
            g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);
        
          for (int j = 0; j < cols; j++)
             g.drawLine(j * cellSize, rows*cellSize,  j * cellSize,0);
            
        for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) { 
              points[x][y].drawCircle(field2screen(x), field2screen(y), g); // call for EACH point to draw 
          }
         }
     }
 если поменять на  points[x][y].paint(field2screen(x), field2screen(y), g);   то решётка выйдет без прорисовки заранее созданных  точек так что смысла в этом нет.
Оба метода для рисования точек на данный момент :
Код

 public void   paint (int  x,int   y,  Graphics g)
    {   g.setColor(color);
        
     if(color==null) {
    }
     else {
      drawCircle(x, y, g); // pass  x, y ,Graphics  g   and draw the points 
    }  
 }
    public void   drawCircle (int  x,int   y,  Graphics g)
    {   g.setColor(color);
        g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
    }       

В методе  mouseWasClicked происходит рисование точек цветами игроков при щелчке мышкой.Они то у нас и гуляют сами по себе .
Нам нужна валидация их координат на предмет совпадения с координатами заранее созданных точек которые ещё не имеют хозяина. Может быть просто перебирать координаты заранее созданных точек на предмет совпадения с координатами щелчка мышкой  плюс минус 5 пикселей ? Если такая точка существует - мы её закрасим , а если нет пускай пробуют ещё раз щёлкнуть smile

PM MAIL   Вверх
Rpahut
Дата 26.1.2009, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

решётка выйдет без прорисовки заранее созданных  точек так что смысла в этом нет.

Смысл есть - для чего мы использовали setNewColor()? Когда игрок тыкает в точку, меняется хранимый в ней цвет, и она рисуется этим цветом.
paintComponent() вызывается всякий раз, когда щелкается мышка (проверьте, в mouseClicked() должна быть строчка repaint();), поэтому всякий раз перерисовывается все поле - если точка получила цвет, она появится на экране.

Ах да мой косяк. Запостил mouseClicked() без repaint'а smile Должен быть repaint()!!, в самом конце метода - он вызывает paintComponent(), без него изменения на поле видно не будет.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 27.1.2009, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



А я  вчера пыталась найти кто же вызывает paintComponent()  ..... 
Мне это было жутко интересно smile 
Потом я смирилась и решила что это какой-то особый метод который и вызывать то не надо - работает автоматом . 
Теперь у нас точки ставятся по углам решётки    smile  
Но  мы ещё не применяли метод 
Код

 private int field2screen(int coord) { // field to screen  convert coordinates
       return coord*cellSize;
    }
  мы будем его использовать для замыкания контура  ?

Будут ли  нарисованные точки   храниться в отдельном массиве  или можно  использовать  массив  который уже есть с заранее созданными точками ?


 
PM MAIL   Вверх
Rpahut
Дата 27.1.2009, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



paintComponent() на самом деле вызывается на усмотрение Явы, например когда окно разворачивается из свернутого состояния. repaint() мы используем чтобы сообщить Яве что мы изменили поле и его надо перерисовать.

А field2screen() уже используется здесь для перевода координат точки на поле в экранные координаты:
Код

points[x][y].paint(field2screen(x), field2screen(y), g);


Работать мы будем с теми точками которые у нас есть.

______________________________________
Собственно прежде чем идти дальше предлагаю внести пару штрихов в код.

1. Сейчас у нас если пощелкать у самого правого края экрана (или внизу) происходит исключение ArrayIndexOutOfBoundsException, потому что в результате пересчета экранных координат щелчка в "полевые" получается что x или y за пределами массива
Код

// GridsCanvas.mouseWasClicked()
...
// exception!
return points[pointX][pointY].setNewColor(playerColor); // pointX or pointY out of bounds

Чтобы этого не происходило мы добавим проверку координат.
Сначала вспомогательный метод для проверки координат:
Код

private boolean goodCoords(int fieldX, int fieldY) {
  /*
  if X is zero or positive and
  if Y is zero or positive and
  if X is less than field width and
  if Y is less than field height...
  */
  if(fieldX>=0 && fieldY>=0 && fieldX<cols && fieldY<rows)
    // ...good coords
    return true;

  // else - bad coords
  return false;
}

Сама проверка:
Код

     public boolean mouseWasClicked(int x, int y, Color playerColor) { // accepts coordinates and the playerColor of the Mouse click
        int pointX = screen2field(x); // count which point was clicked
        int pointY = screen2field(y);

        // check coords
        if( goodCoords(pointX, pointY) ) {
                return points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color
        }
        // else do nothing
        return false;
      }


--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Rpahut
Дата 27.1.2009, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



2. Рисование точек начинается с координат [1,1], т.е. не видно целый столбец и целую строку точек, хотя они все равно обрабатываются программой:
Код

// GridsCanvas.paintComponent()
...
        for(int y=1; y<cols; y++) {
          for(int x=1; x<rows; x++) {

Меняем на 
Код

        for(int y=0; y<cols; y++) {
          for(int x=0; x<rows; x++) {


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

Сначала увеличим размер окна на одну клетку.
Было:
Код

// GridsCanvas.GridsCanvas()
...
        setPreferredSize(new Dimension(600, 600));

Стало:
Код

        // [(numberOfColumns+1)*sizeOfCell , (numberOfRows+1)*sizeOfCell]
        // or [numberOfColumns*sizeOfCell+sizeOfCell , numberOfRows*sizeOfCell+sizeOfCell]
        setPreferredSize(new Dimension( (c+1)*cellSize, (r+1)*cellSize ));


Теперь места достаточно чтобы подвинуть сетку. Дорабатываем paintComponent():
Код

    public void paintComponent(Graphics g) {

        g.translate(cellSize, cellSize); // ADDED

        // lines are shorter now
        for (int i = 0; i < rows; i++)
            //g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);
            g.drawLine(0, cellSize*i, cols*cellSize-cellSize, cellSize*i); // CHANGED
        
          for (int j = 0; j < cols; j++)
             //g.drawLine( j * cellSize, rows*cellSize,  j * cellSize,0 );
             g.drawLine( j * cellSize, rows*cellSize-cellSize,  j * cellSize,0 ); // CHANGED
            
        for(int y=0; y<cols; y++) {
          for(int x=0; x<rows; x++) {
             points[x][y].paint(field2screen(x), field2screen(y), g);   
          }
         }

        g.translate(-cellSize, -cellSize); // ADDED

     }

    translate(x, y) используется чтобы сместить пространство отрисовки. Здесь мы смещаем его вправо-вниз на размер клетки
    так что все рисуемые объекты тоже смещаются на это расстояние.
    translate(-x, -y) в конце используется чтобы вернуть все как было (после отрисовки). Без него поле будет смещаться дальше и дальше
    при каждом вызове paintComponent() и уедет с экрана.

Ну и, раз уж мы сдвинули сетку, придется поправить и screen2field(), чтобы точки попадали в мышку как и раньше.
Код

     int screen2field(int coord) { // screen to field convert coordinates
       //return (coord+cellSize/2) /cellSize; // old
       //return (coord+cellSize/2) /cellSize - 1; // new 1
       return (coord-cellSize/2) /cellSize; // new 2
      }



Это сообщение отредактировал(а) Rpahut - 27.1.2009, 22:56
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 28.1.2009, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Вчера у меня отключился интернет ( ливнем  повредило телефонный кабель ). 
Сейчас пишу с чужого компьютера  .Компилятора под рукой нет но я надеюсь к вечеру интернет будет и я смогу описать  результат проделанной работы. Пока занималась проблемой с лишней кнопкой при закрытии программы .Не знаю как её убрать . Если только весь public void windowClosing(WindowEvent e) убрать и сделать JPaneOption диалог . Мы его использовали когда ещё не пользовались GUI поэтому ещё не факт что с  GUI это будет правильным решением .  
Сегодня  нам  рассказали какую документацию к программе  от нас хотят ... Сказали  написать срочно 50-100 страниц используя используя глаголы в будущем времени потому что мы сначала  должны были  писали эту документацию  а потом уже  программу разрабатывать   .. 
Надо  описать как всё работает  ,  куда что передаётся  , как  и где  принципы обьектно-ориентированного программирования себя проявляют . К алгоритмам надо приложить  диаграммы или псевдо-коде .  Я бы конечно предпочла что-бы мне  заранее  это сказали делать . Но у препода своя  железная логика . Он считает что декабре мы ещё не могли знать что реально мы   напишем и каким путём пойдём . 
У всех студентов сейчас  разные версии .  А тех у кого версии  будут одинаковые будут  "пытать "  в разных кабинетах . Преподаватели  наделают им  ошибок в коде их же собственных  програм  и заставят  их исправить что-бы выяснить кто у кого списал   ..

У меня всё скомпелировалось . Я думаю как можно сделать что-бы последняя поставленная точка мигала привлекая к себе внимание игроков. Надо вызывать paintComponent , но как ..такое впечатление что  нужно установить не просто loop а loop c таймером  для прорисовки через определённый интервал.


Это сообщение отредактировал(а) Qawra - 28.1.2009, 20:42
PM MAIL   Вверх
Rpahut
Дата 28.1.2009, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Пока занималась проблеммой с лишней кнопкой при закрытии программы .Не знаю как её убрать .

Там нужно сделать две вещи.
Во-первых, указать чтобы окно не закрывалось автоматически:
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Во-вторых - вручную закрыть окно, если пользователь выберет Yes.
Код

        addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Would you like to stop the game  ?", "Options ", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.YES_OPTION) {
                    dispose(); // close window
                }
            }
        }); 


__________________________
Вам показывали что BlueJ умеет генерировать документацию? 

Вобщем, он умеет, нужно только составить описание классов и методов.
Код

/**
  * GridsCanvas is a {@url JPanel} extension for Points game
  */
class GridsCanvas extends JPanel{
     public int rows=20;
     public int cols=20;
     public int cellSize=30 ;
     private Color color;
     private DrawablePoint points[][]; // array to hold all possible  points

    /**
      * Creates new game field
      * @param r number of field rows
      * @param c number of field columns
      * @param cellSize cell size in pixels
      */
    GridsCanvas(int r, int c,int cellSize) {
        this.rows = r;
        this.cols = c;
        this.cellSize=cellSize;
        setVisible(true);
        setPreferredSize(new Dimension( (r+1)*cellSize, (c+1)*cellSize ));
        points = new DrawablePoint[cols][rows];
        makePoints(rows,cols);
    }
...

Потом в BlueJ выбираем Tools->Project Documentation и получаем документацию. Вряд ли там получится 100 страниц, но...
How to write Doc Comments for the Javadoc tool

--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 29.1.2009, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



С окошком наконец-то получилось .Я пробовала раньше setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); но это приводило к невозможности закрыть программу вообще . Теперь она закрылась   smile  

То что BlueJ делает документацию от нас естественно держат в секрете .
Хотя не думаю что это может помочь . То что они хотят это скорее реферат чем документация.
====================================================
Часть 1 : 
Описание проблемы , Use-Case Diagrams ( ещё не знаю что это такое , может быть это из UML ), причины по которым написание программы необходимо и возможные пути решения поставленной задачи.

Часть 2:
Описание использованных алгоритмов и их детальный дизайн ( псевдо-код или flow chart )

Часть 3 :
Описание применённых в программе принципов Обьектно-Ориентированного программирования и диаграммы классов .

Часть 4 :
Applications of Java APIs

Часть 5 :
Процедуры тестирования 

Часть 6 :
Solution Evaluation ,User Manual , Screenshoots

Приложение :
Исходный коде программы
==================================================

Приступаю к обдумываю первой части с использованием глаголов в будущем времени .Зачем писали программу ...в целях экономии бумаги школьниками smile



PM MAIL   Вверх
Qawra
Дата 29.1.2009, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Хотелось мне как-то выделить   точку  которая была поставленна последней.
Пока самое простое что пришло в голову это нарисовать у этой точки чёрный ободок. При небольшом дополнении к методу drawCircle
Код

public void   drawCircle (int  x,int   y,  Graphics g)
    {   
        g.setColor(color);
        g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
        g.setColor(new Color(0,0,0));
        g.drawOval(x- 8, y-8, (6*2)+2,(6*2)+2);
        g.setColor(color);
    }      
 такие ободки рисуются у всех точек . А надо что бы ободок изчезал как только поставлена следующая точка. Может быть вынести это в отдельный метод drawCircleNew  и вызывать только когда рисуется новая точка а затем перерисовывать с помощью :
Код

public void   drawCircle (int  x,int   y,  Graphics g)
    {   g.setColor(color);
        g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
    }  
     

PM MAIL   Вверх
Kakadu
Дата 29.1.2009, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



Насчет ободка предлагаю такое решение: добавим ещё одно поле а классе GridsCanvas и назовем его LastPoint. К классу DrawablePoint добавим метод "нарисовать ободок" и После перерисовки всех точек вызовем для последней точки рисование ободка.

У нас получается что поле характеризуется массивом точек, состояние которых описывается в поле color: 1)null - не точки: 2)Цвет 1го игрока - первый игрок, 3) 2го - второй. Мне не кажется это очень хорошим решением. Положим мы дошли до того некоторого места в написании проекта, и теперь нам предстоит заниматься замыканием контура. На сколько я помню игру "точки" замыкать контур можно, если замыканием отрезается область, содержащая хотя бы одну точку противника; при проведении границы мы не должны пересекать уже проведенных вражеских ребер. На текущем этапе проектирования нам придется вводить массив на ребра, находящиеся на поле (читайте хранить несвязный граф) и хранить, участвовала ли каждая точка в замыкании пути. ИМХО, мне это не нравится. Я бы оставил просто массив int равный размеру поля. Обходя его я бы рисовал каждую точку. (Возможно, после замыкания контура мы захотим наводить контур более жирной линией: тут начнутся проблемы. Мелочь типа наведения ободка на данном этапе легко добавляется, как добавить жирный контур мне пока не очевидно). Классы это, конечно грамотно, но... В принципе я с массивом погорячился: можно добавить в класс DrawablePoint атрибут, принадлежит ли она какому-нить замыканию.

Что будем делать, когда игрок делает ход? Тут надо привести нетривиальный алгоритм поиска замыкания. Как известно из курса мат. анализа, положительным направлением обхода контура будет такое направление при котором внешняя нормаль в данной точке границы контура при повороте по часовой стрелке (читайте при умножении на матрицу 2х2: (0 -1 1 0) ) совпадает с направлением касательной, т.е. с направлением движения. 

Итак, мы имеем точку, в которую только что кликнули. окрестные 8 точек можно воспринимать как циклически замкнутую строку (в принципе это даже не так важно). 
Нада какой-нить пример:
Код

110
011
100

вот наши 9 точек, в центр только что нажали. окружность разобьется на две группы точек: {(2,0)} и {(0,0),(0,1),(1,2)}. Проверять, что центральная точка вместе с верхними тремя замкнет контур не нужно, так как мы это уже делали, когда добавляли эти три точки (некая индукция, если рассуждать в терминах математики). значит мы должны проверить не замкнет ли центральная верхние три с нижней. далее мы выберем одно из 4х стартовых направлений (т.к. суммарное кол-во точек в обеих группах=4) и будем так же выбирать направление со следующими точками. При этом  надо маркировать (где-то хранить точки пути)

Кажется я начинаю запутываться.
Извините за этот бред, надеюсь я никого не напугал нашими перспективами.
Сам я Java не изучал (настала пора начинать!), но морской бой в Дельфях написать  могу. Постараюсь помочь в написании этой дикой вещи.


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Rpahut
Дата 30.1.2009, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата(Qawra)

Хотелось мне как-то выделить   точку  которая была поставленна последней.

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

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

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

Поиск контура и захваченных точек задумывался при помощи рекурсии, поскольку рекурсия мне роднее матана smile 
Используются следующие идеи:
1. Если из всех соединенных друг с другом точек выкинуть тупиковые (т.е. имеющие максимум одно нетупиковое соединение) точки, то что останется и будет замкнутым контуром.
2. Построив после этого прямоугольную границу вокруг контурных точек и расширив ее на одну клетку в каждую сторону, можно из внешней части запустить поиск, который, теоретически, найдет все точки вне контура. Сейчас я, кажется, вижу в этом пункте одну серьезную дырку... Также, кажется, я вижу как ее заделать smile 
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 30.1.2009, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Самое лучшее описание алгоритма я видела здесь 
http://pointsxt.logicsworld.net/forum/index.php?showtopic=69
К сожалению регистрация на форуме не работает ( как видимо и сам форум ).
PM MAIL   Вверх
Kakadu
Дата 30.1.2009, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



А мне не понятно зачем выделение последней точки каждого игрока smile Вот посмотришь ты с этим выделением на поле и будет тебе непонятно чей ход. А если одна только точка выделена, то всё очевидно.
Вообще это мелочи. Надо замыкание срочно писать.


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Qawra
Дата 30.1.2009, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Расказываю и показываю  как я последнию точку выделила   smile
Много мучалась потому что ободок зарисовывался цветом игрока .
Пришлось вводить private boolean lastPoint
  два классах подкорректированы 
Код

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

class GridsCanvas extends JPanel{

     public int rows=20;
     public int cols=20;
     public int cellSize=30 ;
     private Color color;
     private DrawablePoint points[][]; // array to hold all possible  points
     
       
    GridsCanvas(int r, int c,int cellSize) {
        this.rows = r;
        this.cols = c;
        this.cellSize=cellSize;
        setVisible(true);
        
        setPreferredSize(new Dimension( (c+1)*cellSize, (r+1)*cellSize )); // we make our window bigger than grid to have extra place and easier access to the points on the edge of the grids
        points = new DrawablePoint[cols][rows];
        makePoints(rows,cols);
    }

    public void paintComponent(Graphics g) {
        
        g.translate(cellSize, cellSize); //we move the grid rigt and down on the distance of the cellSize
        
        for (int i = 0; i < rows; i++)
             g.drawLine( i * cellSize, rows*cellSize-cellSize,  i * cellSize,0 );//g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);
            
        for (int j = 0; j < cols; j++)
            g.drawLine(0, cellSize*j, cols*cellSize-cellSize, cellSize*j); // g.drawLine(j * cellSize, rows*cellSize,  j * cellSize,0);
            
        for(int y=0; y<cols; y++) {
          for(int x=0; x<rows; x++) {
              
              points[x][y].paint(field2screen(x), field2screen(y), g);  //  displays   points     
           }
          }
         g.translate(-cellSize, -cellSize);
       }
     
     public void makePoints ( int rows , int cols)
      {  for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) 
             {  points[x][y] = new DrawablePoint( color); // create  all points    
            }      
          }
         }
     public boolean mouseWasClicked(int x, int y, Color playerColor) // accepts coordinates and the playerColor of the mouse click
     { 
         int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);
         boolean ok = false;
         if( goodCoords(pointX, pointY) ) {
                ok = points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color show that the point is occupied by player    
            }
        // else - do nothing if coorditates is not good 
               return ok;
     }
     
     private boolean goodCoords(int fieldX, int fieldY) {
       /*if X is zero or positive and  if Y is zero or positive and  if X is less than field width and  if Y is less than field height...
       we can use   coordinates of the mouse click */
       if(fieldX>=0 && fieldY>=0 && fieldX<cols && fieldY<rows)  // ...good coordinates
       return true;

       else //  bad coordinates which dive  ArrayIndexOutOfBoundsException
       return false;
       }
   
     private int screen2field(int coord) { // screen to field convert coordinates
       return (coord-cellSize/2) /cellSize; // shift  coordinates of the click by half cellSize to draw points on the corners of the grids  
      }

     private int field2screen(int coord) { // field to screen  convert coordinates
       return coord*cellSize;
      }
  }


и
Код

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;

class DrawablePoint 
{

    private Color color;
    public  int radius;
    private int x;
    private int y;
    private Graphics g;
    private boolean lastPoint;
    
    DrawablePoint(Color color) 
    {
        this.color = color ;
        radius = 6;
        lastPoint = true;
    }
    public void   paint (int  x,int   y,  Graphics g)
    {   
        this.x = x;
        this.y = y;
        this.g = g;

        g.setColor(color);          
        if(color==null) {
            
        }
        else {
            if (lastPoint) {
              drawOutline(x,y);
              lastPoint = false;
            }
            drawCircle(x, y, g); // pass  x, y ,Graphics  g   and draw the points         
        }  
 }
    public void   drawCircle (int  x,int   y,  Graphics g)
    {   
        this.g = g;
        g.setColor(color);
        g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
    }  
     
    public void drawOutline(int x, int y){        
        this.g.setColor(new Color(0,0,0));
        this.g.drawOval(x- 8, y-8, (6*2)+2,(6*2)+2);
        this.g.setColor(color);
    }
    
    public boolean setNewColor(Color playerColor) { // accepts new color
        if(color!=null) // color is changed already
         return false; // do nothing and return false
        color = playerColor; // changes color
         return true;
   }
   
   public int getX(){
       return x;
    }
    
    public int getY(){
        return y;
    }
   
    public Graphics getGraphics(){
        return g;
    }
    
    public boolean isDrawn(){
        return lastPoint;
    }
   
}








Это сообщение отредактировал(а) Qawra - 30.1.2009, 17:48
PM MAIL   Вверх
Rpahut
Дата 30.1.2009, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

будет тебе непонятно чей ход

А ну если в этом смысле... тогда вообще можно надпись сделать вроде "Ход игрока 1" и "Ход игрока 2". Заголовок окна менять например.

Добавлено @ 18:59
Qawra, хитро smile 
Ну это можно убрать:
Код

   this.g = g;

и передавать Graphics прямо в метод:
Код

public void drawOutline(int x, int y, Graphics g){
   g.setColor(Color.black);//g.setColor(new Color(0,0,0));
...

Ни к чему нам плодить ненужные переменные класса.

Это сообщение отредактировал(а) Rpahut - 30.1.2009, 19:01
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Rpahut
Дата 30.1.2009, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Сейчас думаю как организовать соединение точек.

Вообще нужно решить три задачи:
1. Как хранить соединение
2. Как создавать соединение
3. Как отображать соединение

Хранить соединения лучше всего внутри класса DrawablePoint, потому как "соединенность" с другой точкой - это свойство самой точки. Для дальнейшей обработки удобнее хранить их в виде массива DrawablePoint размером [8](максимальное количество соединений у каждой точки). Каждый элемент этого массива будет тогда либо содержать null, либо хранить Точку, с которой у данной точки есть соединение.

Создание соединений обязан выполнять класс GridsCanvas - именно в нем хранится поле, что позволяет нам рассмотреть каждую из соседних точек и определить необходимость соединения. В класс DrawablePoint нужно добавить метод connectTo(DrawablePoint p) чтобы можно было сохранить найденное соединение внутри Точки.

Отображение соединений опять же возлагается на DrawablePoint. Единственное что для его реализации Точка должна знать свои собственные экранные координаты и иметь возможность получить координаты точек с которыми она соединена(для использования drawLine()). Из этих соображений нужно переделать конструктор класса DrawablePoint так, чтобы он принимал не Цвет, а экранные координаты Точки. Тем более что в качестве цвета в конструктор сейчас мы передаем всегда null - можно обойтись без передачи этого параметра. Тем более что в классе уже есть переменные int x, y которые нигде не используются. Тем более что мы рассчитываем и передаем экранные координаты точки каждый раз когда нужно ее нарисовать, хотя они всегда одинаковые и можно рассчитать их один раз.
Еще у Точки должны быть методы
public int getX();
public int getY();
которые позволят получить ее экранные координаты.

====================
Итак:

Добавляем в члены класса DrawablePoint массив
Код

private DrawablePoint connectedTo[] = new DrawablePoint[8];


Модифицируем конструктор DrawablePoint:
Код

    public DrawablePoint(int sx, int sy)
    {
        x = sx;
        y = sy;
        radius = 6;

    }


Добавляем в DrawablePoint методы для получения ее координат:
Код

    public int getX() {
        return x;
    }
    public int getY() {
        return Y;
    }


Добавляем drawConnections() и используем его в DrawablePoint.paint():
Код

    private void drawConnections(Graphics g) {
        DrawablePoint B;

        for(int i=0; i<8; i++) { // for each from connectedTo[]
            B = connectedTo[i];
            if(B==null) break; // if no more points - end loop
            g.drawLine(x, y, B.getX(), B.getY()); // draw line from this point to B point
        }
    }

    public void paint (Graphics g) // x and y is now stored within class
    {   
        g.setColor(color);          
        if(color==null) {
            
        }
        else {
            drawConnections(g); // <- display all connections of this point
            if (lastPoint) {
              drawOutline(x, y, g);
              lastPoint = false;
            }
            drawCircle(x, y, g); // pass  x, y ,Graphics  g   and draw the points         
        }  
     }


=====================
Вторичные изменения:
Поскольку мы изменили код конструктора Точки, создавать точки теперь тоже нужно по-другому:
Код

     public void makePoints ( int rows , int cols)
     {
          for(int y=0; y<cols; y++) {
               for(int x=0; x<rows; x++) {
                    // pass screen coords to point constructor
                    points[x][y] = new DrawablePoint( field2screen(x), field2screen(y) ); // create  all points    
               }      
          }
     }


То же самое с кодом отрисовки - экранные координаты точки теперь хранятся внутри нее и передавать их в paint() не нужно:
Код

     public void paintComponent(Graphics g) {
          g.translate(cellSize, cellSize); //we move the grid rigt and down on the distance of the cellSize

          for (int i = 0; i < rows; i++)
               g.drawLine( i * cellSize, rows*cellSize-cellSize,  i * cellSize,0 );//g.drawLine(0, cellSize*i, cols*cellSize, cellSize*i);

          for (int j = 0; j < cols; j++)
               g.drawLine(0, cellSize*j, cols*cellSize-cellSize, cellSize*j); // g.drawLine(j * cellSize, rows*cellSize,  j * cellSize,0);

          for(int y=0; y<cols; y++) {
               for(int x=0; x<rows; x++) {
                    points[x][y].paint(g);  //  displays   points     
               }
          }
          g.translate(-cellSize, -cellSize);
     }


==================
Кажется ничего не забыл.
Думаю дальше над созданием соединений.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Kakadu
Дата 31.1.2009, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



Гм, Уважаемая. Мне такой подход в наведении окаёма вокруг точек кажется несколько подозрительным, как по мне то нелогично для каждой точки добавлять переменную, показывающую последняя ли она, когда по логике игры таких точек будет максимум две. (Логично ссылки на эти точки вынести полем класса DrawablePoint) Но я поверил наслово, скопипастил и убедился, что указанное выше не очень работает.
Собственно, у меня вопрос. Где вы присваиваете какой-нить точке true в поле для рисования окаёма?

P.S. Мне долго надоедало, что если я нажал мышку, немного её подвигал и точка не ставилась. Теперь я всё, что было написано в MouseClicked переписал в MouseRealeased. Предлагаю автору сделать также.

Это сообщение отредактировал(а) Kakadu - 31.1.2009, 15:00


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Qawra
Дата 31.1.2009, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



А зачем вы нажали мышку и немного подвигали ?  Вы же не рисовать собирались а территорию захватывать smile
Ваш метод рисования ободка я воплотить пыталась но у меня не получилось .Очень бы хотелось взглянуть на код . Буду очень вам признательна если вы его опубликуете и обьясните как он работает .

У нас сейчас с замыканием поля много работы . Я внесла последнии изменения и там есть одно узкое место в paintComponent
Код

public void paintComponent(Graphics g) {
          g.translate(cellSize, cellSize); //we move the grid right and down on the distance of the cellSize

          for (int i = 0; i < rows; i++)
               g.drawLine( i * cellSize, rows*cellSize-cellSize,  i * cellSize,0 );

          for (int j = 0; j < cols; j++)
               g.drawLine(0, cellSize*j, cols*cellSize-cellSize, cellSize*j); 

          for(int y=0; y<cols; y++) {
               for(int x=0; x<rows; x++) {
                    points[x][y].paint(g);  //  displays   points     
               }
          }
          g.translate(-cellSize, -cellSize);
     }
строчка points[x][y].paint(g);  не компелируется 
пишет что не может быть применена к  paint (int  ,int , java.awt.Graphics ) я подставила x и y .Строчка 
Код
points[x][y].paint(x,y,g);
 скомпелировалась нормально . Не факт что я сделала правильно потому что 
начались 

Код

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at DrawablePoint.drawOutline(DrawablePoint.java:49)
    at DrawablePoint.paint(DrawablePoint.java:33)
    at GridsCanvas.paintComponent(GridsCanvas.java:38)
    at javax.swing.JComponent.paint(JComponent.java:1027)
    at javax.swing.JComponent.paintChildren(JComponent.java:864)
    at javax.swing.JComponent.paint(JComponent.java:1036)
    at javax.swing.JComponent.paintChildren(JComponent.java:864)
    at javax.swing.JComponent.paint(JComponent.java:1036)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:564)
    at javax.swing.JComponent.paintChildren(JComponent.java:864)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5129)
    at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:285)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1128)
    at javax.swing.JComponent.paint(JComponent.java:1013)
    at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
    at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
    at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
    at java.awt.Container.paint(Container.java:1797)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:734)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:679)
    at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:659)
    at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:128)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

  если строчку просто отключить то всё компелируется  . Но NullPointerException  остаётся и точки не прорисовываются.

Создаю  сейчас документацию . Use Case Diagram для нашей игры оказалась совсем несложная . user posted image

PM MAIL   Вверх
Rpahut
Дата 31.1.2009, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Цитата

Мне долго надоедало, что если я нажал мышку, немного её подвигал и точка не ставилась. Теперь я всё, что было написано в MouseClicked переписал в MouseRealeased.

Да есть такой момент - но это на мой взгляд вопрос "доводки" игры и решать его именно сейчас, да и решать вообще, мне кажется нет необходимости.
Вообще, если по-хорошему делать, надо запоминать где была нажата кнопка мыши, и если указатель не уходил слишком далеко от этого места, засчитывать отпускание как клик в Точку. Можно и просто следить чтобы нажатие и отпускание было в пределах одной Точки.

Цитата

строчка points[x][y].paint(g);  не компелируется 
пишет что не может быть применена к  paint (int  ,int , java.awt.Graphics ) 

Правильно пишет.
Очевидно метод paint() все еще не исправлен. Он должен начинаться вот так:
Код

    public void paint (Graphics g) // note method parameters; x and y is now stored within class
    {
...


Цитата

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

Нужно код посмотреть. Скорее всего проблема в this.g или может в setColor(color);

Кстати, расшифровка сообщения об ошибке:
Цитата

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at DrawablePoint.drawOutline(DrawablePoint.java:49)         // ошибка в DrawablePoint.drawOutline(); файл DrawablePoint.java строка 49

Смотрите в эту строку и ищите что там не так.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 31.1.2009, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Вы были правы . Я исправила в двух местах this.g на g  и всё нормально заработало . 
Код

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;

class DrawablePoint 
{

    private Color color;
    public  int radius;
    private int x;
    private int y;
    private Graphics g;
    private boolean lastPoint;
    
    private DrawablePoint connectedTo[] = new DrawablePoint[8];   // array  to keep information about points  around each point .
    
    DrawablePoint(int sx, int sy) 
    {
        
        x = sx;
        y = sy;
        radius = 6;
        lastPoint = true;
    }
    public void   paint (  Graphics g)// x and y coordinates are  stored within class
    {  
        g.setColor(color);          
        if(color==null) {
            
        }
        else {
            drawConnections(g); //  display all connections of this point
            if (lastPoint) {
              drawOutline(x,y,g);
              lastPoint = false;
            }
            drawCircle(x, y, g); // pass  x, y ,Graphics  g   and draw the points         
        }  
 }
    
    public void   drawCircle (int  x,int   y,  Graphics g)
    {   
        
        g.setColor(color);
        g.fillOval(x - 6, y - 6, 6 * 2, 6 * 2); 
    }  
     
    public void drawOutline(int x, int y, Graphics g){        
       
        g.setColor(Color.black);
        g.drawOval(x- 8, y-8, (6*2)+2,(6*2)+2);
        g.setColor(color);
    }
    
    public boolean setNewColor(Color playerColor) { // accepts new color
        if(color!=null) // if  color is changed already
         return false; // do nothing and return false
        color = playerColor; // changes color
         return true;
   }
   
   private void drawConnections(Graphics g) {
          DrawablePoint B;

        for(int i=0; i<8; i++) { // for each point  from  connectedTo[]
            B = connectedTo[i];
            if(B==null) break; // if no more points - end loop
            g.drawLine(x, y, B.getX(), B.getY()); // draw line from this point to B point
        }
    }
   
   public int getX(){
       return x;
    }
    
    public int getY(){
        return y;
    }
    
   
    public Graphics getGraphics(){
        return g;
    }
    
    public boolean isDrawn(){
        return lastPoint;
    }
   
}

PM MAIL   Вверх
Kakadu
Дата 2.2.2009, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



user posted image
Я тут кое-что состряпал. Правда пришлось несколько изменить количество классов и логику. Ну да ладно, потом распишу, если будут вопросы.

P.S. прикрепляю исходники на NetBeans.

Это сообщение отредактировал(а) Kakadu - 2.2.2009, 14:08

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  Faraon.zip 41,51 Kb


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Qawra
Дата 2.2.2009, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Cочетание цветов понравилось . В нём что-то есть . У меня к сожалению нет  NetBeans  . Поэтому я просто запустила jar файл и покликала мышкой .
Точки были а крестиков небыло ... Но всё равно неплохо .  
Какие идеи о замыкании поля ?



Это сообщение отредактировал(а) Qawra - 2.2.2009, 20:31
PM MAIL   Вверх
Rpahut
Дата 2.2.2009, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Крестиков в самом деле почему-то нет. В jikes собрать не получилось, качаю Сеть-Бобы.

Кстати, тут та же дырка, что и в моей версии smile :
user posted image
Верхняя красная точка будет считаться захваченной, потому что волна от нее пойдет только по вертикали и горизонтали и до края поля не доберется.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 2.2.2009, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Я поняла что если линии начать рисовать до того как контур можно  замкнуть то играть не получиться . Они будут мешать искать замыкания . Красная линия автоматом соединилась ?
PM MAIL   Вверх
Rpahut
Дата 2.2.2009, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Создание соединений

Создаваться соединения будут в mouseWasClicked(), но сначала подготовим почву.
От Точки нам нужны следующие методы:
Код

// не помню создавали мы его уже или нет
   /**
   * Get point color
   */
   Color getColor() {
      return color;
   }

Код

   /** connect this point to point p
   * @param p DrawablePoint this point should be connected to
   */
   void connectTo(DrawablePoint p) {
      for(int i=0; i<8; i++) {
         if(connectedTo[i]==p) return; // return if already connected to p
         if(connectedTo[i]==null) {
            connectedTo[i] = p; // write p to connectedTo[] array
            return;
         }
      }
   }

Код

   /**
   * check if this point is connected to point p
   * @param p DrawablePoint to be checked
   */
   boolean isConnectedTo(DrawablePoint p) {
      for(int i=0; i<8; i++) {
         if(connectedTo[i] == p) return true; // yes, its connected
      }
      return false; // no its not
   }


Дальше можно вставлять метод создания соединений в GridsCanvas
Код

    /**
    * Create connections for point
    * @param px point x coord
    * @param py point y coord
    */
    private void makeConnections(int px, int py) {
        DrawablePoint a, b;

        a = points[px][py]; // a - current point

        // for all eight points around current point
        for(int j=-1; j<=1; j++) {
            for(int i=-1; i<=1; i++) {
                if( goodCoords(px+i, py+j) ) {
                    b = points[px+i][py+j]; // b - point to check
                    // if not current point but have same color
                    if(a!=b && b.getColor() == a.getColor()) {
                        // if no another diagonal connection in this cell already exists
                        if( !points[px][py+j].isConnectedTo(points[px+i][py]) ) {
                            a.connectTo(b); // connect a to b
                            b.connectTo(a); // connect b to a
                        }
                    }
                } // if goodcoords end
            } // loop i end
        } // loop j end

    }

Используем его в mouseWasClicked():
Код

...
                ok = points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color
                if(ok) {
                    // if color changed - create connections for this point
                    makeConnections(pointX, pointY);
               }
...


Добавлено через 9 минут и 11 секунд
Qawra, да, между соседними точками автоматически образуется соединение, если этому ничего не мешает.
Если в клетке уже есть одно диагональное соединение, то второе там уже не образуется. Это как раз правильно - просто при проверке захвата нам надо будет поиск по другому как-то делать.

user posted image
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Rpahut
Дата 3.2.2009, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Пояснения по поводу создания соединений:
После щелчка пользователя в точку, если ее цвет успешно изменился, мы перебираем все точки рядом с ней. Если цвет соседней точки совпадает с цветом нашей точки, мы их соединяем друг с другом. Так же, чтобы программа не падала, каждый раз проверяются координаты точки (goodCoords()), и если мы соединяем по диагонали, проверяем чтобы в клетке небыло другого диагонального соединения:
Код

if( !points[px][py+j].isConnectedTo(points[px+i][py]) ) {

--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 3.2.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Как интересно получилось ! Мне нравиться ! Можно будет ещё соединяющие линии потолще сделать и цветом заливать захваченную территорию . Совершенно другое ощущение от игры . Не надо ждать пока вражеские точки в плен попадуться . Динамично отхватываешь по кусочку территории и душа радуется smile
Не знаю как увеличить толщину линий .Залить территорию можно с Graphics FillPolygon . Только где его прописать ...В makeConnections ?

Для меня удивительно что компайлер понимает что такое 
Код
a = points[px][py];
  вы уже обьяснили  что  px и  py  это координаты точки p 
Но если бы меня попросили их заранее написать я бы их написала через точку p.x  и p.y    (что выглядит немного странно ) . . 
Теоретически , p   -  это обьект , а координаты это его свойства - поэтому я бы их написала  через точку ...   В каких случаях можно обойтись без точки ?

Буду пробовать изобразить алгоритм графически используя flow chart ... хотя нет ...oн слишком сложный что бы сразу рисовать диаграмму   .Надо сначала в псевдо-коде его описать . 


Это сообщение отредактировал(а) Qawra - 3.2.2009, 14:58
PM MAIL   Вверх
Rpahut
Дата 3.2.2009, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



px и py имеют тип int - это видно там где они созданы:
Код

    private void makeConnections(int px, int py) {

int тоже объект, но объект примитивного типа - т.е. он встроен в сам язык программирования и имеет только одно свойство - значение. Поэтому к этому свойству можно добраться без точки.
Объект DrawablePoint мы создавали сами - написали класс, его переменные и методы, с помощью которых с ним можно что-то делать. К переменным и методам как раз обращение идет через точку.
Код

DrawablePoint p;
int px, py;
...
px = p.getX();
py = p.getY();


Как линии сделать толще я тоже не знаю. Не говоря уж о заливке.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 4.2.2009, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Линии толще  оказывается сделать нельзя . Я попробовала  нарисовать сразу несколько линий вместо одной
и у меня получились такие " гантельки " . 
user posted image
Сейчас  диагональные линии  имеют расширения на концах .
user posted image Пускай  будут  оригинально - диагональными smile







Это сообщение отредактировал(а) Qawra - 4.2.2009, 18:02
PM MAIL   Вверх
Rpahut
Дата 5.2.2009, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



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

1. Добавляем в DrawablePoint:
Код

   // new private member
   private Color captured;

...
   /** Remember who captured this point
   * @param by color of player who captured the point
   */
   void setCaptured(Color by) {
      captured = by; // point is now captured by color 'by'
   }

   /** Get color of player who captured this point
   * @return color of player who captured point, or null
   */
   Color getCaptured() {
      return captured;
   }


2. Добавляем в GridsCanvas массив - член класса:
Код

     private boolean wasHere[][]; // visited points map


3. !!! Рекурсивная ф-ция определения захваченности точки !!!:
Код

     /** Check if point is inside of contour
     * @param px x coord of point to check
     * @param py y coord of point to check
     * @param myColor color of player who set last point
     * @return one of three values: -1 - ignore point; 1 - point captured; 0 - point not captured
     */
     int pointCaptured(int px, int py, Color myColor) {
          // if point is on field
          if(goodCoords(px, py)) {
               if(wasHere[px][py] || // if already was here...
                  (points[px][py].getColor()==myColor && points[px][py].getCaptured()==null) ) // ...or point belongs to current player and not captured
                        return -1; // not interesting

               wasHere[px][py] = true; // mark point as visited

               // recursive call to this method:
               if( pointCaptured(px+1, py, myColor)==0 ) return 0; // right
               if( pointCaptured(px-1, py, myColor)==0 ) return 0; // left
               if( pointCaptured(px, py+1, myColor)==0 ) return 0; // down
               if( pointCaptured(px, py-1, myColor)==0 ) return 0; // up

               // diagonally
               if( !points[px+1][py].isConnectedTo(points[px][py+1]) ) { // if no another diagonal connection...
                   if( pointCaptured(px+1, py+1, myColor)==0 ) return 0; // right-down
               }
               if( !points[px+1][py].isConnectedTo(points[px][py-1]) ) { // --//--
                   if( pointCaptured(px+1, py-1, myColor)==0 ) return 0; // right-up
               }
               if( !points[px-1][py].isConnectedTo(points[px][py-1]) ) { // --//--
                   if( pointCaptured(px-1, py-1, myColor)==0 ) return 0; // left-up
               }
               if( !points[px-1][py].isConnectedTo(points[px][py+1]) ) { // --//--
                   if( pointCaptured(px-1, py+1, myColor)==0 ) return 0; // left-down
               }

               // none of prevous methods returned zero
               return 1; // point is captured
          }
          return 0; // field border reached, point not captured
     }

Тут много буков, но это из за повторяющегося кода. Разберем позже.

4. Добавляем в mouseWasClicked():
Код

                if(ok) {
                    // if color changed
                    makeConnections(pointX, pointY);

                    // new code goes here
                    for(int j=0; j<rows; j++) { // for-all-points loop
                        for(int i=0; i<cols; i++) {
                            wasHere = new boolean[cols][rows]; // clear visited points map
                            if( pointCaptured(i, j, playerColor)==1 ) { // if point is actually captured by current player
                                points[i][j].setCaptured(playerColor); // set it to be captured
                            }
                        }
                    }
               }


--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Rpahut
Дата 5.2.2009, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



______________________________________________
Qawra, вы рекурсию проходили?

Тут в общем смысл в том что метод pointCaptured() вызывает сам себя, но с другими параметрами, для соседних точек. И вызывает до тех пор, пока не убедится что наша точка внутри контура, или наоборот не внутри... Если точка внутри замкнутого контура, то от нее нельзя прошагать до края поля, не наткнувшись на контур. Если мы добрались до края поля, значит контура вокруг точки нет.

Что важно для рекурсивного кода - это чтобы он не вызывал сам себя до бесконечности, иначе мы никогда не дождемся результатов проверки smile Поэтому есть массив wasHere[][], спертый у Kakadu, в котором мы отмечаем пройденные точки и не проверяем их повторно:
Код

               if(wasHere[px][py] || // if already was here...

Вторая половина проверки
Код

                  (points[px][py].getColor()==myColor && points[px][py].getCaptured()==null) )

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


Если мы на этой точке еще не были и если это не граница, помечаем точку
Код

               wasHere[px][py] = true; // mark point as visited

и вызываем pointCaptured() для соседних точек - сначала для точек по горизонтали и вертикали:
Код

               if( pointCaptured(px+1, py, myColor)==0 ) return 0; // right
               if( pointCaptured(px-1, py, myColor)==0 ) return 0; // left
// и т.д. ...

Они тоже вызывают pointCaptured() для своих соседних точек, и те для своих тоже, и так пока есть непроверенные точки.


Правда, если в какой-то момент pointCaptured() будет вызван для точки за пределами поля, то он вернет ноль - тогда в одной из этих строчек сработает проверка, например тут:
Код

if( pointCaptured(px+1, py, myColor)==0 ) return 0; // если нам вернули ноль, тоже возвращаем ноль

В этом случае поиск завершается досрочно - ноль возвращается и возвращается, пока не попадет к нам в руки, сюда:
Код

                            if( pointCaptured(i, j, playerColor)==1 ) { // 0==1? нет! точка не захвачена

откуда мы метод и вызываем.


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

               // none of prevous methods returned zero
               return 1; // point is captured
          }

Единица опять же возвращается сюда
Код

                            if( pointCaptured(i, j, playerColor)==1 ) { // 1==1 - точка захвачена

и так мы понимаем, что точка захвачена.

__________________
Там возможен еще третий вариант - когда точка принадлежит текущему игроку, метод возвращает -1. Так что игрок может захватить собственные точки, только если перед этим они были захвачены другим игроком. Пока не знаю как от этого избавиться.

__________________
В методе pointCaptured() помимо соседних точек по горизонтали и вертикали проверяются еще и точки по диагонали. Как выяснилось это необходимо. Перед этим дополнительно проверяется, нет ли на пути диагональной границы, в остальном здесь то же что и выше.
Код

               if( !points[px+1][py].isConnectedTo(points[px][py+1]) ) { // if no diagonal connection...
                   if( pointCaptured(px+1, py+1, myColor)==0 ) return 0; // right-down
               }
...

--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 5.2.2009, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



3 пункт добавляем в GridCanvas ? Я пока его туда определила ..

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



Это сообщение отредактировал(а) Qawra - 6.2.2009, 00:01
PM MAIL   Вверх
Rpahut
Дата 5.2.2009, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Теорию графов я еще и сам не проходил. Переделаем в следующем году smile 

Да, pointCaptured() должен быть в GridsCanvas - он ведь там и используется.

ЗЫ
Если будут вопросы - задавайте. Разберемся с этим и займемся доводкой программы.

ЗЫЗЫ
Метод pointCaptured() должен быть private. Куда мои глаза глядели...

Это сообщение отредактировал(а) Rpahut - 6.2.2009, 00:00
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 6.2.2009, 00:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Всё скомпелировалось но с функциональной стороны  изменения не заметны . 
Захватываем всё !  И точки ... и пустую территорию ! Ни от чего не отказываемся !

Не знаю точно какой язык будем в следующем году изучать . Звучит как Императивное и обьектно - ориентированное программирование . Наверно С и С++
Видела студентка у них ( на курс старше ) проект  "виртуальное пианино" писала и  страдала что  ей плохо от запоздалой нотной грамотности smile
Значит зададут нам что-то связаное с мультимедия  . 

Это сообщение отредактировал(а) Qawra - 6.2.2009, 00:18
PM MAIL   Вверх
Rpahut
Дата 6.2.2009, 00:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Чтоб было видно изменения, нужно править DrawablePoint.paint() - учесть в коде значение переменной captured и менять отображение точки.
Тут очень много вариантов, как выделять захваченные точки, так что конкретного решения не предлагаю.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 7.2.2009, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Я пока пытаюсь нарисовать flowchart к алгоритмам .

не умею прикреплять большую картинку , даю ссылку не неё 
http://img6.imageshack.us/my.php?image=flowchart2an6.png
Это ещё не реккурсивный зверь . Это тот playerColor о который я так часто спотыкалась smile

Это сообщение отредактировал(а) Qawra - 7.2.2009, 17:54
PM MAIL   Вверх
Kakadu
Дата 9.2.2009, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



Нада мне вас догонять=) Вот выкладываю свое творение.


Присоединённый файл ( Кол-во скачиваний: 10 )
Присоединённый файл  Faraon.zip 52,62 Kb


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Rpahut
Дата 10.2.2009, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Куда ближе к оригинальным правилам smile 

Qawra, как там у вас дела?
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 10.2.2009, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Я пока  медленно схожу с ума  от  Сlass  диаграмм  ...   

Наверно поэтому у меня в последней версии Какаду  линии не рисуются  smile 
PM MAIL   Вверх
Rpahut
Дата 10.2.2009, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Вот собранная версия.

Присоединённый файл ( Кол-во скачиваний: 15 )
Присоединённый файл  Faraon.jar 22,42 Kb
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 10.2.2009, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



У меня не скачивается а открывается..  но при этом ничего не понятно ...

Мы когда в Grid Canvas метод makeConnections прописылали
Код

private void makeConnections(int px, int py) // create connection for the point ,px point x coordinate,py point y coordinate
    {
        DrawablePoint a, b;

        a = points[px][py]; // a - current point

        // for all eight points around current point
        for(int j=-1; j<=1; j++) {
            for(int i=-1; i<=1; i++) {
                if( goodCoords(px+i, py+j) ) {
                    b = points[px+i][py+j]; // b - point to check
                    // if not current point but have same color
                    if(a!=b && b.getColor() == a.getColor()) {
                        // if no another diagonal connection in this cell already exists
                        if( !points[px][py+j].isConnectedTo(points[px+i][py]) ) {
                            a.connectTo(b); // connect a to b
                            b.connectTo(a); // connect b to a
                        }

for(int j=-1; j<=1; j++) {
            for(int i=-1; i<=1; i++) {
 был для зазора в координатах ?

пытаюсь сейчас весь алгоритм рисования линий с начала до конца проследить и словами связно  его обьяснить . пока он у меня идёт от DrawablePoint  к mouseWasClicked . А надо бы наоборот  smile  


Это сообщение отредактировал(а) Qawra - 10.2.2009, 23:34
PM MAIL   Вверх
Kakadu
Дата 10.2.2009, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



Мда, перебилдить забыл, когда архивировал. Извини Qawra.

(Я тут заметил, что с проектированием интерфейса у меня какие-то заморочки. Надо книжку про Swing подчитать. Обидно только, что в четверг уже начинается универ.)

Я вам скажу, Rpahut, что это прикольно придумано так просматривать окружающие точки вложенными циклами от -1 до 1. smile  Максимум на что меня хватило, это создать константный массив из 8 пар приращений к координатам, чтобы просматривать окружающие точки. Или я уже отошел от этого способа... не помню...

Интересно, вы пробовали читать мой код? Мне кажется, что отойдя от строго использования классов при описании поля я нарушил читабельность кода. Вернее, не читабельность, а наглядность реализации идеи... Наверное это не очень хорошо. Можете как-то прокомментировать?


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Qawra
Дата 11.2.2009, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



у меня к сожалению классы не открываются ( программы нет нужной )
поэтому я не смогу код посмотреть и прокоментировать :(
PM MAIL   Вверх
Rpahut
Дата 11.2.2009, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Qawra, исходный код можно посмотреть в архиве который выкладывал Kakadu, файлы с расширением .java . Я выложил только саму программу - архив нужно как есть сохранить на компьютер, щелкнуть его второй кнопкой и выбрать "Открыть с помощью"->Java.
BlueJ кстати тоже умеет так упаковывать, программу вместе с исходными кодами и документацией, или без них.


_______________________________
Цитата

пытаюсь сейчас весь алгоритм рисования линий с начала до конца проследить и словами связно  его обьяснить . пока он у меня идёт от DrawablePoint  к mouseWasClicked . А надо бы наоборот  smile  

Вот это я не совсем понял smile Но тем не менее:
В жизни соединений происходит два важных события - это создание и отрисовка.
Поскольку новые соединения могут образоваться только после добавления новой точки, мы вызываем makeConnections() из mouseWasClicked(), когда известно что точка добавлена. Соединения обнаруживаются и сохраняются в точках.
Отрисовка соединений происходит вместе с отрисовкой точки, что в свою очередь происходит при отрисовке поля.

Попробую запутать вас совсем:
_____________________________
Этот цикл перебирает все точки вокруг проверяемой:
Код

for(int j=-1; j<=1; j++) {
   for(int i=-1; i<=1; i++) {
...

i и j меняют в цикле свои значения от -1 до 1; если i прибавлять к x-координате проверяемой точки, то мы получим х-координату точки слева от проверяемой( х+(-1)=х-1 ), потом с такой же координатой (х+0=х), потом координату точки справа (х+1). Аналогично для координаты y и переменной j.
Все вместе позволяет перебрать точки в таком порядке:
123
456
789
Красным отмечена проверяемая точка.

Внутри циклов выполняется несколько проверок - они необходимы чтобы определить две вещи: необходимость и возможность соединения.
Код

if( goodCoords(px+i, py+j) ) {

Первое что мы проверяем, это не выпали ли наши координаты (x+i и y+j) за пределы поля; не рекомендуется работать с массивом за его пределами smile Конечно, если соседняя точка за пределами поля, т.е. на самом деле не существует, с ней не может быть соединения, спокойно можно ее пропускать и искать дальше. Иначе - есть возможность соединения.
Код

b = points[px+i][py+j];

Здесь не совсем проверка. Просто, поскольку дальше мы несколько раз обращаемся к соседней точке, удобнее выложить ее во временную переменную, тогда нам не нужно будет дальше использовать страшное "points[px+i][py+j]" а вместо него использовать b. Разумеется, при каждом проходе цикла туда кладется очередная соседняя точка.
Код

if(a!=b && b.getColor() == a.getColor()) {

Если a и b - разные точки, и в то же время имеют одинаковый цвет - да, в таком случае соседняя и проверяемая точки принадлежат одному игроку; налицо необходимость соединения.
a!=b мы проверяем, потому что в процессе перебора соседних точек нам должна попасться и текущая точка. Такой уж у нас перебор smile Естественно соединять точку саму с собой мы не хотим.
Код

if( !points[px][py+j].isConnectedTo(points[px+i][py]) ) {

Последняя проверка - на наличие другого диагонального соединения в той же клетке. Если клетка уже перечеркнута по диагонали, мы не можем построить соединение по другой диагонали.
Для этого нам нужно сначала найти две другие точки в той же клетке. Очень удобно то, что для этого достаточно взять x от одной точки и y от другой.
Вот например у нас точки с такими координатами:
[px   py   ] [px+i py   ]
[px   py+j] [px+i py+j]
[px py] это точка a, [px+i py+j] - соответственно точка b.
Тогда две другие точки - это [px+i py] и [px py+j].
Остается проверить, НЕ-соединена ли одна из них с другой - для этого там используется метод isConnectedTo().
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Rpahut
Дата 11.2.2009, 02:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Kakadu, код я ваш читал но не вникал сильно smile Общий смысл во всяком случае понятен.
Кстати, почему не используются Player1Dead и Player2Dead? Как вы собираетесь подсчитывать очки игроков?
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 11.2.2009, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



спасибо.. многое стало понятней .
А линии то всё равно не рисуются  smile 
PM MAIL   Вверх
Rpahut
Дата 12.2.2009, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



У Kakadu игра на захват вражеских точек идет. Так что контур обводится только если внутри него есть вражеская точка.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 13.2.2009, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Rpahut , мне ваша версия так понравилась что я даже картинку прикрепила с почерневшей точкой попавшей в плен smile

user posted image

Исправьте меня если я не права   ,  мы не использовали полиморфизм но мы 
использовали точно  три принципа обьектно-ориентированного программирования :  encapsulation , inheriance , modylarity .
Data  abstraction мы где-то наверно тоже использовали .... Пытаюсь её отыскать ..



Это сообщение отредактировал(а) Qawra - 13.2.2009, 21:32
PM MAIL   Вверх
Kakadu
Дата 14.2.2009, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 19.3.2008

Репутация: нет
Всего: 7



Модульность - это не один из Китов ООП. Полиморфизм - да (но вроде его ни у вас, ни у меня нет). Модульность - вообще ерунда какая-то smile 

P.S. Можете выложить ваши исходники? Просто по всем страницам мне их собирать несколько лень=)
P.P.S. Кстати, наследования у вас вроде тоже нет=)


--------------------
Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли
PM MAIL   Вверх
Rpahut
Дата 14.2.2009, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Ну для полиморфизма маловат проект. А наследуются у нас по меньшей мере JFrame и JPanel, может и что-то еще.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 14.2.2009, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Modularity это не ерунда . Это " the physical and logical decomposition of large and complex things into smaller and manageable   components ". 
У нас она присутствует там где сложные функции разбиты на маленькие методы .
Это она и есть , Modularity .... Мы её учим как принцип  обьектно-ориентированного программирования .

Data Abstruction  можно себе преставить на примере : Водитель водит машину и может не задумываться как двигаются детали внутри  двигателя. Он использует обьект зная только то что ему нужно знать как водителю .А  механик может и не уметь водить машину . Он должен знать все шестерёнки внутри двигателя и уметь их ремонтировать . Один и тот-же обьект  используется по разному .
Вот  этого  различного использования одного и того же обьекта в нашей программе я и не нахожу . 

Исходник большой потому что интерфейс увесистый получился . Ничего сделать не могу .Это мой первый интерфейс ... пускай такой и  будет .
http://rapidshare.com/files/198093947/Project2009.rar.html
PM MAIL   Вверх
Rpahut
Дата 14.2.2009, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



26 метров?! Что там такое в архиве?

Ага понятно. Прикольно smile 

PS Qawra, если все переменные классов public, то это не инкапсуляция smile 

Это сообщение отредактировал(а) Rpahut - 15.2.2009, 00:46
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 15.2.2009, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Ну они же не все публик !
Код

public class Window extends JFrame implements  MouseListener 
{
  private JPanel main, south, north, center;
  private JButton startButton, firstPlayerButton,helpButton, secondPlayerButton;
  private JLabel titleLabel;
  private Color firstDefautColor= Color.blue;
  private Color secondDefautColor= Color.red;
  private static BufferedInputStream stream;
  private static Clip line;
  private static AudioInputStream ais;

Код

public class Grids extends JFrame  implements  MouseListener  
   {
     public GridsCanvas canvas; 
     public int rows=20;
     public int cols=20;
     public int sellSize=30 ;
     private boolean firstPlayerMove;
     public Player first;
     public Player second;

Код

     public int rows=20;
     public int cols=20;
     public int cellSize=30 ;
     private Color color;
     private DrawablePoint points[][]; // array to hold all possible  points

Код

public class DrawablePoint 
{   private Color color;
    public  int radius;
    private int x;
    private int y;
    private Graphics g;
    public  boolean lastPoint;

Код

public  class ColorChooser extends JFrame 
{
  public Color ChangeColor(  Color firstDefautColor) 

Код

public class Player 
 {
  private Color color; 
  public Player first;
  public Player second;


смущает меня то что некоторые из них повторяются в разных классах . Не знаю нормально ли это . 
Изначально так написала потому что иначе не компелировалось .
public Player first;
public Player second;  
и 
 public int rows=20;
 public int cols=20;
 public int cellSize=30 ;
 private Color color;
например   прописаны дважды ...

Под Data Abstruction я хочу подвести класс ColorChooser
Код

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

public  class ColorChooser extends JFrame 
{
  public Color ChangeColor(  Color firstDefautColor) 
  {
     Color choosedColor = JColorChooser.showDialog(this, "Choose your color",  firstDefautColor);
     
       if(choosedColor!=null){    
           return  choosedColor;
        }return  firstDefautColor;
  } 
}
  
Здесь делается то чего мы не знаем что и оно показывает нам диалог выбора цвета smile
 Мы  ведём машину не зная  что происходит внутри двигателя .

Не удалось мне избавиться только от дублирования 
public int rows=20;
public int cols=20;
public int cellSize=30 ;
в двух классах    Grids   и  GridsCanvas

Это сообщение отредактировал(а) Qawra - 15.2.2009, 12:02
PM MAIL   Вверх
Rpahut
Дата 15.2.2009, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Qawra, почитайте еще про инкапсуляцию.
Каждый класс это отдельное пространство; если у нас два класса то в них хоть все переменные могут иметь одинаковые тип и имя. Как ни крути, а Grids.rows и GridsCanwas.rows отличаются полными именами, т.е. хотя и там и там rows, имена переменных все равно разные.

Момент второй - ключевое слово public применяется только если нужно сделать член класса доступным извне напрямую. Уверяю вас что мы нигде не работаем с переменными напрямую, только через методы классов, которые и помечаем как public.
Например у нас в DrawablePoint есть private переменная color и есть public метод setNewColor(). Программа не будет работать правильно, если записывать цвет прямо в переменную, поэтому мы ограничиваем доступ к ней. Если что компилятор даст нам по рукам - так исключается возможность оставить в программе ошибку.

_________
Если мы не знаем что делает JColorChooser.showDialog(), нам лучше им не пользоваться smile . ОК, мы знаем что он делает, но не знаем как - если это и есть абстракция, то мы пользуемся ей сплошь и рядом.
Например тип Color можно считать абстрактным(?). Кто его знает что там у него внутри.

Добавлено через 8 минут и 26 секунд
Вот немного код почистил и добавил кое-что.

Присоединённый файл ( Кол-во скачиваний: 10 )
Присоединённый файл  tochki.rar 5,59 Kb
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 16.2.2009, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Огромное спасибо за кусочек 
Код

firstPlayerButton.setToolTipText("Change fist player color");
secondPlayerButton.setToolTipText("Change second player color");
startButton.setToolTipText("Start game");
    // disable animation lag on rollover
startButton.setRolloverEnabled(false);    

у меня до него никак руки не доходили , хотя я чувствовала что он нужен .

В Grids я полностью убрала Serializable  и поменяла переменные на private ..
Код

import java.awt.*;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.geom.Point2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

   public class Grids extends JFrame  implements  MouseListener  
   {
     private GridsCanvas canvas; 
     private int rows=20;
     private int cols=20;
     private int sellSize=30 ;
     private boolean firstPlayerMove;
     private Player first;
     private Player second;
      
    public Grids(Color firstDefautColor, Color secondDefautColor) // constructor
    {   
        first = new Player(firstDefautColor); // creating a Players
        second = new Player(secondDefautColor);
        firstPlayerMove = true;
        
        canvas = new GridsCanvas(rows, cols, sellSize); 
        add(canvas);
        
        canvas.addMouseListener(this);
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
      
         addWindowListener(new WindowAdapter() 
        {
            public void windowClosing(WindowEvent e) {
                int exitCode = JOptionPane.showConfirmDialog(Grids.this, "Would you like to stop the game  ?", "Options ", JOptionPane.YES_NO_OPTION);
                if (exitCode == JOptionPane.YES_OPTION) {
                    dispose(); // close window
                }
            }
        }); 
        pack();
        setTitle("Points");
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
        
    } 
   
  public void mouseEntered(MouseEvent e){
  }
  public void mouseExited(MouseEvent e) {
  }
  public void mousePressed(MouseEvent e) {
  }
  public void mouseReleased(MouseEvent e) {
  }
  public void mouseClicked(MouseEvent e) {
    
     Player currentPlayer;
  
     int screenX = e.getX(); // gets coordinate of the click
     int screenY = e.getY();
     
   
      if(firstPlayerMove) {
       currentPlayer = first;
       }
      else {
       currentPlayer = second; 
      }
      if( canvas.mouseWasClicked(screenX, screenY, currentPlayer.getColor( )) )
       {// if we change the color - we  change players
         firstPlayerMove = !firstPlayerMove;// we change boolean value to opposite 
       }
        repaint();
    }
}
 в общем то нас как раз учили что по умолчанию всё public .. 
может 
Код

public int rows=20;
public int cols=20;
public int cellSize=30 ;

 просто сделать FINAL  ?

Это сообщение отредактировал(а) Qawra - 16.2.2009, 21:14
PM MAIL   Вверх
Rpahut
Дата 16.2.2009, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



Если не указывать модификатор доступа, члены классы доступны везде внутри пакета, почти как public.

В классе Grids
Код

public int rows=20;
public int cols=20;
public int cellSize=30 ;

можно сделать константами или final, в классе GridsCanvas пускай будут private.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 17.2.2009, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Так и сделаем ... К сороковой  странице документации я уже сдаюсь  на всё .. документацию я  тоже  уже  сдаю .. 
Что будем ещё привинчивать ? 
Можно сделать решётку resizable .  Но как это сделать в момент игры ... У нас же массив с точками создан до начала игры . Если игроки захотят изменить размер поля - массив придётся создавать заново . Значит  точки которые уже нарисованы игроками надо будет скопировать из одного массива в другой . Потдерживает ли Java такие копирования массивов  я не знаю .

PM MAIL   Вверх
Rpahut
Дата 18.2.2009, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


0xdeadbeef
*


Профиль
Группа: Участник
Сообщений: 243
Регистрация: 9.4.2006

Репутация: 5
Всего: 7



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

Для начала добавим в GridsCanvas несколько переменных, для хранения очков:
Код

     private Color playerAColor = null;
     private Color playerBColor = null;
     private int playerAScores = 0;
     private int playerBScores = 0;


Выводить счет будем так:
Код

          // Add this code to the end of GridsCanvas.paintComponent()

          Font font = new Font("Arial", Font.BOLD, 12); // create bold Arial font size 12 points
          g.setFont(font); // use this font

          g.setColor(playerAColor);
          g.drawString( new String(""+playerAScores), 0, field2screen(rows)); // display scores for one player
          g.setColor(playerBColor);
          g.drawString( new String(""+playerBScores), field2screen(cols/2), field2screen(rows));  // display scores for other player


Метод пересчета очков.
Здесь творится полное ГГ, в основном потому что я сразу не подумал о том как будут считаться очки:
Код

     private void calculateScores() {
         Color ownerColor;

         // reset scores
         playerAScores = 0;
         playerBScores = 0;

         // loop for all points
         for(int j=0; j<rows; j++) {
             for(int i=0; i<cols; i++) {

                 // get capturer color
                 ownerColor = points[i][j].getCaptured();
                 // if no capturer - get initial point owner color
                 if( ownerColor==null ) ownerColor = points[i][j].getColor();

                 if( ownerColor!=null ) {
                     // if no A color yet assigned
                     if( playerAColor==null ) {
                         playerAColor = ownerColor;
                     }
                     // A is assigned but B is not
                     else if( playerBColor==null && ownerColor!=playerAColor ) {
                         playerBColor = ownerColor;
                     }

                     // compare colors and score player
                     if( ownerColor==playerAColor ) playerAScores++;
                     if( ownerColor==playerBColor ) playerBScores++;
                 }
             }
         }
     }

Вызывать этот метод нужно после того куска где захватываются точки:
Код

...
                    // if color changed
                    makeConnections(pointX, pointY);
                    for(int j=0; j<rows; j++) {
                        for(int i=0; i<cols; i++) {
                            wasHere = new boolean[cols][rows];
                            if( pointNotCaptured(i, j, playerColor)==0 ) {
                                points[i][j].setCaptured(playerColor);
                            }
                        }
                        calculateScores(); // <--
...

--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею?
PM MAIL   Вверх
Qawra
Дата 19.2.2009, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 188
Регистрация: 6.3.2007

Репутация: 3
Всего: 4



Я наверно его ещё не полностью впаяла .. или он пока просто себя не проявляет  визуально .. Я была  где-то здесь 
Код

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

public class GridsCanvas  extends JPanel
{
     private  int rows=20;
     private  int cols=20;
     private  int cellSize=30 ;
     private DrawablePoint points[][]; // array to hold all possible  points
     
       
    public GridsCanvas(int r, int c,int cellSize) {
        this.rows = r;
        this.cols = c;
        this.cellSize=cellSize;
        
        setPreferredSize(new Dimension( (c+1)*cellSize, (r+1)*cellSize )); 
        // we make our window bigger than grid to have extra place 
        //and easier access to the points on the edge of the grids
        points = new DrawablePoint[cols][rows];
        makePoints(rows,cols); 
    }
    
    public void paintComponent(Graphics g) {
          g.translate(cellSize, cellSize); 
          //we move the grid right and down on the distance of the cellSize

          for (int i = 0; i < rows; i++)
               g.drawLine( i * cellSize, rows*cellSize-cellSize,  i * cellSize,0 );

          for (int j = 0; j < cols; j++)
               g.drawLine(0, cellSize*j, cols*cellSize-cellSize, cellSize*j); 

          for(int y=0; y<cols; y++) {
               for(int x=0; x<rows; x++) {
                    points[x][y].paint(g);  //  displays   points     
               }
          }
          g.translate(-cellSize, -cellSize);
     }
    
     public void makePoints ( int rows , int cols)
      {  for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) // pass screen coords to point constructor
             {  points[x][y] = new DrawablePoint( field2screen(x), field2screen(y) ); 
                 // create  all points     
            }      
          }
         }
         
     public boolean mouseWasClicked(int x, int y, Color playerColor) 
  { // accepts coordinates and the playerColor of the mouse click
         int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);
         boolean result = false;
         if( goodCoords(pointX, pointY) ) {
             result = points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color show that the point is occupied by player    
             if(result) {
                 // if color changed - create connections for this point
                 makeConnections(pointX, pointY);
              }    
          } // else - do nothing if coorditates is not good 
          return result;
       }
    
       
     private boolean goodCoords(int fieldX, int fieldY) {
       /*if X is zero or positive and  if Y is zero or positive 
       and  if X is less than field width and  if Y is less than field height...
       we can use   coordinates of the mouse click */
       if(fieldX>=0 && fieldY>=0 && fieldX<cols && fieldY<rows)  // ...good coordinates
       return true;

       else //  bad coordinates which dive  ArrayIndexOutOfBoundsException
       return false;
       }
   
     private int screen2field(int coord) { // screen to field convert coordinates
       return (coord-cellSize/2) /cellSize; 
  // shift  coordinates of the click by half cellSize to draw points on the corners of the grids  
      }

     private int field2screen(int coord) { // field to screen  convert coordinates
       return coord*cellSize;}
      
    private void makeConnections(int px, int py) 
    // create connection for the point ,px point x coordinate,py point y coordinate
    {
        DrawablePoint a, b;

        a = points[px][py]; // a - current point
        // for all eight points around current point
        for(int j=-1; j<=1; j++) {
            for(int i=-1; i<=1; i++) {
                if( goodCoords(px+i, py+j) ) {
                    b = points[px+i][py+j]; // b - point to check
                    
                    if(a!=b && b.getColor() == a.getColor()) // if not current point but have same color
                    {
                        // if no another diagonal connection in this cell already exists
                        if( !points[px][py+j].isConnectedTo(points[px+i][py]) ) {
                            a.connectTo(b); // connect a to b
                            b.connectTo(a); // connect b to a
                        }
                    }
                } // if goodcoords end
            } // loop i end
        } // loop j end
    }
  }


теперь я пытаюсь скомпелировать это 
Код

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

public class GridsCanvas  extends JPanel
{
     private  int rows=20;
     private  int cols=20;
     private  int cellSize=30 ;
     private DrawablePoint points[][]; // array to hold all possible  points
     
     private Color playerAColor = null;
     private Color playerBColor = null;
     private int playerAScores = 0;
     private int playerBScores = 0;
     
    public GridsCanvas(int r, int c,int cellSize) {
        this.rows = r;
        this.cols = c;
        this.cellSize=cellSize;
        
        setPreferredSize(new Dimension( (c+1)*cellSize, (r+1)*cellSize )); 
        // we make our window bigger than grid to have extra place 
        //and easier access to the points on the edge of the grids
        points = new DrawablePoint[cols][rows];
        makePoints(rows,cols); 
    }
    
    public void paintComponent(Graphics g) {
          g.translate(cellSize, cellSize); 
          //we move the grid right and down on the distance of the cellSize

          for (int i = 0; i < rows; i++)
               g.drawLine( i * cellSize, rows*cellSize-cellSize,  i * cellSize,0 );

          for (int j = 0; j < cols; j++)
               g.drawLine(0, cellSize*j, cols*cellSize-cellSize, cellSize*j); 

          for(int y=0; y<cols; y++) {
               for(int x=0; x<rows; x++) {
                    points[x][y].paint(g);  //  displays   points     
               }
          }
          g.translate(-cellSize, -cellSize);
          
          Font font = new Font("Arial", Font.BOLD, 12); // create bold Arial font size 12 points
          g.setFont(font); // use this font

          g.setColor(playerAColor);
          g.drawString( new String(""+playerAScores), 0, field2screen(rows)); // display scores for one player
          g.setColor(playerBColor);
          g.drawString( new String(""+playerBScores), field2screen(cols/2), field2screen(rows));  // display scores for other player
     }
    
     public void makePoints ( int rows , int cols)
      {  for(int y=0; y<cols; y++)
            {for(int x=0; x<rows; x++) // pass screen coords to point constructor
             {  points[x][y] = new DrawablePoint( field2screen(x), field2screen(y) ); 
                 // create  all points     
            }      
          }
         }
         
     public boolean mouseWasClicked(int x, int y, Color playerColor) 
  { // accepts coordinates and the playerColor of the mouse click
         int pointX = screen2field(x); // count which point was clicked
         int pointY = screen2field(y);
         boolean result = false;
          
         if( goodCoords(pointX, pointY) ) {
             result = points[pointX][pointY].setNewColor(playerColor); // sets the  owner  color show that the point is occupied by player    
             if(result) {
                 // if color changed - create connections for this point
                 makeConnections(pointX, pointY);
                 for(int j=0; j<rows; j++) {
                        for(int i=0; i<cols; i++) {
                            wasHere = new boolean[cols][rows];
                            if( pointNotCaptured(i, j, playerColor)==0 ) {
                                points[i][j].setCaptured(playerColor);
                            }
                        }
                        calculateScores();
              }    
          } // else - do nothing if coorditates is not good 
          return result;
       }
    }
       
     private boolean goodCoords(int fieldX, int fieldY) {
       /*if X is zero or positive and  if Y is zero or positive 
       and  if X is less than field width and  if Y is less than field height...
       we can use   coordinates of the mouse click */
       if(fieldX>=0 && fieldY>=0 && fieldX<cols && fieldY<rows)  // ...good coordinates
       return true;

       else //  bad coordinates which dive  ArrayIndexOutOfBoundsException
       return false;
       }
   
     private int screen2field(int coord) { // screen to field convert coordinates
       return (coord-cellSize/2) /cellSize; 
  // shift  coordinates of the click by half cellSize to draw points on the corners of the grids  
      }

     private int field2screen(int coord) { // field to screen  convert coordinates
       return coord*cellSize;}
      
    private void makeConnections(int px, int py) 
    // create connection for the point ,px point x coordinate,py point y coordinate
    {
        DrawablePoint a, b;

        a = points[px][py]; // a - current point
        // for all eight points around current point
        for(int j=-1; j<=1; j++) {
            for(int i=-1; i<=1; i++) {
                if( goodCoords(px+i, py+j) ) {
                    b = points[px+i][py+j]; // b - point to check
                    
                    if(a!=b && b.getColor() == a.getColor()) // if not current point but have same color
                    {
                        // if no another diagonal connection in this cell already exists
                        if( !points[px][py+j].isConnectedTo(points[px+i][py]) ) {
                            a.connectTo(b); // connect a to b
                            b.connectTo(a); // connect b to a
                        }
                    }
                } // if goodcoords end
            } // loop i end
        } // loop j end
    }     
         private void calculateScores() {
         Color ownerColor;

         // reset scores
         playerAScores = 0;
         playerBScores = 0;

         // loop for all points
         for(int j=0; j<rows; j++) {
             for(int i=0; i<cols; i++) {

                 // get capturer color
                 ownerColor = points[i][j].getCaptured();
                 // if no capturer - get initial point owner color
                 if( ownerColor==null ) ownerColor = points[i][j].getColor();

                 if( ownerColor!=null ) {
                     // if no A color yet assigned
                     if( playerAColor==null ) {
                         playerAColor = ownerColor;
                     }
                     // A is assigned but B is not
                     else if( playerBColor==null && ownerColor!=playerAColor ) {
                         playerBColor = ownerColor;
                     }

                     // compare colors and score player
                     if( ownerColor==playerAColor ) playerAScores++;
                     if( ownerColor==playerBColor ) playerBScores++;
                 }
             }
         }
     }
    }

 и пока    wasHere = new boolean[cols][rows]; не компелируется .Не видит переменную . Наверно нужно создать её заранее как  член класса .
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование игр, графики и искуственного интеллекта"
Rickert

НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.

  • Литературу, связанную с программированием графики, обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы связанные с программированием графики и мультимедии на языках С++ и Delphi
  • Вопросы по реализации алгоритмов рассматриваются здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема »


 




[ Время генерации скрипта: 0.2879 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.