Помощь - Поиск - Пользователи - Календарь
Полная версия: Игра "Солнечная система"
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Другие языки
Страницы: 1, 2
Account
Это не совсем игра, но так написано в моем задании.
Вот что мне надо постараться создать:

Моделируется движение планет в солнечной системе и прохождение комет через нее. В упрощенной модели не следует соблюдать реальные пропорции размеров планет, Солнца и расстояний между ними. В данной модели все планеты движутся вокруг Солнца в одной плоскости но с разной скоростью. У планет, Солнца и комет есть определенные размеры и масса, пропорциональная кубу линейного размера. В одном из углов "Солнечной системы" в случайные моменты времени генерируются кометы, летящие в произвольном направлении. Комета и планета престают существовать при столкновении. При столкновении кометы о Солнцем исчезает только комета. На кометы действуют силы притяжения планет и Солнца в соответствии с законом всемирного тяготения, что изменяет их траекторию. Комета вышедшая за пределы "Солнечной системы* исчезает на всегда. У комет есть хвост, направленный в сторону от Солнца, Управление моделью : при помощи клавиш: начать, закончить.

Итак, делаться будет на с++, с помощью псевдографики как в этой теме.
Как изначально представляю себе это. Будет базовый класс фигура, который будет иметь такие показатели. как радиус планеты, масса, сила притяжения, радиус орбиты. Каждая планета наследник от этого класса.
Не понял вот этого в задании
Цитата
масса, пропорциональная кубу линейного размера
Так же пока не представляю как в случайном какого-либо конца экрана запустить комету в каком то направлении, рисовать ей хвост(какми способом) от солнца, ну и физику притяжения с изменением траектории.

Как наверстаю начальный код по планетам выложу, далее нужна будет конечно помощь. Заранее благодарю всех кто откликнется, за советы и помощь.
sheka
Цитата
с помощью псевдографики как в этой теме.
Что-то не нашел там псевдографики.
Цитата
Не понял вот этого в задании
Цитата
масса, пропорциональная кубу линейного размера
m = p * v;
v = 4 / 3 * Pi * r3
в данной модели нужна имитация только кубической зависимости т.к. коэффициент все равно не правильный будет).
Цитата
как в случайном какого-либо конца экрана запустить комету в каком то направлении
rand()
Цитата
рисовать ей хвост(какми способом) от солнца
Например так: ищешь вектор через центр солнца и центр кометы, нормируешь его, умножаешь вектор на длину хвоста, прибавляешь координаты центра кометы. Это конец хвоста. Соединяешь найденную точку с телом кометы помощью касательных к окружности. Вызываешь FloodFill с координатами центра этого треугольника либо рандомно выводишь пиксели в эту область. Представить можешь или нарисовать?
Цитата
ну и физику притяжения с изменением траектории.
F = G * m1 * m2 / r2
Учитывая, что центр масс системы без данной планеты в упрощенной схеме вряд ли искать надо + от ц. солнца он не сильно отличаться будет, тогда принимаем массу другого тела как ц.м солнца:
vпланеты = sqrt (G * mсолнца / rдо солнца)
IUnknown
Цитата
Будет базовый класс фигура, который будет иметь такие показатели. как радиус планеты, масса, сила притяжения, радиус орбиты. Каждая планета наследник от этого класса.
Наследование в таком виде здесь напрочь не нужно... Меркурий, Венера, ... (и т.д. по списку) - это не подвиды планет, а экземпляры класса Планета...

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

Такой ООП нам не нужен.

> Возможно, ты унаследуешься от единого предка НебесноеТело, от которого пойдет Звезда, Планета, Комета

Я бы сделал единый класс НебесноеТело с полем типа (Звезда, Планета, Комета). Этого часто хватает с лихвой, а код проще и читаемей, чем с иерархиями.

> Итак, делаться будет на с++

Так можно наследование на шаблончиках сделать...
Account
Цитата(sheka @ 18.07.2011 0:12) *

Что-то не нашел там псевдографики.

sheka,я не шарю в этом , а по поводу хвоста не совсем понялblush.gif
Цитата
Наследование в таком виде здесь напрочь не нужно... Меркурий, Венера, ... (и т.д. по списку) - это не подвиды планет, а экземпляры класса Планета...

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

Что то не догоняю.blush.gif Сделать три класса Звезда, Планета, Комета, а планеты просто создавать как экземпляры класса планета?
Цитата
Так можно наследование на шаблончиках сделать...

Раньше что то читал, но в данной ситуации пока не догоняю как применить.

TarasBer
> а планеты просто создавать как экземпляры класса планета?

Ты хотел программу без экземпляров классов?

> Раньше что то читал, но в данной ситуации пока не догоняю как применить

Шаблон "небесное тело", параметр - перечислимого типа (звезда, планета, комета). Для каждого значения параметра определяешь шаблон по-своему.
Account
Цитата(TarasBer @ 18.07.2011 17:59) *

> а планеты просто создавать как экземпляры класса планета?

Ты хотел программу без экземпляров классов?

> Раньше что то читал, но в данной ситуации пока не догоняю как применить

Шаблон "небесное тело", параметр - перечислимого типа (звезда, планета, комета). Для каждого значения параметра определяешь шаблон по-своему.


Вопрос в тупик загнал, так как я спросил (приведенная цитата ) про реализацию, знаний то у меня не много. Поэтому спрашиваю и советуюсь, как сделать лучше. ))))
Про шаблоны теоретически понял, на практике пока все сложновато. Так как в примерах наблюдал и делали только с базовыми типами int, float, а не с перечисляемыми.
sheka
Вот псевдографика http://txtart.ru/index.html
Вот случайный хвост Нажмите для просмотра прикрепленного файла
IUnknown
Цитата
Шаблон "небесное тело", параметр - перечислимого типа (звезда, планета, комета). Для каждого значения параметра определяешь шаблон по-своему.
Для этого надо, чтобы компилятор поддерживал частичную специализацию. Турбо С++, о котором шла речь раньше, ее не поддерживает...

Account, чтоб было понятно, о чем говорит Тарас - вот такой код будет прекрасно работать при использовании любого современного компилятора:
Пример (Показать/Скрыть)
, однако в досовском Турбо С++ ты этот пример работать не заставишь... А в других компиляторах нет поддержки graphics. Замкнутый круг.

P.S. Кстати... Я бы начинал написание программы именно с такого вот текстового "каркаса". Который будет тебе сообщать, что там инициализировалось, что в какой позиции находится, и что с чем взаимодействует. А вот когда это все будет нормально работать - тогда просто будешь заменять методы, печатающие информацию, на методы, отображающие ее графически. По крайней мере, я всегда делаю именно так. А то начнешь, сделаешь уже достаточно много, и красиво, и в самый ответственный момент вдруг выяснится, что вот именно то, что тебе сейчас нужно, компилятор не поддерживает. Ощущение не из приятных - все (или многое) переписывать заново... А с текстом ты сделаешь каркас гораздо быстрее, потеряешь меньше времени, и будет не так обидно.
Account
sheka,спасибо за ссылку и за расчеты хвоста, как доберусь, попробую)))

IUnknown, так же спасибо за наглядный пример. Насчет компилятора тут вот как раз загвоздка, нужно именно на досовском(((

Так что буду делать))) Солнце + одну планету нарисовал, как ее запущу так выложу первые наработки)))
Lapp
Забавная тема smile.gif.
С псевдографикой действительно неясно - Account, что же ты все-таки имел в виду? Кстати, подумалось, что та борландовская графика уже вполне заслуженно может переехать в раздел "псевдо" и гордо носить эту приставку к слову "графика" smile.gif. Sheka, суперская ссылка, просто шедевр, я с удовольствием разглядывал, спасибо, +1.

Все же я полагаю, что тут предполагается не текстовая мода, а графическая - в текстовой делать такую задачу все же странно. НО! Но по-хорошему-то (вау! я не припоминаю, чтоб я раньше встречал слова с двумя дефисами, кроме сложносоставных..), по-хорошему-то, надо писать основной код БЕЗ ГРАФИКИ вообще, а визуализацию всю поместить в отдельный модуль. Тогда графика будет, какая захочешь ("брюки превращаются.. брюки превращаются.. в элегантные шорты!" (С) smile.gif). Более того - то, что предлагал volvo877 (весьма ценный совет, на мой взгляд), легко реализуется в рамках этой же модели (как текстовые сообщения вместо графики).

Что касается хвоста (вроде - мелкая деталь, но вызывает большой интерес)), то я бы делал не так, как Шека предлагает (кстати, Шека, не совсем натурально вышло: хвост не сужается на удалении от кометы, а расширяется, хоть и бледнеет). Я бы описывал хвост тоже как потомок все того же самого небесного тела. Точнее - не весь хвост, а его частицы. По физике дела они такие и есть. То есть, примерно так..

Комета испускает частицы очень малой массы, которые имеют разброс скоростей. Интенсивность этого испускания и диапазон скоростей зависят он нагрева кометы, то есть от ее расстояния до Солнца (это все делается в одну строчку). Отделившись, частица летит сама, как все остальные небесные тела. Но есть одно отличие: она испытывает на себе дополнительную (т.е. кроме гравитации) силу - давление солнечного ветра. Эта сила совсем небольшая (поэтому при расчете движения остальных тел ее можно не учитывать), и действует она по радиусу от Солнца. Частицы хвоста можно изображать точками темного цвета (на фоне черного неба). И, наконец, эти частицы должны иметь некоторое конечное время жизни (это неверно по физике, но для модели сгодится). Вот, как-то так smile.gif.

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

Добавлено через 13 мин.
Вот небольшая иллюстрация: Нажмите для просмотра прикрепленного файла
(взято отсюда). Хвост расширяется и немного загибается (благодаря сохранению момента импульса и увеличению расстояния до Солнца). Оба эти эффекта должны естественным образом получиться в описанной мной модели.
Account
Lapp, да просто как то не воспринимается эта досовская графика как полноценная. вот и обозвал ее псевдо)

Итак, вот что сотворил, сильно не пинайте только))

games (Показать/Скрыть)



Не нравиться дергание при отрисовке на концах радиуса орбиты по оси х, но я так понял убрать это не возможно , так как в координатах используются только целые значения?
Цикл для рисовки естественно потом уберу из метода Move. просто для проверки загнал пока.
IUnknown
Цитата
//подставлять неопределенные заранее значения не дает(((
Можно посмотреть, как пробовал?

Цитата
int ix=getmaxx()/2+orbp;
int iy=getmaxy()/2;
xy[0][0]=ix;
xy--[1][0]=iy; // <--- Вот это компилироваться не должно
Неужели TC пропускает такое?
Account
Цитата(IUnknown @ 19.07.2011 21:54) *

Можно посмотреть, как пробовал?

Неужели TC пропускает такое?


Пробовал так
int xy[2][(orbp*4)];// и даже через дополнительную переменную
// Error: Constant expression recuired


По поводу второго, я при набирании поста просто накосячил)
конечно вот так на деле
xy[1][0]=iy;

Просто на ноуте иногда попадаю на доп. функциональные клавиши, в итоге курсор перепрыгивает + как всегда тороплюсь, невнимателен.
IUnknown
Чтобы передавать в класс размер массива надо сделать немного другое описание класса:

template <int orbp>
class Planeta
{
// вот тут все так же, как и раньше, кроме того, что orb не должно быть в конструкторе
public:
Planeta(int r, int clr, int svr): rp®, clrp(clr), svrp(svr)
{ cout<<"Create Planeta\n"; }

// дальше без изменений
};

template <int orbp>
void Planeta<orbp>::Move()
{
int xy[2][orbp]; // Чудо? Ошибки нет...
int ix=getmaxx()/2+orbp; // Здесь тоже...

// ...
}

// Ну, а создавать объект - так:
Planeta<70> P1(10, 11, 10);
Чувствуешь разницу? Передаешь радиус орбиты как константное выражение, и использовать его уже можно... Ну, или простым new выделять память под двумерный массив xy, если тебе так проще...

Попробуй, должно и на TC компилироваться такое...
TarasBer
Если нужен массив неизвестной при компиляции длины, используй векторы.
Или alloca.
Или чистую сишку без плюсов, в новом стандарте там это есть.
Или другие языки.
IUnknown
Тарас, еще раз: чтобы что-то использовать - оно должно поддерживаться компилятором. Турбо С не знает ни про какие векторы. И про новые стандарты тоже. Отсюда и подобные решения проблем вместо решения задач...
TarasBer
> Турбо С не знает ни про какие векторы.

Ну тогда да, проще передать размер в шаблоне, чем с нуля писать код вектора (хоть его и не так много надо для данной задачи).
IUnknown
Итак, Account, пре-альфа хвоста кометы. Сделано на основе системы частиц, т.е., particle system, как и предлагал Lapp (в принципе, тут других вариантов и быть не могло, все эти генерации точек в конусах и трапециях выглядят уж слишком неестественно). Более того, я дам тебе еще одну идею: я когда-то делал подобную вещь (но не с настолько упрощенной физикой, а с более приближенной к реальности), так там для достоверности еще при удалении от кометы цвет частички менялся. От белого через желтый, через ярко-красный, потом темно-красный, потом коричневый к черному. Как только цвет становился черным - частица удалялась (здесь сделано чуть-чуть по другому, частица удаляется, когда она дальше 40 радиусов от кометы, но принцип тот же, и там и там при некотором удалении от кометы на частицу можно перестать обращать внимание)... Ну, в принципе, тут можно много чего сделать, все ограничено только твоей фантазией...

P.S. Да, я знаю, планета не двигается, код не вычищен, память не освобождается, можно еще кое-что выделить в методы и будет проще. Но на то и пре-альфа: оценка возможностей.
Account
IUnknown, вчерашний предложенный код с шаблоном еще не опробовал. только с работы пришел, отдохну попробую.

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

вот этот кусок кода: (Показать/Скрыть)
, и аналогичный чуть ниже в Recalc...

Цитата
Только я теперь не знаю за что взяться, то ли продолжать свой код (выдрать у тебя только комету с хвостом) , то ли твой исходник переделывать
Ну, это уже тебе решать. Я только показал пример реализации. Справишься с написанием всей программы в подобном стиле - бери и дорабатывай мой каркас. Не справишься - продолжай свою программу.
Account
Цитата(IUnknown @ 20.07.2011 19:56) *

За это отвечает

вот этот кусок кода: (Показать/Скрыть)
, и аналогичный чуть ниже в Recalc...

Ну, это уже тебе решать. Я только показал пример реализации. Справишься с написанием всей программы в подобном стиле - бери и дорабатывай мой каркас. Не справишься - продолжай свою программу.


Вряд ли справлюсь , за пример спасибо, покапаюсь конечно в нем)))
Вот сегодня запустил несколько планет)))) Код конечно плохой, но уж строго не суди, не программист)

И у меня вопрос, можно ли как-нибудь мерцания избежать и перепрыжку рисовки планет через ось по Y ( Если взять центр координат середину экрана)
код: (Показать/Скрыть)
IUnknown
Цитата
и перепрыжку рисовки планет через ось по Y
А ты понимаешь причину такой перепрыжки? smile.gif Хочешь я добавлю к твоему коду 3 строки и ты сразу поймешь в чем дело? Смотри:

for(int dv = 0; dv <= 4 * orbp; dv++) {
putpixel(xy[0][dv], xy[1][dv], LIGHTGRAY);
}
Вот это добавь в самый конец Set(). Так сказать, чтобы очертить орбиту. И обрати внимание, с какой частотой у тебя точки стоят в одном месте, и насколько они редко расположены в другом (вот там где они реже всего и будет "перепрыжка". Но на самом то деле я бы это "перепрыжкой" не называл. Это то, как должно быть, именно там ведь у тебя и нет мерцания, правда? Мерцает в других местах траектории, потому что там обновление происходит слишком часто). Если б мне понадобилось запомнить координаты точек орбиты, я бы прошелся одним циклом от 0 до 359 градусов + sin и cos, и все точки были бы с одинаковой частотой. И тогда не будет вот этих "перепрыжек", и (скорее всего) уменьшится мерцание, ибо перерисовываться-то оно будет, но насколько реже - ты даже не представляешь smile.gif Если же тебе надо не круговую, а эллиптическую орбиту... Ну что ж, уравнение эллипса тоже не является секретом, точки вычисляются ненамного сложнее чем орбита круговая.
Account
Сделал для проверки отдельно

#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <graphics.h>
#include <math.h>
int main()
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode,
"../BGI");
errorcode = graphresult();
if (errorcode != grOk)
{
cerr<<"Graphics error";
cerr<<grapherrormsg(errorcode);
exit(1);

}
for(int i=0;i<6;i++)
{putpixel((getmaxx()/2+70*cos(i)), (getmaxy()/2+70*sin(i)), LIGHTGRAY);delay(200);}
getch();
return 0;
}


Точки не последовательно расположены, что то ни как не догоню. как упорядочить потом координаты?
IUnknown
Ууу... Как все запущено. Радианы и градусы - разные вещи, правда? Вот библиотека math подразумевает, что тригонометрические функции работают с радианами. Делаем проще:
  // Не надо каждый градус, при таком маленьком радиусе достаточно каждого четвертого
for(int i = 0; i < 360; i += 4)
{
putpixel( (getmaxx()/2 + 70*cos(i*M_PI/180)),
(getmaxy()/2 + 70*sin(i*M_PI/180)),
LIGHTGRAY );
delay(50);
}
Account
Цитата(IUnknown @ 20.07.2011 22:58) *

Ууу... Как все запущено. Радианы и градусы - разные вещи, правда? Вот библиотека math подразумевает, что тригонометрические функции работают с радианами. Делаем проще:
  // Не надо каждый градус, при таком маленьком радиусе достаточно каждого четвертого
for(int i = 0; i < 360; i += 4)
{
putpixel( (getmaxx()/2 + 70*cos(i*M_PI/180)),
(getmaxy()/2 + 70*sin(i*M_PI/180)),
LIGHTGRAY );
delay(50);
}



Я и забыл про это blush.gif Стыдно даже(((
Lapp
Вопрос такой..
Тема вызывает интерес, и это понятно. Но BC у меня (и не только, думаю) нет. Можно ли и накормить волков (то есть преподавателей топикстартера), и сохранить овец (чтоб я и остальные могли компилировать прогу)? Я, конечно, могу переделать всю графику.. Но делать так с каждой новой версией кода по мере развития темы - извините, в лом. Есть ли более простой способ обеспечить совместимость?

Добавлено через 4 мин.
P.S.
Я использую gnu в основном.
IUnknown
Можно попробовать воспользоваться вот этим:
http://codecutter.org/tools/winbgim/index.html (сразу говорю: я не пробовал, но положительные отзывы присутствуют. Насколько я помню, даже здесь я приводил эту ссылку уже).

Есть еще вот этот проект: http://sourceforge.net/projects/openbgi/ - он начинался на Сурсах, года три назад, вроде под Билдером и Dev C++ работала графика...

Или написать переходники к основным функциям именно под свой компилятор и под ОС (что там используется из BGI-шного - putpixel и circle? Пока вроде и все)

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

int dc=1; 


В метод Update в конце добавил строку

if (X>maxx+5 || Y<-5) {delete this;dc=0;}


и в цикл запуска всего, просто условие проверки переменной dc и если 0 то заново создать такую же комету, сначала прога работает нормально, но потом через некоторое время вылетает с ненормальным завершением, в чем причина?
IUnknown
Хм... Не знаю, не пробовал делать так, как ты предлагаешь, ибо удалять объект там, где это делаешь ты - не очень хорошая идея. Сделал так: дописал еще один метод в класс Comet:

class Comet : public Celestial
{
// Все то, что и было, но в public-секции еще:

int OutOfSystem()
{
return (X < -5 || X > maxx + 5 || Y < -5 || Y > maxy + 5) ? 1 : 0;
}

};

// И вот это изменение в Run()

// ...

c_01->Update();

if(c_01->OutOfSystem()) // Проверяем, если вышли за пределы - то пересоздаем комету...
{
delete c_01;
c_01 = new Comet(maxx / 2. - 50, maxy, 2, 0, -5);
}

if(kbhit()) ...
, никаких лишних глобальных переменных, ничего больше. Только эти 2 фрагмента. Запустил, уже 20 минут летает, ничего не завершается... smile.gif
Account
Цитата(IUnknown @ 21.07.2011 20:10) *

Хм... Не знаю, не пробовал делать так, как ты предлагаешь, ибо удалять объект там, где это делаешь ты - не очень хорошая идея. Сделал так: дописал еще один метод в класс Comet:

class Comet : public Celestial
{
// Все то, что и было, но в public-секции еще:

int OutOfSystem()
{
return (X < -5 || X > maxx + 5 || Y < -5 || Y > maxy + 5) ? 1 : 0;
}

};

// И вот это изменение в Run()

// ...

c_01->Update();

if(c_01->OutOfSystem()) // Проверяем, если вышли за пределы - то пересоздаем комету...
{
delete c_01;
c_01 = new Comet(maxx / 2. - 50, maxy, 2, 0, -5);
}

if(kbhit()) ...
, никаких лишних глобальных переменных, ничего больше. Только эти 2 фрагмента. Запустил, уже 20 минут летает, ничего не завершается... smile.gif

В одном из фильмов один из героев произнес фразу:"Чувствую себя богом...". А вот моя фраза:"Чувствую себя ЛОХОМ"))))

Спасибо за решение. Твой код почти разобрал. Что не до конца догоню потом спрошу. Жду завтрашнего дня, там выходные можно будет спокойно позаниматься. Буду опять через одно место делать движение планет(в твоем коде)))) После чего только столкновение останется и изменение траектории кометы из за силы притяжения)))
Account
Вот жалкая попытка заставить двигаться планету, и опять вылет с ненормальным завершением выполнения(((

код (Показать/Скрыть)
IUnknown
Что именно приводит к вылету программы, добавление движения планеты, или совместное движение планеты и кометы? Я вот сейчас попробовал запустить твою программу, закомментировав в Run() все, что касается кометы - прекрасно крутится зеленый кружок (хотя мне, например, непонятно твое желание просчитать сразу все точки и хранить массив из 720 int-ов, почему не хранить текущий угол поворота, и по нему рассчитывать координаты на каждой итерации?).

Только вот непорядок получается при переходе X от 359 к нулю. Остается артефакт, половина зеленой окружности (нижняя половина) остается на экране. Я бы сделал все-таки вот так:

   if (bShow)
{
if(X == 359) X = Y = 0;
Y = X++;
}
, тогда по крайней мере артефактов не остается. А вообще - непонятно, почему ты
1) не догадался эти действия производить в методе Recalc(), он же для этого и предназначен: посмотри на Update самого базового класса: сначала гасим изображение, потом пересчитываем то, что нужно пересчитать, и, наконец, проявляем изображение в новом месте.
2) почему до сих пор не догадался, как снять постоянное мерцание Солнца? Оно не должно перерисовываться, у тебя оно все время гасится, потом вызывается пустой Recalc(), потом опять появляется - зачем? Должно быть так: нужно его отобразить один раз, и после этого не гасить и не перерисовывать. Попробуй сделать подобное поведение сам, если не получится - я помогу.
Account
Цитата(IUnknown @ 22.07.2011 22:00) *

Что именно приводит к вылету программы, добавление движения планеты, или совместное движение планеты и кометы? Я вот сейчас попробовал запустить твою программу, закомментировав в Run() все, что касается кометы - прекрасно крутится зеленый кружок (хотя мне, например, непонятно твое желание просчитать сразу все точки и хранить массив из 720 int-ов, почему не хранить текущий угол поворота, и по нему рассчитывать координаты на каждой итерации?).

Только вот непорядок получается при переходе X от 359 к нулю. Остается артефакт, половина зеленой окружности (нижняя половина) остается на экране. Я бы сделал все-таки вот так:

   if (bShow)
{
if(X == 359) X = Y = 0;
Y = X++;
}
, тогда по крайней мере артефактов не остается. А вообще - непонятно, почему ты
1) не догадался эти действия производить в методе Recalc(), он же для этого и предназначен: посмотри на Update самого базового класса: сначала гасим изображение, потом пересчитываем то, что нужно пересчитать, и, наконец, проявляем изображение в новом месте.
2) почему до сих пор не догадался, как снять постоянное мерцание Солнца? Оно не должно перерисовываться, у тебя оно все время гасится, потом вызывается пустой Recalc(), потом опять появляется - зачем? Должно быть так: нужно его отобразить один раз, и после этого не гасить и не перерисовывать. Попробуй сделать подобное поведение сам, если не получится - я помогу.


Наверное второе. Хотя заметил так же происходит вылет при столкновении. По поводу хранения угла, как сделаю отпишусь. У меня не доходит до указанного перехода вылетает с Abnormal programm terminated ( заранее извиняюсь за возможно неправильное написание на английском, не владею). По поводу артефакта понял, поправку принял.

По 1) Как переделаю выложу.
По 2)
код (Показать/Скрыть)


P.S. Вот только не пойму как еще сделать в данном коде разную скорость у планет.
IUnknown
Цитата
По 2)
Хм... Хитрый, да? Это не совсем правильное решение smile.gif Объяснить? Объясняю... Вот этот код, который в Run, нужно будет слегка модифицировать, чтобы отслеживать взаимодействие объектов по схеме "каждое крупное небесное тело с каждой кометой". Для этого удобнее всего будет описать Солнце и планеты не как отдельные экземпляры, а как массив указателей на базовый класс, чтобы потом просто пройти по всему массиву и проверить, как очередной объект взаимодействует с кометой/кометами (если их будет больше одной на экране).

То, что ты сделал - выбивает объект класса Звезда из такой модели. То есть, ты не сможешь просто вызвать Update() в цикле для всех элементов массива КрупныеОбъекты, тебе придется исключать из этого процесса элемент массива, являющийся Солнцем, но проверять на взаимодействие придется со всеми... Опять лишние конструкции, опять if-ы, зачем тебе это? Нужно так модифицировать Star::Show(), чтобы при постоянном вызове Update() не происходило перерисовки объекта smile.gif

Цитата
Вот только не пойму как еще сделать в данном коде разную скорость у планет.
Вот как переделаешь перемещение планеты через угол (только угол не делай целочисленным, сделай вещественным) - поймешь... Будешь задавать для каждой планеты разное приращение угла - будет разная скорость вращения...

Цитата
У меня не доходит до указанного перехода вылетает с Abnormal programm terminated
Это уже я только завтра/послезавтра смогу потестировать, ноут с Windows уже забрали. Если б тебе хотя бы удалось выяснить, где происходит ошибка - было бы проще...
Account
По солнцу сделал вот так, но не уверен что правильно, так как рисоваться то все равно будет, просто наложение так сказать.

void Star :: Show(int)
{
setcolor( YELLOW );
circle((int)X, (int)Y, Size);
}


По поводу вылетов. Закоментировал как и ты все что относилось к комете, в run(). Вылетов не стало.
Account
Вот, что у меня теперь с использованием угла
код (Показать/Скрыть)
IUnknown
Я бы все-таки сделал так:

Нажмите для просмотра прикрепленного файла

Обрати внимание на следующие вещи:
1. Все-таки, пересчет планеты я вынес в Recalc()
2. Celestial::Recalc() сделал не чисто виртуальным, а просто пустым, это дало возможность вообще отказаться от реализации этого метода в классе Star, будет использоваться унаследованный из предка.
3. Я не передаю в конструктор планеты начальный угол, пусть все планеты начинают вращение с одним углом (хотя, есть и другие варианты), но я передаю ΔAngle, на который изменяется угол каждую итерацию. Это дает возможность элементарно реализовать не то что разные скорости вращения, а практически реальные, то, что есть на самом деле в Солнечной системе. Просто делишь те самые 360 градусов, которые предстоит пройти планете на ее реальный период обращения в сутках, и получаешь то, что получаешь, я добавил Марс для примера - он, как и положено, вращается один раз, пока Земля делает почти два оборота. Теперь ты понимаешь, зачем я уточнил, что лучше сделать угол вещественным? smile.gif
4. Что касается Солнца - я тоже сделал так, как задумывалось изначально, чтоб вообще никакого обновления после первого показа не было.

Вроде все, больше ничего не менял.

Ах, да... Мне не удалось дождаться вылета программы: я раскомментировал все строки, касающиеся отображения кометы, и запустил программу. Генерация 30 (тридцати) комет при одновременном вращении двух планет - это достаточное время, чтобы вылет произошел, или надо ждать дольше? Вылета не было...
Account
Цитата(IUnknown @ 23.07.2011 11:19) *

Я бы все-таки сделал так:

Нажмите для просмотра прикрепленного файла

Обрати внимание на следующие вещи:
1. Все-таки, пересчет планеты я вынес в Recalc()
2. Celestial::Recalc() сделал не чисто виртуальным, а просто пустым, это дало возможность вообще отказаться от реализации этого метода в классе Star, будет использоваться унаследованный из предка.
3. Я не передаю в конструктор планеты начальный угол, пусть все планеты начинают вращение с одним углом (хотя, есть и другие варианты), но я передаю ΔAngle, на который изменяется угол каждую итерацию. Это дает возможность элементарно реализовать не то что разные скорости вращения, а практически реальные, то, что есть на самом деле в Солнечной системе. Просто делишь те самые 360 градусов, которые предстоит пройти планете на ее реальный период обращения в сутках, и получаешь то, что получаешь, я добавил Марс для примера - он, как и положено, вращается один раз, пока Земля делает почти два оборота. Теперь ты понимаешь, зачем я уточнил, что лучше сделать угол вещественным? smile.gif
4. Что касается Солнца - я тоже сделал так, как задумывалось изначально, чтоб вообще никакого обновления после первого показа не было.

Вроде все, больше ничего не менял.

Ах, да... Мне не удалось дождаться вылета программы: я раскомментировал все строки, касающиеся отображения кометы, и запустил программу. Генерация 30 (тридцати) комет при одновременном вращении двух планет - это достаточное время, чтобы вылет произошел, или надо ждать дольше? Вылета не было...

Разобрал. спасибо. По солнцу, жалко что сам не догадался (.
Только не пойму вот что, в чем вот разница объявлений(присваивание 0),
virtual void Show(int) = 0;
virtual void Recalc()

Забыл еще спросить по частицам, массив размерностью определенный переменный const int parrSize = 1500;
а используется только 100 ?
maxParticles(100)

Ну и нужен совет как дальше делать, столкновение кометы с планетами и солнцем.
По поводу вылетов, происходят, может что с ОС на этом ноуте. Хочу потестировать на нетбуке, к вечеру отпишусь
Account
Попробовал на нетбуке, тоже вылет, пишется Abnormal program termination.

На ноуте и нетбуке стоят WinXP Zver. Даже как то не посебе, раз у тебя все номрально, а у меня вылетает.
IUnknown
Цитата(Account @ 23.07.2011 13:54) *
Только не пойму вот что, в чем вот разница объявлений(присваивание 0),
virtual void Show(int) = 0;
virtual void Recalc()
Присвоивание нуля методу делает его чисто виртуальным, ты не сможешь создать экземпляр класса Celestial (только потомки, да и то - чтобы их создать, надо чтоб потомок переопределял чисто виртуальную функцию, делал ее просто виртуальной). То есть, пока в классе есть хоть одна чисто виртуальная функция (неважно, описанная в этом классе или унаследованная от любого предка и не перекрытая) - он является абстрактным. Он как бы есть (наследоваться от него можно), но его в то же время и нет (создать экземпляр нельзя). В Паскале, кстати, такие методы как раз и называются Абстрактными...


Цитата(Account @ 23.07.2011 13:54) *
Забыл еще спросить по частицам, массив размерностью определенный переменный const int parrSize = 1500;
а используется только 100 ?
maxParticles(100)
Ага... Тут дело вот в чем: если взять просто массив из 100 частичек, инициализировать их, и потом, когда частички удалятся от кометы, переинициализировать опять рядом с кометой - то будет очень своеобразное поведение? то есть, хвост будет "фонтанировать": он будет создаваться, потом частички будут удаляться все дальше и дальше (при этом ни одна из них еще не уйдет слишком далеко, следовательно, новых-то частиц рядом с кометой не будет), пока не начнут уходить из области влияния комету, тогда она начнет испускать новую порцию частичек. Я попробовал - выглядит ужасно. Поэтому я решил пойти другим путем: я на каждой итерации добавляю по StepParticles - Count новых частичек рядом с кометой (где Count - счетчик удалившихся старых частиц), чтобы выброс шел постоянно. Естественно, что общее число частиц начинает возрастать. И возрастает до тех пор, пока длина хвоста не установится, потом возрастание прекращается. Так вот, для этого и нужно место под 1500 частичек, чтобы массив не переполнялся. Хотя, возможно, это я чересчур загнул, надо гонять программу и проверять, сколько максимально частичек присутствует в хвосте. Хочешь - сделай такую проверку. Мне лень было, я выделил место под 1500 элементов, так сказать, с запасом. Все равно, если б я делал для себя, я б не стал использовать массив, написал бы класс связного списка, и все... Сколько засунешь в него - столько он и будет хранить. Новые будут прибывать, старые - удаляться... Но тебе, чтоб не перегружать программу, я этого делать не стал.

Цитата(Account @ 23.07.2011 13:54) *
Ну и нужен совет как дальше делать, столкновение кометы с планетами и солнцем.
Я тебе уже говорил выше: проверяй комету с каждым телом, если Расстояние(Комета, НебесноеТело) меньше чем RКомета + RНебесноеТело, значит, произошло столкновение... Но тебе до этого надо еще принимать меры, когда комета слишком близко подходит к планете - это будет менять ее траекторию. Принцип - то же самый: проверять на каждом шаге расстояние, и если оно меньше какого-то расстояния, вычисленного по массе планеты (там Шека тебе чего-то писал) - то менять Vx и Vy кометы...

Цитата
Попробовал на нетбуке, тоже вылет, пишется Abnormal program termination.
Значит, запускай трассировку, и смотри, на какой именно строке программа вылетает. Возможно для этого придется перед каждой строкой в Comet::Recalc, Comet::Show и всех вызываемых оттуда функциях выводить тестовое сообщение, и потом смотреть, какое именно из них вывелось последним, значит, на последующей строке произошел вылет. Возможно - будет достаточно просто запустить отладку программы (F7 в IDE), поставить курсор на строку, скажем, с closegraph(), и нажать F4. При вылете программы курсор может быть установлен на строку с ошибкой. Так что ищи, где ошибка, коли она только у тебя воспроизводится...
Account
IUnknown, а можешь скинуть свой компилятор, на какой-нито файлообменник?
В нем проверю.
По F4 ошибок не выдает, по F7 что то при создании частиц слишком долго) но постараюсь сделать
IUnknown
Вот тут мой компилятор валяется: http://vlady.uzelok.net/progs/Tc30.exe
Просто запускай его, он сам распакуется куда скажешь...
Account
Цитата(IUnknown @ 23.07.2011 17:02) *

Вот тут мой компилятор валяется: http://vlady.uzelok.net/progs/Tc30.exe
Просто запускай его, он сам распакуется куда скажешь...


Спасибо. Блин вылет имеется. Буду пробовать по F7.
IUnknown
   for(i = 0; i <= stepParticles - count; i++)
{
// Вот отсюда ...
if(maxParticles + i >= parrSize)
{
cout << "Oops..." << endl;
}
// ... до сюда
trace[maxParticles + i] = new Particle((int)(getX()) - 1 + random(2), (int)(getY()) - 1 + random(2),
Vx + Cvt((int)((getX() - sun->getX()) / Ex)) - 1 + random(2),
Vy + Cvt((int)((getY() - sun->getY()) / Ey)) - 1 + random(2));
// ...
Попробуй добавить вот этот кусок, поставить на вывод Oops курсор и нажать на F4... Если оно туда придет, значит, как я и предполагаю, у тебя по какой-то причине генерируется слишком много частичек и происходит вылет за границы массива. Если нет - то я вообще не понимаю, в чем дело, больше просто негде ошибаться... Вообще-то обычно есть сообщение, по какой причине Abnormal programm termination. Либо Floating point error: Domain, либо еще что-то. Почему у тебя этого не показывает - непонятно...

Тебе сейчас главное - локализовать место, где происходит вылет. Через F7 это на самом деле будет долго, для первого раза выполняй методы не заходя в них, то есть, по F8 на имени метода... Потом, когда будешь знать, в каком именно методе происходит вылет - зайдешь в него и там уже жми на F8... Так каждый раз будешь подбираться все ближе и ближе, пока не найдешь, что именно глючит... Найдешь - говори...
Account
Цитата(IUnknown @ 23.07.2011 17:33) *

код (Показать/Скрыть)
Попробуй добавить вот этот кусок, поставить на вывод Oops курсор и нажать на F4... Если оно туда придет, значит, как я и предполагаю, у тебя по какой-то причине генерируется слишком много частичек и происходит вылет за границы массива. Если нет - то я вообще не понимаю, в чем дело, больше просто негде ошибаться... Вообще-то обычно есть сообщение, по какой причине Abnormal programm termination. Либо Floating point error: Domain, либо еще что-то. Почему у тебя этого не показывает - непонятно...

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

Итак сидел и держал F8, вроде на апдейте кометы, подозреваю на ее recalc(), НО хочу дать потестить кому-ни то из знакомыx, так же было бы не плохо если бы кто-ни то из здешних у себя запустил и протестил. Вдруг может что из-за видео дров, у меня тут периодически вылет их был, когда возвращался из IDE (дос режима)
Account
Итак, дал погонять еще двоим, у одного вылет через 3 секунды, у другого не так быстро но также вылет, с тем же сообщением что я выше писал(((

Что то в комете. Буду искать по возможности.
IUnknown
Ау!!! Почему у меня (ноут с WinXP SP3, запускается через DosBox 0.74, мне на фиг не нужно смотреть на это все в полноэкранном режиме) нет никаких вылетов при том же коде, работающем с кометой ( видео прилагается: http://www.youtube.com/watch?v=PzSfcH3jBEE )? Это что, карма?
Account
Да уж, возможно и карма, а скинь досбокс, я у себя через него запущу. Так же если что установлю uvScreenCamera_4.6.0.100, если будет ошибка попробую записать.
IUnknown
Где-то вот тут: http://www.dosbox.com/download.php?main=1 smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.