Programming Forums

Programming Forums (http://www.programmingforums.org/forumindex.php)
-   C++ (http://www.programmingforums.org/forum15.html)
-   -   Vectors and Classes (http://www.programmingforums.org/showthread.php?t=9243)

Writlaus Apr 6th, 2006 7:49 PM

Vectors and Classes
 
I hate to keep coming back here and asking questions left and right. I feel like I'm getting really annoying.

Anyway, I'm not sure if this is a problem with how I'm using vectors, or how I'm using classes. All I'm trying to do is create an empty vector, add two MyDot objects to it, and then have them bounce around the window, each with their own unique randomly generated starting position and energy. However, when I run the program, it just gives me one dot. The Vector has two items, though, so I'm thinking there are two dots there that are just somehow linked.

Here's my code... any help would be greatly appreciated, as always.

:

#include <windows.h>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <vector>

using namespace std;

int randInt(int end)
{
    return (int)((rand()*1.0/RAND_MAX)*end);
}

const char g_szClassName[] = "myWindowClass";
const int windowWidth=200;
const int windowHeight=200;
const int drawableWidth=windowWidth-13;
const int drawableHeight=windowHeight-39;

class MyDot
{
    public:
    int x,y;
    float realX,realY,energyY,energyX;
    void initialize()
    {
        for (int i=0;i<20;i++)
        {
            rand();
        }
        energyX=((rand()*1.0/RAND_MAX)-.5);
        energyY=((rand()*1.0/RAND_MAX)-.5);
        x=randInt(drawableWidth);y=randInt(drawableHeight);
        realX=x;realY=y;
    }
    void draw(HDC hdc)
    {
        SetPixel(hdc,x,y,RGB(157,4,170));
        SetPixel(hdc,x+1,y,RGB(157,4,170));
        SetPixel(hdc,x,y+1,RGB(157,4,170));
        SetPixel(hdc,x+1,y+1,RGB(157,4,170));
    }
    void go()
    {
        realX+=energyX;realY+=energyY;
        x=(int)realX;y=(int)realY;
    }
    void push(float forceX,float forceY)
    {
        energyX+=forceX;
        energyY+=forceY;
    }
};

int a=0;
vector<MyDot> dots;
RECT myRect;
HBRUSH myBrush;
MyDot dot;
HDC hdcBuffer;
HDC hdc;
HBITMAP hbmBuffer;
HBITMAP hbmOldBuffer;

void paintStuff(HDC hdc)
{
    FillRect(hdcBuffer,&myRect,myBrush);
    dot=dots[0];
    dot.draw(hdcBuffer);
    BitBlt(hdc,0,0,windowWidth,windowHeight,hdcBuffer,0,0,SRCCOPY);
}

// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE:
        {
            srand((unsigned)time(NULL));
            dots.push_back(dot);
            MyDot anotherDot;
            dots.push_back(anotherDot);
            srand((unsigned)time(NULL));
            for (int i=0;i<dots.size();i++)
            {
                dots[i].initialize();
            }
            myBrush=CreateSolidBrush(RGB(255,255,255));
            SetRect(&myRect, 0, 0, windowWidth, windowHeight);
            SetTimer(hwnd,1,17,NULL);
            hdc=GetDC(hwnd);
            hdcBuffer=CreateCompatibleDC(hdc);
            hbmBuffer=CreateCompatibleBitmap(hdc,drawableWidth,drawableHeight);
            SelectObject(hdcBuffer,hbmBuffer);
        }
        break;
        case WM_TIMER:
        {
            a++;
            hdc=GetDC(hwnd);
            paintStuff(hdc);
            ReleaseDC(hwnd, hdc);
            for (int i=0;i<dots.size();i++)
            {
                dots[i].push(0,0.1);
            }
            //Bouncing:
            for (int i=0;i<dots.size();i++)
            {
                if (dots[i].realY>drawableHeight & dots[i].energyY>0)
                {
                    dots[i].energyY*=-1;
                }
                if (dots[i].realY<0 & dots[i].energyY<0)
                {
                    dots[i].energyY*=-1;
                }
                if (dots[i].realX>drawableWidth & dots[i].energyX>0)
                {
                    dots[i].energyX*=-1;
                }
                if (dots[i].realX<0 & dots[i].energyX<0)
                {
                    dots[i].energyX*=-1;
                }
            }
            for (int i=0;i<dots.size();i++)
            {
                dots[i].go();
            }
        }
        break;
        case WM_PAINT:
        {
            PAINTSTRUCT ps;
            hdc=BeginPaint(hwnd,&ps);
            paintStuff(hdc);
            EndPaint(hwnd,&ps);
        }
        break;
        case WM_LBUTTONDOWN:
        {
            char szFileName[MAX_PATH];
            HINSTANCE hInstance = GetModuleHandle(NULL);

            GetModuleFileName(hInstance, szFileName, MAX_PATH);
            MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
        }
        break;
        case WM_MBUTTONDOWN:
        {
            HDC hdc=GetDC(hwnd);

            TextOut(hdc,a,10,"Hello World",11);

            ReleaseDC(hwnd, hdc);
        }
        break;
        case WM_RBUTTONDOWN:
        {

        }
        break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
        {
            KillTimer(hwnd,1);
            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;

    //Step 1: Registering the Window Class
    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  = NULL;
    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;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        g_szClassName,
        "The title of my window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, windowWidth, windowHeight,
        NULL, NULL, hInstance, NULL);

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

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

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}


The Dark Apr 6th, 2006 9:04 PM

This code
:

void paintStuff(HDC hdc)
{
    FillRect(hdcBuffer,&myRect,myBrush);
    dot=dots[0];
    dot.draw(hdcBuffer);
    BitBlt(hdc,0,0,windowWidth,windowHeight,hdcBuffer,  0,0,SRCCOPY);
}

only looks at the first entry in "dots" (dot[0]). If you want it to draw both dots, you need to loop over the vector and draw each entry.

Writlaus Apr 6th, 2006 9:12 PM

Oh god. I can't believe I didn't see that. *Sigh*

Thank you for finding that for me...

It runs now without fail lol... thanks again.

Jimbo Apr 7th, 2006 1:16 AM

by the way, in your initialize function you have:
:

for(int i = 0; i < 20; i++)
{
  rand();
}

:confused:

nnxion Apr 7th, 2006 2:31 AM

Quote:

Originally Posted by Jimbo
by the way, in your initialize function you have:
:

for(int i = 0; i < 20; i++)
{
  rand();
}

:confused:

LOL, if it were srand I could understand, but it still wouldn't work, but this is just weird.

Writlaus Apr 7th, 2006 3:17 AM

Ah, well it seemed like everytime I ran the program without that for loop in there, the rand() function would always return very similar results every time I ran it, with the results getting more and more truly random as the function was called more. So I decided I'd call it 20 times, heh...

DaWei Apr 7th, 2006 6:35 AM

Are you seeding it before use and avoiding reseeding it during use? You might want to review PRNGs, rather than practice voodoo. Just a thought. Easier on the sacrificial chickens.

Arevos Apr 7th, 2006 7:18 AM

Pseudorandom number generators (PRNGs) generate pseudorandom numbers from a specific seed value (usually an integer or a long). If you want the numbers generated to be different each time you run the program, you need to use a different seed value each time. For simple applications you can just use the current time as the seed. See here.

Writlaus Apr 8th, 2006 6:16 PM

Didn't I set the current time as the seed with this line?

srand((unsigned)time(NULL));

DaWei Apr 8th, 2006 7:37 PM

I didn't read all your code to see. If you did, that seeds the PRNG. You only want to do that once, which was the point raised in my post. The PRNG generates a fixed collection of numbers with random-like characteristics for any given seed. Programs are fast. If you seed with time repeatedly, you might get the same number over and over until the time value finally changes. Do it once. Trying to manipulate the 'randomness' of the sequence afterwards by dinking with the number of calls you use is most likely fruitless and will cause more 'non-randomness' than it cures.


All times are GMT -5. The time now is 9:23 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC