Goo-Canvas

 view release on metacpan or  search on metacpan

bin/perltetris.pl  view on Meta::CPAN

    }
    $timer = Glib::Timeout->add(speed(), \&update);
    $canvas->{table}->clear;
    my $s = int(rand(scalar(@$shapes)));
    my $t = int(rand(scalar(@{$shapes->[$s]})));
    $next_shape = [$s, $t];
    new_shape();
}

sub show_heading {
    my $text = shift;
    if ( exists $canvas->{heading} && $canvas->{heading} ) {
        $canvas->{heading}->set(
            'text' => $text
        );
    }
    else {
        $canvas->{heading} =
            Goo::Canvas::Text->new(
                $canvas->get_root_item, $text, 50, 200, -1, 'nw',
                'font' => 'Sans Bold 24',
                'fill-color' => 'red'
            );
    }
}

sub remove_heading {
    if ( exists $canvas->{heading} && $canvas->{heading} ) {
        my $root = $canvas->get_root_item;
        $root->remove_child($root->find_child($canvas->{heading}));
        $canvas->{heading} = undef;
    }
}

sub new_shape {
    my $shape  = Tetris::Shape->new(
        -shape => $shapes->[$next_shape->[0]],
        -type => $next_shape->[1],
        -color => $Config{style}[$next_shape->[0] % @{$Config{style}}],
        -col => int($Config{cols}/2)-2,
        -table => $canvas->{table},
    );
    $shape->draw();
    $canvas->{shape} = $shape;
    # Draw preview
    my $s = int(rand(scalar(@$shapes)));
    my $t = int(rand(scalar(@{$shapes->[$s]})));
    $next_shape = [$s, $t];
    $canvas->{preview}->clear;
    $shape = Tetris::Shape->new(
        -shape => $shapes->[$s],
        -type => $t,
        -color => $Config{style}[$s  % @{$Config{style}}],
        -row => 1,
        -col => 1,
        -table => $canvas->{preview},
    );
    $shape->draw();
}

sub update {
    # print "update $timer_pause\n";
    return TRUE if $timer_pause;
    my $shape  = $canvas->{shape};
    my $hit = $shape->move_down;
    if ( $hit ) {
        done();
    }
    return TRUE;
}

sub done {
    my $shape = $canvas->{shape};
    my $table = $canvas->{table};
    my %row = map { $_->[0] => 1 } @{$shape->cells};
    my $ln = $table->eliminate_line_maybe( keys %row );
    score($ln);
    if ( $table->is_full ) {
        game_over();
    }
    else {
        new_shape();
    }
}

sub score {
    my $ln = shift || 0;
    my $oldscore = $score;
    my @score = ( 0, 10, 20, 40, 60 );
    # my @score = ( 0, 20, 40, 70, 100 );    
    $score += $score[$ln];
    $lines += $ln;

    if ( int($score/100) > int($oldscore/100) ) {
        # print "levelup $level at $score\n";
        $level++;
        $level = $level % 11;   # level: 0-10
        Glib::Source->remove($timer);
        $timer = Glib::Timeout->add(speed(), \&update);
    }
    update_label();
}

sub update_label {
    my $labels = $canvas->{labels};
    $labels->[0]->set_label( make_string("Scores", $score));
    $labels->[1]->set_label( make_string("Lines", $lines));
    $labels->[2]->set_label( make_string("Level", $level));
}

sub speed {
    return int(500/($level*0.5+1));
}

sub rank_dia {
    my $score = shift;
    my ($idx, $new_iter, $new_entry);
    my $max = $Config{max_rank_list}-1;
    if ( defined $score ) {
        if ( !defined $history ) {
            $history = [ $new_entry ];
            $idx = 0;
        } else {
            $new_entry = [$Config{name} || getlogin || getpwuid($<) || 'Nobody', $score];
            $history = [ sort {$b->[1] <=> $a->[1]} @$history ];
            $idx = 0;
            while ( $idx <= $#$history ) {
                last if $score >= $history->[$idx][1];
                $idx++;
            }
            if ( $idx > $max && $idx > $#$history ) {
                return;
            } else {
                splice(@$history, $idx, 0, $new_entry);
                if ( $#$history > $max ) {
                    $#$history = $max;
                }
            }
        }
    }
    if ( @$history == 0 ) {
        my $dia = Gtk2::MessageDialog->new(
            $window, 'destroy-with-parent',
            'info',
            'ok',
            "No rank list yet!",
        );
        $dia->run;
        $dia->destroy;
        return FALSE;
    }
    my $dia = Gtk2::Dialog->new(
        'Rank', $window,
        ['modal', 'destroy-with-parent'],
        'gtk-ok' => 'ok',
    );
    my $vbox = $dia->vbox;
    my $store = Gtk2::ListStore->new( qw/Glib::String Glib::Int/ );
    foreach ( 0..$#$history ) {
        my $iter = $store->append();
        $store->set($iter,
                    0, $history->[$_][0],
                    1, $history->[$_][1],
                );



( run in 0.520 second using v1.01-cache-2.11-cpan-5735350b133 )