|
eing ???
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
“The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet.” - Michael A. Jackson
|
|
|
|
|
For mobiles, use J2ME (Java 2 Mobile Edition)
|
|
|
|
|
only J2ME , even for tools programm .as u know , all mobiles don't support some languages ... .making menu for these languages is necessary for use them .
thanx
s_mostafa_h
|
|
|
|
|
I am doing a TankGame program,and I write a CBullet class.I write a thread function to make it move when it is created:
UINT BulletGo(LPVOID pParam)
{
CBullet* bullet=(CBullet*)pParam;
while(TRUE)
{
switch(bullet->m_bCanGo.GetDirection())
{
case UP:
bullet->GoUp();
break;
case DOWN:
bullet->GoDown();
break;
case LEFT:
bullet->GoLeft();
break;
case RIGHT:
bullet->GoRight();
break;
}
if(!bullet->m_bCanGo)
break;
else
bullet->MoveWindow(bullet->GetPosition().x,
bullet->GetPosition().y,
bullet->GetThisRect().Height(),
bullet->GetThisRec().Width());
Sleep(30);
}
return 0;
}
int CBullet::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CStatic::OnCreate(lpCreateStruct) == -1)
return -1;
m_bCanGo=TRUE;
m_pThread=AfxBeginThread(BulletGo,this); //begin thread
return 0;
}
BOOL CBullet::GoDown()
{
if((m_ptPosition.y+m_rtThis.Height())>m_rtParent.bottom)
{
m_ptPosition.y+=2;
m_bCanGo=TRUE;
return TRUE;
}
else
{
this->DestroyWindow();
m_bCreated=FALSE;
m_bCanGo=FALSE;
return FALSE;
}
}
When the bullet go down and hit the bottom of client rect the program apprear errors.Why...Don't the "break" in the BulletGo() end the thread?
|
|
|
|
|
what exactly is the error?
|
|
|
|
|
The application pops up a dialog about error saying that Debug Assertion Failed!
Program : D:\Code\TankGame\Debug\TankGame.exe
File : wincore.cpp
Line : 304
......
|
|
|
|
|
You need to synchronize the shutdown a bit better.
By the time you set m_bCanGo=FALSE you've destroyed the window,
yet your thread is still doing (attempting) operations on it.
Try something like this:
BOOL CBullet::GoDown()
{
if((m_ptPosition.y+m_rtThis.Height())>m_rtParent.bottom)
{
m_ptPosition.y+=2;
m_bCanGo=TRUE;
return TRUE;
}
else
{
<code> m_bCanGo=FALSE;
::WaitForSingleObject(m_pThread, INFINITE);
</code>
this->DestroyWindow();
m_bCreated=FALSE;
return FALSE;
}
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you for you advice.But it helps nothing to the problem...
|
|
|
|
|
If that's the case, then you need to debug.
Can you post more specifics on the problem? Does it crash?
If so, on what line? If not, does the thread ever exit?
If not, why? Use breakpoints and single step to find out.
Etc...
Running in the debugger you should be able to find what line of
code is causing problems and trace back to why there's a problem.
Your original code is not going to work correctly. You
MUST manage synchronization of your threads!
Also, using a separate thread doesn't mean less CPU cycles are used,
as implied by your post below. One thread per moving object will start
to degrade performance once you have many objects going at once.
Plus it's wasteful of resources. Even one thread on a modern PC is
capable of tracking and rendering MANY moving objects.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I set a breakpoint on "return 0" in the thread function.When the bullet hit the bottom of client rect,the appliction jump to the breakpoint,and I step over,the debugger doesn't pop up error dialog until execute to the line AfxEndThread(nResult) in function UINT APIENTRY _AfxThreadEntry(void* pParam).
How do you think the two methods of conrol the enemies and bullets that one use threads and the other use timer in class?Which waste more CPU resource?
|
|
|
|
|
|
I have found the error:I can't end the thread after destorying the window,right?
|
|
|
|
|
Chen-XuNuo wrote: I can't end the thread after destorying the window,right?
Right Not if the thread is using the window!
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am going to be crazy..
The problem still haven't been solved.
UINT BulletGo(LPVOID pParam)
{
CBullet* bullet=(CBullet*)pParam;
while(TRUE)
{
switch(bullet->GetDirection())
{
case UP:
bullet->GoUp();
break;
case DOWN:
bullet->GoDown();
break;
case LEFT:
bullet->GoLeft();
break;
case RIGHT:
bullet->GoRight();
break;
}
if(!bullet->m_bCanGo)
break;
else
bullet->MoveWindow(bullet->GetPosition().x,bullet->GetPosition().y,
bullet->GetThisRect().Height(),bullet->GetThisRect().Width());
Sleep(30);
}
return 0;
}
BOOL CBullet::GoDown()
{
if(m_rtParent.bottom==0)
GetParent()->GetClientRect(&m_rtParent);
if((m_ptPosition.y+m_rtThis.Height())<m_rtParent.bottom)
{
m_ptPosition.y+=6;
m_bCanGo=TRUE;
return TRUE;
}
else
{
m_bCreated=FALSE;
m_bCanGo=FALSE;
while( ::WaitForSingleObject(m_pThread->m_hThread,1) == WAIT_TIMEOUT)
{
Sleep(1);
}
delete m_pThread;
this->DestroyWindow();
return FALSE;
}
}
I destroy the window after ending the thread.
Is the judgement:
::WaitForSingleObject(m_pThread-&gt;m_hThread,1) == WAIT_TIMEOUT
right?If it is right,where is the problem..
|
|
|
|
|
Chen-XuNuo wrote: ::WaitForSingleObject(m_pThread->m_hThread,1) == WAIT_TIMEOUT
That should work fine, although you really don't need to loop.
A simple
::WaitForSingleObject(m_pThread->m_hThread, INFINITE);
should be good enough.
Chen-XuNuo wrote: delete m_pThread;
This isn't good. CWinThread objects delete themselves by default.
If you delete it twice, whichever delete happens last is going to crash!
You probably should remove that line
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you very much.The problem has been solved.
|
|
|
|
|
If you want my advice, I don't think that you need to create a thread for that. If you keep that logic, it would mean that you will create a thread for every bullet in your game. And probably for every ennemy too. Honnestly, I don't think this is a good idea.
You should better process the position of all your 'entities' (bullets, ennemies, ...) in the message pump and then draw everything on the screen. You don't need a thread for that.
I don't know if you are using the MFC's or not, but if that's the case, then you won't have access to the message pump. But you could override the OnIdle function from your App class and do it there.
|
|
|
|
|
OnIdle...bleh. I'd prefer a multimedia timer for smoother frame rate
Cheers
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mmmm...I think if I draw the 'entities' with DC,I think the application would take large CPU resource,so I do it in thread.And I think using thread to control the enemies and the bullets easier.
I will try you advice, thank you~
|
|
|
|
|
I am exporting two functions. Cleanup and close.
extern "C" __declspec(dllexport) BOOL Cleanup(VOID)
and
extern "C" __declspec(dllexport) BOOL Close(VOID)
In the Cleanup function i am calling Close() method.
if ( temp.lpLocalData->hComm != INVALID_HANDLE_VALUE ) {
Close();
}
This resulted in two compiler error
error C3861: 'Close': identifier not found and
error C2365: 'Close' : redefinition; previous definition was 'formerly unknown identifier'
How to call Close in Cleanup function?
|
|
|
|
|
It should work. If you don't provide prototypes beforehand,
then Close() will have to be defined before Cleanup() so the
compiler knows what it is...
extern "C" __declspec(dllexport) BOOL Close(VOID)
{
return TRUE;
}
extern "C" __declspec(dllexport) BOOL Cleanup(VOID)
{
Close();
return TRUE;
}
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
|
Hello everyone,
I am debugging MSDN code from,
http://msdn2.microsoft.com/en-us/library/0eestyah(VS.80).aspx
here is my output,
1<main.cpp>
1<d:\visual studio="" 2008\projects\test_c4350\test_c4350\main.cpp(21)="" :="" warning="" c4350:="" behavior="" change:="B::B(A)" called="" instead="" of="B::B(B&)">
1> d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(13) : see declaration of 'B::B'
1> d:\visual studio 2008\projects\test_c4350\test_c4350\main.cpp(9) : see declaration of 'B::B'
1> A non-const reference may only be bound to an lvalue
I do not quite understand why there is a warning A non-const reference may only be bound to an lvalue and 'B::B(A)' called instead of 'B::B(B &)'? Could anyone give some descriptions please?
thanks in advance,
George</d:\visual></main.cpp>
|
|
|
|
|
I can't be bothered to go looking at that code, but...
Of course the left value of an assignment has to be non-const.
Otherwise...
7 = a;
The compiler / interpreter will work out the right hand side (which may or may not be const), and then put it into the left hand side. If the left hand side is not "put into-able", then it will fail.
Does that help halfway?
Iain.
|
|
|
|
|
Iain Clarke wrote: Does that help halfway?
why bothering replying ?
you're answer will not be understood, therefore you're probably be down voted for this good answer though.
|
|
|
|