onlyou13

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
//版本一:吃完一个就结束了。

unit
Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls; type TForm1 = class(TForm) Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure Timer1Timer(Sender: TObject); procedure FormPaint(Sender: TObject); private { Private declarations } Snake: array[0..499] of TPoint; SnakeLength: Integer; Food: TPoint; Direction: TPoint; procedure DrawSnake; procedure DrawFood; procedure MoveSnake; procedure CheckCollision; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} const BlockSize = 10; procedure TForm1.FormCreate(Sender: TObject); begin SnakeLength := 1; Snake[0].X := 10; Snake[0].Y := 10; Food.X := 30; Food.Y := 30; Direction.X := 1; Direction.Y := 0; Timer1.Enabled := True; DoubleBuffered := True; end; procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin case Key of VK_UP: begin Direction.X := 0; Direction.Y := -1; end; VK_DOWN: begin Direction.X := 0; Direction.Y := 1; end; VK_LEFT: begin Direction.X := -1; Direction.Y := 0; end; VK_RIGHT: begin Direction.X := 1; Direction.Y := 0; end; end; end; procedure TForm1.FormPaint(Sender: TObject); begin DrawSnake; DrawFood; end; procedure TForm1.Timer1Timer(Sender: TObject); begin MoveSnake; CheckCollision; Repaint; end; procedure TForm1.DrawSnake; var i: Integer; begin for i := 0 to SnakeLength - 1 do begin Canvas.Brush.Color := clGreen; Canvas.FillRect(Rect(Snake[i].X * BlockSize, Snake[i].Y * BlockSize, Snake[i].X * BlockSize + BlockSize, Snake[i].Y * BlockSize + BlockSize)); end; end; procedure TForm1.DrawFood; begin Canvas.Brush.Color := clRed; Canvas.FillRect(Rect(Food.X * BlockSize, Food.Y * BlockSize, Food.X * BlockSize + BlockSize, Food.Y * BlockSize + BlockSize)); end; procedure TForm1.MoveSnake; var i: Integer; begin for i := SnakeLength - 1 downto 1 do Snake[i] := Snake[i - 1]; Snake[0].X := Snake[0].X + Direction.X; Snake[0].Y := Snake[0].Y + Direction.Y; end; procedure TForm1.CheckCollision; var i: Integer; begin if (Snake[0].X = Food.X) and (Snake[0].Y = Food.Y) then begin Inc(SnakeLength); Snake[SnakeLength - 1] := Snake[SnakeLength - 2]; Food.X := Random(ClientWidth div BlockSize); Food.Y := Random(ClientHeight div BlockSize); end; if Snake[0].X < 0 then Snake[0].X := ClientWidth div BlockSize - 1; if Snake[0].X > ClientWidth div BlockSize - 1 then Snake[0].X := 0; if Snake[0].Y < 0 then Snake[0].Y := ClientHeight div BlockSize - 1; if Snake[0].Y > ClientHeight div BlockSize - 1 then Snake[0].Y := 0; for i := 1 to SnakeLength - 1 do if (Snake[0].X = Snake[i].X) and (Snake[0].Y = Snake[i].Y) then Timer1.Enabled := False; end; end.

// 吃完第一个食物就完了。哈哈。于是要求写一个完善一点的。

存在一些小问题,稍微改了一下,可以运行,还算完美。

版本二:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TDirection = (dLeft, dUp, dRight, dDown);

  TSnake = array[0..100] of TPoint;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure Timer1Timer(Sender: TObject);
    procedure Paint; override;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure MoveSnake;
    procedure DrawSnake;
    procedure CheckCollision;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Snake: TSnake;
  SnakeLength: Integer;
  Direction: TPoint;
  Food: TPoint;
  BlockSize: Integer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  SnakeLength := 5;
  BlockSize := 10;
  Snake[0].X := ClientWidth div BlockSize div 2;
  Snake[0].Y := ClientHeight div BlockSize div 2;
  Food.X := Random(ClientWidth div BlockSize);
  Food.Y := Random(ClientHeight div BlockSize);
  Direction.X := 1;
  Direction.Y := 0;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  case Key of
    VK_LEFT:
      if Direction.X <> 1 then
      begin
        Direction.X := -1;
        Direction.Y := 0;
      end;
    VK_UP:
      if Direction.Y <> 1 then
      begin
        Direction.X := 0;
        Direction.Y := -1;
      end;
    VK_RIGHT:
      if Direction.X <> -1 then
      begin
        Direction.X := 1;
        Direction.Y := 0;
      end;
    VK_DOWN:
      if Direction.Y <> -1 then
      begin
        Direction.X := 0;
        Direction.Y := 1;
      end;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  MoveSnake;
  CheckCollision;
  Repaint;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled := True;
end;

procedure TForm1.DrawSnake;
var
  i: Integer;
begin
  Canvas.Pen.Color := clBlack;
  Canvas.Brush.Color := clGreen;
  for i := 0 to SnakeLength - 1 do
    Canvas.Rectangle(Snake[i].X * BlockSize, Snake[i].Y * BlockSize, Snake[i].X * BlockSize + BlockSize, Snake[i].Y * BlockSize + BlockSize);
  Canvas.Brush.Color := clRed;
  Canvas.Rectangle(Food.X * BlockSize, Food.Y * BlockSize, Food.X * BlockSize + BlockSize, Food.Y * BlockSize + BlockSize);
end;

procedure TForm1.MoveSnake;
var
  i: Integer;
begin
  for i := SnakeLength - 1 downto 1 do
    Snake[i] := Snake[i - 1];
  Snake[0].X := Snake[0].X + Direction.X;
  Snake[0].Y := Snake[0].Y + Direction.Y;
end;

procedure TForm1.CheckCollision;
var
  i: Integer;
begin
  if (Snake[0].X >= ClientWidth div BlockSize) or (Snake[0].X < 0) or (Snake[0].Y >= ClientHeight div BlockSize) or (Snake[0].Y < 0) then
  begin
    Timer1.Enabled := False;
    ShowMessage('Game Over');
  end;
  for i := 1 to SnakeLength - 1 do
    if Snake[0].X = Snake[i].X then
      if Snake[0].Y = Snake[i].Y then
      begin
        Timer1.Enabled := False;
        ShowMessage('Game Over');
      end;
  if Snake[0].X = Food.X then
    if Snake[0].Y = Food.Y then
    begin
      Inc(SnakeLength);
      Food.X := Random(ClientWidth div BlockSize);
      Food.Y := Random(ClientHeight div BlockSize);
    end;
end;

procedure TForm1.Paint;
var
  i: Integer;
begin
  inherited;
  Canvas.Pen.Color := clBlack;
  Canvas.Brush.Color := clGreen;
  for i := 0 to SnakeLength - 1 do
    Canvas.Rectangle(Snake[i].X * BlockSize, Snake[i].Y * BlockSize, Snake[i].X * BlockSize + BlockSize, Snake[i].Y * BlockSize + BlockSize);
  Canvas.Brush.Color := clRed;
  Canvas.Rectangle(Food.X * BlockSize, Food.Y * BlockSize, Food.X * BlockSize + BlockSize, Food.Y * BlockSize + BlockSize);
end;

end.

 

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 455
  ClientWidth = 656
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  OnCreate = FormCreate
  OnKeyDown = FormKeyDown
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 504
    Top = 24
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    Visible = False
    OnClick = Button1Click
  end
  object Timer1: TTimer
    Interval = 100
    OnTimer = Timer1Timer
    Left = 304
    Top = 256
  end
end

 

 第三版,让他加上了网格。没有大问题,有些小细节要自己修改。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TDirection = (dLeft, dUp, dRight, dDown);

  TSnake = array[0..100] of TPoint;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure Timer1Timer(Sender: TObject);
    procedure Paint; override;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure MoveSnake;
    procedure DrawSnake;
    procedure DrawGrid;
    procedure CheckCollision;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Snake: TSnake;
  SnakeLength: Integer;
  Direction: TPoint;
  Food: TPoint;
  BlockSize: Integer = 10;
  PlayFieldSize: Integer;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  SnakeLength := 5;
  self.Height := self.Width;
  PlayFieldSize := self.Width div BlockSize - 1;
  Snake[0].X := ClientWidth div BlockSize div 2;
  Snake[0].Y := ClientHeight div BlockSize div 2;
  Food.X := Random(ClientWidth div BlockSize);
  Food.Y := Random(ClientHeight div BlockSize);
  Direction.X := 1;
  Direction.Y := 0;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  case Key of
    VK_LEFT:
      if Direction.X <> 1 then
      begin
        Direction.X := -1;
        Direction.Y := 0;
      end;
    VK_UP:
      if Direction.Y <> 1 then
      begin
        Direction.X := 0;
        Direction.Y := -1;
      end;
    VK_RIGHT:
      if Direction.X <> -1 then
      begin
        Direction.X := 1;
        Direction.Y := 0;
      end;
    VK_DOWN:
      if Direction.Y <> -1 then
      begin
        Direction.X := 0;
        Direction.Y := 1;
      end;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  MoveSnake;
  CheckCollision;
  Repaint;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled := True;
end;

procedure TForm1.DrawGrid;
var
  i: Integer;
begin
  Canvas.Pen.Color := clBlack;
  for i := 0 to PlayFieldSize do
  begin
    Canvas.MoveTo(i * BlockSize, 0);
    Canvas.LineTo(i * BlockSize, PlayFieldSize * BlockSize);
    Canvas.MoveTo(0, i * BlockSize);
    Canvas.LineTo(PlayFieldSize * BlockSize, i * BlockSize);
  end;
end;

procedure TForm1.DrawSnake;
var
  i: Integer;
begin
  Canvas.Pen.Color := clBlack;
  Canvas.Brush.Color := clGreen;
  for i := 0 to SnakeLength - 1 do
    Canvas.Rectangle(Snake[i].X * BlockSize,
      Snake[i].Y * BlockSize,
      Snake[i].X * BlockSize + BlockSize,
      Snake[i].Y * BlockSize + BlockSize);
  Canvas.Brush.Color := clRed;
  Canvas.Rectangle(Food.X * BlockSize, Food.Y * BlockSize,
    Food.X * BlockSize + BlockSize, Food.Y * BlockSize + BlockSize);
end;

procedure TForm1.MoveSnake;
var
  i: Integer;
begin
  for i := SnakeLength - 1 downto 1 do
    Snake[i] := Snake[i - 1];
  Snake[0].X := Snake[0].X + Direction.X;
  Snake[0].Y := Snake[0].Y + Direction.Y;
end;

procedure TForm1.CheckCollision;
var
  i: Integer;
begin
  if (Snake[0].X >= ClientWidth div BlockSize) or (Snake[0].X < 0) or (Snake[0].Y >= ClientHeight div BlockSize) or (Snake[0].Y < 0) then
  begin
    Timer1.Enabled := False;
    ShowMessage('Game Over');
  end;
  for i := 1 to SnakeLength - 1 do
    if Snake[0].X = Snake[i].X then
      if Snake[0].Y = Snake[i].Y then
      begin
        Timer1.Enabled := False;
        ShowMessage('Game Over');
      end;
  if Snake[0].X = Food.X then
    if Snake[0].Y = Food.Y then
    begin
      Inc(SnakeLength);
      Food.X := Random(ClientWidth div BlockSize);
      Food.Y := Random(ClientHeight div BlockSize);
    end;
end;

procedure TForm1.Paint;
var
  i: Integer;
begin
  inherited;
  DrawGrid;
  Canvas.Pen.Color := clBlack;
  Canvas.Brush.Color := clGreen;
  for i := 0 to SnakeLength - 1 do
    Canvas.Rectangle(Snake[i].X * BlockSize, Snake[i].Y * BlockSize, Snake[i].X * BlockSize + BlockSize, Snake[i].Y * BlockSize + BlockSize);
  Canvas.Brush.Color := clRed;
  Canvas.Rectangle(Food.X * BlockSize, Food.Y * BlockSize, Food.X * BlockSize + BlockSize, Food.Y * BlockSize + BlockSize);
end;

end.

 

posted on 2023-02-10 15:49  onlyou13  阅读(287)  评论(0编辑  收藏  举报