A simple game played entirely in audio. For best effect, play with headphones on and eyes shut :)
/*
* KEEPY-UPPY
*
* To run this game, select all the text and press the SuperCollider key for execute-code (on Mac it's Enter).
*
* An AUDIO game written in SuperCollider by Dan Stowell (C) 2005
* Released under the GNU Public Licence
* See http://www.gnu.org/copyleft/gpl.html for licence details
*
* This game is based on being told about the work of "One Switch"
* http://www.oneswitch.org.uk/ - developing games and controllers
* to accommodate various types of disability, including...
* audio-only games.
*
* RULES:
* You are kicking a football into the air. You can hear it fly
* up into the air and down again, and when it comes down you
* must press SPACE to kick it up again.
*
* The ball may move slightly towards the left or right so you
* may need to move left or right using the cursor keys to
* keep within range of the ball (wear headphones for best
* control!)
*
* The aim is to kick it up as many times as you can.
*
*
*/
(
s.waitForBoot{
Task{
// Then send it the SynthDefs we need
(
SynthDef(\kuball, { |amp=0.5, pan=0, freq=100|
Out.ar(0, Pan2.ar(amp * 2 *(BPF.ar(WhiteNoise.ar, freq, 0.1)*10).clip2 * SinOsc.ar(4.5), pan))
}).send(s);
SynthDef(\gameover, { Out.ar(0, SinOsc.ar(
Line.kr(200, 100, 1.0, doneAction:0),
0,
EnvGen.kr(Env([0.3, 0.2, 0.2, 0], [0.1, 0.8, 0.1]), 1, doneAction:2)
).dup(2))}).send(s);
SynthDef(\whackit, {Out.ar(0, SinOsc.ar(74, 0.5pi,
EnvGen.kr(Env.perc(0, 0.05), doneAction:2)).dup(2))}).send(s);
);
0.1.wait;
s.sync;
// Now define the game
(
~announce = Platform.case(
\osx, {{|msg| msg.speak}},
\linux, {{|msg| msg.speak}},
\windows, {{|msg| msg.postln}}
);
~game = {
var whacks, xpos, ypos, xvel, yvel, whack, dogravity, framedur, doc, whackdisabled, whackspacing;
whacks = 0;
xpos = 0;
ypos = 0;
xvel = 0;
yvel = 10;
framedur = 0.1; // The amount of time between two "frames" of calculation
whackdisabled = false;
whackspacing = 0.3; // The amount of time you must wait between whacks
whack = {
if(ypos < 20,
{
if(xpos.abs < 1,
{
if((yvel < 0) && (whackdisabled==false),
{
yvel = rrand(6.0, 14.0);
ypos = max(0.1, ypos);
xvel = 0.1.bilinrand;
Synth(\whackit);
whackdisabled = true;
Task({whackspacing.wait; whackdisabled = false}).play;
whacks = whacks + 1;
//doc.string="WHACK!";
});
},
{
//doc.string="Missed!";
});
},
{
//doc.string="The ball is too high to hit";
});
}; // End of whack function
dogravity = {
yvel = yvel - 1.0;
ypos = ypos + yvel;
xpos = xpos + xvel;
};
Task({
var kuball;
kuball = Synth(\kuball);
// Set up keyboard handlers
AppClock.sched(0.0, {
//doc = Document.new("Use LEFT and RIGHT arrows and SPACEBAR", "");
doc = GUI.window.new("Use LEFT and RIGHT arrows and SPACEBAR");
doc.front;
doc.view.keyDownAction_({arg ...args;
switch(args[3],
32 , {whack.value}, // space
63234, {xpos = xpos + 0.1}, // left arrow
63235, {xpos = xpos - 0.1} // right arrow
);
});
});
0.1.wait;
// This is the loop which runs the game
while({ypos >= 0},
{
dogravity.value;
kuball.set(\amp, 0.5 * (1.0/max(1.0, ypos)),
\pan, max(-1.0, min(1.0, xpos)),
\freq, 200 + max(0, ypos * 10));
framedur.wait;
});
// Destroy keyboard handlers
AppClock.sched(0, {
doc.view.keyDownAction_(nil);
});
kuball.free;
// Run the end-of-game feedback etc
Synth(\gameover);
1.5.wait;
AppClock.sched(0.0, {doc.close;});
switch(whacks,
0, {~announce.("You didn't hit the ball - sorry");},
1, {~announce.("You hit the ball once");},
2, {~announce.("You hit the ball twice");},
3, {~announce.("You hit the ball 3 times");},
4, {~announce.("You hit the ball 4 times - well done");},
5, {~announce.("You hit the ball 5 times - well done");},
{~announce.("You hit the ball "+whacks+" times - well done indeed!");}
);
}).play;
}
);
~game.value; // Press Enter to play!
}.play
}
)