Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Trans-OS PONG simulator!

by wombat (Curate)
on Jul 18, 2003 at 05:21 UTC ( #275506=sourcecode: print w/ replies, xml ) Need Help??

Category: Fun Stuff
Author/Contact Info Wombat wombat@perlmonk.org
Description: So I had bought the Perl/TK book recently, and I decided to begin to hone my skills at making GUI apps. When I came upon the section on how to make decorationless windows, I was struck by a bolt of GENIUS (madness). I already had x2vnc connecting the desktops of my Linux and Windows computers. Why not build a dumb little program that makes it look like the two machines are playing PONG!?

All you need to run this, is ideally two computers side by side. There are three variables inside the program, after the XPM bitmaps, that need to be set properly. This is because I was _lazy_ and didn't feel like adding argument functionality. The variables are:

$left: The computer on the left must have this set to zero. The computer on the right must have this set to one. (Yes, I know it sounds backwards, but left comes before right, and zero comes before one. If it bugs you do a s/\$left/\$right/g.)

$multiplier: My linux box runs at a different resolution than my windows box, due entirely to differing monitors etc. One machine should have a multiplier set to 1.0 (the default) The other should have it set to the ratio of the two resolution heights. My case is 1.36. If both are set to 1.0, then undefined hilarity will ensue when the larger monitor passes a value out of range of the smaller monitor. {Actually, the ball will just get lost, eventually bounce off the rear wall, and then reemerge on the larger monitor})

$player: This needs to be set to the IP address of the opposing computer. That's it.

Message passing is accomplished by a four byte UDP packet being sent on port 9628 each time the ball hits the center divide. Because of the size of the packet, this necessarily will not work properly on monitors with a resolution greater than 9999 pixels in height.

Any other questions or comments, write away!

~W (Yeah, I'm back!)
#!/usr/bin/perl -w
use strict;
use Socket;
use IO::Socket;
use Tk;

#This program sends UDP packets on port 9628 which the astute will not
+ice
#spells out "WMBT" on any common telephone keypad.

my $y=0;                  #Y position of the paddle.
my $dir=0;                #Direction the paddle should move.
my @ballstat= (0,0,0,0);  #(X,Y,dx,dy)

my $ball = <<'END_OF_BALL_DATA';
/* XPM */
static char * BALL_xpm[] = {
"10 10 1 1",
"W c #FFFFFFFFFFFF",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW"};
END_OF_BALL_DATA

my $paddle = <<'END_OF_PIXMAP_DATA';
/* XPM */d
static char * PADDLE_xpm[] = {
"10 80 1 1",
"W c #FFFFFFFFFFFF",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW",
"WWWWWWWWWW"};
END_OF_PIXMAP_DATA

my ($him, $width, $height, $multiplier, $left, $player);

#Set this to 0 for the left/starting side, 1 for the right, receiving 
+side.
$left = 0;

#CHANGE this if the monitors have different resolutions.  Multiplier s
+hould
#be (Height of this monitor) / (Height of other monitor) For me, on th
+is
#machine, that's 1.36.  The other machine should be set to 1.0.
$multiplier = 1.0;

#Set this to the IP address of the other machine.
$player = "192.168.0.1";

socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp"));
my $server = IO::Socket::INET->new(LocalPort => 9628,
                                   Proto     => "udp")
    or die "Couldn't be a udp server on port 9628 : $@\n";

my $pw = MainWindow->new(-background=>"#FFFFFF");
my $bw = MainWindow->new(-background=>"#FFFFFF");
$width = $pw->screenwidth;
$height = $pw->screenheight;
print("I read a resolution of $width x $height\n");
$pw->Label(-image => $pw->Pixmap(-data => $paddle))->pack;
$bw->Label(-image => $bw->Pixmap(-data => $ball))->pack;
$pw->overrideredirect(1);
$bw->overrideredirect(1);
if ($left) {$bw->withdraw();}
else {
  @ballstat=($width/2,$height/2,5,3);
}
while(1){

select(undef,undef,undef,.02);  #The poor man's HiRes sleep timer.

if($y==0) {$dir++;$y+=3;}
if($y==$height-40) {$dir--;$y-=3;}
if($ballstat[1]+5>$y+40) {$y+=3;} else {$y-=3;}

if($ballstat[1]<=0){$ballstat[3]*=-1;}
if($ballstat[1]>=$height-20){$ballstat[3]*=-1;}


if(($left)&&($ballstat[0]<=0)) {
  &send_and_receive();
}

if(!($left)&&($ballstat[0]>=$width-10)) {
  &send_and_receive();
}

if (($left) && ($ballstat[0]>=$width-10)){$ballstat[2]*=-1;}
if (!($left) && ($ballstat[0]<=0)){$ballstat[2]*=-1;}
$ballstat[0]+=$ballstat[2];
$ballstat[1]+=$ballstat[3];

$pw->geometry("+".(($width-10)*$left)."+$y");
$bw->geometry("+".$ballstat[0]."+".$ballstat[1]);
$pw->update;
$bw->update;
}


sub send_and_receive {
  $ballstat[1] /= $multiplier; #Differences in resolution;
       $ballstat[1]%=$height;
  if ($ballstat[3]<0) {
    $ballstat[1]-=(2*$ballstat[1]);
  }
  send(SOCKET, $ballstat[1], 0, sockaddr_in(9628,inet_aton("$player"))
+) == length (
$ballstat[1])
    or die "Can't send the UDP packet!\n$!\n";
  $bw->withdraw();
  $ballstat[2] = 0;
  $ballstat[3] = 0;
  while ($him = $server->recv($ballstat[1], 4, 0)) {
     print "@ballstat $ballstat[1] received!\n";
     $ballstat[1]*=$multiplier; #Because of differences in resolution.
+ :-P
     if ($ballstat[1] > $height) {
       $ballstat[1] = $height;
     }
     if ($left) {$ballstat[2]=5;}
     else {$ballstat[2]=-5;}
     $ballstat[3]=3;
     if ($ballstat[1]<0) {
       $ballstat[1]-=(2*$ballstat[1]);
       $ballstat[3]*=-1;
     }
       $ballstat[1]%=$height;
     $bw->deiconify();
     $bw->raise();
     last;
  }
}

Comment on Trans-OS PONG simulator!
Download Code
Re: Trans-OS PONG simulator!
by robobunny (Friar) on Jul 18, 2003 at 13:53 UTC
    hey, that's pretty cool :) i dragged a couple of monitors next to each other and it has greatly amused my cubicle neighbors. everybody wants a version they can play now.

Back to Code Catacombs

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (10)
As of 2014-09-01 14:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (13 votes), past polls