|
6 | 6 | use Gtk3 '-init';
|
7 | 7 | use Glib qw/TRUE FALSE/;
|
8 | 8 | use Cairo::GObject;
|
| 9 | +use Data::Dumper; |
| 10 | + |
| 11 | +use constant PI => 3.1415927; |
| 12 | +use constant WIDTH => 600; |
| 13 | +use constant HEIGHT => 400; |
| 14 | +use constant RADIUS => 12; |
| 15 | + |
| 16 | +my %status = ( |
| 17 | + vector => { 'x' => 2, 'y' => 3 }, |
| 18 | + position => { 'x' => 20, 'y' => 30 }, |
| 19 | + playerA => { 'y' => 50 }, |
| 20 | + playerB => { 'y' => 50 } |
| 21 | +); |
9 | 22 |
|
10 | 23 | my $window = Gtk3::Window->new('toplevel');
|
11 | 24 | $window->set_title("Grid Example");
|
12 | 25 | $window->set_position("mouse");
|
13 |
| -$window->set_default_size(600, 400); |
| 26 | +$window->set_default_size(WIDTH +50, HEIGHT +100); |
14 | 27 | $window->set_border_width(5);
|
15 | 28 | $window->signal_connect (delete_event => sub { Gtk3->main_quit });
|
| 29 | +$window->signal_connect( key_press_event => \&keypress ); |
| 30 | + |
| 31 | +my $vbox = Gtk3::Box->new("vertical", 5); |
| 32 | +$window->add($vbox); |
| 33 | + |
| 34 | +my $hbox = Gtk3::Box->new("horizontal", 5); |
| 35 | +$vbox->add($hbox); |
| 36 | + |
| 37 | +my $toggle1 = Gtk3::ToggleButton->new_with_label('Text'); |
| 38 | +my $toggle2 = Gtk3::ToggleButton->new_with_label('Percent'); |
| 39 | +my $toggle3 = Gtk3::ToggleButton->new_with_label('Invert'); |
| 40 | +$hbox->pack_start($toggle1, TRUE, TRUE, 0); |
| 41 | +$hbox->pack_start($toggle2, TRUE, TRUE, 0); |
| 42 | +$hbox->pack_start($toggle3, TRUE, TRUE, 0); |
| 43 | + |
| 44 | +my $frame = Gtk3::Frame->new("Pong"); |
| 45 | +$vbox->pack_start($frame, TRUE, TRUE, 5); |
16 | 46 |
|
17 | 47 | my $drawable = Gtk3::DrawingArea->new;
|
18 |
| -$drawable->signal_connect( draw => \&cairo_draw ); |
| 48 | +$drawable->signal_connect( draw => \&cairo_draw, \%status ); |
| 49 | +$frame->add($drawable); |
19 | 50 |
|
20 |
| -$window->add($drawable); |
21 | 51 | $window->show_all;
|
22 | 52 |
|
23 |
| -my $timer = Glib::Timeout->add( 500, \&update ); |
| 53 | +my $timer = Glib::Timeout->add( 20, \&update ); |
24 | 54 |
|
25 | 55 | Gtk3->main;
|
26 | 56 |
|
| 57 | +sub keypress { |
| 58 | + my ( $widget, $event ) = @_; |
| 59 | + |
| 60 | + given($event->key->{'string'}) { |
| 61 | + when ('q') { $status{'playerA'}{'y'} -= 3; } |
| 62 | + when ('a') { $status{'playerA'}{'y'} += 3; } |
| 63 | + when ('p') { $status{'playerB'}{'y'} -= 3; } |
| 64 | + when ('l') { $status{'playerB'}{'y'} += 3; } |
| 65 | + } |
| 66 | + return FALSE; |
| 67 | +} |
| 68 | + |
27 | 69 | sub update {
|
| 70 | + $status{'position'}{'x'} += $status{'vector'}{'x'}; |
| 71 | + $status{'position'}{'y'} += $status{'vector'}{'y'}; |
| 72 | + if ( $status{'position'}{'y'} >= HEIGHT - RADIUS ) { |
| 73 | + $status{'vector'}{'y'} = -$status{'vector'}{'y'}; |
| 74 | + } |
| 75 | + if ( $status{'position'}{'y'} <= RADIUS ) { |
| 76 | + $status{'vector'}{'y'} = -$status{'vector'}{'y'}; |
| 77 | + } |
| 78 | + if ( $status{'position'}{'x'} >= WIDTH - RADIUS ) { |
| 79 | + $status{'vector'}{'x'} = -$status{'vector'}{'x'}; |
| 80 | + } |
| 81 | + if ( $status{'position'}{'x'} <= RADIUS ) { |
| 82 | + $status{'vector'}{'x'} = -$status{'vector'}{'x'}; |
| 83 | + } |
28 | 84 | $drawable->queue_draw;
|
29 | 85 | return TRUE;
|
30 | 86 | }
|
31 | 87 |
|
32 | 88 | sub cairo_draw {
|
33 |
| - my ( $widget, $context ) = @_; |
34 |
| - my $alloc = $widget->get_allocation; |
35 |
| - $context->move_to( rand( $alloc->{'width'} ), rand( $alloc->{'height'} ) ); |
36 |
| - $context->rel_line_to( 10, 10 ); |
37 |
| - $context->stroke; |
38 |
| - say "updated..."; |
| 89 | + my ( $widget, $context, $ref_status ) = @_; |
| 90 | + |
| 91 | + # Background |
| 92 | + $context->set_source_rgb(0.19, 0.69, 0); |
| 93 | + $context->rectangle(0, 0, WIDTH, HEIGHT); |
| 94 | + $context->fill; |
| 95 | + |
| 96 | + # Ball |
| 97 | + $context->set_source_rgb(0.69, 0.19, 0); |
| 98 | + $context->arc( |
| 99 | + $ref_status->{'position'}{'x'}, |
| 100 | + $ref_status->{'position'}{'y'}, |
| 101 | + RADIUS, |
| 102 | + 0, |
| 103 | + PI * 2 |
| 104 | + ); |
| 105 | + $context->stroke_preserve; |
| 106 | + $context->set_source_rgb(0.6, 0.4, 0.2); |
| 107 | + $context->fill; |
| 108 | + |
| 109 | + # Paddle A |
| 110 | + $context->set_source_rgb(0.0, 0.0, 0.7); |
| 111 | + $context->rectangle( 15, $ref_status->{'playerA'}{'y'}, 10, 30); |
| 112 | + $context->fill; |
| 113 | + |
| 114 | + # Paddle B |
| 115 | + $context->set_source_rgb(0.0, 0.0, 0.7); |
| 116 | + $context->rectangle( WIDTH - 15, $ref_status->{'playerB'}{'y'}, 10, 30); |
| 117 | + $context->fill; |
| 118 | + |
39 | 119 | return FALSE;
|
40 | 120 | }
|
0 commit comments