📄 carddraw.pas
字号:
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 + -