#!/usr/bin/perl -w use SDL; use SDL::App; use SDL::Event; use SDL::Surface; use SDL::Timer; use vars qw ( $App $Background @GameObjects @BallSurface @BallDesc $ScreenHeight $ScreenWidth ); @BallDesc = ( { 'size' => 128, 'speedY' => 9 }, { 'size' => 64, 'speedY' => 7 }, { 'size' => 32, 'speedY' => 5 }, { 'size' => 16, 'speedY' => 4 }, ); $ScreenWidth = 800; $ScreenHeight = 600; package GameObject; sub new { my ($class) = @_; my $self = { 'rect' => new SDL::Rect( -x => 0, -y => 0, -width => 0, -height => 0 ), 'speedX' => 2, 'speedY' => 2, 'x' => 0, 'y' => 0, 'w' => 10, 'h' => 10, }; bless $self, $class; } sub Advance { my ($self) = @_; $self->{x} += $self->{speedX}; $self->{y} += $self->{speedY}; } sub Clear { my ($self) = @_; $::App->fill( $self->{rect}, new SDL::Color() ); } sub TransferRect { my ($self) = @_; $self->{rect}->x($self->{x}); $self->{rect}->y($self->{y}); $self->{rect}->width($self->{w}); $self->{rect}->height($self->{h}); } sub Draw { my ($self) = @_; $self->TransferRect(); $::App->fill( $self->{rect}, new SDL::Color(-r => 0x80) ); } package Ball; @ISA = qw(GameObject); sub new { my ($class, $generation, $x, $y) = @_; my ($self); $self = new GameObject; %{$self} = ( %{$self}, 'x' => $x, 'y' => $y, 'generation' => $generation, 'w' => $::BallDesc[$generation]->{size}, 'h' => $::BallDesc[$generation]->{size}, ); bless $self, $class; } sub Advance { my ($self) = @_; $self->{speedY} += 0.1; $self->SUPER::Advance(); if ($self->{y} > $::ScreenHeight - $self->{h}) { $self->{y} = $::ScreenHeight - $self->{h}; $self->{speedY} = -$::BallDesc[$self->{generation}]->{speedY}; } } sub Draw { my ($self) = @_; $self->TransferRect(); $::BallSurface[$self->{generation}]->blit(0, $::App, $self->{rect} ); } package main; sub LoadSurfaces { my ($i); for ($i=0; $i <= 3; ++$i) { $BallSurface[$i] = new SDL::Surface( -name => "ball$i.png" ); } } sub AdvanceGame { foreach my $gameObject (@GameObjects) { $gameObject->Advance(); } } sub DrawGame { my ($gameObject); foreach $gameObject (@GameObjects) { $gameObject->Clear(); } foreach $gameObject (@GameObjects) { $gameObject->Draw(); } $App->sync(); } $App = new SDL::App -title => "test.app", -width => $ScreenWidth, -height => $ScreenHeight, -depth => 32; &LoadSurfaces(); $GameObjects[0] = new GameObject; $GameObjects[1] = new Ball(0, 100, -100); $GameObjects[2] = new Ball(1, 20, -100); $GameObjects[3] = new Ball(2, 220, -100); $GameObjects[4] = new Ball(3, 320, -100); my $event = new SDL::Event; my ($lastTick, $currentTick, $advance); $currentTick = $App->ticks; $lastTick = $currentTick; while (1) { $currentTick = $App->ticks; $advance = int( ($currentTick - $lastTick ) / 10 ); if ($advance > 10) { print STDERR "advance = $advance!\n"; $advance = 10; } if ($advance <= 0) { $App->delay(10); next; } while ($advance--) { &AdvanceGame(); } $lastTick = $currentTick; &DrawGame(); $event->poll(); $type = $event->type(); exit if $type == SDL_QUIT(); }