⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winmain.cpp

📁 [游戏开发参考书-用DirectX编写RPG游戏]这是一个系列的丛书如果你都看并且懂的话你就可以你工作啦!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        MenuSelect.Blit(192,Num*64+126);
    }

    // Draw enabled options
    App->m_Font.Print("New Game", 0,150,640,0,                \
                      0xFFFFFFFF,DT_CENTER);

    if(g_MenuOptions & MENU_BACK)
      App->m_Font.Print("Back to Game",0,214,640,0,           \
                        0xFFFFFFFF,DT_CENTER);

    if(g_MenuOptions & MENU_LOAD)
      App->m_Font.Print("Load Game",0,278,640,0,              \
                        0xFFFFFFFF,DT_CENTER);

    if(g_MenuOptions & MENU_SAVE)
      App->m_Font.Print("Save Game",0,342,640,0,              \
                        0xFFFFFFFF,DT_CENTER);

    App->m_Font.Print("Quit",0,410,640,0,0xFFFFFFFF,DT_CENTER);

    App->m_Graphics.EndScene();
  }
  App->m_Graphics.Display();
}

void cApp::GameFrame(void *Ptr, long Purpose)
{
  cApp *App = (cApp*)Ptr;
  sCharacter *CharPtr;
  BOOL        MonstersInLevel;
  long        TriggerNum;
  char        Filename[MAX_PATH], Stats[256];
  float       MaxY;

  // Only process frame states
  if(Purpose != FRAMEPURPOSE)
    return;

  // Quit to menu screen if ESCAPE pressed
  if(App->m_Keyboard.GetKeyState(KEY_ESC) == TRUE) {
    // Setup menu options
    g_MenuOptions = MENU_BACK | MENU_SAVE | MENU_LOAD;

    // Push main menu state
    App->m_StateManager.Push(App->MenuFrame, App);

    return;
  }

  // If teleporting, then handle that first and return
  if(App->m_TeleportMap != -1) {
    // Free level and process a new one
    App->FreeLevel();
    App->LoadLevel(App->m_TeleportMap);
    
    App->m_TeleportMap = -1;  // Clear out teleport map #

    return;  // No more processing this frame
  }

  // Mark no monsters in level
  MonstersInLevel = FALSE;

  // See if any character are in level. If any monsters,
  // flag as such and change their AI to wander if their
  // charge is less then 70, follow AI otherwise.
  // Also, process whenever a character reaches a route point.
  CharPtr = App->m_CharController.GetParentCharacter();
  while(CharPtr != NULL) {

    // Alter monster's AI based on charge
    if(CharPtr->Type == CHAR_MONSTER) {
      MonstersInLevel = TRUE;

      // Change AI based on charge
      if(CharPtr->Charge >= 70.0f) {
        CharPtr->AI = CHAR_FOLLOW;
        CharPtr->TargetChar = g_PCChar;
        CharPtr->Distance = 0.0f;
      } else {
        CharPtr->AI = CHAR_WANDER;
      }
    }

    // Check if an NPC character has reached last route point
    if(CharPtr->Type==CHAR_NPC && CharPtr->AI==CHAR_ROUTE) {

      // Was last point reached?
      if(App->LastPointReached(CharPtr) == TRUE) {
        // Process the route point script for character.
        sprintf(Filename,"..\\Data\\EOR%lu.mls", CharPtr->ID);
        App->m_Script.Execute(Filename);

        // Don't process any more this frame
        return;
      }
    }

    // Go to next character
    CharPtr = CharPtr->Next;
  }

  // Handle start of combat stuff
  if(MonstersInLevel==TRUE && App->m_MonstersLastFrame==FALSE)
    App->StartOfCombat();

  // Handle end of combat stuff if combat over
  if(MonstersInLevel==FALSE && App->m_MonstersLastFrame==TRUE)
    App->EndOfCombat();

  // Remember if monsters where in this frame
  // And reset player's charge to full if no monsters
  if((App->m_MonstersLastFrame = MonstersInLevel) == FALSE)
    g_PCChar->Charge = 100.0f;

  // Update controllers
  App->m_CharController.Update(33);
  App->m_SpellController.Update(33);

  // Check for triggers and execute script
  if((TriggerNum = App->m_Trigger.GetTrigger(g_PCChar->XPos,  \
                                        g_PCChar->YPos,       \
                                        g_PCChar->ZPos))) {
    sprintf(Filename, "..\\Data\\Trig%lu.mls", TriggerNum);
    App->m_Script.Execute(Filename);
    
    return;  // Don't process any more this frame
  }

  // Position the camera for the scene
  App->m_Graphics.SetCamera(&App->m_Camera);

  // Render everything
  App->m_Graphics.ClearZBuffer();
  if(App->m_Graphics.BeginScene() == TRUE) {
    App->RenderFrame(33);

    // Render the player's charge bar, but only during combat
    if(MonstersInLevel == TRUE) {
      D3DXMATRIX matWorld, matView, matProj;
      D3DVIEWPORT8 vpScreen;
      D3DXVECTOR3 vecPos;

      // Get the world, projection, and view transformations
      D3DXMatrixIdentity(&matWorld);
      App->m_Graphics.GetDeviceCOM()->GetTransform(           \
                              D3DTS_VIEW, &matView);
      App->m_Graphics.GetDeviceCOM()->GetTransform(           \
                              D3DTS_PROJECTION, &matProj);

      // Get viewport
      App->m_Graphics.GetDeviceCOM()->GetViewport(&vpScreen);

      // Offset charge bar by character's height
      g_PCChar->Object.GetBounds(NULL,NULL,NULL,              \
                                 NULL,&MaxY,NULL,NULL);

      // Project coordinates to screen  
      D3DXVec3Project(&vecPos, &D3DXVECTOR3(                  \
                                     g_PCChar->XPos,          \
                                     g_PCChar->YPos + MaxY,   \
                                     g_PCChar->ZPos),         \
                      &vpScreen, &matProj, &matView, &matWorld);

      // move 4 pixels right before displaying
      vecPos.x += 8.0f;

      // Display charge bar below player (flash when full)
      App->m_Graphics.EnableZBuffer(FALSE);
      App->m_Graphics.BeginSprite();
      App->m_Options.Blit((long)vecPos.x,(long)vecPos.y,      \
                           0,0,16,4);
      if(g_PCChar->Charge >= 100.0f) {
        if(timeGetTime() & 1)
         App->m_Options.Blit((long)vecPos.x,(long)vecPos.y,   \
                             0,4,16,4);
      } else {
        App->m_Options.Blit((long)vecPos.x,(long)vecPos.y,    \
                 0,4,(long)(g_PCChar->Charge/100.0f*16.0f),4);
      }

      App->m_Graphics.EndSprite();
    }

    // Draw the player's stats at top-left
    sprintf(Stats, "%ld / %ld HP\r\n%ld / %ld MP",            \
      g_PCChar->HealthPoints, g_PCChar->Def.HealthPoints,     \
      g_PCChar->ManaPoints, g_PCChar->Def.ManaPoints);
    App->m_Stats.Render(Stats);

    App->m_Graphics.EndScene();
  }
  App->m_Graphics.Display();
}

void cApp::BarterFrame(void *Ptr, long Purpose)
{
  cApp *App = (cApp*)Ptr;
  static cCharICS ICS;
  sCharItem *ItemPtr, *ScanPtr;
  char Text[256];
  long Color, Num, Sel;

  // Initialize barter data
  if(Purpose == INITPURPOSE) {
    // Load the ICS to use for bartering
    ICS.Load(g_BarterICS);

    // Set text
    App->m_Header.SetText("Shop");
    App->m_Window.SetText("\r\n\nWhat would you like to buy?");

    return;
  }

  // Shutdown resources used in bartering
  if(Purpose == SHUTDOWNPURPOSE) {
    // Free barter ICS
    ICS.Free();

    return;
  }

  // Process a frame of bartering

  // Exit bartering if ESCAPE or right mouse button pressed
  if(App->m_Keyboard.GetKeyState(KEY_ESC) == TRUE ||          \
     App->m_Mouse.GetButtonState(MOUSE_RBUTTON) == TRUE) {
    App->m_Keyboard.SetLock(KEY_ESC, TRUE);
    App->m_Mouse.SetLock(MOUSE_RBUTTON, TRUE);
    App->m_StateManager.Pop(App);
    return;
  }

  // Determine which item is selected with mouse
  if((Sel = App->m_Mouse.GetYPos() - 128) >= 0)
    Sel /= 32;

  // See if click on item to buy
  if(App->m_Mouse.GetButtonState(MOUSE_LBUTTON) == TRUE) {
    App->m_Mouse.SetLock(MOUSE_LBUTTON, TRUE);

    // See which item was clicked
    if(Sel >= 0 && Sel < ICS.GetNumItems()) {

      // Get pointer to item
      ItemPtr = ICS.GetItem(Sel);

      // Make sure PC has enough gold for item
      if(g_PCChar->Def.Money >=                               \
                        App->m_MIL[ItemPtr->ItemNum].Price) {

        // Search for item already in inventory
        ScanPtr = g_PCChar->CharICS->GetParentItem();
        while(ScanPtr != NULL) {
          // Increase quantity if item already in inventory
          if(ScanPtr->ItemNum == ItemPtr->ItemNum) {
            ScanPtr->Quantity++;
            break;
          }

          // Go to next pointer
          ScanPtr = ScanPtr->Next;
        }

        // Add item to PC's inventory if not already
        if(ScanPtr == NULL)
          g_PCChar->CharICS->Add(ItemPtr->ItemNum, 1, NULL);

        // Deduct price from PC
        g_PCChar->Def.Money -=                                \
                          App->m_MIL[ItemPtr->ItemNum].Price;

        // Play click sound
        App->PlaySound(8);
      }
    }
  }

  // Render the bartering scene
  if(App->m_Graphics.BeginScene() == TRUE) {
    App->RenderFrame();
    App->m_Window.Render();
    App->m_Header.Render();

    // Display items to buy
    Num = 0;
    ItemPtr = ICS.GetParentItem();
    while(ItemPtr != NULL) {

      // Calculate color to draw based on mouse position
      if(Num == Sel)
        Color = D3DCOLOR_RGBA(255,255,0,255);
      else
        Color = D3DCOLOR_RGBA(128,128,128,255);
      
      // Display item name
      App->m_Font.Print(App->m_MIL[ItemPtr->ItemNum].Name,    \
                        32, Num*32+128, 0, 0, Color);

      // Display item price
      sprintf(Text, "$%lu", App->m_MIL[ItemPtr->ItemNum].Price);
      App->m_Font.Print(Text, 300, Num*32+128, 0, 0, Color);

      // Go down one line
      Num++;

      // Go to next item
      ItemPtr = ItemPtr->Next;
    }

    // Display character's gold at top-right
    sprintf(Text, "Money: $%lu", g_PCChar->Def.Money);
    App->m_Font.Print(Text, 320, 32);

    App->m_Graphics.EndScene();
  }
  App->m_Graphics.Display();
}

void cApp::StatusFrame(void *Ptr, long Purpose)
{
  cApp *App = (cApp*)Ptr;
  sCharItem *ItemPtr;
  char Text[256];
  long Color, Num, Sel, i;

  // Initialize status
  if(Purpose == INITPURPOSE) {
    // Set text
    App->m_Header.SetText("Status");

    return;
  }

  // Return on shutdown purpose
  if(Purpose == SHUTDOWNPURPOSE)
    return;

  // Process a frame of status screen

  // Exit screen if ESCAPE or right mouse button pressed
  if(App->m_Keyboard.GetKeyState(KEY_ESC) == TRUE ||          \
     App->m_Mouse.GetButtonState(MOUSE_RBUTTON) == TRUE) {
    App->m_Keyboard.SetLock(KEY_ESC, TRUE);
    App->m_Mouse.SetLock(MOUSE_RBUTTON, TRUE);
    App->m_StateManager.Pop(App);
    return;
  }

  // Determine which item is selected with mouse
  if((Sel = App->m_Mouse.GetYPos() - 128) >= 0)
    Sel /= 32;

  // See if click on item to to use/equip
  if(App->m_Mouse.GetButtonState(MOUSE_LBUTTON) == TRUE) {
    App->m_Mouse.SetLock(MOUSE_LBUTTON, TRUE);

    // See which item was clicked
    if(Sel >= 0 && Sel < g_PCChar->CharICS->GetNumItems()) {

      // Get pointer to item
      ItemPtr = g_PCChar->CharICS->GetItem(Sel);

      // Determine what to do w/item
      switch(App->m_MIL[ItemPtr->ItemNum].Category) {
        case WEAPON:
          // Equip/Unequip weapon
          if(g_PCChar->Def.Weapon == ItemPtr->ItemNum)
            App->m_CharController.Equip(g_PCChar, 0,          \
                                        WEAPON, FALSE);
          else
            App->m_CharController.Equip(g_PCChar,             \
                                        ItemPtr->ItemNum,     \
                                        WEAPON, TRUE);
          break;

        case ARMOR:
          // Equip/Unequip armor
          if(g_PCChar->Def.Armor == ItemPtr->ItemNum)
            App->m_CharController.Equip(g_PCChar, 0,          \
                                        ARMOR, FALSE);
          else
            App->m_CharController.Equip(g_PCChar,             \
                                        ItemPtr->ItemNum,     \
                                        ARMOR, TRUE);
          break;

        case SHIELD:
          // Equip/Unequip shield
          if(g_PCChar->Def.Shield == ItemPtr->ItemNum)
            App->m_CharController.Equip(g_PCChar, 0,          \
                                        SHIELD, FALSE);
          else
            App->m_CharController.Equip(g_PCChar,             \
                                        ItemPtr->ItemNum,     \
                                        SHIELD, TRUE);
          break;

        case HEALING:
          g_PCChar->HealthPoints +=                           \
                           App->m_MIL[ItemPtr->ItemNum].Value;
          if(g_PCChar->HealthPoints>g_PCChar->Def.HealthPoints)
            g_PCChar->HealthPoints=g_PCChar->Def.HealthPoints;
          break;
      }

      // Reduce quantity if flagged as use once
      if(CheckItemFlag(App->m_MIL[ItemPtr->ItemNum].Flags,    \
                                                   USEONCE)) {
        if(ItemPtr->Quantity == 1)
          g_PCChar->CharICS->Remove(ItemPtr);
        else
          ItemPtr->Quantity--;
      }

      // Play click sound
      App->PlaySound(8);
    }
  }

  // Render the scene
  if(App->m_Graphics.BeginScene() == TRUE) {
    App->RenderFrame();
    App->m_Window.Render();
    App->m_Header.Render();

    // Display inventory on left
    App->m_Font.Print("Inventory:", 8, 96);
    Num = 0;
    ItemPtr = g_PCChar->CharICS->GetParentItem();
    while(ItemPtr != NULL) {

      // Calculate color to draw based on mouse position
      if(Num == Sel)
        Color = D3DCOLOR_RGBA(255,255,0,255);
      else
        Color = D3DCOLOR_RGBA(128,128,128,255);
      
      // Display item name w/quantity
      sprintf(Text, "%lu x %s", ItemPtr->Quantity,            \
              App->m_MIL[ItemPtr->ItemNum].Name);
      App->m_Font.Print(Text, 32, Num*32+128, 0, 0, Color);

      // If item is equipped, then show E next to it
      if(g_PCChar->Def.Weapon == ItemPtr->ItemNum ||          \
         g_PCChar->Def.Armor  == ItemPtr->ItemNum ||          \
         g_PCChar->Def.Shield == ItemPtr->ItemNum)
        App->m_Font.Print("E", 16, Num*32+128);

      // Go down one line
      Num++;

      // Go to next item
      ItemPtr = ItemPtr->Next;
    }

    // Display known spells at right
    App->m_Font.Print("Spells:", 300, 220);
    for(i=0;i<64;i++) {
      if(g_PCChar->Def.MagicSpells[i/32] & (1 << (i & 31))) {
        sprintf(Text, "%lu: %s", i+1,                         \
                    App->m_SpellController.GetSpell(i)->Name);
        App->m_Font.Print(Text, 320, i*32+252);
      }
    }

    // Display character's stats at top-right
    App->m_Font.Print("Stats", 300, 32);
    sprintf(Text, "%ld / %ld HP", g_PCChar->HealthPoints,     \
                                  g_PCChar->Def.HealthPoints);
    App->m_Font.Print(Text, 320, 64);
    sprintf(Text, "%ld / %ld MP", g_PCChar->ManaPoints,       \
                                  g_PCChar->Def.ManaPoints);
    App->m_Font.Print(Text, 320, 96);
    sprintf(Text, "$ %lu", g_PCChar->Def.Money);
    App->m_Font.Print(Text, 320, 128);
    sprintf(Text, "Lvl/Exp: %lu / %lu", g_PCChar->Def.Level,  \
                                   g_PCChar->Def.Experience);
    App->m_Font.Print(Text, 320, 160);

    App->m_Graphics.EndScene();
  }
  App->m_Graphics.Display();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -