|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Игра Ксоникс |
|
C/C++ - Игра Ксоникс
|
Пользователь Сообщения: 69 |
Профиль | Отправить PM | Цитировать Пишу игру Ксоникс на C. Подскажите как вырезать картинку.
Есть масив 0000000000 0000000000 0000000000 0000000000 Пользователь произвольно ставит 1. 0000000000 0000000000 0000001111 0000001000 0000100000 0000100000 1111100000 0000000000 Как эти элементы поменять на 2? 1111 1000 00001 00001 11111 |
|
Отправлено: 11:16, 28-12-2008 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Если не прибегать к библиотекам сторонних производителей, например gdi32.dll от микрософт, не пользоваться алгоритмами стандартной библиотеки c++, то код будет выглядеть примерно так:
typedef int surf_bit_t; struct rect_t { int left, top, right, bottom; } struct surface_desc { surf_bit_t *begin; // начало данных unsigned width, height, stride; // длина, ширина блока, длина строчки }; void __blt(surface_desc* from, surface_desc* to) { // копирование без проверки исходых данных. // чтобы случайно не попортить память при записи, руководствуемся размерами конечной области for(surf_bit_t *row_first1=to->begin, *row_last1=to->begin+from->stride*to->width, *row_first2=from->from->begin; row_first1<row_last1; row_first1+=to->stride, row_first2+=from->stride) { // закомментирован пример кода для копирования, // можешь поиграться с ним (переделать в закрашивание) // for(unsigned col=0; col<to->width; ++col) // { // row_first1[col] = row_first2[col]; // } memcpy(row_first2, row_first1, to->width*sizeof(surf_bit_t)); } } inline int __constraint(int x, int min, int max) { return x < min ? min : (x < max ? x : max); } void blt(surface_desc* from, int x, int y, int width, int height, surface_desc* to, int to_x, int to_y) { // более удобный для пользователя интерфейс // с проверкой исходных данных // вычисляем перекрывающийся прямоугольник для копирования. surface_desc from1, to1; { // пересечение прямоугольника {0, 0, width, height} с // исходным изображением, в координатах копируемого окошка rect_t rect_src = { __constraint(-x, 0, width), __constraint(-y, 0, height), __constraint(from->width - x, 0, width), __constraint(from->height - y, 0, height)}, // пересечение {0, 0, width, height} с // конечным изображением и сразу с пересечённым исходным rect_src rect_dest = { __constraint(__constraint(-x_to, 0, width), rect_src.left, rect_src.right), __constraint(__constraint(-y_to, 0, height), rect_src.top, rect_src.bottom), __constraint(__constraint(to->width - x_to, 0, width), rect_src.left, rect_src.right), __constraint(__constraint(to->height - y_to, 0, height), rect_src.top, rect_src.bottom)}; // составляем полётное задание для __blt from1.begin = from->begin + (rect_dest.top + y)*from->stride + rect_dest.left + x; from1.stride = from->stride; from1.width = rect_desc.right - rect_dest.left; from1.height = rect_desc.bottom - rect_dest.top; to1.begin = to->begin + (rect_dest.top + to_y)*from->stride + rect_dest.left + to_x; to1.stride = to->stride; to1.width = rect_desc.right - rect_dest.left; to1.height = rect_desc.bottom - rect_dest.top; } __blt(&from1, &to1); } ... // как пользоваться surf_bit_t screen1_bits[320*200]; surface_desc screen1 = {&screen1_bits, 320, 200, 320}; surf_bit_t screen2_bits[50*100]; surface_desc screen2 = {&screen2_bits, 50, 100, 50}; ... blt(&screen1, 100, 100, 60, 60, &screen2, 10, 10); |
Отправлено: 23:21, 28-12-2008 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Пользователь Сообщения: 69
|
Профиль | Отправить PM | Цитировать Не могу разобраться в коде не могли бы вы упростить код или объяснить доходчивей
|
Отправлено: 18:31, 30-12-2008 | #3 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Цитата Doom77:
Добавил комментариев // это чтобы можно было легко подменить тип-носитель // для "цвета" ячейки typedef int surf_bit_t; struct rect_t { // прямоугольник - понадобится для пересечений int left, top, right, bottom; } // стркуктура, которая указывает, в каком виде хранится картинка. // данные хранятся в виде линейного массива определённой ширины строчки // на картинке нарисован массив, у которого stride = 6, // x x x x x x width = 4, height = 3. Можно сказать, что мы работаем // x x 1 1 1 1 с большим массивом 6x5, а можно что с // x x 1 0 0 0 1 1 1 1 ? ? маленьким 4x3, строчки которого // x x 1 0 0 0 1 0 0 0 ? ? расположены через 6 элементов. // x x x x x x 1 0 0 0 ? ? begin в последнем случае указывает на // начало "маленького" массива. struct surface_desc { surf_bit_t *begin; // начало данных unsigned width, height, stride; // длина, ширина блока, длина строчки }; void __blt(surface_desc* from, surface_desc* to) { // функция НЕ ПОЗВОЛЯЕТ копировать в себя, то есть когда from и to могут пересекаться. // копирование без проверки исходых данных. // чтобы случайно не попортить память при записи, руководствуемся размерами конечной области // эта функция используется как внутренняя, исходные данные должны быть уже проверены. // в качестве аргументов получает поверхности экрана, описанные выше (surface_desc) // row_first1 пробегает строчки, куда копировать, от начала до конца, с шагом stride // row_last1 - это и есть конец (посчитали и запомнили) // row_first1 пробегает строчки, откуда копировать, с шагом stride for(surf_bit_t *row_first1=to->begin, *row_last1=to->begin+from->stride*to->width, *row_first2=from->from->begin; row_first1<row_last1; row_first1+=to->stride, row_first2+=from->stride) { // закомментирован пример кода для копирования, // можешь поиграться с ним (переделать в закрашивание) for(unsigned col=0; col<to->width; ++col) { // копирование row_first1[col] = row_first2[col]; // а это могло бы быть закрашивание // row_first1[col] = 2; } // простейший случай - просто копирование памяти. Сэкономил код функцией // memcpy(row_first2, row_first1, to->width*sizeof(surf_bit_t)); } } inline int __constraint(int x, int min, int max) { // ограничивает значение x - прибмвает к одному из порогов. // нужно для пересечения прямоугольников return x < min ? min : (x < max ? x : max); } // функция, которая вычисляет аргументы для __blt // x x x x x x по заданным исходному прямоугольнику и конечной // x x 1 1 1 1 y 1 1 1 1 y y точке, куда содержимое этого прямоугольника // x x 1 0 0 0 -> y 1 0 0 0 y y скопировать. // x x 1 0 0 0 y 1 0 0 0 y y Надо учесть случаи, когда часть прямоугольника // x x x x x x будет выходить за пределы исходного или // конечного экранов. Для этого сделаем следующее: // (1) пересчитаем координаты прямоугольников экранов в координатах исходного и конечного // прямоугольника, (2) пересечём их с исходным и конечным прямоугольником. Затем (3) // пересечём что получилось между собой. Получится прямоугольник (4), который и надо // копировать. Пересчитаем его в координатах экранов (5), запишем в виде поверхностей (6) и // отдадим функции __blt // // (0,0) (0,0) (0,0) // +---+ (w,0) +---+ (w,0) +---+ (w,0) // | | | | | | // | x|x x x |y y|y y y -> | N| область, которая_ // | x|x x x |y y|y y y | N| будет скопирована // +--x+x x x +y-y+y y y +--N+ // (0,h) x x x x (0,h) (0,h) // void blt(surface_desc* from, /*поверхность-откуда*/ int x, int y, /*координаты, откуда копировать*/ int width, int height, /*размеры окошка*/ surface_desc* to, /*поверхность-куда*/ int to_x, int to_y) /*координаты куда*/ { // более удобный для пользователя интерфейс // с проверкой исходных данных // вычисляем перекрывающийся прямоугольник для копирования. surface_desc from1, to1; { // пересечение прямоугольника {0, 0, width, height} с // исходным изображением, в координатах копируемого окошка rect_t rect_src = { /*2*/__constraint(/*1*/-x, 0, width), /*2*/__constraint(/*1*/-y, 0, height), /*2*/__constraint(/*1*/from->width - x, 0, width), /*2*/__constraint(/*1*/from->height - y, 0, height)}, // пересечение {0, 0, width, height} с // конечным изображением и сразу с пересечённым исходным rect_src rect_dest = /*4*/{ /*3*/__constraint(/*2*/__constraint(/*1*/-x_to, 0, width), rect_src.left, rect_src.right), /*3*/__constraint(/*2*/__constraint(/*1*/-y_to, 0, height), rect_src.top, rect_src.bottom), /*3*/__constraint(/*2*/__constraint(/*1*/to->width - x_to, 0, width), rect_src.left, rect_src.right), /*3*/__constraint(/*2*/__constraint(/*1*/to->height - y_to, 0, height), rect_src.top, rect_src.bottom)}; // составляем полётное задание для __blt from1.begin = /*6*/from->begin + (/*5*/rect_dest.top + y)*from->stride + /*5*/rect_dest.left + x; from1.stride = /*6*/from->stride; /*сохраняется для подобласти*/ from1.width = /*6*/rect_desc.right - rect_dest.left; from1.height = /*6*/rect_desc.bottom - rect_dest.top; to1.begin = /*6*/to->begin + (/*5*/rect_dest.top + to_y)*from->stride + /*5*/rect_dest.left + to_x; to1.stride = /*6*/to->stride; /*сохраняется для подобласти*/ to1.width = /*6*/rect_desc.right - rect_dest.left; to1.height = /*6*/rect_desc.bottom - rect_dest.top; } __blt(&from1, &to1); } // как пользоваться_ // где-то в программе выделена память под экран, сделано описание для этой памяти: surf_bit_t screen1_bits[/*width*/320 * /*height*/200]; surface_desc screen1 = {/*begin*/ &screen1_bits, /*width*/320, /*height*/200, /*stride=width*/320}; surf_bit_t screen2_bits[/*width*/50 * /*height*/100]; surface_desc screen2 = {/*begin*/ &screen2_bits, /*width*/50, /*height*/100, /*stride=width*/50}; // в том месте, где надо скопировать делаем так: // копируем прямоугольник 60x60 из точки (100,100) в (10,10) на другом экране blt(&screen1, 100, 100, 60, 60, &screen2, 10, 10); |
|
Отправлено: 12:03, 31-12-2008 | #4 |
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Не устанавливается игра | Monsterup | Непонятные проблемы с Железом | 1 | 09-06-2008 15:28 | |
Не работает игра. | Dosmod | Microsoft Windows Vista | 4 | 05-05-2007 13:53 | |
незапускается игра | pirat0 | Microsoft Windows Vista | 2 | 26-02-2007 11:42 | |
игра по сети | idon | Сетевые технологии | 1 | 04-01-2006 17:42 | |
Игра по модему | Dronvelikii | Сетевые технологии | 1 | 02-08-2004 17:17 |
|