![]() |
|
Модераторы: Rickert |
![]()
|
|
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
есть кнопка , есть класс для выбора игроком цвета
При нажатии кнопки должен выходить диалог выбора цвета для игрока . Я думала что достаточно при нажатии кнопки
создать игрока из конструктора класса Игрок который уже выберет себе цвет но не знаю как этот конструктор прописать что-бы он выбирал цвет . Мой конструктор видимо в принципе ошибочный.Он ничего не выбирает поэтому я его здесь и не отображаю . |
||||
|
|||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Если цвет выбирается в момент создания игрока, то:
В конструкторе класса Игрок:
Добавлено @ 18:59 Если цвет хочется менять во время игры, то: 1. Создаем кнопки или пункты меню "Поменять цвет Игрока1" "Поменять цвет Игрока2" 2. Клеим их к основному окну 3. В класс Игрок добавляем метод смены цвета:
4. В основном окне отслеживаем нажатие кнопок (или выбор пункта меню) и вызываем метод ChangeColor() соответствующего игрока. ЗЫ С Праздником! Это сообщение отредактировал(а) Rpahut - 31.12.2008, 19:03 --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Qawra |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
C Наступившим ...и ещё с наступающими !
получился у меня такой синтакс на кнопке
такой ColorChooser
проблема сейчас с игроком
на строчке this.playerColor = this.cchooser.ShowChooser(Color playerColor ); компайлер ругается что ему нужна ещё ")" Я пробовала различные варианты написания , но ему всё равно нужна ещё одна скобка. |
||||||
|
|||||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
И еще:
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
почему-то компайлер хочет ещё одну круглую скобку. Видимо ему что-то другое не нравится в этом варианте конструктора
но пишет он что нужна ещё одна круглая скобка в строчке playerColor = cchooser.ShowChooser(Color playerColor ); Я уже видела "лишнии" с моей точки зрения круглые скобки в примерах с Java кодом , но как и почему их ставят - не знаю. Они бывают не парные !!! и откуда они берутся не понятно . В данном случае я попробовала поставить лишнию скобку - компайлер всё равно пишет что скобки не хватает .Значит дело не в ней а в чём то другом ... |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Ваша ошибка тут:
playerColor = cchooser.ShowChooser(
Скобки, кавычки и прочие знаки, используемые для отделения части текста, всегда парные - одна указывает начало куска, вторая конец. При большом нагромождении скобок бывает трудно определить на глаз, все ли в коде правильно. Небольшие куски кода часто пишутся "из головы" и не проверяются на корректность - так что там могут быть и ошибки. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Вы правы .. Это конечно объест класса Color но в данном случае он используется как аргумент ... Перестраховалась я
Теперь всё скомпилировалось но при нажатии на кнопку компайлер как ни странно находит кучу exceptions типа java.lang.NullPointerException .
Нам показывали exceptions которые возникают при вводе данных . А здесь мы пока ещё ничего не вводили .. Я что-то неправильно импортировала ? |
|||
|
||||
| arilou |
|
||||
![]() Великий МунаБудвин ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2646 Регистрация: 15.7.2004 Где: город-герой Минск Репутация: 6 Всего: 61 |
Видимо ошибка вот тут
т.е. в 16 строке в файле Player.java. Судя по всему, член класса
нигде не инициализируется, т.е. ему ничего не присваивается, поэтому происходит java.lang.NullPointerException |
||||
|
|||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
private ColorChooser cchooser был инициализирован но ему действительно ничего не присваивалось
Надо было видимо создать обьект класса ColorChooser cchooser = new ColorChooser (); Только что ему присваивать как цвет если сразу у двух игроков есть предустановленные цвета . .. null видимо .. Ничего присваивать оказалось не нужно .Просто оставить пустые скобочки и всё работает ! Это сообщение отредактировал(а) Qawra - 5.1.2009, 13:55 |
|||
|
||||
| arilou |
|
||||||
![]() Великий МунаБудвин ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2646 Регистрация: 15.7.2004 Где: город-герой Минск Репутация: 6 Всего: 61 |
Qawra,
это и значит, что "ничего не присваивалось"
ничего не понял, ну да ладно.
также, вызывает сомнение этот код. Что ты им хотела сказать? |
||||||
|
|||||||
| Rpahut |
|
||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Здесь если cchooser.ShowChooser(playerColor) возвращает null, игроку присваивается цвет по умолчанию.
И это при том, что в яве указателей нету ColorChooser не нужно делать членом класса, потому как после выполнения конструктора класса Player он уже не будет нужен. Лучше создать его там где он используется:
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||
|
|||||||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
да.. так оно тоже работает . А когда мы отключаем
//this.playerColor = color; то как быть с цветом для игрока заданным по умолчанию ? Мы ведь с ним теперь не работаем в конструкторе . Я правда не могу это сейчас практически проверить . Попробовать нарисовать точки без выбора цвета игрока пока нечем .Нужен отдельный класс Points где точки будут рисоваться по очереди цветами игроков и только в углах клеток решётки . Вызывается решётка кодом на кнопке
есть по умолчанию два цвета для игроков red и blue . Но ведь если игрок не станет выбирать цвет то он не запустит конструктор и цвета по умолчанию тоже не будет .. Хотелось бы написать
Как при нажатии кнопки старт проверить что были нажаты firstPlayerButton и secondPlayerButton ? |
||||
|
|||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Цвет по умолчанию мы передаем в ColorChooser: playerColor = cchooser.ShowChooser(color); так что либо пользователь изменит и выберет цвет - тогда его мы присвоим игроку, либо пользователь откажется от выбора - тогда срабатывает проверка на null и цвет по умолчанию записывается в playerColor. Конструктор вызывается автоматически при создании экземпляра объекта.
Вручную конструкторы вызывать не стоит. Они существуют для инициализации объектов при создании - в случае класса Player для инициализации его переменных playerColor и orderOfPlayers.
Так у вас при нажатии кнопки Старт создаются оба игрока, т.е. для каждого из них будет выполнен конструктор, а значит два раза на экране появится ColorChooser с предложением поменять цвет. Вполне приемлимый вариант, только firstPlayerButton и secondPlayerButton в таком случае можно убрать. Если вы желаете выбирать цвет для игроков перед началом игры, нужно: 1. При нажатии кнопок firstPlayerButton и secondPlayerButton показывать ColorChooser, запоминать выбранный цвет. 2. При нажатии кнопки Start создавать Игроков и передавать им (их конструкторам) цвета. 3. В конструкторе класса Player в таком случае ColorChooser показывать не нужно, просто записываем полученный цвет в playerColor. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Qawra |
|
||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
что бы изменить код на кнопках мне пришлось дополнительно декларировать в этом классе две переменные
Класс Player совсем укоротился и выглядит так
переменную private Color playerColor; пришлось прописать дважды в двух разных классах , иначе не компелировалось . А что будет если игрок сразу нажмёт кнопку старт ? У него не будет предустановленного цвета ? Может быть приравнять в начале класса private Color playerColor = Color.white ; и на кнопке старт сделать проверку playerColor.Если он всё ещё white значит игроки отказываются выбирать цвет и мы им назначим цвет по умолчанию прямо здесь на кнопке старт ... сейчас пытаюсь сообразить как построить класс Points что-бы проверить каким цветом будет рисоваться . Пока только сам процесс рисования скомпоновался.
Там самый ужас что надо ставить точки только в углах решётки . Причем нужен небольшой зазор в координатах иначе человек должен будет " целится" в определённый пиксель.. Решётка в двух классах выглядит так
Это сообщение отредактировал(а) Qawra - 6.1.2009, 16:37 |
||||||||||
|
|||||||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Извините что вопрос про решётку не выделила в отдельную тему
Это сообщение отредактировал(а) Qawra - 6.1.2009, 16:43 |
|||
|
||||
| arilou |
|
|||
![]() Великий МунаБудвин ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2646 Регистрация: 15.7.2004 Где: город-герой Минск Репутация: 6 Всего: 61 |
Qawra, я переименую тему в "Разработка игры "Территория", обащайтесь на здоровье.
|
|||
|
||||
| Rpahut |
|
||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Да уж с темами кавардак...
Давайте что-ли сначала выбор цвета добьем. Итак, мы желаем чтобы пользователь мог выбрать цвета игроков, до того как будут созданы сами игроки. Поскольку игроков еще нет, сохранить цвет в них мы не можем, стало быть нам понадобятся переменные для хранения цвета, и их нужно будет две, потому что игроков двое и каждый из них должен иметь свой цвет. Одной переменной playerColor тут не обойтись.
Да. Сам по себе он не появится.
Вначале - это в конструкторе. И, если у нас будет две переменные, можно будет в каждую из них положить свой цвет - например красный и синий. Потом, когда создаем игроков, передаем каждому его цвет. И ничего уже проверять не нужно будет - независимо от того, станет пользователь менять цвет или нет, игроки все равно будут разноцветные. Дополнительно, хотя и не обязательно: 1. Вставьте проверку на null в метод ShowChooser():
Вместо того чтобы всякий раз проверять что там нам вернулось, так можно быть уверенным что вернется то что нужно. Сам метод стоит переименовать, чтобы название соответствовало тому, что он делает с точки зрения программы - например ChangeColor или что-то в таком духе. 2. private ColorChooser cchooser = new ColorChooser (); Не нужно делать ColorChooser членом класса. Он не хранит внутри никаких данных, которые были бы нужны классу, и его можно создать когда он понадобится, например в методе где обрабатываются кнопки, а после использования выкинуть и забыть. Так, что еще...
Тут зависит от того, как будет игра построена, но хранить orderOfPlayers внутри класса Игрок скорее всего не понадобится. Как раз должен быть вышестоящий класс, заведующий порядком ходов. В любом случае у нас уже есть переменные first и second, ясно что first это first, а second соответственно second. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||
|
|||||||||
| Rpahut |
|
||||||||||
![]() 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]
но! Перед тем как просить точку нарисоваться, канвас будет вызывать Graphics.translate():
так что когда точка станет рисовать Oval, координаты [0, 0] будут именно там, где должна отобразиться точка. В принцип работы translate() можно не вникать. Главное это после отрисовки точки вернуть все как было:
иначе [0, 0] будет сдвигаться все дальше и дальше по мере рисования точек и улетит совсем. Не говоря уже о том, что точки будут появляться совсем не там где нам нужно. Все вместе: Если в классе Точка есть
тогда в GridsCanvas.paint() пишем так:
Как считать координаты точки, зависит от того, как мы их храним. Я делал двумерный массив Точек размером [rows][cols], в цикле рисования поля у меня были переменные x и y, соответсвенно координаты точки [x][y] = [x*cellSize, y*cellSize]. Точки создаются все сразу, при создании игрового поля, и существуют уже до того как игроки их поставят. Вобще игроки у нас не ставят точки, они их просто помечают как свои... Точка, если она не помечена, либо не рисуется совсем, либо рисуется с меньшим радиусом, либо как-нибудь так рисуется чтобы ее можно было отличить от помеченной - ну это потом можно будет метод paint() точки дорабатывать по мере надобности. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||
|
|||||||||||
| Qawra |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
По порядку и старательно :
1. рисуем две независимые переменные хранящие предустановленный цвет игроков.
на кнопках теперь будет
2 . без строчки private ColorChooser cchooser = new ColorChooser (); не компелируется ( не может найти cchooser ) 3. В конструкторе Player опять проблема с именем переменной хранящей цвет .
|
||||||||
|
|||||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
с решёткой .....я рассматриваю свой GridsCanvas и его конструктор
О методе getPreferredSize() я не знала я просто хотела наложить решётку на новую JFrame . Надеюсь то тогда целиться в точки будет удобнее . Начиная с фразы "Клетки чертятся по точкам, а не точки в углах клеток. Вообще сетку мы рисуем для красоты, работать все будет и без нее." я впала в процесс осмысления который видимо затянется до утра ... Завтра я постараюсь нарисовать что я поняла |
|||
|
||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Ну, вернемся к основам... cchooser.ChangeColor(firstDefaultColor); Когда мы вызываем метод, мы передаем ему аргументы. В данном случае у нас вписана переменная firstDefaultColor, в которой хранится Color.blue. Фишка в том, что мы не передаем саму переменную, мы не можем никак передать переменную - мы передаем значение которое хранится в переменной. Т.е. ChangeColor(firstDefaultColor) это то же самое что ChangeColor(СинийЦвет). Внутри метода мы принимаем параметр public Color ChangeColor(Color ?"?"?) { не важно как он называется здесь, Ява просто засунет в эту переменную значение, которое мы передали(СинийЦвет). И Ява не запутается что куда класть, потому что метод принимает цвет, и мы передаем цвет, и там это первый параметр(и единственный), и тут первый параметр... Короче, компилятор ориентируется по типу и порядку аргументов, а не по их имени. Для самого метода этот параметр вообще выглядит как переменная, в которой как-то сам собой оказался синий цвет. Программисту в отличии от компилятора проще ориентироваться по имени. Удобно называть параметр defaultColor, потому что это и есть по сути цвет по умолчанию, хотя вы можете выбрать название на свой вкус.
А попробуйте сами его найти Его надо создать. Кажется, я писал об этом. Всякий объект перед тем как его можно будет использовать, должен быть создан. Но не нужно вписывать его как член класса, а нужно его прямо там создать где он используется, в методе где обрабатываются нажатия кнопок. Потому что он используется только там, потому что не хранит никакой нужной нам информации; нет никакой причины делать его членом класса. Вы же не выписываете все используемые в классе переменные в члены класса.
А вот и нет. Тут то же что и с ChangeColor() - имя менять не нужно. Будет работать как есть. Все. Когда с выбором цвета будет покончено, тогда перейдем к игровому полю. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Qawra |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Я решилась оставить только две переменные хранящие цвет
На кнопках результат такого сокращения выглядит как то странно , но с точки компайлера возможно это вполне разумно
При выборе цвета у меня получилось
Конструктор для игрока предполагает дополнительную переменную playerColor
|
||||||||
|
|||||||||
| Rpahut |
|
||||||||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Работать это будет очень интересно:
Нам же нужно, чтобы возвращался: 1. цвет выбранный пользователем, если он его выбрал; 2. а если не выбрал - то цвет по умолчанию (нам обязательно нужно вернуть обратно какой-то цвет, ради этого и существует метод; если пользователь не хочет выбирать цвет, нам придется вернуть цвет по умолчанию - потому что другого у нас просто нет). Записываем это дело по-русски:
дальше переводим:
а теперь просто записываем то же самое на Яве:
============================================
Не надо так париться с именами. Когда мы возвращаем значение, мы возвращаем значение, т.е. то, что лежит внутри переменной. Мы пишем имя переменной, чтобы Ява знала, из какой переменной взять значение. Сама переменная не передается и не возвращается.
Или вот еще пример:
А ведь внутри метода showDialog тоже есть строчка return ...; И мы даже не знаем, какое там имя используется. Нам и не нужно этого знать. Достаточно того что мы знаем какого типа значение возвращает метод - так мы можем создать подходящую переменную чтобы в нее положить значение:
Вобщем смысл всего этого: 1. Когда пишете какой-нибудь метод, позаботьтесь о том чтобы он делал то, что от него требуется. Определите, какая информация ему потребуется для работы - это и будут входные параметры. Как вы их назовете не важно, главное чтобы вы сами не путались в них. 2. Когда вызываете метод, передавайте значения, которые требуются ему для работы. Не важно как называются переменные, в которых эти значения лежат. 3. Если вы хотите чтобы метод возвращал вам что-то, нужна переменная соответствующего типа. С любым именем. 4. Перепишите метод ChangeColor(). Переименуйте параметр конструктора класса Игрок из firstDefautColor в color; конструктор будет работать и так, но у препода могут возникнуть вопросы. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||||||||
|
|||||||||||||||||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Спасибо за такой подробный перевод с Java на русский .
В рамках нашего курса , программированию посвящено только два часа в неделю поэтому многие вещи просто не досказаны. Например, нам говорили то что компайлер различает конструкторы только по типу аргументов , но примеры всегда были с одинаковыми названиями этих самых аргументов в конструкторе и как членов класса ... Теперь у меня получилось так :
Для того что бы начать рисовать точки нам нужно их предварительно создать и сохранить ещё до начала игры. Это правда что хранить их лучше в Vector а не в Array ? О векторах мы знаем только то что это dynamic array (мы проходили это в топике data structures). Теоретически , если точки это обьекты то когда они созданы память под них уже выделена . Количество их во время игры тоже не измениться ... Какой выигрыш от использования векторов ? Мы ещё ни разу не обращались к ним на программировании . |
||||
|
|||||
| Rpahut |
|
||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Можно написать с использованием векторов, но реальной причины для этого я не вижу. Вектора понадобятся нам позже, а точки поля мы будем хранить в двумерном массиве. Массив этот должен быть членом класса Поле (или GridCanvas? или полем у вас будет другой класс?). Пара слов об инициализации массива: если массив мы определим так
то у нас ничего не получится, потому что, во-первых, эта строчка выполнится до конструктора класса Поле, а значит в переменных rows и cols будут еще лежать нули(получится points[0][0], массив нулевого размера). Во-вторых, никаких Точек эта строчка не создает, независимо от размеров, а создает она массив. Мы определили массив, мы его и получили, и ничего больше. Поэтому мы напишем так:
и в конструкторе класса Поле:
Вот так мы создаем массив точек. Этот кусок кстати разумно выложить из конструктора в отдельный метод, потому что каждый раз начиная новую игру мы будем (пере)создавать массив. =================================================== Когда точки созданы, можно попробовать их отрисовать. Так как DrawablePoint у нас extends Component, то по идее можно добавлять точки к GridsCanvas(метод add()) и они будут автоматически перерисовываться при перерисовке самого поля(т.е. автоматически будет вызываться метод paint() точек). Вот этого я делать не пробовал, вобще это больше по яве - а значит не совсем ко мне. У меня метод paint после нескольких попыток стал вызываться, но точек все равно не видно --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||
|
|||||||||
| Rpahut |
|
|||
![]() 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Как продать идею? |
|||
|
||||
| Qawra |
|
||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Работать с полем я хотела в отдельном классе потому что иначе я запутаюсь
Назовём его BattleField .
что когда рисуется решётка и точки - результат зависит от порядка действий . Решётка может зарисовывать точки . А что ещё мы будем делать в конструкторе поля ? Добавлено @ 23:39 класс Точка в наброске пока выглядит так
пришлось снова прописать public Color color ; потому что со словом this. иначе не компелируется Это сообщение отредактировал(а) Qawra - 9.1.2009, 23:45 |
||||||||||
|
|||||||||||
| Rpahut |
|
||||||||||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Переделайте
1:
2:
3:
Имеет смысл все-таки объединить классы GridsCanvas и BattleField. Два класса там во всяком случае не нужны. Чтобы вы не путались, попробую обрисовать как это все должно выглядеть: GridsCanvas(или BattleField) будет создавать, хранить точки и рисовать их на экран Grids будет окном игры; окно нужно чтобы GridsCanvas можно было отобразить на экране В классе Grids в качестве члена класса вписываем GridsCanvas. В конструкторе Grids, когда известны размеры поля, создаем(инициализируем, передаем размеры) GridsCanvas. В классе GridsCanvas в члены класса вписываем массив points[][], в конструкторе инициализируем этот массив, точно так, как это сейчас сделано в BattleField. Теперь чтобы создать поле в окне со всеми точками достаточно создать Grids с правильными параметрами; когда создается Grids, будет создан и GridsCanvas, а он в свою очередь создаст точки. Касательно параметров конструктора Grids:
title - не нужен; заголовок каждый раз будет тот же(или нет?), можно вписать в конструктор:
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-метод для перевода координат на поле в экранные:
Использовать его можно например так:
============================ Тока сейчас заметил - у вас опять написаны параметры вместе с типом!
============================ По возможности вносите изменения небольшими кусками и компилируйте код - Ява покажет где у вас ошибки. В помощь - поправленный класс Grids:
Это сообщение отредактировал(а) Rpahut - 10.1.2009, 22:46 --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||||||||||
|
|||||||||||||||||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Когда я поменяла в class GridsCanvas extends Canvas на extends JPanel решётка перестала выходить нормально. Появляется окошко очень узкое и нерастягивающееся. Так что Canvas я пока оставила .Природа его не известна но на решётку он действует положительно .
Пытаюсь изменить свой класс Grid но пока от этого становиться только хуже. Окошко выходит но решётки на нём нет . w, h я пока хочу оставить потому окошко будет иметь постоянные размеры. У нас в школе разрешение мониторов компьютером 800/600 и я не буду вводить функцию изменения размеров поля . Оно и так занимает весь экран . Параметры у меня действительно написаны вместе с типом потому что иначе не комперировалось
в строчке private void drawCircle ( x, y, radius, Graphics g) компайлер требует идентифаер .. |
|||
|
||||
| Rpahut |
|
||||||||||||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Ну нерастягивающееся оно потому что в коде так написано. А что касается размера, то когда вы в Grids вызываете pack(), Ява спрашивает у GridsCanvas через метод getPreferredSize(), какой бы ей хотелось иметь размер. Чтобы Ява знала, какой нам нужен размер, сначала надо вызвать setPreferredSize() с указанным размером. Так же нужно вызвать setVisible(true) в конструкторе GridsCanvas, потому как по умолчанию элементы спрятаны и отображаться не будут.
Пока GridsCanvas не будет правильно оформлен, окно будет пустым или очень маленьким, это нормально; главное чтобы оно отображалось на экране и нормально закрывалось при нажатии [Х]. Это будет озачать что Grids работает.
Если размер постоянный, то передавать его через параметры совсем уж не нужно. Можно просто вписать его в класс. То же самое касается количества точек - если настройки не будет, все можно вписывать внутрь класса Grids.
Вот такое у меня хоть убейте не компилируется:
В заголовке метода типы должны указываться. Без них никак. Я уже писал о том что типы нужны компилятору. Я имел ввиду кусок, в котором инициализируется массив точек:
Разве BlueJ не ругается на эту строчку? ====================================== ОК, давайте по порядку. Класс Grids Можно скопировать код который я выкладывал. Если конструктор Grids не принимает параметров-размеров, скобки у него оставляем пустыми, но добавляем в него переменные:
Тут у нас гадкая неопределенность - мы можем либо задать размер окна, размер клетки и вычислить сколько точек поместится в окне; либо мы можем задать опять размер окна, желаемое количество клеток, и из них посчитать размер клетки. Второй вариант мне не нравится, потому как размер клетки все-таки важнее количества точек, от него зависит насколько удобно будет тыкать в точки и как они будут выглядеть. Поэтому я прикинул и вписал клетку размером 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 - это
Класс DrawablePoint
Еще нужно добавить метод
Когда все это заработает, в метод GridsCanvas.paintComponent() можно будет добавить цикл, перебирающий все точки и вызывающий для каждой ее метод paint() - так наши точки будут рисоваться на экран. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||||||||||||
|
|||||||||||||||||||||||
| Qawra |
|
||||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Эту строчку я не могу найти
Судя по всему я её успела отредактировать как
Класс Grids я скомпелировала так
Где-то закралась ошибка потому что окошко выходит без решётки и не по центру экрана . Закрывается нормально но есть Terminal window с текстом
На кнопке старт я изменила вызов конструктора с new Grids("Points", 800, 800, 20, 20).setVisible(true); на new Grids( ); DrawablePoints выглядят теперь так
И остался ещё класс BattleField который нам не нужен но там прописан метод
|
||||||||||||
|
|||||||||||||
| Rpahut |
|
||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Эта плоха. Быть она должна.
Вот после этой строчки у вас был там цикл инициализации массива в котором я видел ошибку... Если вы ее уже поправили - тогда ладно.
Одно замечание: canvas.setSize(rows*sellSize , cols*sellSize); можно убрать. Для JPanel размер устанавливается через setPreferredSize(), и делать это нужно в конструкторе GridsCanvas.
Видимо ему не нравится extends класса GridsCanvas. Пока там не будет extends JPanel ошибка так и останется.
Норм. Метод makePoints() нужно перенести из BattleField в GridsCanvas. Класс BattleField можно после этого убрать совсем. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||
|
|||||||||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Нашла ! Эта строчка была в классе BattleField который мы уже не используем .Там мы инициализировали массив точек в методе makePoints
нужно видимо ввести соординаты x,y как аргументы , либо сделать два разных конструктора DrawablePoint . Один только с цветом а второй только с координатами . class GridsCanvas extends JFrame было ещё вчера .. Сегодня ошибка повторилась . "adding a window to a container" может означать что мы добавляем add(canvas); неправильно с точки зрения компайлера ..? |
||||
|
|||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
extends JPanel. JFrame - это окно, нельзя добавить окно в окно. Конструктор точки пусть остается как есть. Цикл инициализации массива нужно модифицировать - передавать точке вместо координат цвет. Кроме того x и y мы будем передавать точке во время отрисовки. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
C extends JPanel всё получилось замечательно.Сообщение о ошибке изчезло и решётка вышла нормально .
|
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Ну вот, дальше собственно берем цикл
и вставляем его в GridsCanvas в метод paintComponent(). Точки должны рисоваться цветом, который вы передаете им при создании. И не удивляйтесь если точки окажутся неправильно расположены на сетке. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Я изменила цикл инициализации массива
на строчке
Это сообщение отредактировал(а) Qawra - 13.1.2009, 18:34 |
||||||
|
|||||||
| arilou |
|
|||
![]() Великий МунаБудвин ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2646 Регистрация: 15.7.2004 Где: город-герой Минск Репутация: 6 Всего: 61 |
Qawra,
[
опечатка. должно быть cellSize |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Угу.
И переменные rowHt и rowWid в методе paintComponent() это тот же cellSize, так что от них можно избавиться.
В остальных местах где эти переменные используются меняем их на cellSize. Кстати, переменные-члены класса у нас везде должны быть private, потому что пользуется ими только сам класс. Да и вообще разумно спрятать переменные класса от остальной программы. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Если отключить
без них ничего нарисовать в данный момент нельзя.
|
||||
|
|||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
и дальше в том же духе --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
скомпелировалось так
|
||||||
|
|||||||
| Rpahut |
|
||||||||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Вот этого я не ожидал
А почему именно их? Давайте разберемся: Лини рисуются при помощи drawLine() + Линии рисуются неправильно = Неправильно используется метод drawLine() drawLine() принимает четыре аргумента: drawLine(x1, y1, x2, y2) x1 и y1 это координаты начала линии, x2 и y2 - координаты ее конца. Нам, чтобы начертить сетку, нужно нарисовать вертикальные и горизонтальные линии на поле
У горизонтальных линий y1 и y2 должны быть одинаковые, иначе они не будут горизонтальными. Вообще любая точка на горизонтальной прямой имеет ту же координату Y. У вертикальных линий должны быть одинаковые x1 и x2. Дальше - первую горизонтальную линию нам надо начертить в самом верху поля, все остальные - ниже предыдущей на cellSize. Т.е. координата Y кратна cellSize и равна cellSize*номерСтроки; у нас в цикле уже есть переменная i которая считает строки и содержит номер текущей строки. Записываем:
Теперь x1 и x2. Каждая линия должна идти от одного края поля до другого, для этого один икс должен быть равен нулю(у левого края поля x=0), а другой равен ширине поля (т.е. cols*cellSize); вписываем иксы:
Аналогично для вертикальных линий: X начала и конца каждой линии одинаковый. X кратен cellSize и равен cellSize*номерСтолбца (вместо номера столбца опять используем переменную i). Y начала линии - ноль. Y конца линии - расстояние от верха до низа поля = высота поля = количествоСтрок*cellSize ===========================
В этой строке:
такое исключение может возникнуть, только если points[x][y] не содержит точки. Скорее всего что-то случилось с циклом инициализации массива points. Вообще с этим массивом мы много чего делаем, напомню самые важные моменты:
Когда мы создаем массив, в его ячейки раскладывается значение null. Если не инициализировать массив, null так там и останется. Если после этого попытаться что-то сделать с элементом в массиве, например
возникает NullPointerException. Когда инициализация у вас будет работать как надо, на экране сразу появятся точки. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||||||||
|
|||||||||||||||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Зашла в интернет утром перед школой и убегаю ..В школе попробую переделать . У меня часовой пояс на два часа раньше чем московкий .Поэтому я иногда не успеваю
|
|||
|
||||
| Qawra |
|
||||||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Решётка теперь рисуется нормально.
Цикл инициализации массива points ... Мне кажется чего - то нехватает в классе DrawablePoint .. Но начнём по порядку : В классе GridsCanvas если мы инициализируем как член класса
Если мы передадим цвет при создании точек (не знаю правда какой реально это цвет с точки зрения компайлера ..наверно firstPlayerColor..) то сообщение об ошибке изчезает
Осталась нарисовать точки...Для этого нам нужны аргументы. В классе DrawablePoint у нас прописано почему- то даже два метода
когда я пытаюсь нарисовать точки как
|
||||||||||||||
|
|||||||||||||||
| Rpahut |
|
||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Эту строчку можно было хотя бы скопировать у меня. Зачем там квадратные скобки (points [][]...
У BlueJ конечно кривые сообщения об ошибках, но если он ругается на эту строчку, значит ошибку стоит искать именно в ней. Зачем исправлять объявление массива, к которому у Явы нет никаких претензий?
...то массив будет нулевого размера, потому что эта строка выполняется до конструктора класса, и в переменных cols и rows еще лежат нули. Дальше вы еще пытаетесь с этим массивом что-то делать - отсюда и все ошибки. Так делать не надо!
Метод drawCircle() вы добавили сами ;). Пусть он пока остается, только сделайте его private. Для отрисовки точки используйте ее метод paint().
Читайте все что я пишу внимательнее. Мы по несколько раз на одни и те же грабли наступаем. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||
|
|||||||||||
| Qawra |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Я поняла ..у меня даже точки прорисовались ...правда они пока выглядят пустыми кружками .Надо наверно одновременно с рисованием вызывать метод закрашивающий кружки . Цвет у них по умолчанию чёрный.
Попыталась я закрасить кружочки добавив строчку
пытаюсь добавить MouseListener к решётке
Это сообщение отредактировал(а) Qawra - 17.1.2009, 00:24 |
||||||||
|
|||||||||
| Rpahut |
|
||||||||||||||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Это замечательно! Рекомендации по движению дальше: 1. Сначала прочитайте, не вникая сильно, что я тут понаписал, постарайтесь уловить суть идеи. 2. Начните читать с начала, подробнее разбирая каждый пункт. Вносите изменения в код по мере продвижения. 3. Добавляйте в свой код комментарии, особенно касательно новых для вас вещей - так лучше усваивается. 4. Спрашивайте, если что непонятно. ______________________________________ Так, мы убедились что GridsCanvas и точки рисуются, так что пока отложим доработки (мы еще доработаем рисование сетки и точки). Есть более важная весчь - это обработка мыши, чтобы можно было щелкать по точкам. Для того чтобы ловить события мыши, мы добавим implements MouseListener в класс Grids, и в него же впишем метод:
Пояснение: 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 вставляем:
Теперь с другой стороны - когда щелкается кнопка мыши, это значит что игрок пытается сделать ход. Поскольку игроков у нас двое, нужно знать не только координаты где произошел щелчок, но и чей (какого из игроков) сейчас ход. Поэтому добавляем в Grids переменную
а в конструкторе Grids присваиваем ей значение:
Теперь чтобы узнать чей ход можно написать
По ходу игры значение этой переменной будет меняться, и соответственно будут "переключаться" игроки - один ходит, второй отдыхает. -------------------- Теперь мы можем узнать где и какой игрок щелкнул мышкой. Дальше, допустим, мы хотим чтобы точка, в которую щелкнули, красилась цветом игрока, который щелкнул (это займет много текста). Точками управляет класс GridsCanvas (массив points находится в нем, значит он за них и отвечает), поэтому информацию о щелчке нужно сначала передать ему. Для этого можно добавить в GridsCanvas метод, принимающий соответствующие параметры, например такой:
Класс GridsCanvas уже может рассчитать в какую точку попал щелчок(если вообще попал) и передать цвет этой точке. Но, опять, чтобы точка могла принять цвет, у нее должен быть метод по типу такого:
Как рассчитать, в какую Точку попадают координаты щелчка: если чтобы определить экранные координаты точки, мы умножали ее координаты-на-поле на cellSize то здесь нам нужно наоборот, определить координаты-на-поле, поэтому делим экранные координаты на cellSize --------------отступление-------------------- Настоятельно рекомендую поместить код преобразования координат экран->поле и поле->экран в отдельные методы класса GridsCanvas:
Это важно, потому что дальше код преобразования координат у нас поменяется немного, может быть несколько раз, и вам придется либо везде менять x*cellSize на новую формулу, либо можно будет просто подправить метод field2screen(). -------------------------------------------------- Так... Метод DrawablePoint.setNewColor() я выше описал, теперь GridsCanvas.mouseWasClicked().
Довольно просто. Можете потом пощелкать в окне в стороне от сетки и посмотреть что получится =) Теперь метод mouseClicked(), с которого все и началось.
Тут, как видно, нам еще нехватает метода 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Как продать идею? |
||||||||||||||||||||||||
|
|||||||||||||||||||||||||
| Qawra |
|
||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
в Grids пришлось прописать как членов класса две переменные Player first и Player second
которые создаются при нажатии на кнопки в стартовом окошке
Я создала метод setNewColor в классе DrawablePoint . Но " пощелкать в окне в стороне от сетки " мне не удалось .У меня там пока только решётка и ничего больше нет Класс Player скомпелировался
Сначала я поместила
Это сообщение отредактировал(а) Qawra - 17.1.2009, 16:16 |
||||||||||
|
|||||||||||
| Rpahut |
|
||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Блин какая путаница с классами. Я как-то позабыл, что игроки у нас создаются в стартовом окне. Ну ничего, это можно поправить - вы правильно прописали игроков, осталось только убрать эти переменные из стартового окна. А то так у нас четверо игроков - двое прописаны там и двое тут. Еще нужно немного исправить программу. Привожу код:
Когда это добавите, ошибка nullPointerException должна пропасть. ________________________________
Ну, Player.getColor() на самом деле гораздо проще:
Смысл именно в том чтобы получить от игрока его цвет. first.getColor() - возвращает цвет первого игрока second.getColor() - возвращает цвет второго игрока currentPlayer.getColor() - возвращает цвет того игрока, который сейчас ходит _______________________________
=) Эти строки используются в Grids.mouseClicked(), немного в другом виде правда. Отдельно я их писал в качестве примера. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||
|
|||||||||||||
| Qawra |
|
||||||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
В Grids.mouseClicked(MouseEvent e) мы создаём обьект currentPlayer который
видимо будет использоваться только в этом классе . Могу я его обьявить private или даже наверно "protected ?
Какой идентифаер присвоить firstDefautColor и secondDefautColor пока не знаю . Они у нас появляются в стартовом окошке как private
Запустила я программу полюбоваться на решётку ... Если кликнуть то часть точек меняет цвет на цвет игрока Там правда прорисовывается лишняя точка в левом верхнем углу с координатами (0,0) которой там теоретически быть не должно . Мы рисуем точки начиная с x=1 , y=1
Точка эта тоже способна менять цвет на цвет игрока. Причём делает она это при первом же шелчке мышки на решётке ! |
||||||||||||||
|
|||||||||||||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
А зачем?. И объект мы не создаем, нет никакого new Player(). Мы создаем переменную, и создаем мы ее внутри метода, так что за пределами метода ее "видно" не будет. private и protected приписывается членам класса чтобы обозначить, возможен ли к ним доступ из других классов или нет. К переменным метода из за его пределов нельзя добраться независимо от того хотите вы этого или нет.
Так новую игру начать в любом случае не выйдет. Нужно стартовое окно setVisible(true) а Grids закрыть. Советую на это забить сейчас.
g.fillOval(getX() - 6, getY() - 6, 6 * 2, 6 * 2); - А вот здесь что у вас??? --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Это я пробовала сама кружочки закрасить
Без этого тоже работает так что я это уже отключила. Точнее я это перенесла в метод
может быть это и вызывало лишнию точку потому что теперь её ужё нет . |
|||
|
||||
| Qawra |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Теперь я думаю можно скрыть точки которые мы создали и попытаться нарисовать точки за игроков .В GridsCanvas я отключаю пока
Когда мы нажимаем кнопку старт у нас запускается конструктор Grids
Метод Grids.mouseClicked я попыталась изменить что-бы начать рисовать точки по очереди цветами игроков . Даже не целюсь в углы решётки.Просто пытаюсь передать цвет и ход .
Это сообщение отредактировал(а) Qawra - 21.1.2009, 21:56 |
||||||
|
|||||||
| Rpahut |
|
||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Вообще говоря у нас программа, если она правильно работает, уже должна менять цвет точки на цвет игрока при щелчке. Так что отключать и менять ничего не надо. Другое дело что у нас не передается ход от одного игрока другому. Логика программы такая: пока пользователь ничего не делает, в нашей программе ничего не происходит. Тут то же что и в настоящих точках, на листочке - пока вы не поставите точку, игра никуда не продвинется. Как только происходит щелчок - запускается метод mouseClicked() и все остальные, в которых наш код и выполняет всю работу, а потом программа снова засыпает до следующего щелчка. Как я раньше и писал:
Не компилируется потому что у вас опять тип переменной вместе с параметром вписан - видно это ваши самые любимые грабли Этот метод вызывает сама Ява - каждый раз когда mouse clicked. Нам этого делать не нужно! Да и в MouseEvent наша программа тогда должна перед этим вписать координаты щелчка, которого еще небыло - как вы собирались заставить это работать?... У нас в Grids.mouseClicked был кусок такой:
Чтобы игроки ходили по очереди, нужно его подправить немного:
Переменную secondPlayerMove выкиньте вообще и забудьте. У нас если fistPlayerMove равно true - значит сейчас ход первого игрока; если fistPlayerMove равно false - значит ход не первого игрока - это то есть второго. Если не ходит первый, значит однозначно ходит второй - у нас их всего двое. ----- Можно посмотреть весь код - классы Grids, GridsCanvas, DrawablePoint и Player? --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||
|
|||||||||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Методом проб и ошибок я нашла чего не хватало для рисования точек при щелчке мышкой .Точки у нас уже созданы и при щелчке они меняют цвет ,но если их создать не прорисовывая , то щелчки по пустой решётке ни к какому эфекту не приводят .
В методе mouseWasClicked вместо repaint(); нужен был points[pointX][pointY].drawCircle(x,y,this.getGraphics());
Любимые мои грабли засели в подсознании . Я слишком много и быстро прочитала о Java . Когда обьём информации превысил определённый уровень - детали перестали цеплятся сознанием и стали формироваться образы в которых переменные были прописаны вместе с параметрами ... Наверно это с сайта sun на котором я каждый день читала структуры классов что бы нарисовать GUI . Особенно трудно когда я за компьютером в школе потому что русский язык там не отображается .В результате я не могу прочитать в текстовом файле то что вы мне рекомендуете сделать и действую как получается . И получаются грабли
|
||||
|
|||||
| Rpahut |
|
||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Боюсь что все то же самое, но не на русском, я написать не смогу. No vy mozhete perevesti russkij tekst v translit na etoj stranice
Ладно.
Точки в любом случае меняют цвет, но этого естественно не видно, если у вас отключена отрисовка. Я так понял вы хотите чтобы пока точка не поставлена ее небыло видно? Для этого достаточно подправить метод DrawablePoint.paint(). Я как-то помнится советовал вам использовать DrawablePoint.paint() вместо drawCircle() - потому что drawCircle(), очевидно, рисует круг и ничего больше, а paint() отображает Точку, и отображает в том виде, в каком нам хочется. У меня например не рисуется сетка на поле - вместо этого непоставленные точки отображаются в виде пустых кружков светло-серого цвета. Поставленные точки закрашиваются цветом игрока. Вы можете сделать как вам больше нравится - например не рисовать "пустые" точки совсем - но paint() все равно должен вызываться для каждой точки. В метод paint() можно добавить условие, проверяющее поставлена точка или нет, и в зависимости от результата менять код рисования точки. Я пробежался по коду и сдается мне что у ваших точек color==null когда они не поставлены - это можно использовать:
И не надо ломать голову - просто вызываете paint(), а точка уже сама решит, рисоваться ей или нет. Объектно-ориентированное "разделяй и властвуй" в самой наглядной его форме. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||
|
|||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
В транслите я не только глаза сломаю но и мозги могу вывихнуть .
Русский конечно лучше ... cегодня на свой ноут самодельные русские буквы приклеила Я уже пробовала использовать paint() , но у меня по какой-то причине не рисовалось и я этот метод удалила . Потом я использовала drawCircle и он рисовал пустые кружочки . Затем я заменила в самом методе drawCircle на fillOval и всё чудно прорисовалось. То есть мои точки немного овальные получились но не пустыми. Название метода drawCircle осталось по инерции. Сам метод рисует овальные цветные точки .Нужно ли его менять в интересах логики игры или можно оставить ? У меня решётка прорисовывается но точки ставятся где угодно ( даже друг на друга можно ставить ) . Для того что-бы они могли ставиться только в углах решётки нужно видимо подкорректировать методы работающие с координатами
но думаю что это не будет работать во всех возможных случаях . Могут быть OutOfBoundary Exceptions... |
||||
|
|||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Ну для начала - в предыдущем сообщении я приводил код, там метод подразумевался именно paint(); я сам запутался и не то название написал.
Игре абсолютно безразлично, как называются методы (кроме спец. случаев, вроде mouseClicked); но принято давать методам(и классам и переменным) имена, отражающие их назначение - с расчетом на то, что кто-то помимо программиста будет читать код, или вы сами, скажем через годик, откроете исходники и попытаетесь в них разобраться. Пока метод drawCircle() рисует только круг - можно называть его так. Но - опять то о чем я говорил, и немного забегая вперед - рисование точки это не просто рисование круга. По меньшей мере там: 1. не рисуется ничего, если точка не поставлена 2. рисуется круг, если точка поставлена 3. когда точка захвачена (внутри замкнутого контура), это тоже влияет на внешний вид точки Все вместе это нужно называть более общим словом - вроде paint() или display(). Дальше - все что нужно для рисования точек у нас уже есть. Если вас не устраивает, как рисуется точка, то вы меняете код в методе paint() (или drawCircle()) - потому что именно этот метод определяет, как рисуется точка. Может показаться не очень логичным, что paint() нужно вызывать даже для точек, которые не должны быть видны.
Но класс GridsCanvas, в котором у нас рисуются точки, не может решать, какую точку рисовать, а какую нет - у нас происходит "разделение труда" между классами, и GridsCanvas(второе имя Field) отвечает за то чтобы каждая точка рисовалась на положенном ей месте на поле. Точка не может решать, на каком месте ей нарисоваться, но она может решать рисоваться ли ей вообще. ====================================== Смысл Объектно-Ориентированного программирования в том, что программа разделяется на объекты-классы, каждый из которых занят своим делом. Когда вы пишете код класса DrawablePoint, вам не нужно держать в голове код остальных классов. Можно вообще забыть на время что есть еще какие-то классы - потому что все нужное точке она хранит внутри себя:
То же с классом GridsCanvas:
Чо-то опять длинновато получилось... --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Методы я разделила . Теперь они выглядят так
|
|||
|
||||
| Rpahut |
|
||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Погонял немного нашу программку.
На данный момент есть следующие недочеты: 1. Точка закрашивается при щелчке в клетку справа-внизу от нее. Пришла пора править screen2field():
2. Точка перекрашивается даже если она уже занята другим игроком. Чтобы этого не происходило, нужно добавить проверку в setNewColor()
3. Ход все равно передается следующему игроку, даже если предыдущий щелкнул в занятую точку. Мы используем значение, возвращаемое setNewColor(), чтобы определить, удалось ли игроку поставить точку или нет, и передадим ход только если удалось:
4. При закрытии окна появляется диалог "Would you like to stop the game ?", но окно закрывается независимо от того would я like или нет. Может оставить одну кнопку Yes? --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||
|
|||||||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Точки которые созданы заранее и хранятся в массиве у меня на решётке не видны .А точки создаваемые при щелчке мышкой рисуются там где мышкой щёлкнули..даже друг на друге .
Я попробовала изменить screen2field но пока поведение точек не изменилось.Может быть надо поправить и field2screen что бы был эффект попадания в углы решётки ? После введения проверки в setNewColor() точки перестали перекрашивать друг друга но при неполном перекрывании новая точка того же цвета всё-таки рисуется. Если щёлкать мышкой и чуть чуть смещать курсор можно нарисовать линию из частично перекрывающихся точек одного цвета. В mouseWasClicked мне пришлось оставить points[pointX][pointY].paint(x,y,this.getGraphics()); потому что без него точки не рисуются .
видимых изменений это не принесло потому что мы не смогли привязать координаты новых точек к координатам точек в массиве. Наши точки пока гуляют сами по себе mouseClicked скомпелировался нормально . Кнопочку я попыталась убрать изменив ту часть кода где она мне встретилась
Хотя это пустяк по сравнению с точками "гуляющими" по решётке . |
||||
|
|||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
ТАМ они и не должны рисоваться. У вас есть метод paintComponent() в котором происходит(ну, должна происходить) отрисовка. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
paintComponent() происходит отрисовка точек которые заранее созданы в массиве и самой решётки .Мы не определяем их цвет .
Оба метода для рисования точек на данный момент :
В методе mouseWasClicked происходит рисование точек цветами игроков при щелчке мышкой.Они то у нас и гуляют сами по себе . Нам нужна валидация их координат на предмет совпадения с координатами заранее созданных точек которые ещё не имеют хозяина. Может быть просто перебирать координаты заранее созданных точек на предмет совпадения с координатами щелчка мышкой плюс минус 5 пикселей ? Если такая точка существует - мы её закрасим , а если нет пускай пробуют ещё раз щёлкнуть |
||||
|
|||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Смысл есть - для чего мы использовали setNewColor()? Когда игрок тыкает в точку, меняется хранимый в ней цвет, и она рисуется этим цветом. paintComponent() вызывается всякий раз, когда щелкается мышка (проверьте, в mouseClicked() должна быть строчка repaint();), поэтому всякий раз перерисовывается все поле - если точка получила цвет, она появится на экране. Ах да мой косяк. Запостил mouseClicked() без repaint'а --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
А я вчера пыталась найти кто же вызывает paintComponent() .....
Мне это было жутко интересно Потом я смирилась и решила что это какой-то особый метод который и вызывать то не надо - работает автоматом . Теперь у нас точки ставятся по углам решётки Но мы ещё не применяли метод
Будут ли нарисованные точки храниться в отдельном массиве или можно использовать массив который уже есть с заранее созданными точками ? |
|||
|
||||
| Rpahut |
|
||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
paintComponent() на самом деле вызывается на усмотрение Явы, например когда окно разворачивается из свернутого состояния. repaint() мы используем чтобы сообщить Яве что мы изменили поле и его надо перерисовать.
А field2screen() уже используется здесь для перевода координат точки на поле в экранные координаты:
Работать мы будем с теми точками которые у нас есть. ______________________________________ Собственно прежде чем идти дальше предлагаю внести пару штрихов в код. 1. Сейчас у нас если пощелкать у самого правого края экрана (или внизу) происходит исключение ArrayIndexOutOfBoundsException, потому что в результате пересчета экранных координат щелчка в "полевые" получается что x или y за пределами массива
Чтобы этого не происходило мы добавим проверку координат. Сначала вспомогательный метод для проверки координат:
Сама проверка:
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||
|
|||||||||
| Rpahut |
|
||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
2. Рисование точек начинается с координат [1,1], т.е. не видно целый столбец и целую строку точек, хотя они все равно обрабатываются программой:
Меняем на
Теперь рисуются все точки, но слева и сверху они прилипли к краю окна. Нам придется сдвинуть всю сетку вместе с точками вправо-вниз, и заодно увеличить окно, чтобы точки не выезжали там за его край. Сначала увеличим размер окна на одну клетку. Было:
Стало:
Теперь места достаточно чтобы подвинуть сетку. Дорабатываем paintComponent():
translate(x, y) используется чтобы сместить пространство отрисовки. Здесь мы смещаем его вправо-вниз на размер клетки так что все рисуемые объекты тоже смещаются на это расстояние. translate(-x, -y) в конце используется чтобы вернуть все как было (после отрисовки). Без него поле будет смещаться дальше и дальше при каждом вызове paintComponent() и уедет с экрана. Ну и, раз уж мы сдвинули сетку, придется поправить и screen2field(), чтобы точки попадали в мышку как и раньше.
Это сообщение отредактировал(а) Rpahut - 27.1.2009, 22:56 --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||
|
|||||||||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 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 |
|||
|
||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Там нужно сделать две вещи. Во-первых, указать чтобы окно не закрывалось автоматически: setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); Во-вторых - вручную закрыть окно, если пользователь выберет Yes.
__________________________ Вам показывали что BlueJ умеет генерировать документацию? Вобщем, он умеет, нужно только составить описание классов и методов.
Потом в BlueJ выбираем Tools->Project Documentation и получаем документацию. Вряд ли там получится 100 страниц, но... How to write Doc Comments for the Javadoc tool --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
С окошком наконец-то получилось .Я пробовала раньше setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); но это приводило к невозможности закрыть программу вообще . Теперь она закрылась
То что BlueJ делает документацию от нас естественно держат в секрете . Хотя не думаю что это может помочь . То что они хотят это скорее реферат чем документация. ==================================================== Часть 1 : Описание проблемы , Use-Case Diagrams ( ещё не знаю что это такое , может быть это из UML ), причины по которым написание программы необходимо и возможные пути решения поставленной задачи. Часть 2: Описание использованных алгоритмов и их детальный дизайн ( псевдо-код или flow chart ) Часть 3 : Описание применённых в программе принципов Обьектно-Ориентированного программирования и диаграммы классов . Часть 4 : Applications of Java APIs Часть 5 : Процедуры тестирования Часть 6 : Solution Evaluation ,User Manual , Screenshoots Приложение : Исходный коде программы ================================================== Приступаю к обдумываю первой части с использованием глаголов в будущем времени .Зачем писали программу ...в целях экономии бумаги школьниками |
|||
|
||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Хотелось мне как-то выделить точку которая была поставленна последней.
Пока самое простое что пришло в голову это нарисовать у этой точки чёрный ободок. При небольшом дополнении к методу drawCircle
|
||||
|
|||||
| Kakadu |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 273 Регистрация: 19.3.2008 Репутация: нет Всего: 7 |
Насчет ободка предлагаю такое решение: добавим ещё одно поле а классе GridsCanvas и назовем его LastPoint. К классу DrawablePoint добавим метод "нарисовать ободок" и После перерисовки всех точек вызовем для последней точки рисование ободка.
У нас получается что поле характеризуется массивом точек, состояние которых описывается в поле color: 1)null - не точки: 2)Цвет 1го игрока - первый игрок, 3) 2го - второй. Мне не кажется это очень хорошим решением. Положим мы дошли до того некоторого места в написании проекта, и теперь нам предстоит заниматься замыканием контура. На сколько я помню игру "точки" замыкать контур можно, если замыканием отрезается область, содержащая хотя бы одну точку противника; при проведении границы мы не должны пересекать уже проведенных вражеских ребер. На текущем этапе проектирования нам придется вводить массив на ребра, находящиеся на поле (читайте хранить несвязный граф) и хранить, участвовала ли каждая точка в замыкании пути. ИМХО, мне это не нравится. Я бы оставил просто массив int равный размеру поля. Обходя его я бы рисовал каждую точку. (Возможно, после замыкания контура мы захотим наводить контур более жирной линией: тут начнутся проблемы. Мелочь типа наведения ободка на данном этапе легко добавляется, как добавить жирный контур мне пока не очевидно). Классы это, конечно грамотно, но... В принципе я с массивом погорячился: можно добавить в класс DrawablePoint атрибут, принадлежит ли она какому-нить замыканию. Что будем делать, когда игрок делает ход? Тут надо привести нетривиальный алгоритм поиска замыкания. Как известно из курса мат. анализа, положительным направлением обхода контура будет такое направление при котором внешняя нормаль в данной точке границы контура при повороте по часовой стрелке (читайте при умножении на матрицу 2х2: (0 -1 1 0) ) совпадает с направлением касательной, т.е. с направлением движения. Итак, мы имеем точку, в которую только что кликнули. окрестные 8 точек можно воспринимать как циклически замкнутую строку (в принципе это даже не так важно). Нада какой-нить пример:
вот наши 9 точек, в центр только что нажали. окружность разобьется на две группы точек: {(2,0)} и {(0,0),(0,1),(1,2)}. Проверять, что центральная точка вместе с верхними тремя замкнет контур не нужно, так как мы это уже делали, когда добавляли эти три точки (некая индукция, если рассуждать в терминах математики). значит мы должны проверить не замкнет ли центральная верхние три с нижней. далее мы выберем одно из 4х стартовых направлений (т.к. суммарное кол-во точек в обеих группах=4) и будем так же выбирать направление со следующими точками. При этом надо маркировать (где-то хранить точки пути) Кажется я начинаю запутываться. Извините за этот бред, надеюсь я никого не напугал нашими перспективами. Сам я Java не изучал (настала пора начинать!), но морской бой в Дельфях написать могу. Постараюсь помочь в написании этой дикой вещи. -------------------- Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Kakadu дело говорит; только я бы сделал выделение двух последних точек, по одной на игрока, иначе зачем это не совсем понятно. Kakadu, на правила мы забили. Точки можно соединять если они рядом, принадлежат одному игроку и если новое соединение не пересекает уже существующее. Счет ведется по захваченной площади. По поводу нетривиального алгоритма поиска - не совсем понятно как найти внешнюю нормаль, если имеется только взаимно равноправное соединение между точками и где внешняя сторона еще не известно. Предполагается добавление в DrawablePoint массива для хранения точек, с которыми соединена данная точка, и через него все остальные действия. Поиск контура и захваченных точек задумывался при помощи рекурсии, поскольку рекурсия мне роднее матана Используются следующие идеи: 1. Если из всех соединенных друг с другом точек выкинуть тупиковые (т.е. имеющие максимум одно нетупиковое соединение) точки, то что останется и будет замкнутым контуром. 2. Построив после этого прямоугольную границу вокруг контурных точек и расширив ее на одну клетку в каждую сторону, можно из внешней части запустить поиск, который, теоретически, найдет все точки вне контура. Сейчас я, кажется, вижу в этом пункте одну серьезную дырку... Также, кажется, я вижу как ее заделать --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Самое лучшее описание алгоритма я видела здесь
http://pointsxt.logicsworld.net/forum/index.php?showtopic=69 К сожалению регистрация на форуме не работает ( как видимо и сам форум ). |
|||
|
||||
| Kakadu |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 273 Регистрация: 19.3.2008 Репутация: нет Всего: 7 |
А мне не понятно зачем выделение последней точки каждого игрока
Вообще это мелочи. Надо замыкание срочно писать. -------------------- Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли |
|||
|
||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Расказываю и показываю как я последнию точку выделила
Много мучалась потому что ободок зарисовывался цветом игрока . Пришлось вводить private boolean lastPoint два классах подкорректированы
и
Это сообщение отредактировал(а) Qawra - 30.1.2009, 17:48 |
||||
|
|||||
| Rpahut |
|
||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
А ну если в этом смысле... тогда вообще можно надпись сделать вроде "Ход игрока 1" и "Ход игрока 2". Заголовок окна менять например. Добавлено @ 18:59 Qawra, хитро Ну это можно убрать:
и передавать Graphics прямо в метод:
Ни к чему нам плодить ненужные переменные класса. Это сообщение отредактировал(а) Rpahut - 30.1.2009, 19:01 --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||
|
|||||||
| Rpahut |
|
||||||||||||
![]() 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 массив
Модифицируем конструктор DrawablePoint:
Добавляем в DrawablePoint методы для получения ее координат:
Добавляем drawConnections() и используем его в DrawablePoint.paint():
===================== Вторичные изменения: Поскольку мы изменили код конструктора Точки, создавать точки теперь тоже нужно по-другому:
То же самое с кодом отрисовки - экранные координаты точки теперь хранятся внутри нее и передавать их в paint() не нужно:
================== Кажется ничего не забыл. Думаю дальше над созданием соединений. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||
|
|||||||||||||
| Kakadu |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 273 Регистрация: 19.3.2008 Репутация: нет Всего: 7 |
Гм, Уважаемая. Мне такой подход в наведении окаёма вокруг точек кажется несколько подозрительным, как по мне то нелогично для каждой точки добавлять переменную, показывающую последняя ли она, когда по логике игры таких точек будет максимум две. (Логично ссылки на эти точки вынести полем класса DrawablePoint) Но я поверил наслово, скопипастил и убедился, что указанное выше не очень работает.
Собственно, у меня вопрос. Где вы присваиваете какой-нить точке true в поле для рисования окаёма? P.S. Мне долго надоедало, что если я нажал мышку, немного её подвигал и точка не ставилась. Теперь я всё, что было написано в MouseClicked переписал в MouseRealeased. Предлагаю автору сделать также. Это сообщение отредактировал(а) Kakadu - 31.1.2009, 15:00 -------------------- Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли |
|||
|
||||
| Qawra |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
А зачем вы нажали мышку и немного подвигали ? Вы же не рисовать собирались а территорию захватывать
Ваш метод рисования ободка я воплотить пыталась но у меня не получилось .Очень бы хотелось взглянуть на код . Буду очень вам признательна если вы его опубликуете и обьясните как он работает . У нас сейчас с замыканием поля много работы . Я внесла последнии изменения и там есть одно узкое место в paintComponent
пишет что не может быть применена к paint (int ,int , java.awt.Graphics ) я подставила x и y .Строчка
начались
Создаю сейчас документацию . Use Case Diagram для нашей игры оказалась совсем несложная . ![]() |
||||||
|
|||||||
| Rpahut |
|
||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Да есть такой момент - но это на мой взгляд вопрос "доводки" игры и решать его именно сейчас, да и решать вообще, мне кажется нет необходимости. Вообще, если по-хорошему делать, надо запоминать где была нажата кнопка мыши, и если указатель не уходил слишком далеко от этого места, засчитывать отпускание как клик в Точку. Можно и просто следить чтобы нажатие и отпускание было в пределах одной Точки.
Правильно пишет. Очевидно метод paint() все еще не исправлен. Он должен начинаться вот так:
Нужно код посмотреть. Скорее всего проблема в this.g или может в setColor(color); Кстати, расшифровка сообщения об ошибке:
Смотрите в эту строку и ищите что там не так. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||
|
|||||||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Вы были правы . Я исправила в двух местах this.g на g и всё нормально заработало .
|
|||
|
||||
| Kakadu |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 273 Регистрация: 19.3.2008 Репутация: нет Всего: 7 |
![]() Я тут кое-что состряпал. Правда пришлось несколько изменить количество классов и логику. Ну да ладно, потом распишу, если будут вопросы. P.S. прикрепляю исходники на NetBeans. Это сообщение отредактировал(а) Kakadu - 2.2.2009, 14:08 Присоединённый файл ( Кол-во скачиваний: 5 )
Faraon.zip 41,51 Kb-------------------- Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Cочетание цветов понравилось . В нём что-то есть . У меня к сожалению нет NetBeans . Поэтому я просто запустила jar файл и покликала мышкой .
Точки были а крестиков небыло ... Но всё равно неплохо . Какие идеи о замыкании поля ? Это сообщение отредактировал(а) Qawra - 2.2.2009, 20:31 |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Крестиков в самом деле почему-то нет. В jikes собрать не получилось, качаю Сеть-Бобы.
Кстати, тут та же дырка, что и в моей версии ![]() Верхняя красная точка будет считаться захваченной, потому что волна от нее пойдет только по вертикали и горизонтали и до края поля не доберется. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Я поняла что если линии начать рисовать до того как контур можно замкнуть то играть не получиться . Они будут мешать искать замыкания . Красная линия автоматом соединилась ?
|
|||
|
||||
| Rpahut |
|
||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Создание соединений
Создаваться соединения будут в mouseWasClicked(), но сначала подготовим почву. От Точки нам нужны следующие методы:
Дальше можно вставлять метод создания соединений в GridsCanvas
Используем его в mouseWasClicked():
Добавлено через 9 минут и 11 секунд Qawra, да, между соседними точками автоматически образуется соединение, если этому ничего не мешает. Если в клетке уже есть одно диагональное соединение, то второе там уже не образуется. Это как раз правильно - просто при проверке захвата нам надо будет поиск по другому как-то делать. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||
|
|||||||||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Пояснения по поводу создания соединений:
После щелчка пользователя в точку, если ее цвет успешно изменился, мы перебираем все точки рядом с ней. Если цвет соседней точки совпадает с цветом нашей точки, мы их соединяем друг с другом. Так же, чтобы программа не падала, каждый раз проверяются координаты точки (goodCoords()), и если мы соединяем по диагонали, проверяем чтобы в клетке небыло другого диагонального соединения:
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Как интересно получилось ! Мне нравиться ! Можно будет ещё соединяющие линии потолще сделать и цветом заливать захваченную территорию . Совершенно другое ощущение от игры . Не надо ждать пока вражеские точки в плен попадуться . Динамично отхватываешь по кусочку территории и душа радуется
Не знаю как увеличить толщину линий .Залить территорию можно с Graphics FillPolygon . Только где его прописать ...В makeConnections ? Для меня удивительно что компайлер понимает что такое
Но если бы меня попросили их заранее написать я бы их написала через точку p.x и p.y (что выглядит немного странно ) . . Теоретически , p - это обьект , а координаты это его свойства - поэтому я бы их написала через точку ... В каких случаях можно обойтись без точки ? Буду пробовать изобразить алгоритм графически используя flow chart ... хотя нет ...oн слишком сложный что бы сразу рисовать диаграмму .Надо сначала в псевдо-коде его описать . Это сообщение отредактировал(а) Qawra - 3.2.2009, 14:58 |
|||
|
||||
| Rpahut |
|
||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
px и py имеют тип int - это видно там где они созданы:
int тоже объект, но объект примитивного типа - т.е. он встроен в сам язык программирования и имеет только одно свойство - значение. Поэтому к этому свойству можно добраться без точки. Объект DrawablePoint мы создавали сами - написали класс, его переменные и методы, с помощью которых с ним можно что-то делать. К переменным и методам как раз обращение идет через точку.
Как линии сделать толще я тоже не знаю. Не говоря уж о заливке. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||
|
|||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
||||
|
||||
| Rpahut |
|
||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Ок, выкладываю что у меня получилось. Алгоритм еще нуждается в проверке.
1. Добавляем в DrawablePoint:
2. Добавляем в GridsCanvas массив - член класса:
3. !!! Рекурсивная ф-ция определения захваченности точки !!!:
Тут много буков, но это из за повторяющегося кода. Разберем позже. 4. Добавляем в mouseWasClicked():
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||
|
|||||||||
| Rpahut |
|
||||||||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
______________________________________________
Qawra, вы рекурсию проходили? Тут в общем смысл в том что метод pointCaptured() вызывает сам себя, но с другими параметрами, для соседних точек. И вызывает до тех пор, пока не убедится что наша точка внутри контура, или наоборот не внутри... Если точка внутри замкнутого контура, то от нее нельзя прошагать до края поля, не наткнувшись на контур. Если мы добрались до края поля, значит контура вокруг точки нет. Что важно для рекурсивного кода - это чтобы он не вызывал сам себя до бесконечности, иначе мы никогда не дождемся результатов проверки
Вторая половина проверки
это собственно проверка на попадание в границу - если наткнулись на незахваченную точку с цветом текущего игрока, то дальше тоже не идем. Вернее возвращаемся на шаг назад, и идем дальше в каком-нибудь другом направлении. Если мы на этой точке еще не были и если это не граница, помечаем точку
и вызываем pointCaptured() для соседних точек - сначала для точек по горизонтали и вертикали:
Они тоже вызывают pointCaptured() для своих соседних точек, и те для своих тоже, и так пока есть непроверенные точки. Правда, если в какой-то момент pointCaptured() будет вызван для точки за пределами поля, то он вернет ноль - тогда в одной из этих строчек сработает проверка, например тут:
В этом случае поиск завершается досрочно - ноль возвращается и возвращается, пока не попадет к нам в руки, сюда:
откуда мы метод и вызываем. Если точка внутри замкнутого контура, то проверка продолжится пока мы не посетим все точки внутри контура. В этом случае ноль нигде не возвращается и выполнение доходит до строки
Единица опять же возвращается сюда
и так мы понимаем, что точка захвачена. __________________ Там возможен еще третий вариант - когда точка принадлежит текущему игроку, метод возвращает -1. Так что игрок может захватить собственные точки, только если перед этим они были захвачены другим игроком. Пока не знаю как от этого избавиться. __________________ В методе pointCaptured() помимо соседних точек по горизонтали и вертикали проверяются еще и точки по диагонали. Как выяснилось это необходимо. Перед этим дополнительно проверяется, нет ли на пути диагональной границы, в остальном здесь то же что и выше.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||||||||||||
|
|||||||||||||||||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
3 пункт добавляем в GridCanvas ? Я пока его туда определила ..
Mы реккурсию на практике будем проходить через год .Но я о ней читала . Теория графов которая нужна в нашем случае тоже начнётся в следующем году . Это сообщение отредактировал(а) Qawra - 6.2.2009, 00:01 |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Теорию графов я еще и сам не проходил. Переделаем в следующем году
Да, pointCaptured() должен быть в GridsCanvas - он ведь там и используется. ЗЫ Если будут вопросы - задавайте. Разберемся с этим и займемся доводкой программы. ЗЫЗЫ Метод pointCaptured() должен быть private. Куда мои глаза глядели... Это сообщение отредактировал(а) Rpahut - 6.2.2009, 00:00 --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Всё скомпелировалось но с функциональной стороны изменения не заметны .
Захватываем всё ! И точки ... и пустую территорию ! Ни от чего не отказываемся ! Не знаю точно какой язык будем в следующем году изучать . Звучит как Императивное и обьектно - ориентированное программирование . Наверно С и С++ Видела студентка у них ( на курс старше ) проект "виртуальное пианино" писала и страдала что ей плохо от запоздалой нотной грамотности Значит зададут нам что-то связаное с мультимедия . Это сообщение отредактировал(а) Qawra - 6.2.2009, 00:18 |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Чтоб было видно изменения, нужно править DrawablePoint.paint() - учесть в коде значение переменной captured и менять отображение точки.
Тут очень много вариантов, как выделять захваченные точки, так что конкретного решения не предлагаю. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Я пока пытаюсь нарисовать flowchart к алгоритмам .
не умею прикреплять большую картинку , даю ссылку не неё http://img6.imageshack.us/my.php?image=flowchart2an6.png Это ещё не реккурсивный зверь . Это тот playerColor о который я так часто спотыкалась Это сообщение отредактировал(а) Qawra - 7.2.2009, 17:54 |
|||
|
||||
| Kakadu |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 273 Регистрация: 19.3.2008 Репутация: нет Всего: 7 |
Нада мне вас догонять=) Вот выкладываю свое творение.
Присоединённый файл ( Кол-во скачиваний: 10 )
Faraon.zip 52,62 Kb-------------------- Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Куда ближе к оригинальным правилам
Qawra, как там у вас дела? --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Я пока медленно схожу с ума от Сlass диаграмм ...
Наверно поэтому у меня в последней версии Какаду линии не рисуются |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
У меня не скачивается а открывается.. но при этом ничего не понятно ...
Мы когда в Grid Canvas метод makeConnections прописылали
for(int j=-1; j<=1; j++) { for(int i=-1; i<=1; i++) { был для зазора в координатах ? пытаюсь сейчас весь алгоритм рисования линий с начала до конца проследить и словами связно его обьяснить . пока он у меня идёт от DrawablePoint к mouseWasClicked . А надо бы наоборот Это сообщение отредактировал(а) Qawra - 10.2.2009, 23:34 |
|||
|
||||
| Kakadu |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 273 Регистрация: 19.3.2008 Репутация: нет Всего: 7 |
Мда, перебилдить забыл, когда архивировал. Извини Qawra.
(Я тут заметил, что с проектированием интерфейса у меня какие-то заморочки. Надо книжку про Swing подчитать. Обидно только, что в четверг уже начинается универ.) Я вам скажу, Rpahut, что это прикольно придумано так просматривать окружающие точки вложенными циклами от -1 до 1. Интересно, вы пробовали читать мой код? Мне кажется, что отойдя от строго использования классов при описании поля я нарушил читабельность кода. Вернее, не читабельность, а наглядность реализации идеи... Наверное это не очень хорошо. Можете как-то прокомментировать? -------------------- Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
у меня к сожалению классы не открываются ( программы нет нужной )
поэтому я не смогу код посмотреть и прокоментировать :( |
|||
|
||||
| Rpahut |
|
||||||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Qawra, исходный код можно посмотреть в архиве который выкладывал Kakadu, файлы с расширением .java . Я выложил только саму программу - архив нужно как есть сохранить на компьютер, щелкнуть его второй кнопкой и выбрать "Открыть с помощью"->Java.
BlueJ кстати тоже умеет так упаковывать, программу вместе с исходными кодами и документацией, или без них. _______________________________
Вот это я не совсем понял В жизни соединений происходит два важных события - это создание и отрисовка. Поскольку новые соединения могут образоваться только после добавления новой точки, мы вызываем makeConnections() из mouseWasClicked(), когда известно что точка добавлена. Соединения обнаруживаются и сохраняются в точках. Отрисовка соединений происходит вместе с отрисовкой точки, что в свою очередь происходит при отрисовке поля. Попробую запутать вас совсем: _____________________________ Этот цикл перебирает все точки вокруг проверяемой:
i и j меняют в цикле свои значения от -1 до 1; если i прибавлять к x-координате проверяемой точки, то мы получим х-координату точки слева от проверяемой( х+(-1)=х-1 ), потом с такой же координатой (х+0=х), потом координату точки справа (х+1). Аналогично для координаты y и переменной j. Все вместе позволяет перебрать точки в таком порядке: 123 456 789 Красным отмечена проверяемая точка. Внутри циклов выполняется несколько проверок - они необходимы чтобы определить две вещи: необходимость и возможность соединения.
Первое что мы проверяем, это не выпали ли наши координаты (x+i и y+j) за пределы поля; не рекомендуется работать с массивом за его пределами
Здесь не совсем проверка. Просто, поскольку дальше мы несколько раз обращаемся к соседней точке, удобнее выложить ее во временную переменную, тогда нам не нужно будет дальше использовать страшное "points[px+i][py+j]" а вместо него использовать b. Разумеется, при каждом проходе цикла туда кладется очередная соседняя точка.
Если a и b - разные точки, и в то же время имеют одинаковый цвет - да, в таком случае соседняя и проверяемая точки принадлежат одному игроку; налицо необходимость соединения. a!=b мы проверяем, потому что в процессе перебора соседних точек нам должна попасться и текущая точка. Такой уж у нас перебор
Последняя проверка - на наличие другого диагонального соединения в той же клетке. Если клетка уже перечеркнута по диагонали, мы не можем построить соединение по другой диагонали. Для этого нам нужно сначала найти две другие точки в той же клетке. Очень удобно то, что для этого достаточно взять 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Как продать идею? |
||||||||||||
|
|||||||||||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Kakadu, код я ваш читал но не вникал сильно
Кстати, почему не используются Player1Dead и Player2Dead? Как вы собираетесь подсчитывать очки игроков? --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
спасибо.. многое стало понятней .
А линии то всё равно не рисуются |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
У Kakadu игра на захват вражеских точек идет. Так что контур обводится только если внутри него есть вражеская точка.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Rpahut , мне ваша версия так понравилась что я даже картинку прикрепила с почерневшей точкой попавшей в плен
![]() Исправьте меня если я не права , мы не использовали полиморфизм но мы использовали точно три принципа обьектно-ориентированного программирования : encapsulation , inheriance , modylarity . Data abstraction мы где-то наверно тоже использовали .... Пытаюсь её отыскать .. Это сообщение отредактировал(а) Qawra - 13.2.2009, 21:32 |
|||
|
||||
| Kakadu |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 273 Регистрация: 19.3.2008 Репутация: нет Всего: 7 |
Модульность - это не один из Китов ООП. Полиморфизм - да (но вроде его ни у вас, ни у меня нет). Модульность - вообще ерунда какая-то
P.S. Можете выложить ваши исходники? Просто по всем страницам мне их собирать несколько лень=) P.P.S. Кстати, наследования у вас вроде тоже нет=) -------------------- Добрые мариносы долго кормили украдкой маленьких зерлингов. От этой украдки зерлинги пухли и дохли |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Ну для полиморфизма маловат проект. А наследуются у нас по меньшей мере JFrame и JPanel, может и что-то еще.
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 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 |
|||
|
||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
26 метров?! Что там такое в архиве?
Ага понятно. Прикольно PS Qawra, если все переменные классов public, то это не инкапсуляция Это сообщение отредактировал(а) Rpahut - 15.2.2009, 00:46 --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
||||||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Ну они же не все публик !
смущает меня то что некоторые из них повторяются в разных классах . Не знаю нормально ли это . Изначально так написала потому что иначе не компелировалось . public Player first; public Player second; и public int rows=20; public int cols=20; public int cellSize=30 ; private Color color; например прописаны дважды ... Под Data Abstruction я хочу подвести класс ColorChooser
Здесь делается то чего мы не знаем что и оно показывает нам диалог выбора цвета Мы ведём машину не зная что происходит внутри двигателя . Не удалось мне избавиться только от дублирования public int rows=20; public int cols=20; public int cellSize=30 ; в двух классах Grids и GridsCanvas Это сообщение отредактировал(а) Qawra - 15.2.2009, 12:02 |
||||||||||||||
|
|||||||||||||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Qawra, почитайте еще про инкапсуляцию.
Каждый класс это отдельное пространство; если у нас два класса то в них хоть все переменные могут иметь одинаковые тип и имя. Как ни крути, а Grids.rows и GridsCanwas.rows отличаются полными именами, т.е. хотя и там и там rows, имена переменных все равно разные. Момент второй - ключевое слово public применяется только если нужно сделать член класса доступным извне напрямую. Уверяю вас что мы нигде не работаем с переменными напрямую, только через методы классов, которые и помечаем как public. Например у нас в DrawablePoint есть private переменная color и есть public метод setNewColor(). Программа не будет работать правильно, если записывать цвет прямо в переменную, поэтому мы ограничиваем доступ к ней. Если что компилятор даст нам по рукам - так исключается возможность оставить в программе ошибку. _________ Если мы не знаем что делает JColorChooser.showDialog(), нам лучше им не пользоваться Например тип Color можно считать абстрактным(?). Кто его знает что там у него внутри. Добавлено через 8 минут и 26 секунд Вот немного код почистил и добавил кое-что. Присоединённый файл ( Кол-во скачиваний: 10 )
tochki.rar 5,59 Kb--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Огромное спасибо за кусочек
у меня до него никак руки не доходили , хотя я чувствовала что он нужен . В Grids я полностью убрала Serializable и поменяла переменные на private ..
может
Это сообщение отредактировал(а) Qawra - 16.2.2009, 21:14 |
||||||
|
|||||||
| Rpahut |
|
|||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
Если не указывать модификатор доступа, члены классы доступны везде внутри пакета, почти как public.
В классе Grids
можно сделать константами или final, в классе GridsCanvas пускай будут private. --------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
|||
|
||||
| Qawra |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Так и сделаем ... К сороковой странице документации я уже сдаюсь на всё .. документацию я тоже уже сдаю ..
Что будем ещё привинчивать ? Можно сделать решётку resizable . Но как это сделать в момент игры ... У нас же массив с точками создан до начала игры . Если игроки захотят изменить размер поля - массив придётся создавать заново . Значит точки которые уже нарисованы игроками надо будет скопировать из одного массива в другой . Потдерживает ли Java такие копирования массивов я не знаю . |
|||
|
||||
| Rpahut |
|
||||||||
![]() 0xdeadbeef ![]() Профиль Группа: Участник Сообщений: 243 Регистрация: 9.4.2006 Репутация: 5 Всего: 7 |
А вы захват точек уже впаяли в программу? Если да, предлагаю сначала добавить подсчет очков.
Для начала добавим в GridsCanvas несколько переменных, для хранения очков:
Выводить счет будем так:
Метод пересчета очков. Здесь творится полное ГГ, в основном потому что я сразу не подумал о том как будут считаться очки:
Вызывать этот метод нужно после того куска где захватываются точки:
--------------------
C/C++ GameDevRSS Раздела программирования игрOpenGL - уроки от NeHeКак продать идею? |
||||||||
|
|||||||||
| Qawra |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 188 Регистрация: 6.3.2007 Репутация: 3 Всего: 4 |
Я наверно его ещё не полностью впаяла .. или он пока просто себя не проявляет визуально .. Я была где-то здесь
теперь я пытаюсь скомпелировать это
|
||||
|
|||||
![]()
|
| Правила форума "Программирование игр, графики и искуственного интеллекта" | |
|
|
НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |