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

📄 isomath.pas

📁 一款RPG游戏的引擎可以自己制作一款RPG游戏的引擎可以自己制作
💻 PAS
字号:
unit isoMath;

{****************************************************************************
     The contents of this file are subject to the Mozilla Public License
     Version 1.1 (the "License"); you may not use this file except in
     compliance with the License. You may obtain a copy of the License at
     http://www.mozilla.org/MPL/

     Software distributed under the License is distributed on an "AS IS"
     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
     License for the specific language governing rights and limitations
     under the License.

     The Original Code is IsoEdit.

     The Initial Developer of the Original Code is No.2 Games, Inc. and
     Michael Wilson. Portions created by Michael Wilson are Copyright
     (C) No.2 Games, Inc.  All Rights Reserved.

     Contributor(s):
******************************************************************************}

// *****************************************
// *  isoMath - 256 cycle trig functions   *
// *  and vector equations that are        *
// *  useful in isometric perspective      *
// *  games.  All functions are skewed     *
// *  to reflect a 2:1 orthoginal          *
// *  perspective. (c)1999 Michael Wilson  *
// *****************************************

interface


const

  isoPi = 3.14159; //                    (192)
  isoNorth = 192; // screen up            n        Clock-wise
  isoSouth = 64; // screen down   (128) w + e (0)   rotation
  isoWest = 128; // screen left           s
  isoEast = 0; // screen right          (64)

type
  isoPolar = record
    a {ngle}: integer; // 256 cycle angle [0..255] is more than enough
    v {elocity}: single; // pixel movements as small as 0.00000001
  end;

  isoVector = record
    x, y: single; // pixel movements as small as 0.00000001
  end;

  // these are used to represent x,y locations in a grid
  // so if you see a function using TGridint or
  // TCellsCoord, it's dealing with cells, not pixels
  TGridInt = Integer;

  TCellsCoord = record
      X, Y: TGridInt;
  end;


function isoSin(a {ngle}: integer): single;
function isoCos(a {ngle}: integer): single;
// function isoArcTanAsm(Y, X: extended): extended;
function normArcTan(dy, dx: single): byte;
function isoArcTan(dy, dx: single): byte;
function normFindAngle(x, y, x1, y1: integer): byte;
function isoFindAngle(x, y, x1, y1: integer): byte;
function isoIsLeft(a {ngle}, t {est}: byte): boolean;
function isoNormAngle(angle: integer): byte;
function isoDistance(x, y, x1, y1: integer): integer;
function isoPointInQuad(x0, y0, x1, y1, x2, y2, x3, y3, x, y: integer): boolean;
function GetNW(FromCell : TCellsCoord) : TCellsCoord;
function GetNE(FromCell : TCellsCoord) : TCellsCoord;
function GetSW(FromCell : TCellsCoord) : TCellsCoord;
function GetSE(FromCell : TCellsCoord) : TCellsCoord;

implementation

function isoSin(a {ngle}: integer): single; // integer allows for negative angles
begin
  result := sin(((a and 255) / 256) * 2 * isoPi) / 2 // one-half of the y vector
end; {function}

function isoCos(a {ngle}: integer): single;
begin
  result := cos(((a and 255) / 256) * 2 * isoPi)
end; {function}

{function isoArcTanAsm(Y, X: extended): extended;
asm
  FLD    Y
  FLD    X
  FPATAN
  FWAIT
end;}

function normArcTan(dy, dx: single): byte;
begin
  result := abs(round(ArcTan(dy / dx) * (128 / isoPi))); // one-half of the y vector
end; {function}

function isoArcTan(dy, dx: single): byte;
begin
  result := abs(round(ArcTan((dy / 2) / dx) * (128 / isoPi))); // one-half of the y vector
end; {function}

function normFindAngle(x, y, x1, y1: integer): byte;
var
  dx, dy: integer;
begin
  dx := (x - x1); {get dx dy}
  dy := (y - y1);

  if (dx = 0) then
    begin {check special cases}
      if (dy > 0) then
        result := 64
      else
        result := 192;
      exit;
    end; {special cases}

  if (dx < 0) and (dy > 0) then { 2nd quad }
    result := 128 - normarctan(dy, dx)
  else
    if (dx < 0) and (dy <= 0) then { 3rd quad }
      result := 128 + normarctan(dy, dx)
    else
      if (dx > 0) and (dy < 0) then { 4th quad }
        result := 256 - normarctan(dy, dx)
      else { 1st quad }
        result := normarctan(dy, dx)
end; {function}

function isoFindAngle(x, y, x1, y1: integer): byte;
var
  dx, dy: integer;
begin
  dx := (x - x1); {get dx dy}
  dy := (y - y1);

  if (dx = 0) then
    begin {check special cases}
      if (dy > 0) then
        result := 64
      else
        result := 192;
      exit;
    end; {special cases}

  if (dx < 0) and (dy > 0) then { 2nd quad }
    result := 128 - isoarctan(dy, dx)
  else
    if (dx < 0) and (dy <= 0) then { 3rd quad }
      result := 128 + isoarctan(dy, dx)
    else
      if (dx > 0) and (dy < 0) then { 4th quad }
        result := 256 - isoarctan(dy, dx)
      else { 1st quad }
        result := isoarctan(dy, dx)
end; {function}

function isoIsLeft(a {ngle}, t {est}: byte): boolean;
var loop: integer; // loop
begin
  loop:=0;
  repeat
    inc(loop)
  until (isonormangle(a + loop) = t) or (isonormangle(a - loop) = t);
  if (isonormangle(a - loop) = t) then result := true
  else
    result := false;
end;

function isoNormAngle(angle: integer): byte;
begin
  result := angle and 255;
end; {function}

function isoDistance(x, y, x1, y1: integer): integer;
begin
  result := round(sqrt((x - x1) * (x - x1) + ((y - y1) * 2) * ((y - y1) * 2)));
end; {function}

function isoPointInQuad(x0, y0, x1, y1, x2, y2, x3, y3, x, y: integer): boolean;
begin
  result := false;
  if ((y0 - y1) * (x - x1) + (x1 - x0) * (y - y1) > -1) and
    ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2) > -1) and
    ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3) > -1) and
    ((y3 - y0) * (x - x0) + (x0 - x3) * (y - y0) > -1) then
    result := true;
  if ((y0 - y1) * (x - x1) + (x1 - x0) * (y - y1) < 1) and
    ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2) < 1) and
    ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3) < 1) and
    ((y3 - y0) * (x - x0) + (x0 - x3) * (y - y0) < 1) then
    result := true;
end; { function }

function GetNW(FromCell : TCellsCoord) : TCellsCoord;
begin
  result.y := FromCell.Y -1;
  if (FromCell.Y and 1)<>0 then Result.X := FromCell.x
  else Result.X := FromCell.X-1;
end;

function GetNE(FromCell : TCellsCoord) : TCellsCoord;
begin
  result.y := FromCell.Y -1;
  if (FromCell.Y and 1)<>0 then Result.X := FromCell.x+1
  else Result.X := FromCell.X;
end;

function GetSW(FromCell : TCellsCoord) : TCellsCoord;
begin
  result.y := FromCell.Y +1;
  if (FromCell.Y and 1)<>0 then Result.X := FromCell.x
  else Result.X := FromCell.X-1;
end;

function GetSE(FromCell : TCellsCoord) : TCellsCoord;
begin
  result.y := FromCell.Y +1;
  if (FromCell.Y and 1)<>0 then Result.X := FromCell.x+1
  else Result.X := FromCell.X;
end;


end.

⌨️ 快捷键说明

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