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

📄 m_move.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
        Exit;
     end;

     Result := False;    // walked off an edge
     Exit;
  end;

// check point traces down for dangling corners
  VectorCopy (trace.endpos, ent^.s.origin);

  if (not M_CheckBottom (ent)) then
  begin
    if (ent^.flags and FL_PARTIALGROUND) <> 0 then
    begin
      // entity had floor mostly pulled out from underneath it
      // and is trying to correct
      if relink then
      begin
         gi.linkentity (ent);
         G_TouchTriggers (ent);
      end;
      Result := True;
      Exit;
    end;
    VectorCopy (oldorg, ent^.s.origin);
    Result := False;
    Exit;
  end;

  if (ent^.flags and FL_PARTIALGROUND) <> 0 then
  begin
     ent^.flags := ent^.flags and (not FL_PARTIALGROUND);
  end;
  ent^.groundentity := trace.ent;
  ent^.groundentity_linkcount := edict_p(trace.ent)^.linkcount;

// the move is ok
  if relink then
  begin
     gi.linkentity (ent);
     G_TouchTriggers (ent);
  end;
  Result := True;
end;

//============================================================================

(*
===============
M_ChangeYaw

===============
*)
procedure M_ChangeYaw (ent: edict_p);
var
  ideal: single;
  current: single;
  move: single;
  speed: single;
begin
  current := anglemod (ent^.s.angles[q_shared.YAW]);
  ideal := ent^.ideal_yaw;

  if current = ideal then
    Exit;

  move := ideal - current;
  speed := ent^.yaw_speed;
  if ideal > current then
  begin
    if move >= 180 then
      move := move - 360;
  end
  else
  begin
    if move <= -180 then
      move := move + 360;
  end;
  if move > 0 then
  begin
    if move > speed then
      move := speed;
  end
  else
  begin
    if move < -speed then
      move := -speed;
  end;

  ent^.s.angles[q_shared.YAW] := anglemod (current + move);
end;

(*
======================
SV_StepDirection

Turns to the movement direction, and walks the current distance if
facing it.

======================
*)
function SV_StepDirection (ent: edict_p; yaw: single; dist: single): qboolean;
var
  move, oldorigin: vec3_t;
  delta: single;
begin
  ent^.ideal_yaw := yaw;
  M_ChangeYaw (ent);

  yaw := yaw * M_PI * 2 / 360;
  move[0] := cos(yaw) * dist;
  move[1] := sin(yaw) * dist;
  move[2] := 0;

  VectorCopy (ent^.s.origin, oldorigin);
  if (SV_movestep (ent, move, false)) then
  begin
    delta := ent^.s.angles[q_shared.YAW] - ent^.ideal_yaw;
    if ((delta > 45) and (delta < 315)) then
    begin		// not turned far enough, so don't take the step
      VectorCopy (oldorigin, ent^.s.origin);
    end;
    gi.linkentity (ent);
    G_TouchTriggers (ent);
    Result := True;
    Exit;
  end;
  gi.linkentity (ent);
  G_TouchTriggers (ent);
  Result := False;
end;

(*
======================
SV_FixCheckBottom

======================
*)
procedure SV_FixCheckBottom (ent: edict_p);
begin
  ent^.flags := ent^.flags or FL_PARTIALGROUND;
end;

(*
================
SV_NewChaseDir

================
*)
const	DI_NODIR = -1;

procedure SV_NewChaseDir (actor: edict_p; enemy: edict_p; dist: single);
var
  deltax, deltay: single;
  d: array [0..2] of single;
  tdir, olddir, turnaround: single;
begin
  //FIXME: how did we get here with no enemy
  if (enemy = nil) then
    Exit;

  olddir := anglemod(Trunc((actor^.ideal_yaw/45)*45) );
  turnaround := anglemod(olddir - 180);

  deltax := enemy^.s.origin[0] - actor^.s.origin[0];
  deltay := enemy^.s.origin[1] - actor^.s.origin[1];
  if (deltax > 10) then
    d[1] := 0
  else if (deltax < -10) then
    d[1] := 180
  else
    d[1] := DI_NODIR;
  if (deltay < -10) then
    d[2] := 270
  else if (deltay > 10) then
    d[2] := 90
  else
    d[2] := DI_NODIR;

// try direct route
  if ((d[1] <> DI_NODIR) and (d[2] <> DI_NODIR)) then
  begin
    if (d[1] = 0) then
    begin
      if d[2] = 90 then
        tdir := 45
      else
        tdir := 315;
    end
    else
    begin
      if d[2] = 90 then
        tdir := 135
      else
        tdir := 215;
    end;

    if ((tdir <> turnaround) and (SV_StepDirection(actor, tdir, dist))) then
      Exit;
  end;

// try other directions
  if (((rand() and 3) and 1) <> 0) or (abs(deltay) > abs(deltax)) then
  begin
    tdir := d[1];
    d[1] := d[2];
    d[2] := tdir;
  end;

  if ((d[1] <> DI_NODIR) and (d[1] <> turnaround)
  and (SV_StepDirection(actor, d[1], dist))) then
    Exit;

  if ((d[2] <> DI_NODIR) and (d[2] <> turnaround)
  and (SV_StepDirection(actor, d[2], dist))) then
    Exit;

(* there is no direct path to the player, so pick another direction *)

  if ((olddir <> DI_NODIR) and (SV_StepDirection(actor, olddir, dist))) then
    Exit;

  if (rand() and 1) <> 0 then 	(*randomly determine direction of search*)
  begin
    tdir := 0;
    while (tdir <= 315) do
    begin
      if ((tdir <> turnaround) and (SV_StepDirection(actor, tdir, dist)) ) then
        Exit;
      tdir := tdir + 45;
    end;
  end
  else
  begin
    tdir := 315;
    while (tdir >= 0) do
    begin
      if ((tdir <> turnaround) and (SV_StepDirection(actor, tdir, dist)) ) then
        Exit;
      tdir := tdir - 45;
    end;
  end;

  if ((turnaround <> DI_NODIR) and (SV_StepDirection(actor, turnaround, dist)) ) then
    Exit;

  actor^.ideal_yaw := olddir;		// can't move

// if a bridge was pulled out from underneath a monster, it may not have
// a valid standing position at all

  if (not M_CheckBottom (actor)) then
    SV_FixCheckBottom (actor);
end;


(*
======================
SV_CloseEnough

======================
*)
function SV_CloseEnough (ent: edict_p; goal: edict_p; dist: single): qboolean;
var
  i: smallint;
begin
  for i:= 0 to 2 do
  begin
    if (goal^.absmin[i] > ent^.absmax[i] + dist) then
    begin
      Result := false;
      Exit;
    end;
    if (goal^.absmax[i] < ent^.absmin[i] - dist) then
    begin
      Result := false;
      Exit;
    end;
  end;
  Result := true;
end;


(*
======================
M_MoveToGoal
======================
*)
procedure M_MoveToGoal (ent: edict_p; dist: single);
var
  goal: edict_p;
begin
  goal := ent^.goalentity;

  if (ent^.groundentity = nil) and ((ent^.flags and (FL_FLY or FL_SWIM)) = 0) then
    Exit;

// if the next step hits the enemy, return immediately
  if (ent^.enemy <> nil) and  (SV_CloseEnough(ent, ent^.enemy, dist)) then
    Exit;

// bump around...
  if  ((rand() and 3) = 1) or  (not SV_StepDirection (ent, ent^.ideal_yaw, dist)) then
  begin
    if (ent^.inuse) then
      SV_NewChaseDir (ent, goal, dist);
  end;
end;


(*
===============
M_walkmove
===============
*)
function M_walkmove (ent: edict_p; yaw: single; dist: single): qboolean;
var
  move: vec3_t;
begin
  if (ent^.groundentity = nil) and ((ent^.flags and (FL_FLY or FL_SWIM)) = 0) then
  begin
    Result := false;
    Exit;
  end;

  yaw := yaw * M_PI * 2 / 360;

  move[0] := cos(yaw) * dist;
  move[1] := sin(yaw) * dist;
  move[2] := 0;

  Result := SV_movestep(ent, move, true);
end;


end.

⌨️ 快捷键说明

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