ChucK/Examples/Pong2
From CSWiki
This fun little program creates a MAUI window with a moving ball and paddle in it, and plays a Pong-style game in real time, responding to mouse motion. Although there is some ghosting if you move the mouse too quickly, it is a promising demonstration of how the MAUI user interface can create dynamic window content. Pong anyone?
// experiment with mouse moving a button in MAUI
// copyright 2008 Les Hall
// This software is protected by the GNU General Public License
// define some variables
400 => int x_max; // width of window
400 => int y_max; // height of window
1280 => int screen_width; // horizontal resolution of screen
960 => int screen_height; // vertical resolution of screen
1 => int x_drift; // sets drift motion of the button in x direction
1 => int y_drift; // sets drift motion of the button in y direction
0 => int bounce; // 1 when button bounces off a wall
0 => int player_score; // let's make it fun by keeping score
0 => int chuck_score; // chuck scores when ball falls off window
200 => int x_pos; // x position of button
200 => int y_pos; // y position of button
60 => int button_size; // size of button
x_pos - button_size / 2 => int paddle_pos; // position of paddle
30::ms => dur envelope_duration; // how long to ramp up/down whooping sound
// set up the view panel
MAUI_View mouse_view;
mouse_view.size (x_max, y_max);
mouse_view.position (screen_width/2 - x_max/2, screen_height/2 - y_max/2);
mouse_view.name ("Play Pong with ChucK!");
mouse_view.display ();
// create the bouncing button
MAUI_Button mouse_button;
mouse_button.toggleType ();
mouse_button.size (button_size, button_size);
mouse_button.position (x_pos - button_size / 2, y_pos - button_size / 2);
mouse_button.name ("");
mouse_view.addElement (mouse_button);
// create a score button
MAUI_Button score_button;
score_button.toggleType ();
score_button.size (x_max, button_size);
score_button.position (0, 0);
score_button.name ("Score: ChucK " + chuck_score + " You " + player_score);
mouse_view.addElement (score_button);
// create a paddle button
MAUI_Button paddle_button;
paddle_button.toggleType ();
paddle_button.size (2 * button_size, button_size);
paddle_button.position (paddle_pos, y_max - button_size);
paddle_button.name ("You");
mouse_view.addElement (paddle_button);
// It's a ChucK program, we gotta make some sound!
SinOsc sinosc => JCRev jcrev => dac;
jcrev.mix (0.1);
Phasor phasor => SinOsc whoop => Envelope envelope => dac;
phasor.freq (3);
phasor.gain (500);
whoop.gain (0);
envelope.duration (envelope_duration);
0 => int device;
Hid hid;
HidMsg hidmsg;
if (!hid.openMouse (device)) me.exit();
// shred to handle the human interface device (the mouse)
function void hid_handler () {
// infinite time loop
while (true) {
// wait on event
hid => now;
// loop over scores
while (hid.recv (hidmsg)) {
if (hidmsg.isButtonDown()) {
// put something fun here later
}
if (hidmsg.isButtonUp ()) {
// put something fun here later
}
if( hidmsg.isMouseMotion() )
{
// adjust paddle position
hidmsg.deltaX +=> paddle_pos;
// check lower limit on paddle
if (paddle_pos < 0) {
0 => paddle_pos;
}
// check upper limit on paddle
if (paddle_pos > x_max - 2 * button_size) {
x_max - 2 * button_size => paddle_pos;
}
}
}
}
}
// i live to spork
spork ~ hid_handler ();
// move the button, make sure it stays in the window,
// change drift direction when button bounces,
// and update the SinOsc
while (true) {
// make the button move by itself
x_drift +=> x_pos;
y_drift +=> y_pos;
// check lower limit on x (left side)
if (x_pos <= 0) {
0 => x_pos;
1 => x_drift;
1 => bounce;
}
// check upper limit on x (right side)
if (x_pos >= x_max - button_size) {
x_max - button_size => x_pos;
-1 => x_drift;
1 => bounce;
}
// check lower limit on y (top)
if (y_pos <= button_size - 36) {
button_size - 36 => y_pos;
1 => y_drift;
1 => bounce;
player_score++;
score_button.name ("Score: ChucK " + chuck_score + " You " + player_score);
}
// check upper limit on y (bottom)
if (y_pos >= y_max - button_size - 20) {
if (Math.abs (paddle_pos + button_size - 20 - x_pos) < button_size) {
if (y_pos <= y_max - button_size) {
y_max - button_size - 20 => y_pos;
-1 => y_drift;
1 => bounce;
}
}
}
// check if button falls off bottom of screen
if (y_pos > y_max) {
button_size => y_pos;
chuck_score++;
score_button.name ("Score: ChucK " + chuck_score + " You " + player_score);
phasor.phase (0);
whoop.gain (1);
envelope.keyOn ();
1::second - envelope_duration => now;
envelope.keyOff ();
envelope_duration => now;
whoop.gain (0);
}
// move the bouncing button
mouse_button.position (x_pos, y_pos);
mouse_view.addElement (mouse_button);
// move the paddle button
paddle_button.position (paddle_pos, y_max - button_size);
mouse_view.addElement (paddle_button);
// adjust frequency and amplitude of sound source
if (bounce) {
// make a clicking sound when button bounces
sinosc.freq (1000);
sinosc.gain (1);
0 => bounce;
} else {
// make a gentle woo-woo sound as ball moves
sinosc.freq (500 * x_pos / (x_max $ float));
sinosc.gain (1 - y_pos / (y_max $ float));
}
// must delay or ChucK will have a psychotic episode!
10::ms => now;
}

