|
Ah, okay gotcha.
Well, in that case you can use floats or doubles for the position and the velocity. It's just a matter of rounding the position to an int before using it to display the ball.
Or of course, you could keep an integer position of last impact, along with an integer number of frames since it occured and a double velocity, or position increment per frame. Each time you display, just show the ball at [impact.x + frames*velocity.x, impact.y + frames*velocity.y]
But the easier is to just keep the position and velocity as doubles, converting to an int when using for display purposes. (You might also have to add code that will check if the ball is within a threshold distance, since non-integers will mean your ball wont hit the walls or paddle 'exactly' - well not at the exact moment of a frame, anyway.
|
|
|
|
|
I'm not sure I understand. Do you understand what I'm trying to do? after the ball hits the paddle it should move left/right depending on how far from the center it is. Just need finer precision on the angle(xvel) of the ball. Thanks.
I tried something like this. I took a number like 1.65 and did
1.65 - Math::Floor(1.65) to get just the decimal part of the number 0.65.Then every frame I added 0.65 to 0.65 and checked if it was >= 1. If it was I added 1.0 to the left/right property of the box. I then repeated that.
The problem with it was I wasn't encounting for the speed of the ball. If the speed of the ball is 6 it moves 6 frames every timer tick. The code I was trying only moved 1 pixel at a time.
I'm just not sure on the math to incorporate the speed into it.
|
|
|
|
|
Sorry about that. Um, I think I understand your intention.
It sounds to me much like a game of pong or similar. Lord knows what I've done with my old code. I can't be bothered even think about the physics right now, but I've thrown together some code that will throw a red dot into a parabolic arc.
In such a path, we'll have to both be able to have small increments of movement, and be able to vary them. You just have to assign the ball's velocity and position in an appropriate way for your application.
Enjoy.
#include <windows.h>
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "CodeBlocksWindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&wincl))
return 0;
hwnd = CreateWindowEx (
0,
szClassName,
"Click to release a ball",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
544,
375,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL
);
ShowWindow (hwnd, nCmdShow);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
float ballPosX, ballPosY, ballVelocityX, ballVelocityY;
const int myTimerId = 1;
const int intervalMs = 50;
VOID CALLBACK myTimerProc(HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
ballPosX += ballVelocityX;
ballPosY += ballVelocityY;
ballVelocityY -= 0.1;
InvalidateRect(hwnd, NULL, true);
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_DESTROY:
KillTimer(hwnd, myTimerId);
PostQuitMessage (0);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SetPixel(hdc, ballPosX, ballPosY, RGB(250,0,0));
SetPixel(hdc, ballPosX, ballPosY+1, RGB(250,0,0));
SetPixel(hdc, ballPosX+1, ballPosY, RGB(250,0,0));
SetPixel(hdc, ballPosX+1, ballPosY+1, RGB(250,0,0));
EndPaint(hwnd, &ps);
break;
case WM_LBUTTONUP:
ballPosX=0;
ballPosY=0;
ballVelocityX=3.2;
ballVelocityY=8.1;
KillTimer(hwnd, myTimerId);
SetTimer(hwnd, myTimerId, intervalMs, myTimerProc);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
|
|
|
|
|
I got bored. Here try if this if you like - it's two balls, a red one and a white one. If you hit the red one with the white one it will move in a direction away from the white one before being slowed to a halt by friction. Of course your collision handling stuff will be different(hopefully pixel-accurate, unlike mine) for the paddle and the ball, but it's the same concepts at work.
#include <math.h>
#include <windows.h>
#include <windowsx.h>
#include <wingdi.h>
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void handleCollisions();
char szClassName[ ] = "CodeBlocksWindowsApp";
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor =LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
if (!RegisterClassEx (&wincl))
return 0;
hwnd = CreateWindowEx (
0,
szClassName,
"Click to release a ball",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
544,
375,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL
);
ShowWindow (hwnd, nCmdShow);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
float ballPosX, ballPosY, ballVelocityX, ballVelocityY;
float curMouseX, lastMouseX, curMouseY, lastMouseY;
int clientWidth, clientHeight;
const int myTimerId = 1;
const int intervalMs = 50;
const int ballRadius = 10;
const int cursorRadius = 15;
void handleCollisions()
{
float dx, dy, dist;
dx = ballPosX - curMouseX;
dy = ballPosY - curMouseY;
dist = sqrt( dx*dx + dy*dy);
if (dist<ballRadius+cursorRadius)
{
ballVelocityX = 0.5 * dx;
ballVelocityY = 0.5 * dy;
}
if (ballPosX < ballRadius)
ballVelocityX = abs(ballVelocityX);
if (ballPosY < ballRadius)
ballVelocityY = abs(ballVelocityY);
if (ballPosX > clientWidth-ballRadius)
ballVelocityX = -1 * abs(ballVelocityX);
if (ballPosY > clientHeight-ballRadius)
ballVelocityY = -1 * abs(ballVelocityY);
}
VOID CALLBACK myTimerProc(HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
ballPosX += ballVelocityX;
ballPosY += ballVelocityY;
ballVelocityX *= 0.9;
ballVelocityY *= 0.9;
handleCollisions();
InvalidateRect(hwnd, NULL, true);
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
RECT clientRect;
HBRUSH newBr, oldBr;
switch (message)
{
case WM_CREATE:
ballPosX = 100;
ballPosY = 100;
SetTimer(hwnd, myTimerId, intervalMs, myTimerProc);
GetClientRect(hwnd, &clientRect);
clientWidth = clientRect.right;
clientHeight = clientRect.bottom;
return true;
case WM_DESTROY:
KillTimer(hwnd, myTimerId);
PostQuitMessage (0);
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
newBr = CreateSolidBrush(RGB(250,0,0));
oldBr = (HBRUSH)SelectObject(hdc, newBr);
Ellipse(hdc, ballPosX-ballRadius,ballPosY-ballRadius,ballPosX+ballRadius,ballPosY+ballRadius);
SelectObject(hdc, oldBr);
DeleteObject(newBr);
Ellipse(hdc, curMouseX-cursorRadius, curMouseY-cursorRadius, curMouseX+cursorRadius, curMouseY+cursorRadius);
EndPaint(hwnd, &ps);
break;
case WM_MOUSEMOVE:
lastMouseX = curMouseX;
lastMouseY = curMouseY;
curMouseX = GET_X_LPARAM(lParam);
curMouseY = GET_Y_LPARAM(lParam);
InvalidateRect(hwnd,NULL,true);
break;
case WM_LBUTTONUP:
ballPosX=11;
ballPosY=11;
ballVelocityX=6.2;
ballVelocityY=18.1;
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
}
|
|
|
|
|
Thanks for the examples. The first one has smooth transitions in motion. Exactly what I need. However I'm using .net(managed code) not winAPI. It seems .net rounds the floats down to a whole number?
Would you be able to help me with the formula for moving an object using my previous post idea?
Thanks.
|
|
|
|
|
That's okay. I had fun playing around with it.
Cyclone_S wrote: However I'm using .net(managed code) not winAPI. It seems .net rounds the floats down to a whole number?
I'd be very surprised.
You're not giving it the impression that this is your intention, by (I don't know, say) multiplying floats with ints - I've no idea what the result is - real or integer..
I don't understand, you have the formula for moving the ball. - BallPos += Velocity - You also have a way of applying gravity or friction - just alter the velocity.
Perhaps you'd be better off in the right forum?
Perhaps
http://www.codeproject.com/Forums/3785/Managed-Cplusplus-CLI.aspx[^]
or
http://www.codeproject.com/Forums/1649/Csharp.aspx[^]
All the best.
|
|
|
|
|
Hi. I got the following situation,
void FunctionA(some params)
{
SOCKET sock = create new socket();
WSAEVENT hEvent = new event();
wsaeventselect(sock, event, some flags);
FunctionB(sock);
delete event();
}
void FunctionB(sock)
{
}
The thing is, i dont have access to FunctionA() but it calls
FunctionB() , where i am the master and can do anything. In function B i am receiving a socket which has an event associated with it but nothing else. I got no handle to an event - nothing, just a socket. Is there any way to get this event handle having only socket descriptor? If there is no such API, windows system should store these events somewhere, right? Is there any way to dig into this place and grab events from there?
Thanks
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
I don't know anything at all about WSA sockets, save for the few crumbs I just picked up reading the winsock function reference at msdn.
However, I can see nothing to indicate this to be the case - nor can I think of a reason why this would necessarily be included - i.e if it's a socket you've created, then surely it is also you thas already attached said event to it - in which case you'd already have it's handle.. At least that's the way I guess it.
With that in mind, and the preparedness to go poking about in windows' memory space, I'd suggest that there is likely to be a far simpler way - unless of course FunctionA is in the kernel.
When FunctionB ends, it has to be able to return control to FunctionA, right? With this address available, you can look at the (machine) code for FunctionA, so with a little fancy footwork you can easily get the location in memory of the variable that is used to store the newly created event, and snatch the handle from there..
You know how I'd go about it? I'd write a dummy FunctionB, and put a statement something like
printf("here is my marker");
I'd then fire-up the program in OllyDbg, and search for refferences to "here is my marker". When I'd found the place that the memory containing this string was referenced, I'd know that I'd found my FunctionB. From there I would simply place a break-point inside my function, start the program running and wait for it to hit the break-point. Single-stepping would then allow me to return to FunctionA, where I could grab the required handle from the memory it was originally stored into.
Might take 30 mins to come up with working code for a real FunctionB to grab the event handle, so long as there's no bumps along the way like protected memory. I forget how to go about reading a process's memory but I've got code some where to do it.
You sure have got me curious about your project..
|
|
|
|
|
The thing is, socket is not created by me. Well, i was able to grab a list of events using ntquerysysteminformation and ntqueryobject but there seems to be no way to find out if a current event was selected by WSAEventSelect for a specified socket. enhzflep, this rather must be "out-of-the-box-working-template-automated-appliable-to-everything" code :P
Seems like the easiest way would be to just insert inline hook, but more hooks - less stable the app become =/
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
Even if you could get the event handle, what would you do with it? I assume you also don't have control over how the event is being used so you won't have any synchronization with whatever thread(s) are already using the event...
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
There are lots of things i can do with event, Mark. I can wait on it, so i dont have to deselect old event and select new one, so the original thread have a control over this original event. I can block signaling this event and signal it when i am done with my job, so original thread will be notified when it is appropriate.
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
csrss wrote: I can wait on it, so i dont have to deselect old event and select new one, so the original thread have a control over this original event
Then do you have a race condition? Which thread calls WSAEnumNetworkEvents() first? Or is only one FD_XXX event being "listened for" so WSAEnumNetworkEvents() isn't called?
csrss wrote: I can block signaling this event and signal it when i am done with my job
How do you block signalling of an event (just curious...I didn't know it was possible since I've never needed to)?
You must have intimate knowledge of the existing code to believe this is feasible
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
This is actually more an experiment then a real life solution - i am trying to create my own layer without writing and installing one. It looks like this: some event is created in some function which sends some data over a socket:
WSAEVENT hEvent = WSACreateEvent();
::WSAEventSelect(sock, hEvent, FD_WRITE | FD_READ);
WSASend(....);
And then a thread waits for event, in fact event occurs when we got some bytes waiting for us or when we are able to write some bytes. WSASend is out of the question here, because all my job is done before WSASend gets executed. The pain is WSARecv, because after this call i have some thing to do and after i am done i can return control to a function which waits for WSARecv to complete. BTW, i am hooking these calls so when WSAsomething is called control goes to my function, where i am calling WSAsomething and additionally do some work with outgoing || incoming data.
So the thing is to prevent WSAsomething completion event signaling and signal it when i am done with my part.
I know it is wrong :P and all bad things might happen and there can be a disaster crash or something and this is not what i am going to implement in final solution. I am trying and learning how to dig into system and control it in every ways possible. About blocking event, well, i can save old event handle, select new event, do my stuff, and when done, - signal old event and delete mine, for example :P Or i can go deeper into the cave and try to hook something here and there and do some crazy stuff, you know
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
csrss wrote: About blocking event, well, i can save old event handle, select new event, do my stuff, and when done, - signal old event and delete mine,
Right. Problem is, when the event is signaled, WSAEnumNetworkEvents() is usually called by the waiting/polling thread to determine which event(s) occurred. Only one thread can make that call for a given event signal on a given socket (even if you duplicate the socket) because the call resets its event status.
Good luck though
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hmmm, thanks...
Yeah, i've abandoned this idea
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
I try to read all files ( path files ) from 'Recent File List' from registry , and I failed ... I try with RegEnumValue function , but this give me string values ( File1 , File2 etc. ) not path of this files... I read RegEnumValue remarks and I see that somehow , with LPBYTE lpData parameter I could have string values , but I have no ideea how to convert LPBYTE to CString or char ... and Google didn't help me ( I didn't find a sample appropiate to my request ) ... can you help me , please ... maybe you have front with this problem ... Thank you.
|
|
|
|
|
Using the RegEnumValue() [^] function returns you the name of the value (File1 etc) and the content as a byte array. It also returns you a value item in lpType which tells you what type of data the value has. Assuming you check that this is a REG_SZ (null terminated string) then you can merely cast the pointer to the appropriate type and thence handle it as required, something like:
HKEY hKey
DWORD dwIndex = 0;
char szValueName[256];
DWORD cchValueName = 256;
DWORD dwType;
BYTE bData[4096];
DWORD cbData = 4096;
RegEnumValue(hKey, dwIndex, szValueName, &cchValueName, NULL, &dwType, bData, &cbData)
LPSTR pszValue = reinterpret_cast<LPSTR>(bData);
The best things in life are not things.
|
|
|
|
|
Thank you so much , I will try your solution and let you know what I have done .
modified on Tuesday, June 21, 2011 2:52 AM
|
|
|
|
|
Up-voted - I have no idea what sort of moron would 1-vote what is a totally reasonable response to my post.
The best things in life are not things.
|
|
|
|
|
Take away bad intention from various people, you do here best job, it' always a pleasure to talk here with so many good programmers that post here from altruism. Kindly thank you.
P.S. I didn't try your code yet, catch with other things.
|
|
|
|
|
Great , does function ! Thanks again !
|
|
|
|
|
Happy to help.
The best things in life are not things.
|
|
|
|
|
I've been interested in game development and have been using C++ for the past 3 years now, as well as OpenGL just recently. But does anyone here know of a good sound API? I've seen OpenAL, which has a basic extent of features, but I'd like something a little more flexible if possible. I've also taken a look at fmod and liked the looks of it until I saw the price tags for publishing a game with it (ranged from $500 - $9000 per platform).
Thanks for any suggestions!
|
|
|
|
|
A senior C#/C++ developer asked me this question during the interview. I thought I share it with you guys.
int x= 0;
int y= 0;
thread1
{
while (x==0) { just sit here};
printf("%d",y);
}
thread2
{
y=42;
x=1;
}
He said Assume that we know for sure Thread 1 had started before thread2:
Q1) what will printf print for answer? I said 42, that was correct.
Q2) Then he said, but suppose the answer was y=0, do you know how could that happen knowing thd1 started before thd2?
I did not get the answer correct. I did think threading, mutexes,..etc it wasn't what he was trying to get at I guess! I do know the answer, but I would like to see how you might answer.
|
|
|
|
|
Well, I think, the main reason would be that because y is not marked as volatile, the compiler might have read y (into a register) before the the while loop not knowing that the variable could be modified externally.
Without that clue, I would have probably assumed that it always works... And it probably does in many cases (platform, compiler and compiler options).
Philippe Mori
|
|
|
|
|