Codebase list pangzero / 09eba78 lib / Games / PangZero / Guy.pm
09eba78

Tree @09eba78 (Download .tar.gz)

Guy.pm @09eba78raw · history · blame

##########################################################################
package Games::PangZero::Guy;
##########################################################################

@ISA = qw(Games::PangZero::GameObject);
use vars qw(%Guys $GuyId);

sub new {
  my ($class, $player) = @_;
  my $self             = Games::PangZero::GameObject->new();
  my $number           = $player->{number};
  %{$self}             = ( %{$self},
    'player' => $player,
    'number' => $number,
    'x' => $player->{startX},
    'y' => $Games::PangZero::ScreenHeight - 64,
    'w' => 64,
    'h' => 64,
    'collisionw' => '28',
    'collisionh' => '48',
    'delay' => 0,
    'speedY' => 0,
    'speedX' => 0,
    'dir' => $number % 2,
    'state' => 'idle',
    'killed' => 0,
    'harpoons' => 0,
    'invincible' => 0,
    'surface' => $player->{guySurface},
    'whiteSurface' => $player->{whiteGuySurface},
    'weapon' => 'Harpoon',
    'bonusDelay' => 0,
    'id' => ++$GuyId,
  );
  bless $self, $class;
  $self->SetupCollisions();
  $self->CalculateAnimPhases();
  $Guys{$self->{id}} = $self;
  return $self;
}

sub Delete {
  my $self = shift;

  $self->SUPER::Delete;
  delete $Guys{$self->{id}};
}

sub CalculateAnimPhases {
  my $self = shift;

  $self->{animPhases} = $self->{player}->{guySurface}->w / 128,
}

sub DemoMode {
  my ($self)     = shift;
  $self->{state} = 'demo';
  $self->{dir}   = 1;
}

sub Fire {
  my ($self) = @_;

  if ($self->{harpoons} < $Games::PangZero::DifficultyLevel->{harpoons}) {
    ++$self->{harpoons};
    eval("unshift \@Games::PangZero::GameObjects, (Games::PangZero::$self->{weapon}::Create(\$self));");
    $self->{state} = 'shoot';
    $self->{delay} = 7;
    Games::PangZero::Music::PlaySound('shoot');
    return 1;
  }
  return 0;
}

sub AdvanceWhileFlying {
  my $self = shift;

  $self->{speedY} += $Games::PangZero::Ball::Gravity * 2;
  $self->{y}      += $self->{speedY};
  $self->{x}      += $self->{dir} > 0 ? 1 : -1;
  if ($self->{x} < -16) {
    $self->{x} = 0;
    $self->{dir} = 1;
  }
  if ($self->{x} > $Games::PangZero::ScreenWidth - $self->{w} + 16) {
    $self->{x} = $Games::PangZero::ScreenWidth - $self->{w}; $self->{dir} = 0;
  }
  if ($self->{y} >= $Games::PangZero::ScreenHeight - $self->{h}) {
    $self->{state}  = 'idle';
    $self->{y}      = $Games::PangZero::ScreenHeight - $self->{h};
    $self->{speedX} = $self->{dir} ? 1 : -1;
  }
}

sub Advance {
  my ($self) = @_;
  my ($slippery, $keys);

  $slippery = $Games::PangZero::Slippery ? 0.0625 : 0;

  return if $self->{killed};
  return if $self->{state} eq 'demo';
  --$self->{invincible};

  if ($self->{bonusDelay} > 0) {
    --$self->{bonusDelay};
    $self->{weapon} = 'Harpoon' if $self->{bonusDelay} <= 0;
  }

  if ($self->{state} eq 'fly') {
    $self->AdvanceWhileFlying();
    return;
  }

  if ($self->{delay} > 0) {
    --$self->{delay};
    $keys = [ 0, 0, 0 ];
  } else {
    $keys = $self->{player}->{keys};
  }

  $self->{speedX} = 0 unless $slippery;
  $self->{state} = 'idle';

  if ( $Games::PangZero::Events{$keys->[2]} ) {
    return if $self->Fire();
  }
  if ( $Games::PangZero::Keys{$keys->[0]} ) {
    if ($slippery) {
      $self->{speedX} -= $slippery * 2 if $self->{speedX} > -3;
    } else {
      $self->{speedX} = -3;
    }
    $self->{dir} = 0;
    $self->{state} = 'walk';
  } elsif ( $Games::PangZero::Keys{$keys->[1]} ) {
    if ($slippery) {
      $self->{speedX} += $slippery * 2 if $self->{speedX} < 3;
    } else {
      $self->{speedX} = 3;
    }
    $self->{dir} = 1;
    $self->{state} = 'walk';
  } else {
    if ($slippery) {
      $self->{speedX} += $slippery if $self->{speedX} < 0;
      $self->{speedX} -= $slippery if $self->{speedX} > 0;
    }
  }
  $self->{x} += $self->{speedX};

  if ($self->{x} < -16) {
    $self->{x} = -16; $self->{speedX} = 0;
  }
  if ($self->{x} > $Games::PangZero::ScreenWidth - $self->{w} + 16) {
    $self->{x} = $Games::PangZero::ScreenWidth - $self->{w} + 16; $self->{speedX} = 0;
  }
}

sub Draw {
  my ($self) = @_;
  my ($surface, $srcrect, $srcx, $srcy, $srcw, $srch);

  return if ($self->{killed});
  $surface = $self->{surface};
  $surface = $self->{whiteSurface} if $self->{invincible} > 0 and (int($self->{invincible} / 2) % 3 == 0);

  $srcw = $srch = 64;
  if ($self->{state} eq 'idle') {
    $srcx = $self->{dir} * 128;
    $srcy = 64;
  } elsif ($self->{state} eq 'walk') {
    $srcx = $self->{dir} * $self->{animPhases} * 64 + (int($self->{x} / 50) % $self->{animPhases}) * 64;
    $srcy = 0;
  } elsif ($self->{state} eq 'demo') {
    $srcx = $self->{dir} * $self->{animPhases} * 64 + (int($Games::PangZero::Game->{anim} / 16) % $self->{animPhases}) * 64;
    $srcy = 0;
  } elsif ($self->{state} eq 'shoot') {
    $srcx = $self->{dir} * 128 + 64;
    $srcx -= 64 if ($self->{delay} <= 1);
    $srcy = 64;
  } elsif ($self->{state} eq 'fly') {
    $srcx = ($self->{dir} > 0 ? 0 : 64);
    $srcy = 128;
  }
  $srcrect = SDL::Rect->new($srcx, $srcy, $srcw, $srch );
  $self->TransferRect();
  SDL::Video::blit_surface($surface, $srcrect, $Games::PangZero::App, $self->{rect});
}

sub Kill {
  my ($self) = @_;

  return if $Games::PangZero::Cheat;
  return if $self->{invincible} > 0;
  $self->{justkilled} = 1;
  $Games::PangZero::GameEvents{'kill'} = 1;
  print "player killed\n" if $ENV{PANGZERO_TEST};
}

sub Earthquake {
  my ($self, $amplitude) = @_;

  return if $self->{state} eq 'fly';
  $self->{speedY} = -($amplitude->[0]);
  $self->{dir} = $amplitude->[1] > $self->{x} ? 0 : 1;
  $self->{state} = 'fly';
  $self->{y} -= 3;
}

sub DeleteHarpoons {
  my ($self) = @_;
  my (@gameObjects, $harpoon);

  @gameObjects = @Games::PangZero::GameObjects;
  foreach $harpoon (@gameObjects) {
    $harpoon->Delete if ($harpoon->{guy} and $harpoon->{guy} eq $self);
  }
}

sub GiveScore {
  my ($self, $score) = @_;

  my $player = $self->{player};
  $player->{score} += $score;
  if ($player->{score} >= $player->{scoreforbonuslife}) {
    ++$player->{lives};
    $player->{scoreforbonuslife} += 200000;
    Games::PangZero::Music::PlaySound('bonuslife');
  }
}

1;