Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

pong paddles are not going equally fast

by Anonymous Monk
on Jul 22, 2020 at 16:46 UTC ( #11119665=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, i have put together a working version of the pong game, where two paddles play the ball to each other, using the SDL module. I have found this code in a manual and everything seems fine. There is just one problem: the paddles, that move only vertically, are faster moving up then moving downwards, while they are given the same speed. This is where it happens:

$app->add_event_handler(sub { my $event= shift; if($event->type == SDL_KEYDOWN){ if($event-> key_sym == SDLK_UP){ $player1->{v_y} = -2; } elsif($event->key_sym == SDLK_DOWN){ + $player1->{v_y} = 2; } } elsif($event->type == SDL_KEYUP){ if($event->key_sym == SDLK_DOWN || $event->key_sym == SDL +K_UP){ $player1->{v_y} = 0; } } });

This code looks alright to me. I have added the entire code so you can see for yourself, it's slower when moving down. I hate to solve this problem with given different speeds. Hope you can help.

use strict; use warnings; use SDL; use SDLx::App; use SDL::Events; use SDLx::Rect; use SDLx::Text; my $app = SDLx::App->new(w =>500,h=>500,t=>"Pong",exit_on_quit=>1,dt=> +0.02); my $player1={paddle=>SDLx::Rect->new(10,$app->h/2,10,40),v_y=>0,score= +>0}; my $player2={paddle=>SDLx::Rect->new($app->w-20,$app->h/2,10,40),v_y=> +0,score=>0}; my $ball = {rect => SDLx::Rect->new($app->w / 2, $app->h / 2, 10, 10), +v_x=>-3,v_y=>1.5}; my $score = SDLx::Text->new(x=>240); $app->add_show_handler(sub{ $app->draw_rect([0,0,$app->w,$app->h],[0,0,0,0]); $app->draw_rect($ball->{rect},[255,0,0,0]); $app->draw_rect($player1->{paddle},[255,0,0,0]); $app->draw_rect($player2->{paddle},[255,0,0,0]); $score->write_to($app,$player1->{score}.'x'.$player2->{score}); $app->update; }); $app->add_move_handler(sub { my $step = shift; my $paddle = $player1->{paddle}; my $v_y = $player1->{v_y}; $paddle->y($paddle->y + ($step * $v_y)); if($paddle->y >= $app->h){ $paddle->y(0); } elsif($paddle->y + 40 <= 0){ $paddle->y(500); } }); $app->add_move_handler(sub { my $step = shift; my $paddle = $player2->{paddle}; my $v_y = $player2->{v_y}; if($ball->{rect}->y > $paddle->y){ $v_y = 2; } elsif($ball->{rect}->y < $paddle->y){ $v_y = -2; } else{ $v_y = 0; } $paddle->y($paddle->y + ($step * $v_y)); }); $app->add_move_handler(sub{ my $step = shift; my $ball_rect = $ball->{rect}; $ball_rect->x( $ball_rect->x + ($ball->{v_x} * $step) ); $ball_rect->y( $ball_rect->y + ($ball->{v_y} * $step) ); if($ball_rect->bottom >= $app->h){ $ball_rect->bottom($app->h); $ball->{v_y}*=-1; } elsif($ball_rect->top<=0){ $ball_rect->top(0); $ball->{v_y}*=-1; } elsif($ball_rect->right>=$app->w){ $player1->{score}++; reset_game(); return } elsif($ball_rect->left<=0){ $player2->{score}++; reset_game(); return; } elsif(check_collision($ball_rect,$player1->{paddle})){ $ball_rect->left($player1->{paddle}->right); $ball->{v_x} *= -1; } elsif(check_collision($ball_rect,$player2->{paddle})){ $ball_rect->right($player2->{paddle}->left); $ball->{v_x} *= -1; } }); $app->add_event_handler(sub { my $event= shift; if($event->type == SDL_KEYDOWN){ if($event-> key_sym == SDLK_UP){ $player1->{v_y} = -2; } elsif($event->key_sym == SDLK_DOWN){ + $player1->{v_y} = 2; } } elsif($event->type == SDL_KEYUP){ if($event->key_sym == SDLK_DOWN || $event->key_sym == SDL +K_UP){ $player1->{v_y} = 0; } } }); $app->run; sub check_collision{ my($A,$B) = @_; return if $A->bottom < $B->top; return if $A->top > $B->bottom; return if $A->right < $B->left; return if $A->left > $B->right; return 1; } sub reset_game{ $player1->{paddle}->y($app->h/2); $player2->{paddle}->y($app->h/2); $ball->{rect}->x($app->w/2); $ball->{rect}->y($app->h/2); $ball->{v_x} = (4 + rand(2)) * (rand (2) > 1 ? 1 : -1); $ball->{v_y} = (1.5 + rand(1)) * (rand (2) > 1 ? 1 : -1); }

Replies are listed 'Best First'.
Re: pong paddles are not going equally fast
by bliako (Prior) on Jul 23, 2020 at 08:10 UTC

    New paddle position also depends on $step which is the time slice.

    When you press UP-arrow this checks only the 1st condition. When you press DOWN-arrow it checks both conditions. Could that be affecting $step? Ideally no but try print $step and see.

    if($event-> key_sym == SDLK_UP){ $player1->{v_y} = -2; } elsif($event->key_sym == SDLK_DOWN){ + $player1->{v_y} = 2; }

    bw, bliako

      > Could that be affecting $step?

      Can be easily tested by swapping the conditions.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: pong paddles are not going equally fast
by kcott (Bishop) on Jul 23, 2020 at 11:16 UTC

    [Disclaimer: I am not a user of SDL and I do not have it installed. The following is untested guesswork (actually, perl -c says "syntax OK", but untested beyond that).]

    After looking at your posted code, I had a similar thought to what ++bliako wrote.

    I can see that you've copied the code from "[PDF] SDL::Manual": a visual inspection shows no problems there.

    Try replacing this entire call:

    $app->add_event_handler(sub { ... });

    with

    { my %paddle_move; my $key_joiner; BEGIN { $key_joiner = '~'; %paddle_move = ( SDL_KEYDOWN . $key_joiner . SDLK_UP, -2, SDL_KEYDOWN . $key_joiner . SDLK_DOWN, 2, SDL_KEYUP . $key_joiner . SDLK_UP, 0, SDL_KEYUP . $key_joiner . SDLK_DOWN, 0, ); } $app->add_event_handler(sub { my $event = shift; my $paddle_key = $event->type . $key_joiner . $event->key_sym; if (exists $paddle_move{$paddle_key}) { $player1->{v_y} = $paddle_move{$paddle_key}; } }); }

    That will set up all of the possible values for $player1->{v_y} once, at compile time. Assigning those values now only requires a single if condition, instead of the multiple if and elsif conditions you currently have.

    — Ken

Re: pong paddles are not going equally fast
by perlfan (Vicar) on Jul 22, 2020 at 17:25 UTC
    Sounds like faulty coordinate math.

      Yes, but which part? I have gone over the entire code at least a dozen times but cannot find anything.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11119665]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (9)
As of 2021-03-02 21:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favorite kind of desktop background is:











    Results (63 votes). Check out past polls.

    Notices?