Advertisement

win 32 pong

Started by July 01, 2019 09:49 PM
40 comments, last by phil67rpg 5 years, 2 months ago

can I get some input on this question?

So far I'm interpreting your question as, "How to set up raw win32 message processing and a game loop". The last suggestion received is your entry into the current traditional solution of the windows target profile. Do you understand why PeekMessage is desirable here? Are you aware of the concept of a non-blocking function? 

Where in the overall code is your game loop? You don't have one in the original code you provided. You have a (blocking)message processing loop. But we should be past that with the PeekMessage addition. (which btw, we havn't seen your correction)

Where do you place the movement code? I wouldn't place that anywhere as is unless a few pixel jitter is the desired effect. 

21 hours ago, phil67rpg said:

when I press the space bar the computer paddle moves up and down

you will notice that behavior with any non system key press.

As for additional input, sure...I dislike the flow through from the WM_KEYDOWN message straight into the WM_PAINT message. Oh, and for that extra kick, we invalidate and process at the same time. Pretty sure paint will fire again...no thanks. I put your code to the compiler. The dangling process was the first I looked at. Did you get that sorted? Is this from the Big C++ Book thing you blogged?

Maybe go from here where I've untangled you a little and fixed the major broken bits.


#ifndef UNICODE
#define UNICODE
#endif 

#include <windows.h>
#include <chrono>
#include <sstream>
std::chrono::system_clock::time_point lastTime;
std::chrono::duration<float> deltaTime = std::chrono::duration<float>(0.0f);

float comp_move = 0.0f;
int screen_width = 800;
int screen_height = 600;

HBRUSH blackBrush;
HBRUSH blueBrush;
HBRUSH redBrush;
HBRUSH whiteBrush;

// forward declaration
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

// entry point
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
   const wchar_t CLASS_NAME[] = L"Sample Window Class";

   WNDCLASS wc = { };
   wc.lpfnWndProc = WindowProc;
   wc.hInstance = hInstance;
   wc.lpszClassName = CLASS_NAME;
   RegisterClass(&wc);

   RECT windowRect = {0, 0, screen_width, screen_height};
   AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, false); // client is the user size now

   HWND hwnd = CreateWindowEx(
      0,                              // Optional window styles.
      CLASS_NAME,                     // Window class
      L"Pong",                        // Window text
      WS_OVERLAPPEDWINDOW,            // Window style
      CW_USEDEFAULT, CW_USEDEFAULT,   // Size and position
      windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
      NULL,       // Parent window    
      NULL,       // Menu
      hInstance,  // Instance handle
      NULL        // Additional application data
   );

   if (hwnd == NULL) { return 0; }
   ShowWindow(hwnd, nCmdShow);

   blackBrush = CreateSolidBrush(RGB(0, 0, 0));
   blueBrush = CreateSolidBrush(RGB(0, 0, 255));
   redBrush = CreateSolidBrush(RGB(255, 0, 0));
   whiteBrush = CreateSolidBrush(RGB(255, 255, 255));

   // Run the message loop.
   lastTime = std::chrono::system_clock::now();
  
   MSG msg = {};
   while(msg.message != WM_QUIT)
   {
      if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) // accept all messages
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }

      deltaTime = std::chrono::system_clock::now() - lastTime;
      if( deltaTime.count() > 0.0166f ) // todo : something with the left over time
      {
         lastTime = std::chrono::system_clock::now();
         std::ostringstream title;
         title << "timer : " << deltaTime.count();
         std::string strTitle = title.str();
         ::SetWindowTextA(hwnd, strTitle.c_str());

         static float sign = -5.f; // todo : give me some smarts
         comp_move += sign;
         if(comp_move < 50) { comp_move = 50.f; sign = 5.f; }
         if(comp_move > screen_height-50) { comp_move = screen_height-50.f; sign = -5.f; }
         InvalidateRect(hwnd, nullptr, false); // hmm...good enough?
      }
   }
   return (int)msg.wParam;
}

int y = 50;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch (uMsg) {

   case WM_DESTROY:
      PostQuitMessage(0);
      break; // let Windows do internal cleanup 

   case WM_KEYDOWN:
      // todo : get ready for testing ball collision (refactor to usable rect(s))
      switch (wParam) 
      {
      case VK_UP:
         y -= 5;
         if (y < 50)
         {
            y = 50;
         }
         return 0;
      case VK_DOWN:
         y += 5;
         if (y > screen_height - 50)
         {
            y = screen_height - 50;
         }
         return 0;
      }
      break;

   case WM_PAINT:
   {
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint(hwnd, &ps);

      FillRect(hdc, &ps.rcPaint, blackBrush);

      RECT rect = { 0,LONG(comp_move - 50),30,LONG(comp_move + 50) };
      FillRect(hdc, &rect, blueBrush);

      RECT rect_one = { screen_width-30, y-50, screen_width, y+50 };
      FillRect(hdc, &rect_one, redBrush);

      RECT rect_two = { 702,340,722,360 }; // todo : proper ball rect tracking
      FillRect(hdc, &rect_two, whiteBrush);
      EndPaint(hwnd, &ps);
      break;
   }

   case WM_CLOSE:
      DestroyWindow(hwnd);
      break;

   }
   return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

 

 

Advertisement

thanks for all the code but I want to figure this out on my own, I just need a hint on how to move the computer paddle.

Are you sure? It's 95% your code. Trust me, I wouldn't write more than 5% of what that is. If you don't even bother to take a look then we are wasting our time. I've given you a hint, a pretty crappy one at that, which moves in the dumbest manner possible. Pretty sure you can figure out a better way, jumping off from something that actually works. Have a great day friend. 

edit: I do appreciate the revisit to window creation and message processing. Usually it's something auto generated or part of a library doing the dirty work. Maybe touched once and not thought about for the rest of the entire project. Justifies the effort. 

well I have found some code in my book that I can use to draw sprites which look nicer then rectangles.

well good on you. I would save then for polish stage and keep with the rectangles during prototyping. 

Advertisement

thanks I am going to work on breakout.

you go...make that thing happen. You have to flap those wings really hard...keep a laser focus. Fail faster. 

Let's see you do pong first. I'm expecting to see a game link of your's to kick off this next decade. There may be a call for a vote, but I'm thinking non-optional :) 

Twisting a @nsmadsen* concept of "are you even playing games, <no?>then you're 'kinda missing the point" to "if we're not playing each others games, then we're missing (the) point". Whatever you need to get there buddy...

* Sorry for the ping...I was stealing one of your winds of wisdom and an attempt to reach outside the hole we find self in.

I am working on the computer paddle , it almost works but it jitters back and forth for a little bit but I want it to move from left to right and back left for the whole screen, here is the code I am  using. I just need to tweak it a little bit.


if  ( comp_move < -10.0f )
{
  comp_velocity = 0.1f;
}
else
{
  comp_velocity = -0.1f;
}

if ( comp_velocity == 0.1f )
{
  comp_move += 5.0f;
}
else
{
  comp_move -= 5.0f;
}	

 

How about....


comp_move += 5.0f * comp_velocity;

if(comp_move < (LEFT_EXTENT)) 
{  
  comp_velocity = 1.0f; 
}
if(comp_move > (RIGHT_EXTENT)) 
{ 
  comp_velocity = -1.0f; 
}

where LEFT_EXTENT and RIGHT_EXTENT are two (1D points) you want the reversal to happen on.

This topic is closed to new replies.

Advertisement