API Windows problème (C + +, VS08)

  • Bozebo
  • Expert
  • Expert
  • Avatar de l’utilisateur
  • Inscription: Fév 15, 2006
  • Messages: 709
  • Loc: 404
  • Status: Offline

Message Novembre 13th, 2009, 8:56 am

Salut, je travaille sur mes travaux universitaires et j'ai besoin pour produire un jeu 2D de base en utilisant l'API de Windows (pas de dx / OpenGL nécessaire encore). Il est globalement très simple, mais il est une question stupide avec l'API Windows qui m'embête.

Tout d'abord, je benne mon code:
CPP Code: [ Select ]
//Windows Example Code
//Matthew Bett 2005
 
#include <windows.h>
#include <stdio.h>
#include <mmsystem.h>
#include <math.h>
 
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
 
/* not using any mouse input
typedef struct Mouse{
  int x,y;
} Mouse;
*/
 
typedef struct Sprite{
  int x, y, width, height;
  HBITMAP bitmap;
} Sprite;
 
int xpos, ypos;
int ticker = 0;
 
HBITMAP theOldFrontBitMap, theOldBackBitMap;
HWND ghwnd;
RECT screenRect;
HDC backHDC, frontHDC, bitmapHDC;   //Hardware device contexts for the Buffers
 
bool keys[256];
 
Sprite TestSprite;
 
BOOL waitFor(unsigned long delay);
 
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
 
void RegisterMyWindow(HINSTANCE hInstance){
  WNDCLASSEX  wcex;                          
 
  wcex.cbSize = sizeof(wcex);
  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = WndProc;
  wcex.cbClsExtra = 0;
  wcex.cbWndExtra = 0;
  wcex.hInstance = hInstance;
  wcex.hIcon = 0;
  wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
               
  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  wcex.lpszMenuName = NULL;
  wcex.lpszClassName = L" FirstWindowClass";
  wcex.hIconSm = 0;
 
  RegisterClassEx(&wcex);
}
 
 
BOOL InitialiseMyWindow(HINSTANCE hInstance, int nCmdShow){
  HWND hwnd;
  hwnd = CreateWindow(L" FirstWindowClass", L" Double Buffering", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
  CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, NULL,   NULL, hInstance,
  NULL);                     
  if(!hwnd) return FALSE;
 
  ShowWindow(hwnd, nCmdShow);                
  UpdateWindow(hwnd);  
  ghwnd = hwnd;
  return TRUE;
}
 
 
 
BOOL WaitFor(unsigned long delay){
  static unsigned long clockStart = 0;
  unsigned long timePassed;
  unsigned long now = timeGetTime();
 
  timePassed = now - clockStart;
  if(timePassed > delay){
    clockStart = now;
    return TRUE;
  } //why was there an else here? <!-- s;) --><img src=\"{SMILIES_PATH}/icon_wink.gif\" alt=\";)\" title=\"Wink\"><!-- s;) -->
  return FALSE;
}
 
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
  switch(message){                                         
    case WM_CREATE:  
    break;
 
    case WM_SIZE:
    break;
 
    case WM_KEYDOWN:
    keys[wParam]=true;
    break;
 
    case WM_KEYUP:
    keys[wParam]=false;
    break;
 
    /*
    case WM_MOUSEMOVE:
    MousePos.x = LOWORD (lParam);
    MousePos.y = HIWORD (lParam);
    break;
    */
 
    case WM_PAINT:
    break;
 
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
  }
 
  return DefWindowProc(hwnd, message, wParam, lParam);
}
 
HBITMAP LoadABitmap(LPCWSTR szFileName){
  return (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
}
 
void drawSprite(Sprite theSprite){
  HBITMAP originalBitMap;
  originalBitMap = (HBITMAP)SelectObject(bitmapHDC,theSprite.bitmap);
  BitBlt(backHDC,theSprite.x,theSprite.y,theSprite.x+theSprite.width,theSprite.y+theSprite.height,bitmapHDC,0,0,SRCCOPY);
  SelectObject(bitmapHDC,originalBitMap);
}
 
void setBuffers(){
  GetClientRect(ghwnd, &screenRect); //creates rect based on window client area
  frontHDC = GetDC(ghwnd); // Initialises front buffer device context (window)
  backHDC = CreateCompatibleDC(frontHDC); // sets up Back DC to be compatible with the front
  bitmapHDC=CreateCompatibleDC(backHDC);
  theOldFrontBitMap = CreateCompatibleBitmap(frontHDC, screenRect.right,
  screenRect.bottom); //creates bitmap compatible with the front buffer
  theOldBackBitMap = (HBITMAP)SelectObject(backHDC, theOldFrontBitMap);
  //creates bitmap compatible with the back buffer
  FillRect(backHDC, &screenRect, (HBRUSH)GetStockObject(0));   
}
 
void displayFrame(){
  BitBlt(frontHDC, screenRect.left,screenRect.top, screenRect.right,
  screenRect.bottom, backHDC, 0, 0, SRCCOPY);
  FillRect(backHDC, &screenRect, (HBRUSH)GetStockObject(0));   
}
 
void releaseResources(){
  SelectObject(backHDC,theOldBackBitMap);
  DeleteDC(backHDC);
  DeleteDC(bitmapHDC);
  ReleaseDC(ghwnd,frontHDC);
}
 
/*
  classes
*/
 
//player ship
class Player{
  public:
  int x,y,height,width;
  float vSpeed,maxVSpeed,acceleration,friction;
  bool visible;
  Sprite sprite;
 
  //constructor
  Player(int setX, int setY, LPCWSTR bmp, int w, int h){
    sprite.bitmap = LoadABitmap(bmp);
    sprite.x = setX;
    sprite.y = setY;
    sprite.width = w;
    sprite.height = h;
    x = setX;
    y = setY;
    visible = true;
    vSpeed = 0;
    maxVSpeed = 14;
    acceleration = 1.3;
    friction = 0.7;
  }
 
  //every frame
  void step(){
    /*
      basic movement physics
    */
 
    //up
    if(keys[87]){
      //if not moving too fast upwards
      if(vSpeed > -maxVSpeed){
        //accelerate up
        vSpeed -= acceleration;
        //cap speed
        if(vSpeed < -maxVSpeed) vSpeed = -maxVSpeed;
      }
    }
    //down
    if(keys[83]){
      //if not moving too fast downwards
      if(vSpeed < maxVSpeed){
        //accelerate down
        vSpeed += acceleration;
        //cap speed
        if(vSpeed > maxVSpeed) vSpeed = maxVSpeed;
      }
    }
 
    //friction
    if(vSpeed > 0){
      vSpeed -= friction;
      if(vSpeed < 0) vSpeed = 0;
    } else if(vSpeed < 0){
      vSpeed += friction;
      if(vSpeed > 0) vSpeed = 0;
    }
 
 
    //apply motion
    y += vSpeed;
 
    //don't go out of the screen
    if(y < 0){
      vSpeed = 0;
      y = 0;
    } else if(y > 428){
      vSpeed = 0;
      y = 428;
    }
  }
 
  void draw(){
    if(!visible)
      return;
    sprite.x = x;
    sprite.y = y;
    drawSprite(sprite);
  }
};
 
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  PSTR szCmdLine, int nCmdShow){                         
  MSG msg;
  HDC hdcWindow;
 
  //create the player
  Player player(50,SCREEN_HEIGHT/2,L" icon.bmp",32,32);
 
  RegisterMyWindow(hInstance);
 
  if(!InitialiseMyWindow(hInstance, nCmdShow))
    return FALSE;
 
  setBuffers();
  while(TRUE){                   
    if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
      if(msg.message==WM_QUIT)
        break;
 
      TranslateMessage(&msg);                  
      DispatchMessage(&msg);
    } else if(WaitFor(10)){  
      //step the player
      player.step();
      //draw the player
      player.draw();
         
      displayFrame();  
    }
  }
 
  releaseResources();
  return msg.wParam;                           
}
 
 
  1. //Windows Example Code
  2. //Matthew Bett 2005
  3.  
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <mmsystem.h>
  7. #include <math.h>
  8.  
  9. #define SCREEN_WIDTH 640
  10. #define SCREEN_HEIGHT 480
  11.  
  12. /* not using any mouse input
  13. typedef struct Mouse{
  14.   int x,y;
  15. } Mouse;
  16. */
  17.  
  18. typedef struct Sprite{
  19.   int x, y, width, height;
  20.   HBITMAP bitmap;
  21. } Sprite;
  22.  
  23. int xpos, ypos;
  24. int ticker = 0;
  25.  
  26. HBITMAP theOldFrontBitMap, theOldBackBitMap;
  27. HWND ghwnd;
  28. RECT screenRect;
  29. HDC backHDC, frontHDC, bitmapHDC;   //Hardware device contexts for the Buffers
  30.  
  31. bool keys[256];
  32.  
  33. Sprite TestSprite;
  34.  
  35. BOOL waitFor(unsigned long delay);
  36.  
  37.  
  38. LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
  39.  
  40. void RegisterMyWindow(HINSTANCE hInstance){
  41.   WNDCLASSEX  wcex;                          
  42.  
  43.   wcex.cbSize = sizeof(wcex);
  44.   wcex.style = CS_HREDRAW | CS_VREDRAW;
  45.   wcex.lpfnWndProc = WndProc;
  46.   wcex.cbClsExtra = 0;
  47.   wcex.cbWndExtra = 0;
  48.   wcex.hInstance = hInstance;
  49.   wcex.hIcon = 0;
  50.   wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  51.                
  52.   wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  53.   wcex.lpszMenuName = NULL;
  54.   wcex.lpszClassName = L" FirstWindowClass";
  55.   wcex.hIconSm = 0;
  56.  
  57.   RegisterClassEx(&wcex);
  58. }
  59.  
  60.  
  61. BOOL InitialiseMyWindow(HINSTANCE hInstance, int nCmdShow){
  62.   HWND hwnd;
  63.   hwnd = CreateWindow(L" FirstWindowClass", L" Double Buffering", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
  64.   CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH, SCREEN_HEIGHT, NULL,   NULL, hInstance,
  65.   NULL);                     
  66.   if(!hwnd) return FALSE;
  67.  
  68.   ShowWindow(hwnd, nCmdShow);                
  69.   UpdateWindow(hwnd);  
  70.   ghwnd = hwnd;
  71.   return TRUE;
  72. }
  73.  
  74.  
  75.  
  76. BOOL WaitFor(unsigned long delay){
  77.   static unsigned long clockStart = 0;
  78.   unsigned long timePassed;
  79.   unsigned long now = timeGetTime();
  80.  
  81.   timePassed = now - clockStart;
  82.   if(timePassed > delay){
  83.     clockStart = now;
  84.     return TRUE;
  85.   } //why was there an else here? <!-- s;) --><img src=\"{SMILIES_PATH}/icon_wink.gif\" alt=\";)\" title=\"Wink\"><!-- s;) -->
  86.   return FALSE;
  87. }
  88.  
  89. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
  90.   switch(message){                                         
  91.     case WM_CREATE:  
  92.     break;
  93.  
  94.     case WM_SIZE:
  95.     break;
  96.  
  97.     case WM_KEYDOWN:
  98.     keys[wParam]=true;
  99.     break;
  100.  
  101.     case WM_KEYUP:
  102.     keys[wParam]=false;
  103.     break;
  104.  
  105.     /*
  106.     case WM_MOUSEMOVE:
  107.     MousePos.x = LOWORD (lParam);
  108.     MousePos.y = HIWORD (lParam);
  109.     break;
  110.     */
  111.  
  112.     case WM_PAINT:
  113.     break;
  114.  
  115.     case WM_DESTROY:
  116.     PostQuitMessage(0);
  117.     break;
  118.   }
  119.  
  120.   return DefWindowProc(hwnd, message, wParam, lParam);
  121. }
  122.  
  123. HBITMAP LoadABitmap(LPCWSTR szFileName){
  124.   return (HBITMAP)LoadImage(NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  125. }
  126.  
  127. void drawSprite(Sprite theSprite){
  128.   HBITMAP originalBitMap;
  129.   originalBitMap = (HBITMAP)SelectObject(bitmapHDC,theSprite.bitmap);
  130.   BitBlt(backHDC,theSprite.x,theSprite.y,theSprite.x+theSprite.width,theSprite.y+theSprite.height,bitmapHDC,0,0,SRCCOPY);
  131.   SelectObject(bitmapHDC,originalBitMap);
  132. }
  133.  
  134. void setBuffers(){
  135.   GetClientRect(ghwnd, &screenRect); //creates rect based on window client area
  136.   frontHDC = GetDC(ghwnd); // Initialises front buffer device context (window)
  137.   backHDC = CreateCompatibleDC(frontHDC); // sets up Back DC to be compatible with the front
  138.   bitmapHDC=CreateCompatibleDC(backHDC);
  139.   theOldFrontBitMap = CreateCompatibleBitmap(frontHDC, screenRect.right,
  140.   screenRect.bottom); //creates bitmap compatible with the front buffer
  141.   theOldBackBitMap = (HBITMAP)SelectObject(backHDC, theOldFrontBitMap);
  142.   //creates bitmap compatible with the back buffer
  143.   FillRect(backHDC, &screenRect, (HBRUSH)GetStockObject(0));   
  144. }
  145.  
  146. void displayFrame(){
  147.   BitBlt(frontHDC, screenRect.left,screenRect.top, screenRect.right,
  148.   screenRect.bottom, backHDC, 0, 0, SRCCOPY);
  149.   FillRect(backHDC, &screenRect, (HBRUSH)GetStockObject(0));   
  150. }
  151.  
  152. void releaseResources(){
  153.   SelectObject(backHDC,theOldBackBitMap);
  154.   DeleteDC(backHDC);
  155.   DeleteDC(bitmapHDC);
  156.   ReleaseDC(ghwnd,frontHDC);
  157. }
  158.  
  159. /*
  160.   classes
  161. */
  162.  
  163. //player ship
  164. class Player{
  165.   public:
  166.   int x,y,height,width;
  167.   float vSpeed,maxVSpeed,acceleration,friction;
  168.   bool visible;
  169.   Sprite sprite;
  170.  
  171.   //constructor
  172.   Player(int setX, int setY, LPCWSTR bmp, int w, int h){
  173.     sprite.bitmap = LoadABitmap(bmp);
  174.     sprite.x = setX;
  175.     sprite.y = setY;
  176.     sprite.width = w;
  177.     sprite.height = h;
  178.     x = setX;
  179.     y = setY;
  180.     visible = true;
  181.     vSpeed = 0;
  182.     maxVSpeed = 14;
  183.     acceleration = 1.3;
  184.     friction = 0.7;
  185.   }
  186.  
  187.   //every frame
  188.   void step(){
  189.     /*
  190.       basic movement physics
  191.     */
  192.  
  193.     //up
  194.     if(keys[87]){
  195.       //if not moving too fast upwards
  196.       if(vSpeed > -maxVSpeed){
  197.         //accelerate up
  198.         vSpeed -= acceleration;
  199.         //cap speed
  200.         if(vSpeed < -maxVSpeed) vSpeed = -maxVSpeed;
  201.       }
  202.     }
  203.     //down
  204.     if(keys[83]){
  205.       //if not moving too fast downwards
  206.       if(vSpeed < maxVSpeed){
  207.         //accelerate down
  208.         vSpeed += acceleration;
  209.         //cap speed
  210.         if(vSpeed > maxVSpeed) vSpeed = maxVSpeed;
  211.       }
  212.     }
  213.  
  214.     //friction
  215.     if(vSpeed > 0){
  216.       vSpeed -= friction;
  217.       if(vSpeed < 0) vSpeed = 0;
  218.     } else if(vSpeed < 0){
  219.       vSpeed += friction;
  220.       if(vSpeed > 0) vSpeed = 0;
  221.     }
  222.  
  223.  
  224.     //apply motion
  225.     y += vSpeed;
  226.  
  227.     //don't go out of the screen
  228.     if(y < 0){
  229.       vSpeed = 0;
  230.       y = 0;
  231.     } else if(y > 428){
  232.       vSpeed = 0;
  233.       y = 428;
  234.     }
  235.   }
  236.  
  237.   void draw(){
  238.     if(!visible)
  239.       return;
  240.     sprite.x = x;
  241.     sprite.y = y;
  242.     drawSprite(sprite);
  243.   }
  244. };
  245.  
  246.  
  247. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  248.   PSTR szCmdLine, int nCmdShow){                         
  249.   MSG msg;
  250.   HDC hdcWindow;
  251.  
  252.   //create the player
  253.   Player player(50,SCREEN_HEIGHT/2,L" icon.bmp",32,32);
  254.  
  255.   RegisterMyWindow(hInstance);
  256.  
  257.   if(!InitialiseMyWindow(hInstance, nCmdShow))
  258.     return FALSE;
  259.  
  260.   setBuffers();
  261.   while(TRUE){                   
  262.     if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
  263.       if(msg.message==WM_QUIT)
  264.         break;
  265.  
  266.       TranslateMessage(&msg);                  
  267.       DispatchMessage(&msg);
  268.     } else if(WaitFor(10)){  
  269.       //step the player
  270.       player.step();
  271.       //draw the player
  272.       player.draw();
  273.          
  274.       displayFrame();  
  275.     }
  276.   }
  277.  
  278.   releaseResources();
  279.   return msg.wParam;                           
  280. }
  281.  
  282.  

REMARQUE: l'éditeur de liens d'entrée: winmm.lib

Maintenant, permettez-moi d'expliquer le problème. Quand je définis SCREEN_HEIGHT en 640, je serais certainement s'attendre à la surface utilisable de la fenêtre à 640px de haut, non? Eh bien, Windows semble penser que ce serait amusant de prendre la barre de titre et de la frontière de cette valeur (avec aussi SCREEN_WIDTH). Alors, quand je programmer divers morceaux de code que j'ai à coder en dur dans la valeur de décalage par rapport à la frontière, pour mettre fin à ce qui se passe lorsque l'utilisateur se déplace vers le bas pendant trop longtemps:
Image

Maintenant, je peux résoudre ceci (en fixant la valeur codée en dur parce que je ne fixait pas / le supprimer dans l'exemple de capture d'écran). Mais, ce sera différent pour les différentes versions de Windows et également si l'utilisateur a changé leur thème. Alors, est-il un moyen au sein de l'API Windows pour savoir quelle est l'épaisseur de cette frontière est si je peux le réparer? Curieusement, le Y = 0 position est au bon endroit, mais le fond du travail sont de la fenêtre est compensée par l'épaisseur de la barre de titre.

Cela peut-il être corrigé? Ou ai-je fait quelque chose de terriblement mal?
  • Anonymous
  • Bot
  • No Avatar
  • Inscription: 25 Feb 2008
  • Messages: ?
  • Loc: Ozzuland
  • Status: Online

Message Novembre 13th, 2009, 8:56 am

Afficher de l'information

  • Total des messages de ce sujet: 1 message
  • Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 153 invités
  • Vous ne pouvez pas poster de nouveaux sujets
  • Vous ne pouvez pas répondre aux sujets
  • Vous ne pouvez pas éditer vos messages
  • Vous ne pouvez pas supprimer vos messages
  • Vous ne pouvez pas joindre des fichiers
 
 

© 2011 Unmelted, LLC. Ozzu® est une marque déposée de Unmelted, LLC