|
You are using logical OR (|| ) instead of AND (&& ). In the first case if BALL.RIGHT is greater than BRICK.LEFT OR BALL.LEFT is less than BRICK.RIGHT you slow it down. However you need both conditions to be true; for example if BALL.RIGHT is greater than BRICK.LEFT then you change velocity, but the ball is not necessarily less than BRICK.RIGHT at this point. I think the same holds true for the vertical movement.
The best things in life are not things.
|
|
|
|
|
I tried using && instead of || but it messed up the ball physics. The ball would return in the same direction back towards the paddle.
The problem seems to be that Ball.right is is always going to be greater then Ball.left when the ball is colliding with the top or bottom of the brick so the check for horizontal collision will also get executed. I'm not sure how to work around this.
Thanks.
|
|
|
|
|
Cyclone_S wrote: Ball_List[b]->gameBall->Right >= Brick1->Left
Physically, the ball have already passed the bound of the brick, i.e. reversing the speed is not enough: you should update the position accordingly.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
This is as close as I got so far but it makes the ball pause for a moment when it hits the top and bottom of the brick. This code is in the timer event. Any solution to this? Thanks.
if(left == false && Ball_List[b]->gameBall->Bounds.IntersectsWith(Brick1->Bounds))
{
if((Ball_List[b]->gameBall->Right >= Brick1->Left || Ball_List[b]->gameBall->Left <= Brick1->Right))
{
Ball_List[b]->xVel = -Ball_List[b]->xVel; left = true; top = true;
}
}
else {left=false;}
if(top == false && Ball_List[b]->gameBall->Bounds.IntersectsWith(Brick1->Bounds))
{
if((Ball_List[b]->gameBall->Bottom >= Brick1->Top || Ball_List[b]->gameBall->Top <= Brick1->Bottom))
{
Ball_List[b]->yVel = -Ball_List[b]->yVel; top = true;
}
}
else{top=false;}
|
|
|
|
|
Recently I've found a very neat blog that explains how to implement some basic physics of a very similar kind as what you are trying to achieve. Check out Physics engine for dummies for some very useful explanations and code that can get you started. The explanations you can find there on how best to implement collision control are very exhaustive.
Although the code examples do not feature rectangular bricks, I am sure you can adapt them quite easily by stealing the code from the collision control with the outside border. You just need to make sure that you will always have to check all borders, rather than just 1 at a time. However, for a start it may be easier to just use circular bricks and a circular ball.
|
|
|
|
|
Hi!
How to set the Background color and BackGround Image to a CExplorer control in MFC?
modified on Thursday, May 5, 2011 7:42 AM
|
|
|
|
|
What is CExplorer?
http://www.mono-project.com/Main_Page
|
|
|
|
|
|
|
I've added a Html Browser control to a Dialog in MFC. Initially it is displayed with white background. I want ot change to some other color. How to do this?
|
|
|
|
|
Don't you need to do this via HTML ?
Watched code never compiles.
|
|
|
|
|
No. Through C++/MFC code.
|
|
|
|
|
maximilien is right; the window doesn't belong to you, you've given it to the web browser
you can either embed an html resource in your own exe/dll and Navigate2 to it using the res:// namespace (see http://msdn.microsoft.com/en-us/library/aa767740.aspx[^]) or you can dynamically build an HTMLDocument2 and use IPersistStream to get it into the web browser
I'd choose the res protocol - much simpler
|
|
|
|
|
well, if u insist on it, subclass your web browser control. I think the CExplorer class (generated from web browser activeX) would be derived from CWnd. Handle WM_PAINT or ON_WM_ERASEBKGND messages in it. do your background painting there.
hopefully this may work.
DECLARE_MESSAGE_MAP()
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
BEGIN_MESSAGE_MAP(CExplorer, CWnd)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
BOOL CExplorer1::OnEraseBkgnd(CDC* pDC)
{
CRect rc;
GetClientRect(&rc);
pDC->FillSolidRect(&rc, RGB(255, 0, 0));
return TRUE;
}
*But this lives only till you load your first web page in browser control.
|
|
|
|
|
Yes it has to work since CExplorer1 is also Derived From CWnd. and mark your comment as answer.My 5.
http://www.mono-project.com/Main_Page
|
|
|
|
|
Using the following code to get the file type icon in the dll, such as .exe .cpp .c .h file icon
SHFILEINFO sInfo;
SHGetFileInfo(strTempTest,bIsDir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL,&sInfo,sizeof(sInfo),
SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_SYSICONINDEX);
using following code to set the image list to ListCtrl
SHFILEINFO sfi;
HIMAGELIST imagelist;
imagelist=(HIMAGELIST)SHGetFileInfo(_T(""),
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON ) ;
if(imagelist!=NULL)
{
SetItemImage(CImageList::FromHandle(imagelist),0);
}
But only the folder icon can be display. the file icon cannot show.
But I find a strange thing that if adding the following code in the main application, the icon of the .cpp file in DLL can display.
CoInitialize(0);
CString strTempTest;
int nPos = strName.ReverseFind(_T('.'));
if(nPos != -1)
strTempTest = strName.Right(strName.GetLength() - nPos);
else
{
if(!bIsDir)
strTempTest = strName;
else
strTempTest = _T("C:\\Windows");
}
SHFILEINFO sInfo;
SHGetFileInfo(_T(".cpp"), (bIsDir ? FILE_ATTRIBUTE_DIRECTORY : 0), &sInfo, sizeof(sInfo),
SHGFI_USEFILEATTRIBUTES | SHGFI_SMALLICON | SHGFI_ICON);
if (sInfo.hIcon)
DestroyIcon(sInfo.hIcon);
I donot know why. I google serveral times, but cannot get reason.
modified on Tuesday, May 10, 2011 9:20 AM
|
|
|
|
|
Are you making a copy of the image list and using that copy as the list view's imagelist? If so, that's the problem.
Each process gets its own copy of the system imagelist. That copy only contains a handful of icons at first. When you query for a file type's icon the first time, the icon is added to your process's copy of the imagelist.
If you use the HIMAGELIST returned by SHGetFileInfo as the list view's image list, and be sure that the list control has LVS_SHAREIMAGELISTS so it doesn't destroy the imagelist unexpectedly, you should be able to use new icons right away as they are added.
--Mike--
Dunder-Mifflin, this is Pam.
|
|
|
|
|
Michael's given you a good answer. I had exactly the same problem a while ago with drive icons.
Have a look at my article (and especially the comments) for some solutions:
Detecting when drives are added or removed[^]
Iain.
I am one of "those foreigners coming over here and stealing our jobs". Yay me!
|
|
|
|
|
Oh yeah, I resolved this problem. After move the set imageList code from the my ListCtrl controls.
But I donot know why it is.
thanks Michael Dunn & Iain Clarke, Warrior Programmer
|
|
|
|
|
Hi all .
Please tell me if I can integrate more object data types into a single MFC data structures ( Array , List or Map ).
If I have an CStringArray object , let's say m_saType , ( CStringArray type ) , and m_saItem ( CStringArray type too ) , and m_saPerson ( CStringArray type too ) ... how can I integrate all togheter into CObList MFC object , because I want to serialize all m_saType, m_saItem, m_saPerson into a single file on disk.
Thank you . I accept any ideea .
|
|
|
|
|
m_saType.Serialize(ar);
m_saItem.Serialize(ar);
m_saPerson.Serialize(ar);
Of course a better way is to declare a CObject derived class CPerson with CString members m_sType, m_sItem, m_sPerson
Implementing Serialize in this class the using a CObList and calling its Serialize...
|
|
|
|
|
#include <afxtempl.h>
class CDataPack : public CObject
{
public:
CStringArray m_saType;
CStringArray m_saItem;
CStringArray m_saPerson;
const CDataPack& operator=(const CDataPack& rdp)
{
m_saType.Copy(rdp.m_saType);
m_saItem.Copy(rdp.m_saItem);
m_saPerson.Copy(rdp.m_saPerson);
return *this;
}
BOOL IsSerializable() const { return TRUE; }
virtual void Serialize(CArchive& ar)
{
m_saType.Serialize(ar);
m_saItem.Serialize(ar);
m_saPerson.Serialize(ar);
}
};
typedef CArray<CDataPack, CDataPack&> CDataPackType;
void AnyFunc()
{
CString strElement(_T("An Element"));
CDataPack pkt;
pkt.m_saType.Add(strElement);
pkt.m_saItem.Add(strElement);
pkt.m_saPerson.Add(strElement);
CDataPackType arrData;
arrData.Add(pkt);
CFile file;
CArchive ar(&file, CArchive::store);
arrData.Serialize(ar);
}
If you don't want to use template counterpart, you can also use CObArray or even CPtrArray (or List ones such as CObList, CPtrList, see afxcoll.h). Just beware cleanup of objects.
|
|
|
|
|
Thank you very much ! You are very kind !
And if gave me good ideas , I push my luck and ask more : which structure of collection data you choose if you want to clone 3 SQL tables , every one with one unique key integer type and other fiels is strings , but keep link between tables through those unique key integer ?
|
|
|
|
|
I think, you mean which collection class? If so, Array is more efficient on random access.
I also think, you need to access the elements with Primary Keys/Forein Keys in master-detail relationships.
If you need rows in sorted order, you can fill this array sorted. You can take advantage of SQL's SELECT with ORDER BY clause while filling. If the array is sorted, you can access its items by using binary search to speed up searches.
If you just need to access items by the key, you can simply employ CMap to access its elements with key-value pair.
typedef CMap<int, int, CDataPack, CDataPack&> CDataPackMap;
You need to keep relationships yourself, or maybe, you may create more sophisticated structures.
[edit]BTW, Not at all. [/edit]
|
|
|
|
|
I think that CMap is most good ideea . Thanks again . Best wishes !
|
|
|
|