初学多线程,对多线程不是很理解。
  程序要求:鼠标左键单击出现一个固定尺寸和颜色的小球,立刻以一个随机速度向随机方向运动。每单击一下都会出现一个同样规格同样要求的小球,只是速度和方向不同。要求用多线程实现,每单击一下就是一个小球线程。
  目前的状况:创建了一个CBall类,包含了一个画的方法Draw()和运动的方法Move ().在MainFrame中加了一个CObArray的数据成员m_obBalls,每次单击一下,单击出来的小球就存到数组中,然后在OnPaint()中从数组中一一取出小球,调用Draw(),在OnTimer()中从数组中调出小球,调用Move(),弹到边界和碰到其他小球反弹问题略。目前程序大概就是这样,如此就已经可以实现多个小球运动了,但始终不知如果加上多线程应该怎么用。急求高人指点!希望能指出用多线程的关键点!多谢!

解决方案 »

  1.   

    多线程是为了防止单线程的假死,提高资源交互能力;你用ontimer能解决了,又何必引入多线程;如果用多线程,可以这么设计,主线程处理逻辑和创建boll,新开一个线程draw,省略ontimer.
      

  2.   

    还是不会写!怎么都和多线程联系不起来。代码不算多,我把代码贴上来,希望大虾们帮忙用多线程给改一下!很感谢!!!!
    //ball.hclass CApp : public CWinApp
    {
    public:
    virtual BOOL InitInstance();
    };class CBall : public CObject
    {
    protected:

    public:
    CBall(CPoint ptCenter,int nRadius,COLORREF clr);
    CPoint m_ptLeftTop;
    CPoint m_ptRightBottom;
    int m_nDeltax;
    int m_nDeltay;
    COLORREF m_clrBall;
    void Draw(CDC* pDC);
    void Move(CRect rect);
    };class CMainWnd : public CFrameWnd
    {
    public:
    CMainWnd();
    protected:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnPaint();
    afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
    afx_msg void OnTimer(UINT nIdEvent);
    DECLARE_MESSAGE_MAP()
    virtual void PostNcDestroy();
    protected:
    CObArray m_obBalls;   //存放小球的数组
    CPoint m_ptCenter;
    };//ball.cpp#include <afxwin.h>
    #include <afxcmn.h>
    #include <time.h>
    #include <stdlib.h>
    #include <math.h>#include "ball.h"#define ID_BALL 1000CApp app;
    BOOL CApp::InitInstance()
    {
    this->m_pMainWnd = new CMainWnd;
    this->m_pMainWnd->ShowWindow(this->m_nCmdShow);
    this->m_pMainWnd->UpdateWindow();
    return TRUE;
    }BEGIN_MESSAGE_MAP(CMainWnd,CFrameWnd)
    ON_WM_PAINT()
    ON_WM_LBUTTONDOWN()
    ON_WM_TIMER()
    END_MESSAGE_MAP()CMainWnd::CMainWnd()
    {
    Create(NULL,"");
    };int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if(CFrameWnd::OnCreate(lpCreateStruct) == -1)
    {
    return -1;
    }

    return 0;
    }void CMainWnd::OnPaint()
    {
    CPaintDC dc(this);
    int amt = m_obBalls.GetSize();
    for(int i = 0; i < amt; i++)
    {
    CBall* ball = (CBall*)m_obBalls.GetAt(i);   //依次从数组取出小球,
    ball->Draw(&dc);                            //然后画
    }
    }void CMainWnd::OnLButtonDown(UINT nFlags,CPoint point)
    {
    CBall* ball = new CBall(point,50,RGB(200,200,0));
    m_obBalls.Add(ball);      //每单击出一个小球就把小球加进数组
    this->Invalidate();
    this->SetTimer(ID_BALL,100,0);
    }void CMainWnd::OnTimer(UINT nIdEvent)
    {
    CRect rect;
    this->GetClientRect(&rect);
    int amt = m_obBalls.GetSize();
    for(int i = 0; i < amt; i++)
    {
    CBall* ball = (CBall*)m_obBalls.GetAt(i);
    CPoint ptCenter;
    ptCenter.x = ball->m_ptRightBottom.x - 50;
    ptCenter.y = ball->m_ptRightBottom.y - 50;

    //以下处理小球互相碰撞后反弹的问题
    int j = 0;
    while(j < amt)
    {
    CBall* ball1 = (CBall*)m_obBalls.GetAt(j);
    CPoint ptCenter1;
    ptCenter1.x = ball1->m_ptRightBottom.x - 50;
    ptCenter1.y = ball1->m_ptRightBottom.y - 50;
    if( sqrt( ((float)(ptCenter.x - ptCenter1.x)*(float)(ptCenter.x - ptCenter1.x)) + 
    ((float)(ptCenter.y-ptCenter1.y)*(float)(ptCenter.y-ptCenter1.y)) ) <= 100)
    {
    ball->m_nDeltax = -ball->m_nDeltax;
    ball->m_nDeltay = -ball->m_nDeltay;
    ball1->m_nDeltax = -ball1->m_nDeltax;
    ball1->m_nDeltay = -ball1->m_nDeltay;
    break;
    }
    j++;
    }
    ball->Move(&rect);
    this->Invalidate();
    }
    }
    void CMainWnd::PostNcDestroy()
    {
    int amt = m_obBalls.GetSize();
    for(int i = 0; i < amt; i++)
    {
    CBall* ball = (CBall*)m_obBalls.GetAt(i);
    delete ball;
    }
    m_obBalls.RemoveAll();
    this->KillTimer(ID_BALL);
    CFrameWnd::PostNcDestroy();
    }CBall::CBall(CPoint ptCenter,int nRadius,COLORREF clr)
    {
    m_ptLeftTop.x = ptCenter.x - nRadius;
    m_ptLeftTop.y = ptCenter.y - nRadius;
    m_ptRightBottom.x = ptCenter.x + nRadius;
    m_ptRightBottom.y = ptCenter.y + nRadius;

    m_clrBall = clr; srand((unsigned)time(0));
    m_nDeltax = rand() % 30;
    m_nDeltay = rand() % 20;
    }void CBall::Draw(CDC* pDC)
    {
    CBrush brush;
    brush.CreateSolidBrush(m_clrBall);
    CBrush* pOld = pDC->SelectObject(&brush);
    pDC->Ellipse(m_ptLeftTop.x, m_ptLeftTop.y, m_ptRightBottom.x, m_ptRightBottom.y);
    pDC->SelectObject(pOld);
    }void CBall::Move(CRect rect)
    {
    m_ptLeftTop.x += m_nDeltax;
    m_ptRightBottom.x += m_nDeltax;
    m_ptLeftTop.y += m_nDeltay;
    m_ptRightBottom.y += m_nDeltay;

            //以下处理小球碰到边界反弹问题,有点问题,暂且不管
    if(m_ptLeftTop.x < rect.left || m_ptRightBottom.x > rect.right)
    {
    m_nDeltax = -m_nDeltax;
    }
    else if(m_ptLeftTop.y < rect.top || m_ptRightBottom.y > rect.bottom)
    {
    m_nDeltay = -m_nDeltay;
    }
    }
      

  3.   

    用多线程就不用数组了,每个线程里面管理一个小球对象。定时器move也不用了,在线程里面自己Sleep(),然后Move()就是了
      

  4.   

    我记得这个是我去柯达面试的一道题目随机数量,随机大小,随机方向,随机初始速度,随机位置,随机质量,碰撞动画时间1个小时。。我当时看了有点傻。。后来回去我就做出来了,3个小时,悲剧啊。
    给你提示下吧:不需要多线程,直接SetTime就可以搞定的。我当时和面试官说用多线程,面试官笑笑。。我无语了
      

  5.   

    回七楼:
    我也知道直接SetTimer就可以搞定的,而且我也搞定了,但是现在是在学多线程,所以想用多线程来实现。谢谢解答!
    希望给出多线程方面的思路。
      

  6.   

    回六楼tiger9991(乖孩子) :
    怎么和一楼意思相反啊,一楼说不要开多个线程,你却说每个线程管理一个小球对象,那意思就是一个小球一个线程喽?
    唉,到底该怎么做啊?
    求高人指点!