![]() |
|
Модераторы: Rickert |
![]()
|
|
| 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Как продать идею? |
||||||||||||||||||||||
|
|||||||||||||||||||||||
![]()
|
| Правила форума "Программирование игр, графики и искуственного интеллекта" | |
|
|
НА ЗЛОБУ ДНЯ: Дорогие посетители, прошу обратить внимание что новые темы касающиеся новых вопросов создаются кнопкой "Новая тема" а не "Ответить"! Любые оффтопиковые вопросы, заданные в текущих тематических темах будут удалены а их авторы, при рецедиве, забанены.
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rickert. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Программирование игр, графики и искусственного интеллекта | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |