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

📄 unit_classes.pas

📁 类似打蜜蜂的游戏
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{*************************************}
{                                     }
{      Game: Aliens                   }
{      Author: arming                 }
{      2005/12/5 in Seu, Nanjing      }
{      http://arming.com.cn           }
{      mail: xjr555@126.com           }
{                                     }
{*************************************}

unit Unit_classes;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  StdCtrls, ExtCtrls, ImgList;

const
  Img_Str_Width  = 6;
  Img_Str_Height = 9;
  Img_Obj_Width  = 16;
  Img_Obj_Height = 16;
  Img_Obj_Str    = '!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ';

  Img_Str_Path   = '..\images\text.bmp';
  Img_Obj_Path   = '..\images\object.bmp';
  Img_Title_Path = '..\images\title.bmp';

  Game_Timer_Interval = 50;
  
type

  // Image String
  TImgStr = class( TPersistent )
  public
    constructor Create( imglist: TImageList );
    destructor  Destroy; override;
    procedure   DrawString( Canvas: TCanvas; x,y,space,max_width: integer;
      Str: string ); overload;
    procedure   DrawString( Canvas: TCanvas; x,y,space: integer;
      Str: string ); overload;
    procedure   DrawString( Canvas: TCanvas; x,y: integer;
      Str: string ); overload;
  private
    ImageList: TImageList;
    ImgString: string;
    function    IndexOfChar( chr: Char ): integer;
  end;


  // Image Object
  TImgObjIndex = ( bug1, bug2, bugl, bugr, bullet, exp1, exp2, exp3, flame1,
                   flame2, missile, ship );

  TImgObj = class( TPersistent )
  public
    constructor Create( imglist: TImageList );
    destructor  Destroy; override;
    procedure   DrawObj( Canvas: TCanvas; x,y: integer; Obj: TImgObjIndex  );
  private
    ImageList: TImageList;
  end;

  // Game Widget
  TGameModes = ( gmShooting, gmMarching );
  TGameState = ( gsIntro, gsPlaying, gsDying, gsLevelCompleted, gsGameOver );
  TGameDir   = ( gdLeft, gdRight, gdNone );
  TGameKey   = ( gkKey_Left, gkKey_Right, gkKey_Up, gkKey_Down, gkKey_Start, gkKey_Fire );

  TGameWidget = class( TPersistent )
  public
    constructor Create( ptBox: TPaintBox );
    destructor  Destroy; override;
    procedure   updateMode( mode: TGameModes );
    procedure   start();    procedure   stop();    procedure   pause();    procedure   unpause();    procedure   setSpeed( speed: integer );   // speed: 20~100, default 70;    function    getSpeed: integer;     procedure   keyPressed( Key: TGameKey );    procedure   keyReleased( Key: TGameKey );    procedure   mouseMove( mouseX, mouseY: integer );  private
    timer: TTimer;
    paintBox: TPaintBox;
    imgListStr, imgListObj: TImageList;
    imgObj: TImgObj;
    imgStr: TImgStr;
    imgTitle: TImage;
    m_bug: array[0..1] of TImgObjIndex;
    m_bugdir: array[0..1] of TImgObjIndex;
    m_explosion: array[0..2] of TImgObjIndex;
    m_flame: array[0..2] of TImgObjIndex;
    max_lives, max_bullets, max_missiles, max_aliens, max_stars: integer;
    m_mode: TGameModes;
    m_state: TGameState;
    m_counter, m_alien_counter: integer;
    m_level, m_score, m_lives, m_num_diving: integer;
    m_player_dir: TGameDir;
    m_player_x, m_player_req_x: integer;
    m_bullets, m_bullets_fired, m_aliens_killed: integer;
    m_bullet_x, m_bullet_y: array of integer;    m_missiles: integer;    m_missile_x, m_missile_y: array of integer;    m_aliens: integer;    m_alien_x,m_alien_y,m_alien_state,m_alien_xhome,m_alien_yhome,      m_alien_statehome: array of integer;    m_stars: integer;    m_star_x,m_star_y,m_star_speed,m_star_size: array of integer;    procedure   timerTick( Sender: TObject );    procedure   newLevel();    procedure   updateLevel();    procedure   fireBullet();    procedure   deleteBullet( i: integer );    procedure   fireMissile( i: integer );    procedure   deleteMissile( i: integer );    procedure   deleteAlien( i: integer );    procedure   switchState( state: TGameState );    procedure   drawIntro();    procedure   drawPlaying();    procedure   drawGameOver();    procedure   addScore( score: integer );    procedure   rePaint( flag: boolean );  end;

implementation

uses Unit_Main;

{ TImgStr }

constructor TImgStr.Create(imglist: TImageList);
begin
  ImageList := imglist;
  ImgString := Img_Obj_Str;
end;

destructor TImgStr.Destroy;
begin
  ImageList := nil;
  inherited;
end;

procedure TImgStr.DrawString(Canvas: TCanvas; x, y, space: integer;
  Str: string);
var i: integer;
    index: integer;
begin
  for i:= 0 to Length( Str ) do
  begin
    index := IndexOfChar( Str[i+1] );
    if index >= 0 then
      ImageList.Draw( Canvas, x+i*( space + Img_Str_Width ), y,
                      IndexOfChar( Str[i+1] ) );
  end;
end;

procedure TImgStr.DrawString(Canvas: TCanvas; x, y: integer; Str: string);
begin
  DrawString( Canvas, x, y, 0, Str );
end;

procedure TImgStr.DrawString(Canvas: TCanvas; x, y, space,
  max_width: integer; Str: string);
var i: integer;
    index: integer;
    x_pos, y_pos, line: integer;
begin
  line := 1;
  for i:= 0 to Length( Str ) do
  begin
    index := IndexOfChar( Str[i+1] );
    x_pos := x+i*( space + Img_Str_Width );
    y_pos := y;
    if x_pos >= ( max_width + x ) then
    begin
      line := (x_pos - x) div max_width;
      x_pos := x_pos - line * max_width;
      y_pos := y + line * (Img_Str_Height + 2);
    end;
    if index >= 0 then
      ImageList.Draw( Canvas, x_pos, y_pos,
                      IndexOfChar( Str[i+1] ) );
  end;
end;

function TImgStr.IndexOfChar(chr: Char): integer;
var i: integer;
begin
  Result := -1;
  for i := 0 to Length( ImgString ) do
    if UpCase( chr ) = ImgString[i+1] then
    begin
      Result := i;
      Exit;
    end;
end;

{ TImgObj }

constructor TImgObj.Create(imglist: TImageList);
begin
  ImageList := imglist;
end;

destructor TImgObj.Destroy;
begin
  ImageList := nil;
  inherited;
end;

procedure TImgObj.DrawObj( Canvas: TCanvas; x, y: integer;
  Obj: TImgObjIndex);
begin
  ImageList.Draw( Canvas, x, y, integer( Obj ) );
end;

{ TGameWidget }

procedure TGameWidget.addScore(score: integer);
var old_score: integer;
begin
  old_score := m_score;
  m_score := m_score + score;  if (m_mode = gmShooting) then  begin	  if ((m_score mod 1000) < (old_score mod 1000)) then    begin	    m_lives := m_lives+1;	  end;  end else  begin	  if ((m_score mod 2000) < (old_score mod 2000)) then	    m_lives := m_lives+1;  end;
end;

constructor TGameWidget.Create( ptBox: TPaintBox );
begin
  Randomize;
  paintBox := ptBox;
  timer := TTimer.Create( nil );
  timer.Enabled := False;
  timer.Interval := Game_Timer_Interval;
  timer.OnTimer := timerTick;

  {
  imgTitle := TImage.Create( nil );
  imgTitle.Picture.LoadFromFile( Img_Obj_Path );
  //imgTitle.Picture.Graphic.SaveToStream(  );
  imgListObj := TImageList.Create( nil );
  imgListObj.Width := Img_Obj_Width;
  imgListObj.Height := Img_Obj_Height;
  imgListObj.Add( imgTitle.Picture.Bitmap, nil );
  imgListStr := TImageList.Create( nil );
  imgListStr.Height := Img_Str_Height;
  imgListStr.Width := Img_Str_Width;
  imgTitle.Picture.LoadFromFile( Img_Str_Path );
  imgListStr.Add( imgTitle.Picture.Bitmap, nil );
  imgTitle.AutoSize := True;
  imgTitle.Picture.LoadFromFile( Img_Title_Path );
   }

  imgListObj := frmMain.ImageList_Obj;
  imgListStr := frmMain.ImageList_Str;
  imgTitle   := frmMain.Image_Title;


  imgObj := TImgObj.Create( imgListObj );
  imgStr := TImgStr.Create( imgListStr ); 

  max_lives := 3;
  max_bullets := 3;
  max_missiles := 8;
  max_aliens := 30;
  max_stars := 20;

  SetLength( m_bullet_x, max_bullets );
  SetLength( m_bullet_y, max_bullets );
  SetLength( m_missile_x, max_missiles );
  SetLength( m_missile_y, max_missiles );
  SetLength( m_alien_x, max_aliens );
  SetLength( m_alien_y, max_aliens );
  SetLength( m_alien_state, max_aliens );
  SetLength( m_alien_xhome, max_aliens );
  SetLength( m_alien_yhome, max_aliens );
  SetLength( m_alien_statehome, max_aliens );
  SetLength( m_star_x, max_stars );
  SetLength( m_star_y, max_stars );
  SetLength( m_star_speed, max_stars );
  SetLength( m_star_size, max_stars );

  m_bug[0] := bug1;
  m_bug[1] := bug2;
  m_bugdir[0] := bugl;
  m_bugdir[1] := bugr;
  m_explosion[0] := exp1;
  m_explosion[1] := exp2;
  m_explosion[2] := exp3;
  m_flame[0] := flame1;
  m_flame[1] := flame2;

  timer.Enabled := True;
end;

procedure TGameWidget.deleteAlien(i: integer);
begin
  m_aliens := m_aliens-1;
  m_aliens_killed := m_aliens_killed+1;  while (i < m_aliens) do  begin    m_alien_x[i] := m_alien_x[i + 1];    m_alien_y[i] := m_alien_y[i + 1];    m_alien_state[i] := m_alien_state[i + 1];    m_alien_xhome[i] := m_alien_xhome[i + 1];    m_alien_yhome[i] := m_alien_yhome[i + 1];    m_alien_statehome[i] := m_alien_statehome[i + 1];    i := i+1;  end;
end;

procedure TGameWidget.deleteBullet(i: integer);
begin
  m_bullets := m_bullets-1;
  while (i < m_bullets) do  begin    m_bullet_x[i] := m_bullet_x[i + 1];    m_bullet_y[i] := m_bullet_y[i + 1];    i := i+1;  end;
end;

procedure TGameWidget.deleteMissile(i: integer);
begin
  m_missiles := m_missiles-1;
  while (i < m_missiles) do  begin    m_missile_x[i] := m_missile_x[i + 1];    m_missile_y[i] := m_missile_y[i + 1];    i := i+1;  end;
end;

destructor TGameWidget.Destroy;
begin
  paintBox := nil;
  timer.Enabled := False;
  timer.OnTimer := nil;
  timer.Free;
  {
  imgListObj.Free;
  imgListStr.Free;
  imgTitle.Free;
   }
  imgObj.Free;
  imgStr.Free;
  inherited;
end;

procedure TGameWidget.drawGameOver;
var
  max_x, max_y: integer;
  buffer: string;
begin
  max_x := paintBox.width;  max_y := paintBox.height;  if( m_level > 30 ) then	m_level := 30;     	//A for 30 level  with paintBox do  begin    Canvas.Brush.Color := clBlack;    Canvas.FillRect( paintBox.BoundsRect );    Canvas.Draw((max_x - imgTitle.Width) div 2, (100 - imgTitle.Height) div 2,      imgTitle.Picture.Bitmap);    imgObj.DrawObj( Canvas, 20, 100, ship );    imgObj.DrawObj( Canvas, 20, 116, m_flame[(m_counter div 15) mod 2]);    buffer := Format( ' You Scored %d Points in %d Level ', [ m_score, m_level ] ) ;    imgStr.DrawString ( Canvas, 50, 100, buffer);//max_x - 20, buffer);    imgObj.DrawObj( Canvas, 20, 150, m_bug[(m_counter div 10) mod 2] );    buffer := Format( 'Bullers Fired: %d', [ m_bullets_fired ] );    imgStr.DrawString( Canvas, 50, 150, buffer );//max_x - 20, buffer);    imgObj.DrawObj( Canvas, 20, 200, m_bugdir[(m_counter div 10) mod 2]);    buffer := Format( 'Aliens Killed: %d ', [ m_aliens_killed ] );    imgStr.DrawString( Canvas, 50, 200, buffer); //max_x - 20, buffer);    imgStr.DrawString( Canvas, 50, max_y - 20, // max_x - 20,      'Press Start or UP Key');    end;end;

procedure TGameWidget.drawIntro;
var
  max_x, max_y: integer;
begin
  max_x := paintBox.width;
  max_y := paintBox.height;  with paintBox do  begin    Canvas.TryLock;    Canvas.Brush.Color := clBlack;    Canvas.FillRect( paintBox.BoundsRect );    Canvas.Draw((max_x - imgTitle.Width) div 2, (100 - imgTitle.Height) div 2,      imgTitle.Picture.Bitmap);    imgObj.DrawObj( Canvas, 20, 100, ship );    imgObj.DrawObj( Canvas, 20, 116, m_flame[(m_counter div 15) mod 2]);    imgStr.DrawString( Canvas, 50, 100, 0, max_x - 60,      'MOVE YOUR SHIP LEFT AND RIGHT USING THE CURSOR KEYS, FIRE USING SPACE');    imgObj.DrawObj( Canvas, 20, 150, m_bug[(m_counter div 10) mod 2] );    if (((m_counter div 20) mod 2) = 0) then	    imgObj.DrawObj( Canvas, 20, 166, missile);    imgStr.DrawString( Canvas, 50, 150, 0, max_x - 60,      'THESE BUGS WILL SHOOT AT YOU');    imgObj.DrawObj( Canvas, 20, 200, m_bugdir[(m_counter div 10) mod 2]);    imgStr.DrawString( Canvas, 50, 200, 0, max_x - 60,      'THESE BUGS WILL KILL YOU IF YOU TOUCH THEM');    imgStr.DrawString( Canvas, 50, max_y - 20, 0, max_x - 60,      'PRESS Start OR UP KYE');      Canvas.Unlock;  end;end;

procedure TGameWidget.drawPlaying;
var
  max_x, max_y, i: integer;
  buffer: string;
begin
  max_x := paintBox.width;
  max_y := paintBox.height;  with paintBox do  begin    Canvas.Brush.Color := clBlack;    Canvas.FillRect( paintBox.BoundsRect );    // draw the stars first, so they are overwritten by all other actors    for i := 0 to m_stars-1 do    begin      Canvas.Pixels[m_star_x[i], m_star_y[i]] := (m_star_size[i] * 8) + 128;      Canvas.Pixels[m_star_x[i], m_star_y[i] + 1]:= (m_star_size[i] * 8) + 128;    end;    // then, draw all the other actors    for i := 0 to m_bullets -1 do	    imgObj.DrawObj( Canvas, m_bullet_x[i], m_bullet_y[i], bullet);    for i := 0 to m_missiles-1 do	    imgObj.DrawObj( Canvas, m_missile_x[i], m_missile_y[i], missile);    for i := 0 to m_aliens-1 do	    if (m_alien_state[i] < 2) then	      imgObj.DrawObj( Canvas, m_alien_x[i], m_alien_y[i],            (m_bug[(m_counter div 10) mod 2]))      else if (m_alien_state[i] < 4) then	      imgObj.DrawObj( Canvas, m_alien_x[i], m_alien_y[i],            (m_bugdir[m_alien_state[i] mod 2]))      else	      imgObj.DrawObj( Canvas, m_alien_x[i], m_alien_y[i],		        (m_explosion[((m_alien_state[i] - 4) div 3) mod 3]));    // draw the player last    if (m_state = gsDying) then    begin	    if (m_counter < 9) then	      imgObj.DrawObj( Canvas, m_player_x, max_y - 32, m_explosion[(m_counter div 3) mod 3])	    else if (m_counter >= 18)and((((m_counter - 18) div 2) mod 2)<>0)and(m_lives > 1) then	      imgObj.DrawObj( Canvas, m_player_x, max_y - 32, ship);    end else begin	    imgObj.DrawObj( Canvas, m_player_x, max_y - 32, ship);	    imgObj.DrawObj( Canvas, m_player_x, max_y - 16, m_flame[(m_counter div 15) mod 2]);    end;    // draw some info last    if (m_state = gsLevelCompleted)and((m_counter mod 4) <>0 ) then    begin      if(m_level < 30) then        buffer := Format( 'LEVEL %d COMPLETED', [ m_level ] )      else        buffer := Format( 'THE TOP LEVEL %d COMPLETED!' , [ m_level ] );      imgStr.DrawString ( Canvas, (max_x - Length(buffer) * 7) div 2, 100, buffer);//max_x, buffer);    end else if (m_state = gsDying)and((m_counter mod 4)<>0)and(m_lives > 1) then    begin	    buffer := Format( 'YOU DIED, %d LIVES LEFT', [ m_lives - 1 ] );	    imgStr.DrawString ( Canvas, (max_x - Length(buffer) * 7) div 2, 100, buffer);//max_x, buffer);    end  end;end;

procedure TGameWidget.fireBullet;
begin
  if (m_bullets < max_bullets) then
  begin
    m_bullet_x[m_bullets] := m_player_x;    m_bullet_y[m_bullets] := paintBox.height - 36;    m_bullets := m_bullets+1;    m_bullets_fired := m_bullets_fired+1;  end;
end;

procedure TGameWidget.fireMissile(i: integer);
begin
  if (m_missiles < max_missiles) then
  begin
    m_missile_x[m_missiles] := m_alien_x[i];    m_missile_y[m_missiles] := m_alien_y[i] + 16;    m_missiles := m_missiles+1;  end;
end;

function TGameWidget.getSpeed: integer;
begin
  Result := 120 - timer.Interval;
end;

⌨️ 快捷键说明

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