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

📄 cell.cpp

📁 通用网络游戏开发框架
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ============================================================================
// Cell implementation
//
// (c) 2003 Ken Reed
//
// This is free software. You can redistribute it and/or modify it under the
// terms of the GNU General Public License version 2 as published by the Free
// Software Foundation.
// ============================================================================

#include "stdafx.h"
#include "cell.h"
#include "brush.h"
#include "pen.h"
#include "universal.h"
#include "socket.h"

#include <fstream>
#include <assert.h>
#include <math.h>
#include <sstream>
#include <cmath>

using namespace std;

struct CellBuffer {
   int    sync;
   int    i, j, player, type;
   double troops, elevation, strength;
   POINT  position;
   bool   vector[6];
};

class spoint {                               // Signed version of POINT
public:                                      // that can be statically
   int x;                                    // initialised
   int y;
};

namespace {
   const int c = cell_size;                  // Abbreviations for data
   const int h = half_cell_size;             // initialisation
   const int q = quarter_cell_size;
   const int t = cell_size - q;

   const double deg_to_rad = 3.1415925 / 180;

   // The x coordinate for a movement vector that isn't straight up or down
   // is 3/8th of the cell size.

   const int m = q + (q / 2);

   POINT     hexagon[]  = {q,0, t,0, c,h, t,c, q,c, 0,h, q,0};
   spoint    offset[6]  = {m,q, 0,h, -m,q, -m,-q,  0,-h, m,-q}; 
   spoint    unitvec[6] = {1,1, 0,1, -1,1, -1,-1,  0,-1, 1,-1}; 

   COLORREF  colours[max_players] = {RGB(255, 50, 50),   RGB(255, 50, 255), 
                                     RGB(255, 255, 255), RGB(255, 255, 0),
                                     RGB(100, 255, 100), RGB(150, 150, 255)  
   }; 

   const int    num_points  (sizeof(hexagon) / sizeof(POINT));
}


// ============================================================================
// Reset a cell to its default state
// ============================================================================

void Cell::reset(bool exploring)
{
   changed     = false;
   elevation   = 0;
   explored    = ! exploring;
   march       = false;
   scanned     = false;
   player      = -1;
   troops      = 0;
   type        = Empty;
   strength    = 0;

   for (int i = 0; i < 6; i++) {
      vector[i] = false;
   }
}


// ============================================================================
// Construction
// ============================================================================

Cell::Cell()
{
   reset(true);
}


// ============================================================================
// Draw a circle
// ============================================================================

static void circle(HDC hdc, POINT center, int diameter)
{
   int x = center.x - (diameter / 2);
   int y = center.y - (diameter / 2);

   Ellipse(hdc, x, y, x + diameter, y + diameter);
}


// ============================================================================
// Draw a cell
// ============================================================================

void Cell::draw_cell(HDC hdc, bool hide_vectors, int client)
{
   POINT     points[num_points];
   COLORREF  cell_colour;

   // The cell background colour depends on its elevation. Sea-level is green
   // and the colour shifts to brown with increasing altitude. Shades of blue
   // are used for negative altitudes (sea).

   int    hue        (225);
   double adjustment (abs((double) hue * (elevation / max_elevation)));

   if (elevation < 0) {
      cell_colour = RGB(0, 0, hue - (adjustment * 0.7));
   }
   else {
      cell_colour = RGB(adjustment * 0.5, hue - (adjustment * 0.7), 0);
   }

   if (explored == false) {
      cell_colour = RGB(128, 128, 128);
   }

   Brush cell_brush(hdc, cell_colour);
   int   i;

   for (i = 0; i < num_points; i++) {
      points[i].x = hexagon[i].x + position.x;
      points[i].y = hexagon[i].y + position.y;
   }

   Polygon(hdc, points, num_points);

   if (explored == false) return;

   POINT centre = get_centre();
   COLORREF player_colour(colours[player]);
   Pen      troop_pen(hdc,   player_colour, 1);
   Brush    troop_brush(hdc, player_colour);
   int      circle_size(0);
   int      scale(1);

   // If there are troops in this cell draw a solid circle of a representative
   // size.

   if (troops > 0.0) {
      circle_size = (int) (((double) cell_size-8) * (troops / max_troops));
      circle_size |= 1;
      circle(hdc, centre, circle_size);
   }
   else {
      scale = 2;
   }

   // Draw movement vectors in the player's colour. If the cell is empty,
   // vectors are drawn half size. For readability, draw the bit of the
   // movement vector that is inside the troop circle in black.

   double theta(30);
   double radius(circle_size / 2);

   if ((player == client) || !hide_vectors || (troops > 0)) { 
      for (i = 0; i < 6; i++) {
         if (vector[i]) {
            int x = centre.x + (offset[i].x / scale);
            int y = centre.y + (offset[i].y / scale);

            Pen troop_pen(hdc, player_colour, 3);
            MoveToEx(hdc, centre.x, centre.y, 0);
            LineTo(hdc, x, y);
            
            if (circle_size > 2) {
               int xo = (int)(radius * cos(theta * deg_to_rad));
               int yo = (int)(radius * sin(theta * deg_to_rad));
               
               xo += centre.x; 
               yo += centre.y;
               
               Pen black_pen(hdc, RGB(0, 0, 0), 1);
               MoveToEx(hdc, centre.x, centre.y, 0);
               LineTo(hdc, xo, yo);
            }
         }
         theta += 60;
      }
   }

   HBRUSH null_brush = static_cast<HBRUSH>(GetStockObject(HOLLOW_BRUSH));
   SelectObject(hdc, null_brush);

   // Draw a circle to indicate the strength of this base

   if (type == Base) {
      Pen pen(hdc, RGB(0,0,0), 2);

      double size(cell_size - 3);
      size *= strength / 100.0;
      circle(hdc, centre, size);
   }
}


// ============================================================================
// Draw this cell
// ============================================================================

void Cell::draw(HWND window, bool hide_vectors, int client)
{
   HDC hdc (GetDC(window));
   assert(hdc != 0);

   HBRUSH old_brush = static_cast<HBRUSH>(GetCurrentObject(hdc, OBJ_BRUSH));
   HPEN   old_pen   = static_cast<HPEN>  (GetCurrentObject(hdc, OBJ_PEN));

   draw_cell(hdc, hide_vectors, client);

   SelectObject(hdc, old_brush);
   SelectObject(hdc, old_pen);
   ReleaseDC(window, hdc);
}



// ============================================================================
// Update this cell
// ============================================================================

void Cell::update(double elapsed)
{
   if ((type == Base) && (troops < max_troops)) {
      troops += (growth_rate * (strength / 100)) * elapsed;
      if (troops > max_troops) troops = max_troops;
      changed = true;
   }
}


// ============================================================================
// Put a cell into march mode
// ============================================================================

void Cell::set_march(Point position)
{
   clear_vector(all_vectors);
   int side (which_side(position));

   if (side == -1) {
      return;
   }

   march_vector = side;
   march        = true;;
   march_timer  = 0;
}


// ============================================================================
// Toggle a movement vector
// ============================================================================

void Cell::toggle_vector(Point position)
{
   march        = false;
   int side (which_side(position));

⌨️ 快捷键说明

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