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

📄 carddraw.pas

📁 这是一个扑克牌游戏。 1.抓有黑桃7 的玩家首先出黑桃7。 2.然后按逆时针方向出牌。每位玩家依次出牌
💻 PAS
📖 第 1 页 / 共 2 页
字号:

procedure TCardDraw.Lock;
begin
  FCurrentDesk.OnMouseDown := nil;
  Application.ProcessMessages;
end;

procedure TCardDraw.UnLock;
begin
  Application.ProcessMessages;
  FCurrentDesk.OnMouseDown := MouseDown;
end;

procedure TCardDraw.DrawPlayerName(APlayerIndex: Integer);
var
  pt: TPoint;
begin
  pt := GetPlayerNamePoint(APlayerIndex);
  FDesk.Canvas.TextOut(pt.X, pt.Y, FPlayerName[APlayerIndex]);
end;

procedure TCardDraw.ErasePlayerName(APlayerIndex: Integer);
var
  pt: TPoint;
  w, h: Integer;
begin
  pt := GetPlayerNamePoint(APlayerIndex);
  w := FDesk.Canvas.TextWidth(FPlayerName[APlayerIndex]);
  h := FDesk.Canvas.TextHeight(FPlayerName[APlayerIndex]);
  FDesk.Canvas.Rectangle(pt.X, pt.Y, pt.X + w, pt.Y + h);
end;

procedure TCardDraw.DrawPlayerCard(APlayerIndex: Integer);
var
  i, id, mode: Integer;
  pt: TPoint;
begin
  //还原背景
  FDesk.Canvas.Rectangle(FPlayerCardRect[APlayerIndex]);
  //画牌图片
  for i := 0 to PLAYER_CARD_COUNT - 1 do
  begin
    if FCards.PlayerCards[APlayerIndex].Card[i] = scNone then Continue;
    pt := GetPlayerCardPoint(APlayerIndex, i);
    if APlayerIndex = 0 then  //当前玩家画正面
    begin
      id := CardIDToPicID(FCards.PlayerCards[APlayerIndex].Card[i]);
      mode := 0;
    end
    else begin                //其它玩家画反面
      id := FCardBackIndex;
      mode := 1;
    end;
    if id <> scNone then
      cdtDraw(FDesk.Canvas.Handle, pt.X, pt.Y, id, mode, clGreen);
  end;
end;

procedure TCardDraw.DrawPlayerCoverCardRect(APlayerIndex: Integer);
var
  pt: TPoint;
begin
  //还原背景
  FDesk.Canvas.Rectangle(FPlayerCoverCardRect[APlayerIndex]);
  //画盖牌区图片
  pt.X := FPlayerCoverCardRect[APlayerIndex].Left;
  pt.Y := FPlayerCoverCardRect[APlayerIndex].Top;
  if FCards.PlayerCoverCards[APlayerIndex].Count > 0 then
    cdtDraw(FDesk.Canvas.Handle, pt.X, pt.Y, FCardBackIndex, 1, clGreen)
  else
    cdtDraw(FDesk.Canvas.Handle, pt.X, pt.Y, 53, 1, clGreen);
end;

procedure TCardDraw.DrawPlayerCoverCard(APlayerIndex: Integer);
var
  i, id: Integer;
  pt: TPoint;
begin
  //还原背景
  FDesk.Canvas.Rectangle(FPlayerCardRect[APlayerIndex]);
  FDesk.Canvas.Rectangle(FPlayerCoverCardRect[APlayerIndex]);
  //画牌图片
  for i := 0 to FCards.PlayerCoverCards[APlayerIndex].Count - 1 do
  begin
    pt := GetPlayerCardPoint(APlayerIndex, i);
    id := CardIDToPicID(FCards.PlayerCoverCards[APlayerIndex].Card[i]);
    cdtDraw(FDesk.Canvas.Handle, pt.X, pt.Y, id, 0, clGreen);
    //Sleep(40 + FSpeed * 20);   /
    //UpdateDesk;
  end;
end;

procedure TCardDraw.DrawMyCoverCard;
var
  i, x, y, id: Integer;
begin
  x := FPlayerCoverCardRect[0].Left;
  for i := FCards.PlayerCoverCards[0].Count - 1 downto 0 do
  begin
    y := FPlayerCoverCardRect[0].Top - i * CARD_BETWEEN_SPACE;
    id := CardIDToPicID(FCards.PlayerCoverCards[0].Card[FCards.PlayerCoverCards[0].Count - 1 - i]);
    cdtDraw(FDesk.Canvas.Handle, x, y, id, 0, clgreen);
  end;
end;

procedure TCardDraw.DrawNotOutCard(ACardIndex: Integer);
var
  id: Integer;
  pt: TPoint;
begin
  //画牌闪动图片
  pt := GetPlayerCardPoint(0, ACardIndex);
  id := CardIDToPicID(FCards.PlayerCards[0].Card[ACardIndex]);
  cdtDraw(FDesk.Canvas.Handle, pt.X, pt.Y, id, 2, clWhite);
  UpdateDesk;
  Sleep(300);  //延时
  //还原操作区
  DrawPlayerCard(0);
  UpdateDesk;
end;

procedure TCardDraw.DrawOutCard(ACardSuit: Integer);
var
  i, x, y, id: Integer;
begin
  //还原背景
  FDesk.Canvas.Rectangle(FOutCardRect[ACardSuit]);
  //画花色出牌情况
  if FCards.OutCards[ACardSuit].Max = scNone then exit;  //若当前花色未出过牌,则退出
  x := FOutCardRect[ACardSuit].Left;
  for i := FCards.OutCards[ACardSuit].Max downto FCards.OutCards[ACardSuit].Min do
  begin
    y := FOutCardRect[ACardSuit].Top
      + (FOutCardRect[ACardSuit].Bottom - FOutCardRect[ACardSuit].Top - FCardHeight) div 2
      + (6 - i) * CARD_BETWEEN_SPACE;
    id := CardIDToPicID(ACardSuit * 13 + i);
    cdtDraw(FDesk.Canvas.Handle, x, y, id, 0, clGreen);
  end;
end;

procedure TCardDraw.DrawDesk;
var
  i: Integer;
begin
  for i := 0 to 3 do
  begin
    DrawPlayerName(i);  //画玩家名字
    DrawPlayerCoverCardRect(i);  //画玩家的已盖标志牌
    DrawPlayerCard(i); //画玩家的待出牌
    DrawOutCard(i);   //画已出牌
  end;
  //更新桌面
  UpdateDesk;
end;

procedure TCardDraw.UpdateDesk;
begin
  FCurrentDesk.Canvas.CopyRect(FCurrentDesk.ClientRect, FDesk.Canvas, FDesk.ClientRect);
  FCurrentDesk.Refresh;
end;

procedure TCardDraw.PlayerCardClick(ACardIndex: Integer);
var
  gocard: TGoCard;
begin
  gocard := FCards.HumanGo(ACardIndex);
  if FHumanSound then   //播放出牌声音
    PlayCardSound(gocard.State);
  if gocard.State <> gcsError then
  begin
    MovieCard(gocard);
    GameGo;
  end
  else
    DrawNotOutCard(ACardIndex);
end;

procedure TCardDraw.PlayerCoverCardClick;
begin
  DrawMyCoverCard;
  UpdateDesk;
end;

procedure TCardDraw.PlayCardSound(AGoState: TGoCardState);
begin
  case AGoState of
  gcsOut:    //出牌
    PlaySound('out', HInstance, Snd_ASync or Snd_Memory or snd_Resource);
  gcsCover:    //盖牌
    PlaySound('cover', HInstance, Snd_ASync or Snd_Memory or snd_Resource);
  gcsError:    //错误
    PlaySound('err', HInstance, Snd_ASync or Snd_Memory or snd_Resource);
  end;
end;

procedure TCardDraw.MoveCard(ACardID: Integer; AStart, AEnd: TPoint; AMode: Integer);
var
  olddesk: TImage;
  x, y, sx, sy, id: Integer;
begin
  olddesk := TImage.Create(nil);
  olddesk.Width := FDesk.Width;
  olddesk.Height := FDesk.Height;
  olddesk.Canvas.CopyRect(olddesk.ClientRect, FDesk.Canvas, FDesk.ClientRect);
  id := CardIDToPicID(ACardID);
  sx := (AEnd.X - AStart.X) div (6 + FSpeed * 3);   //x 移动步长
  sy := (AEnd.Y - AStart.Y) div (6 + FSpeed * 3);   //y 移动步长
  x := AStart.X;
  y := AStart.Y;
  //移动图片
  while (Abs(AEnd.X - x) >= Abs(sx)) and (Abs(AEnd.Y - y) >= Abs(sy)) do
  begin
    if AMode = 0 then
      cdtDraw(FDesk.Canvas.Handle, x, y, id, AMode, clGreen)
    else
      cdtDraw(FDesk.Canvas.Handle, x, y, FCardBackIndex, AMode, clGreen);
    UpdateDesk;
    x := x + sx;
    y := y + sy;
    Sleep(10); //延时
    FDesk.Canvas.CopyRect(FDesk.ClientRect, olddesk.Canvas, olddesk.ClientRect);  //还原桌面
  end;
  olddesk.Free;
end;

procedure TCardDraw.MovieCard(AGoCard: TGoCard);
begin
  if AGoCard.State = gcsOut then
    MovieOutCard(AGoCard)
  else if AGoCard.State = gcsCover then
    MovieCoverCard(AGoCard);
end;

procedure TCardDraw.MovieOutCard(AGoCard: TGoCard);
var
  ptstart, ptend: TPoint;
  suit, num: Integer;
begin
  suit := AGoCard.CardID div 13;
  num := AGoCard.CardID mod 13;
  //更新出牌玩家的牌
  DrawPlayerCard(AGoCard.PlayerIndex);
  //计算起止点
  ptstart := GetPlayerCardPoint(AGoCard.PlayerIndex, AGoCard.CardIndex);
  ptend := GetOutCardPoint(suit, num);
  //移牌动画
  MoveCard(AGoCard.CardID, ptstart, ptend, 0);
  //更新出牌区
  DrawOutCard(suit);
  UpdateDesk;
end;

procedure TCardDraw.MovieCoverCard(AGoCard: TGoCard);
var
  ptstart, ptend: TPoint;
begin
  //更新盖牌玩家的牌
  DrawPlayerCard(AGoCard.PlayerIndex);
  //计算起止点
  ptstart := GetPlayerCardPoint(AGoCard.PlayerIndex, AGoCard.CardIndex);
  ptend.X := FPlayerCoverCardRect[AGoCard.PlayerIndex].Left;
  ptend.Y := FPlayerCoverCardRect[AGoCard.PlayerIndex].Top;
  //移牌动画
  MoveCard(AGoCard.CardID, ptstart, ptend, 1);
  //更新盖牌区图片
  DrawPlayerCoverCardRect(AGoCard.PlayerIndex);
  UpdateDesk;
end;

procedure TCardDraw.SetCardBackIndex(ACardIndex: Integer);
begin
  FCardBackIndex := ACardIndex;
  if FCards.State <> gsEnd  then DrawDesk; //当游戏进行时才重画桌面
end;

function TCardDraw.GetOutCardPoint(ACardSuit, ACardNum: Integer): TPoint;
begin
  Result.X := FOutCardRect[ACardSuit].Left;
  Result.Y := FOutCardRect[ACardSuit].Top
        + (FOutCardRect[ACardSuit].Bottom - FOutCardRect[ACardSuit].Top - FCardHeight) div 2
        + (6 - ACardNum) * CARD_BETWEEN_SPACE;
end;

function TCardDraw.GetPlayerNamePoint(APlayerIndex: Integer): TPoint;
begin
  case APlayerIndex of
  0:
    begin
      Result := GetPlayerCardPoint(APlayerIndex, 12);
      Result.X := Result.X + FCardWidth + 5;
      Result.Y := Result.Y + FCardHeight - FDesk.Canvas.TextHeight(FPlayerName[APlayerIndex]);
    end;
  1:
    begin
      Result := GetPlayerCardPoint(APlayerIndex, 12);
      Result.X := Result.X + FCardWidth - FDesk.Canvas.TextWidth(FPlayerName[APlayerIndex]);
      Result.Y := Result.Y - FDesk.Canvas.TextHeight(FPlayerName[APlayerIndex]) - 5;
    end;
  2:
    begin
      Result := GetPlayerCardPoint(APlayerIndex, 12);
      Result.X := Result.X - FDesk.Canvas.TextWidth(FPlayerName[APlayerIndex]) - 5;
      Result.Y := Result.Y;
    end;
  3:
    begin
      Result := GetPlayerCardPoint(APlayerIndex, 12);
      Result.X := Result.X;
      Result.Y := Result.Y + FCardHeight + 5;
    end;
  end;
end;
   
function TCardDraw.GetPlayerName(APlayerIndex: Integer): String;
begin
  Result := FPlayerName[APlayerIndex];
end;

procedure TCardDraw.SetPlayerName(APlayerIndex: Integer; AName: String);
begin
  //清除原名字
  ErasePlayerName(APlayerIndex);
  //画新名字
  FPlayerName[APlayerIndex] := AName;
  DrawPlayerName(APlayerIndex);
  if FCards.State <> gsEnd then UpdateDesk;
end;

end.



⌨️ 快捷键说明

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