Форум программистов CodeGuru
24 Июнь 2018, 16:28:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости:
 
   Начало   Помощь Войти Регистрация  
Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Помогите, пожалуйста, с созданием проги на C++  (Прочитано 9188 раз)
0 Пользователей и 1 Гость смотрят эту тему.
gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« : 26 Октябрь 2008, 06:17:47 »

Проблема такая: я пытаюсь сделать небольшую игру. Одним из аспектов является передвижение игрока, управляемого компьютером, вверх, вниз, вправо или влево. У меня в игре выбор реализуется путем рандомных чисел. Все работает. Но есть проблема. После нескольких десятков ходов ходить он прекращает, а еще через некоторое время программа просто зависает. Подскажите пожалуйста, с чем это может быть связано и как это исправить.
Записан
gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #1 : 03 Ноябрь 2008, 13:30:56 »

Люди Програмисты Как вас там еще)) Неужели никто ничем не может помочь?
Записан
Exmap
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля WWW
« Ответ #2 : 03 Ноябрь 2008, 21:44:13 »

Ты код сюда давай. Вряд ли дело в рандомных числах. Кстати, не исключено, что это - баг графики
Записан
gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #3 : 04 Ноябрь 2008, 20:07:20 »

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

Сообщений: 262



Просмотр профиля
« Ответ #4 : 04 Ноябрь 2008, 20:22:45 »

ну отрежь кусок, именно тот, который реализует рандомное движение Улыбка
Записан

Елси вы хотите купить, продать, отремонтировать автомобиль в Ижевске: Вам сюда =)
(c)holdmann
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #5 : 04 Ноябрь 2008, 22:58:51 »

а именно зависает прога, причем система тоже начинает лагать.
Если под винду, если "система тоже начинает лагать" - возможно, приложение не освобождает дескрипторы GDI при рисовании. Т.е. всякие кисти/перья/регионы/растры, и.т.д. создаются, но не освобождаются.
В винде максимально возможно 16384 дескриптора GDI одновременно (насколько я помню).
При этом пара сотен выделена под предопределенные объекты.
Остальные могут быстро кончиться (если не освобождать).
В реестре где то, кстати, есть параметр, ограничивающий число объектов GDI, которое может откушать 1 приложение (10000 по умолчанию).

З.Ы. а что тема в курилке ?
З.З.Ы. а код - это да, это надо показать Улыбка Иначе беспредметный разговор получается.
Записан

gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #6 : 05 Ноябрь 2008, 19:45:20 »

Код:

#include <windows.h>
#include "resource.h"
#include <stdio.h>
#include <math.h>
#include "time.h"


const char g_szClassName[] = "myWindowClass";
PAINTSTRUCT paintstruct;
HWND hwnd;
int i,j,k=0,p=0,t=0,s=0,m,n,sem,u,o,ff,r=1,l=0,v=0,d=0,ppc=0,xz=0,q,qq,rr,ll,vv,dd,ss,z=0,zz,zzz=0,gr=0;

double kk;
bool tt=true;
bool wtf=false;
bool bred=false;

int rul[10][10];
int rul1[10][10];

int rul3[5000];
int right[5000];
int dawn[5000];
HDC hdc;
HDC memdc;




LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintstruct;
  HBITMAP hbit;


srand( (unsigned)time( NULL ) );
static int maxX, maxY;
    switch(msg)
    {
case WM_CREATE:

maxX = GetSystemMetrics (SM_CXSCREEN);
  maxY = GetSystemMetrics (SM_CYSCREEN);
  hdc = GetDC(hwnd);
  memdc = CreateCompatibleDC(hdc);
  hbit = CreateCompatibleBitmap (hdc,maxX,maxY);
  SelectObject (memdc, hbit);
SelectObject (memdc,GetStockObject (WHITE_BRUSH));
PatBlt (memdc, 0, 0, maxX, maxY, PATCOPY);
ReleaseDC (hwnd, hdc);
SelectObject (memdc, CreatePen (PS_SOLID,1,RGB(0,0,0)));

SelectObject (memdc,GetStockObject (BLACK_BRUSH));




break;
case WM_PAINT:
SelectObject (memdc,GetStockObject (WHITE_BRUSH));

SelectObject (memdc,GetStockObject (BLACK_BRUSH));

for(i=0;i<11;i++)
{

MoveToEx(memdc,100,50*i,0);
LineTo(memdc,600,50*i);



}
for(j=0;j<11;j++)
{
MoveToEx(memdc,100+50*j,0,0);
LineTo(memdc,100+50*j,500);



}


for(m=0;m<11;m++)
{
for(n=0;n<11;n++)
{
if((double)(1.0*rand()/(RAND_MAX))>0.6  && tt==true)
{
rul[m][n]=1;
}
}
}
for(u=0;u<11;u++)
{
for(o=0;o<11;o++)
{
if((double)(1.0*rand()/(RAND_MAX))>0.6  && tt==true)
{
rul1[u][o]=1;
}
}
}
for(ppc=0;ppc<5000;ppc++)
{
if((double)(1.0*rand()/(RAND_MAX))<0.35)
{
rul3[ppc]=1;
q=1;
}
if((double)(1.0*rand()/(RAND_MAX))<0.5 && q!=1)
{
rul3[ppc]=2;
qq=2;
}
if((double)(1.0*rand()/(RAND_MAX))<0.85 && q!=1 && qq!=2)
{

rul3[ppc]=3;
}
if((double)(1.0*rand()/(RAND_MAX))>0.85)
{
rul3[ppc]=4;
}
q=5;
qq=5;

}
tt=false;
for(m=0;m<11;m++)
{
for(n=0;n<10;n++)
{

if(rul[m][n]==1 && tt==false)
{
SelectObject (memdc, CreatePen (PS_SOLID,5,RGB(100,0,0)));
MoveToEx(memdc,100+50*m,50*n,0);
LineTo(memdc,100+50*m,50+50*n);
SelectObject (memdc, CreatePen (PS_SOLID,1,RGB(0,0,0)));
}
}
}
for(u=0;u<10;u++)
{
for(o=0;o<10;o++)
{

if(rul1[u][o]==1 && tt==false)
{
SelectObject (memdc, CreatePen (PS_SOLID,5,RGB(100,0,0)));
MoveToEx(memdc,100+50*u,50*o,0);
LineTo(memdc,150+50*u,50*o);
SelectObject (memdc, CreatePen (PS_SOLID,1,RGB(0,0,0)));
}
}
}







SelectObject (memdc,GetStockObject (WHITE_BRUSH));
SelectObject (memdc,GetStockObject (BLACK_BRUSH));

switch(sem)
{
case 1:
PatBlt (memdc, 100+3+50*(p-s-1),3+50*(k-t),44,44, PATCOPY);
sem=0;
break;

case 2:
PatBlt (memdc, 100+3+50*(p-s),50*(k-t+1)+3,44,44, PATCOPY);
sem=0;
break;

case 3:
PatBlt (memdc, 100+3+50*(p-s+1),3+50*(k-t),44,44, PATCOPY);
sem=0;
break;

case 4:
PatBlt (memdc, 100+3+50*(p-s),50*(k-t-1)+3,44,44, PATCOPY);
sem=0;
break;

case 5:
PatBlt (memdc, 100+3+50*(r-l-1),3+50*(v-d),44,44, PATCOPY);
sem=0;
break;

case 6:
PatBlt (memdc, 100+3+50*(r-l+1),3+50*(v-d),44,44, PATCOPY);
sem=0;
break;

case 7:
PatBlt (memdc, 100+3+50*(r-l),50*(v-d-1)+3,44,44, PATCOPY);
sem=0;
break;

case 8:
PatBlt (memdc, 100+3+50*(r-l),50*(v-d+1)+3,44,44, PATCOPY);
sem=0;
break;

case 9:
PatBlt (memdc, 100+47+50*(r-l),1+50*(v-d),6,48, PATCOPY);
//PatBlt (memdc, 0, 0, maxX, maxY, PATCOPY);
sem=0;
break;

case 10:
PatBlt (memdc, 97+50*(r-l+1),1+50*(v-d),6,48, PATCOPY);

sem=0;
break;
}
SelectObject (memdc,GetStockObject (BLACK_BRUSH));
Ellipse(memdc,110+50*(p-s),10+50*(k-t),140+50*(p-s),40+50*(k-t));
SelectObject (memdc,GetStockObject (WHITE_BRUSH));
SelectObject (memdc, CreatePen (PS_SOLID,5,RGB(100,100,0)));
Ellipse(memdc,110+50*(r-l),10+50*(v-d),140+50*(r-l),40+50*(v-d));
SelectObject (memdc, CreatePen (PS_SOLID,1,RGB(0,0,0)));
SelectObject (memdc,GetStockObject (BLACK_BRUSH));



  hdc = BeginPaint(hwnd,&paintstruct);
BitBlt (hdc, 0, 0, maxX,maxY, memdc,0,0,SRCCOPY);
  EndPaint(hwnd,&paintstruct);
break;

case WM_TIMER:


if(ss>25)
{
gr=gr+1;
wtf=false;
bred=true;
}
if(ss>30)
{
vv=0;
dd=0;
rr=0;
ll=0;

}

ss++;
if(wtf==false)
{
right[z]=r-l;
dawn[z]=v-d;
z=z+1;

}
if(r-l<9 )

{

if(rul3[xz]==1 && rul[r-l+1][v-d]!=1 && ll!=1)
{
for(zz=0;zz<z;zz++)
{
if(right[zz]==r+1-l && dawn[zz]==v-d && bred==false)
{
wtf=true;
}
}

if(wtf==false)
{
sem=5;
r=r+1;
rr=1;
vv=0;
dd=0;
ss=0;
bred=false;

      UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
}

if( r-l>0)
{

if(rul3[xz]==2 && rul[r-l][v-d]!=1 && rr!=1)
{
for(zz=0;zz<z;zz++)
{
if(right[zz]==r-l-1 && dawn[zz]==v-d && bred==false)
{
wtf=true;
}
}
if(wtf==false)
{
sem=6;
l=l+1;
ll=1;
vv=0;
dd=0;
ss=0;
bred=false;
     UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
}
if( v-d<9)
{

if(rul3[xz]==3 && rul1[r-l][v-d+1]!=1 && dd!=1)
{
for(zz=0;zz<z;zz++)
{
if(right[zz]==r-l && dawn[zz]==v+1-d && bred==false)
{
wtf=true;
}
}
if(wtf==false)
{
sem=7;
v=v+1;
ss=0;
vv=1;
rr=0;
ll=0;
bred=false;
     UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
}
if( v-d>0)
{

if(rul3[xz]==4 && rul1[r-l][v-d]!=1 && vv!=1)
{
for(zz=0;zz<z;zz++)
{
if(right[zz]==r-l && dawn[zz]==v-d-1 && bred==false)
{
wtf=true;
}
}
if(wtf==false)
{
sem=8;
d=d+1;
ss=0;
dd=1;
rr=0;
ll=0;
bred=false;
     UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
}

if(gr>50)
{
if(rul[r-l+1][v-d]==1)
{
sem=9;
rul[r-l+1][v-d]=0;


gr=0;
UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
else if(rul[r-l][v-d]==1)
{
sem=10;
rul[r-l][v-d]=0;

gr=0;
UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}

xz=xz+1;
wtf=false;
break;



case WM_COMMAND:
switch (LOWORD(wParam))

{
case ID_TIMER:

SetTimer(hwnd,1,80,NULL);
break;

case ID_RIS:
UpdateWindow(hwnd);
break;



case ID_EXIT:
if (MessageBox(hwnd, "Are you sure?",
"Exit",MB_YESNO | MB_ICONQUESTION) == IDYES)
DestroyWindow(hwnd);
break;
}
break;


case WM_KEYDOWN:
if((char)wParam==VK_DOWN)
{
if(k-t<9 && rul1[p-s][k-t+1]!=1)
{
//MessageBox(hwnd, "???????? ??????","INFO",MB_OK);
sem=4;
k=k+1;
                UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
if((char)wParam==VK_RIGHT)

{

if(p-s<9 && rul[p-s+1][k-t]!=1)
{

sem=1;
p=p+1;
                UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
if((char)wParam==VK_UP)
{
if(k-t>0 && rul1[p-s][k-t]!=1)
{

sem=2;
t=t+1;
                UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
if((char)wParam==VK_LEFT)
{
if(p-s>0 && rul[p-s][k-t]!=1)
{

sem=3;
s=s+1;
                UpdateWindow(hwnd);

InvalidateRect(hwnd, NULL, FALSE);
}
}
break;



        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)

{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;


   
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = (LPSTR) IDR_MENU1;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

   
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 500, 500,
        NULL, NULL, hInstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

   
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

« Последнее редактирование: 05 Ноябрь 2008, 22:16:16 от 3V » Записан
gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #7 : 05 Ноябрь 2008, 19:48:26 »

Вот оно) Решил все таки весь копирнуть Заранее предупреждаю-стиль програмирования у меня отвратный Но уж как есть)

to 3v: А как бороться с захламлением этих самых дескрипторов?
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #8 : 05 Ноябрь 2008, 22:31:34 »

to 3v: А как бороться с захламлением этих самых дескрипторов?

Ну вот, например, там есть строки:

Код:

for(m=0;m<11;m++)
{
for(n=0;n<10;n++)
{

if(rul[m][n]==1 && tt==false)
{
SelectObject (memdc, CreatePen (PS_SOLID,5,RGB(100,0,0)));
MoveToEx(memdc,100+50*m,50*n,0);
LineTo(memdc,100+50*m,50+50*n);
SelectObject (memdc, CreatePen (PS_SOLID,1,RGB(0,0,0)));
}
}
}


В цикле в контекст устройства выбирается перо. Перо создается тут же при помощи CreatePen.
Перо - это объект GDI. Его надо создавать только при необходимости, а после того, как становится ненужным - удалять.
При этом следует учитывать:
1. объект GDI, выбранный в контекст устройства, не удалиться
2. в только что созданном контексте устройства уже выбраны по умолчанию некоторые объекты GDI, например, в совместимых контекстах устройств (создаются при помощи CreateCompatibleDC) в качестве графической поверхности сразу после создания выбран монохромный растр, состоящий всего из 1-го пикселя
Т.о. общий принцип работы с объектами GDI:
1. создали
2. выбрали в контекст устройства, при этом сохранив предыдущий объект (его дескриптор сохраняем)
3. рисуем что надо
4. выбираем в контекст предыдущий объект
5. удаляем ненужный объект GDI

т.е. предыдущий фрагмент кода примерно так можно переписать:

Код:

for(m=0;m<11;m++)
{
for(n=0;n<10;n++)
{

if(rul[m][n]==1 && tt==false)
{
HPEN hPen = CreatePen(PS_SOLID,5,RGB(100,0,0));
HPEN hOldPen = SelectObject(memdc, hPen);

MoveToEx(memdc,100+50*m,50*n,0);
LineTo(memdc,100+50*m,50+50*n);

SelectObject(memdc, hOldPen); // выбрали то перо, которое было раньше

DeleteObject(hPen);
}
}
}


И вот при таких операциях:

Код:
SelectObject(memdc,GetStockObject (WHITE_BRUSH));

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

gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #9 : 06 Ноябрь 2008, 00:18:50 »

Оооо Спасибо большое Завтра перепишу А еще что нибудь можно оптимизировать?
Записан
3V
Администратор
Ветеран
*****
Офлайн Офлайн

Сообщений: 1347



Просмотр профиля WWW
« Ответ #10 : 06 Ноябрь 2008, 00:47:27 »

Ну, желательно сначала, чтобы объекты GDI "не текли". Кстати, в диспетчере задач в винде можно посмотреть количество объектов для процесса. Если постоянно растет - значит что-то не то.
Улыбка
Записан

gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #11 : 07 Ноябрь 2008, 19:20:07 »

3v
Я попробовал переписать код, как ты посоветовал. Результатом последовала следующая ошибка
error C2440: 'initializing' : cannot convert from 'void *' to 'struct HPEN__ *'
Что делать?
Записан
Valery
Пользователь
***
Офлайн Офлайн

Сообщений: 83


Просмотр профиля
« Ответ #12 : 12 Ноябрь 2008, 16:49:17 »

Для начала при обработке WM_PAINT надо вызывать функции BeginPaint EndPaint
которые убирают сообщения о перерисовке  из очереди сообщений. Иначе у тебя всегда будет перерисоватся окно
 потом
SelectObject (memdc,GetStockObject (WHITE_BRUSH)); Выбираем белую кисть 

SelectObject (memdc,GetStockObject (BLACK_BRUSH)); и тут же черную
Зачем???

error C2440: 'initializing' : cannot convert from 'void *' to 'struct __ *'
Не может привести тип приводи собственоручно
(HPEN*)SelectObject (memdc,GetStockObject (WHITE_BRUSH))


С уважением Валерий
Записан
gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #13 : 12 Ноябрь 2008, 19:11:28 »

SelectObject (memdc,GetStockObject (WHITE_BRUSH)); Выбираем белую кисть 

SelectObject (memdc,GetStockObject (BLACK_BRUSH)); и тут же черную
Зачем???

Просто это недоработанная версия Я при запуске проги комментирую одну из строк для тестирования
А насчет совета - спасибо Ща попробую
Записан
gREY
Интересующийся
**
Офлайн Офлайн

Сообщений: 11


Просмотр профиля
« Ответ #14 : 12 Ноябрь 2008, 19:33:17 »

Валерий Спасибо большое, что напомнили Как я мог забыть про BeginPaint EndPaint ума не приложу
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!