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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Borland C++] 2D графика в DOS, довести до ума исправить баги 
V
    Опции темы
Игорек
  Дата 12.1.2010, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Код

#include<graphics.h>
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<math.h>

#define PATHTODRIVER "d:\\BC31\\BGI\\"



void okr(int x,int y,int r,int color){       //рисует окружность
    setcolor(color);
    circle(x,y,r);
}



void main(void){
    int a[]={100,200,400,100,250,200,300,120,180,400,300,400,325};   //координата Х
    int b[]={100,400,200,200,100,250,180,140,120,400,300,325,400};   //координата у
    int c[]={10,10,10,10,10,10,10,10,10,10,10,10,10};                //радиус
    int d[]={3,3,3,3,3,3,3,3,3,3,3,3,3};                             //приращение dx
    int e[]={3,3,3,3,3,3,3,3,3,3,3,3,3};                             //приращение dy
    int n;
    int i,j;

    
#define dt 50


    int maxx;
     int maxy;


    int gdriver = DETECT;
    int gmode;
    int errorcode;


    initgraph(&gdriver,&gmode,PATHTODRIVER);
    errorcode = graphresult();

    if (errorcode == grOk){
        
        maxx = getmaxx();
        maxy = getmaxy();
        while(!kbhit()){
             
            j=0;
            for(i=0;i<13;i++){
                okr(a[j],b[j],c[j],j+1);    //рисует окружность по координатам и радиусу произвольного цвета
                j++;
            }
            delay(dt);
            j=0;
            for(i=0;i<13;i++){
                
                okr(a[j],b[j],c[j],BLACK);  //"стирает окружность" закрашивая её окружностью цвета фона
                a[j]+=d[j];                 //изменение координаты х
                b[j]+=e[j];                 //изменение координаты у
                if ((a[j]-c[j])<=0 || (a[j]+c[j])>=maxx) d[j]=-d[j];    //пузырёк дошол до края экрана по х смена направления движения dx
                if ((b[j]-c[j])<=0 || (b[j]+c[j])>=maxy) e[j]=-e[j];    //пузырёк дошол до края экрана по у смена направления dy   
                for(n=0;n<6;n++){
                    if(fabs(a[j]+c[j]-a[n]-c[n])<=(c[j]+c[n]) && fabs(b[j]+c[j]-b[n]-c[n])<=(c[j]+c[n]) && j!=n){    
                                                 //если расстояния между пузырьками по х и по у меньше суммы радиусов пузырьков значит они столкнулись
                                                 //пробовал через теорему пифагора но вышла чушь
                                                 //затем примитивнейший отскок пузырьков друг от друга без учёта угла столкновения
                    d[j]=-d[j];                                                                                      
                    e[j]=-e[j];                                                                                       
                    d[n]=-d[n];
                    e[n]=-e[n];
                    }
                }
                j++;
            }    
        }
        closegraph();
    }
    else{
        printf("OLLIu6ka: %d\n",errorcode);
        puts("Ha)I(Mume <Enter>");
        getch();
    }
}

в принципе программа работает но результат оставляет желать лучшего
несколько очень печальных ситуаций:
1) В 20% случаев пузырьки неотталкиваются друг от друга а тупо пролетают насквозь
2) Иногда один шарик забивает другова за края экрана и тот начинает судорожно дёргаться 
3) Самая забавная часть )) 2 и более шариков сцепляются между собой и если повезёт какойнибудь шарик разбивает их но это происходит невсегда иногда они дёргаются давольно долго )
помогите довести до ума
само задание выглядит так :
    По экрану движутся в разных направлениях пузырьки, сталкиваясь  друг с другом и отскакивая от краев экрана.
ПС: Я первокурсник поэтому неиспользуйте очень замудрёные слова в коментариях
PM MAIL   Вверх
Игорек
Дата 12.1.2010, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



подскажите как сделать упругое столкновение без учёта массы и скорости чтобы угол отскакивания пузырька от пузырька был реалистичнее
PM MAIL   Вверх
Игорек
Дата 12.1.2010, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



я вроде разобрался с залетанием и застреванием в краях экрана
подскажите что надо сделать чтобы шарики постоянно отскакивали друг от друга а не чтобы как повезёт
PM MAIL   Вверх
Игорек
Дата 13.1.2010, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



как ни печельно но тут только мои коменты  smile  smile 
PM MAIL   Вверх
t_gran
Дата 14.1.2010, 05:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 33
Всего: 37



Код

for(n=0;n<6;n++){

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

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

#include<graphics.h>
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<math.h>

#define dt 50

#define _OBJ_ 13

#define PATHTODRIVER "d:\\BC31\\BGI\\"

void okr (int x, int y, int r, int color)        //рисует окружность
{
   setcolor(color);
   circle(x, y, r);
}

int main (int argc, char **argv)
{
   int a[_OBJ_]= {100,200,400,100,250,200,300,120,180,400,300,400,325};   //координата Х
   int b[_OBJ_]= {100,400,200,200,100,250,180,140,120,400,300,325,400};   //координата у
   int c[_OBJ_]= {10,10,10,10,10,10,10,10,10,10,10,10,10};                //радиус
   int d[_OBJ_]= {3,3,3,3,3,3,3,3,3,3,3,3,3};                             //приращение dx
   int e[_OBJ_]= {3,3,3,3,3,3,3,3,3,3,3,3,3};                             //приращение dy
   int n, i;
   int maxx, maxy;
   int gdriver= DETECT, gmode;
   int errorcode;
   initgraph(&gdriver,&gmode,PATHTODRIVER);
   errorcode= graphresult();
   if (errorcode != grOk)
   {
      printf("OLLIu6ka: %d\n", errorcode);
      puts("Ha)I(Mume <Enter>");
      getch();
      return 1;
   }
   maxx= getmaxx();
   maxy= getmaxy();
   int page= 0;
   while (!keypressed(KEY_ESCAPE))
   {
      page= page ? 0 : 1;
      setactivepage(page);
      clearviewport();
      for (i= 0; i<_OBJ_; i++)
      {
         okr(a[i], b[i], c[i], i+1);    //рисует окружность по координатам и радиусу произвольного цвета
      }
      setvisualpage(page);
      delay(dt);
      for (i= 0; i<_OBJ_; i++)
      {
         //okr(a[i], b[i], c[i], BLACK); //"стирает окружность" закрашивая её окружностью цвета фона
         a[i]+= d[i];                  //изменение координаты х
         b[i]+= e[i];                  //изменение координаты у
         if ((a[i]-c[i])<=0 || (a[i]+c[i])>=maxx)
            d[i]= -d[i];               //пузырёк дошол до края экрана по х смена направления движения dx
         if ((b[i]-c[i])<=0 || (b[i]+c[i])>=maxy)
            e[i]=-e[i];                //пузырёк дошол до края экрана по у смена направления dy
         for (n= 0; n<_OBJ_; n++)
         {
            if (fabs(a[i]+c[i]-a[n]-c[n])<=(c[i]+c[n]) && fabs(b[i]+c[i]-b[n]-c[n])<=(c[i]+c[n]) && i!=n)
            {
               //если расстояния между пузырьками по х и по у меньше суммы радиусов пузырьков значит они столкнулись
               //пробовал через теорему пифагора но вышла чушь
               //затем примитивнейший отскок пузырьков друг от друга без учёта угла столкновения
               d[i]= -d[i];
               e[i]= -e[i];
               d[n]= -d[n];
               e[n]= -e[n];
            }
         }
      }
   }
   closegraph();
   return 0;
}


Исходник с исполняемым файлом можете взять в прикреплённом архиве.

P.S.: Я не исправлял всех ваших ошибок, а всего лишь ответил на один из ваших вопросов
Цитата

1) В 20% случаев пузырьки не отталкиваются друг от друга а тупо пролетают насквозь


Это сообщение отредактировал(а) t_gran - 14.1.2010, 05:28

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  buble.zip 14,01 Kb


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
Игорек
Дата 14.1.2010, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



огромное спасибо ) 
я во всех циклах поправил до 13 а этот пропустил наверно )))
PM MAIL   Вверх
Игорек
Дата 14.1.2010, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

while (!keypressed(KEY_ESCAPE))

я земенил её на окончание по нажатию энтэр
Код

 while(!kbhit()){

после этого программа запустилась но работала некорректно шарики очень сильно мерцали
подскажите на чём вы писали эту программу 
и если можно то коментарии к
Код

int main (int argc, char **argv)

для чего вводятся int argc, char **argv
Код

 int page= 0;
   while (!keypressed(KEY_ESCAPE))
   {
      page= page ? 0 : 1;
      setactivepage(page);
      clearviewport();
      for (i= 0; i<_OBJ_; i++)
      {
         okr(a[i], b[i], c[i], i+1);    //рисует окружность по координатам и радиусу произвольного цвета
      }
      setvisualpage(page);



если вас незатруднит прокомментируйте создание и использование страниц

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


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

Репутация: 33
Всего: 37



Игорек, всё очень просто: рисуем на одной, а показываем другую, а затем меняем их местами.
Код

page= page ? 0 : 1;
 
setactivepage(page) - устанавливаем активную страницу (для рисования)
setvisualpage(page) - устанавливаем видимую страницу (которая отображается на данный момент)

Код

while (!keypressed(KEY_ESCAPE))

Ошибка действительно имела место быть. Я давно уже не видел BorlandC++, а пользуюсь компилятором GCC, просто в своё время я нашёл библиотеку OpenBGI которая позволяет старые DOS-графические программки компилить под Win32.

Код

int main (int argc, char **argv)

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

Код

 int page= 0; // Номер страницы
   while (!keypressed(KEY_ESCAPE)) // Пока не нажата клавиша ESC
   {
      page= page ? 0 : 1; // Если 1 то 0, Если 0 то 1 (в общем чередуем страницы)
      setactivepage(page); // Устанавливаем страницу для рисования
      clearviewport(); // Очищаем экран
      for (i= 0; i<_OBJ_; i++) // Рисуем
      {
         okr(a[i], b[i], c[i], i+1);    //рисует окружность по координатам и радиусу произвольного цвета
      }
      setvisualpage(page); // Делаем видимой нарисованную нами страницу


P.S.: Пардон, если не всё успел описать, опаздываю на трамвай. smile


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
Игорек
Дата 14.1.2010, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



спасибо за помощ думаю что смогу довести своё ужасное тварение до ума  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.1241 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.