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

📄 ps.cpp

📁 Beginning Direct3D Game Programming源代码Part3chapter122dbitarray.rar
💻 CPP
字号:
#include <windows.h>
#include "ps.h"

template<class T>
T Min(T t1, T t2)
{
  return (t1<t2 ? t1 : t2);
}

template<class T>
T Max(T t1, T t2)
{
  return (t1>t2 ? t1 : t2);
}

PhysicalSprite::PhysicalSprite(PIXELVALUE* pix, int w, int h, 
                               PIXELVALUE transparent)
: width(w),
  height(h),
  x(0),
  y(0)
{
  CalculateBitArray(pix,transparent);
}

PhysicalSprite::~PhysicalSprite()
{
  delete[] bitarray;
}

void PhysicalSprite::CalculateBitArray(PIXELVALUE* pix, 
                                       PIXELVALUE transparent)
{
  groups_number = width/32;
  int extra=width%32;
  if (extra != 0) groups_number++;
  bitarray=new unsigned[height*groups_number];
  for(int i=0;i<height;i++)
  {
    int base=i*groups_number;
    int basepix = i*width;
    for(int k=0;k<groups_number;k++)
    {
      // Initialize the integer bit array, before using it.
      bitarray[base+k]=0;
      for(int j=k*32;j<width && j<(k+1)*32;j++)
      {
        // Determine if the pixel is solid or transparent
        bool solid = (pix[basepix+j] != transparent);
        // Shift the bit array left by 1
        bitarray[base+k] <<= 1;
        // Set the lowest bit to this pixel's value
        bitarray[base+k] |= (solid ? 1 : 0);
      }
    }
    if (extra!=0) 
      bitarray[base+groups_number-1]<<=(32-extra);
  }
}

unsigned PhysicalSprite::GetBitArray(int x, int y) const
{
  // Check vertical bounds
  if (y<0 || y>=height) return 0;

  // Prepare calculated values.
  int gx = x / 32;
  int extra = x % 32;
  int base = y * groups_number;

  // If the position is 32 bit aligned, simply return the value
  if (extra == 0) return bitarray[base+gx];

  // If the horizontal position is invalid, return 0
  if (gx < 0 || gx >= groups_number) return 0;
  // Take the bits from the value to the left of this position
  unsigned result = bitarray[base+gx] << extra;
  // If no other value is available (right edge) return what we've got
  if (gx+1 >= groups_number) return result;
  // Add the bits from the value to the right of this position
  return result | (bitarray[base+gx+1] >> (32 - extra));
}

bool PhysicalSprite::DetectCollision(const PhysicalSprite& other)
{
  // Calculate the other sprite's offset relative to this one.
  int ox = other.x - x;
  int oy = other.y - y;

  // Calculate the intersection rectangle
  // Remember that the coordinates are relative to the current sprite.
  RECT isect;
  isect.left = Max(ox,0);
  isect.right = Min(ox+other.width,width);
  isect.top = Max(oy,0);
  isect.bottom = Min(oy+other.height,height);
  // See if the intersection rectangle is valid (width and height > 0)
  // If the rectangle is not valid, there is no collision
  if (isect.right<isect.left || isect.bottom<isect.top) return false;

  // Width of the rectangle
  int bits_to_check = isect.right - isect.left;
  // Height of the rectangle
  int rows_to_check = isect.bottom - isect.top;
  int groups_to_check = bits_to_check / 32;
  int extra = bits_to_check % 32;
  if (extra != 0) groups_to_check++;
  
  for(int i=0;i<rows_to_check;i++)
  {
    int row=isect.top+i;
    int group = groups_to_check;
    // Check in groups of 32 pixels
    for(int j=isect.left;j<=isect.right;j+=32)
    {
      unsigned bits1=GetBitArray(j,row);
      unsigned bits2=other.GetBitArray(j-ox,row-oy);
      if ((bits1 & bits2) != 0) return true;
    }
  }
  return false;
}

⌨️ 快捷键说明

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