Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Apr 6th, 2006, 8:49 PM   #1
Writlaus
Hobbyist Programmer
 
Writlaus's Avatar
 
Join Date: Nov 2005
Posts: 149
Rep Power: 4 Writlaus is on a distinguished road
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;
}
Writlaus is offline   Reply With Quote
Old Apr 6th, 2006, 10:04 PM   #2
The Dark
Expert Programmer
 
Join Date: Jun 2005
Posts: 884
Rep Power: 4 The Dark is on a distinguished road
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.
The Dark is online now   Reply With Quote
Old Apr 6th, 2006, 10:12 PM   #3
Writlaus
Hobbyist Programmer
 
Writlaus's Avatar
 
Join Date: Nov 2005
Posts: 149
Rep Power: 4 Writlaus is on a distinguished road
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.
Writlaus is offline   Reply With Quote
Old Apr 7th, 2006, 2:16 AM   #4
Jimbo
Battle Programmer
 
Jimbo's Avatar
 
Join Date: Feb 2006
Location: Bellevue, WA, USA
Posts: 770
Rep Power: 3 Jimbo is on a distinguished road
by the way, in your initialize function you have:
for(int i = 0; i < 20; i++)
{
   rand();
}
Jimbo is offline   Reply With Quote
Old Apr 7th, 2006, 3:31 AM   #5
nnxion
Programming Guru
 
nnxion's Avatar
 
Join Date: Jun 2005
Location: elemental plane
Posts: 1,429
Rep Power: 5 nnxion is on a distinguished road
Quote:
Originally Posted by Jimbo
by the way, in your initialize function you have:
for(int i = 0; i < 20; i++)
{
   rand();
}
LOL, if it were srand I could understand, but it still wouldn't work, but this is just weird.
__________________
"Employ your time in improving yourself by other men's writings, so that you shall gain easily what others have labored hard for."
-- Socrates
nnxion is offline   Reply With Quote
Old Apr 7th, 2006, 4:17 AM   #6
Writlaus
Hobbyist Programmer
 
Writlaus's Avatar
 
Join Date: Nov 2005
Posts: 149
Rep Power: 4 Writlaus is on a distinguished road
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...
Writlaus is offline   Reply With Quote
Old Apr 7th, 2006, 7:35 AM   #7
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
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.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Apr 7th, 2006, 8:18 AM   #8
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
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.
Arevos is offline   Reply With Quote
Old Apr 8th, 2006, 7:16 PM   #9
Writlaus
Hobbyist Programmer
 
Writlaus's Avatar
 
Join Date: Nov 2005
Posts: 149
Rep Power: 4 Writlaus is on a distinguished road
Didn't I set the current time as the seed with this line?

srand((unsigned)time(NULL));
Writlaus is offline   Reply With Quote
Old Apr 8th, 2006, 8:37 PM   #10
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
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.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 2:40 AM.

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