Skip to content

Instantly share code, notes, and snippets.

@redcapital
Created February 3, 2013 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save redcapital/4702075 to your computer and use it in GitHub Desktop.
Save redcapital/4702075 to your computer and use it in GitHub Desktop.
Rain in your terminal. Run with `php Rain.php`
<?php
/**
* Renders rain. The code was like 10 times shorter before moving it into the class
*/
class Renderer
{
protected $width, $height, $text;
private $_middle, $_textBeginPos, $_textLength, $_line;
private $_resetPos;
public function __construct($width, $height, $text)
{
$this->width = $width;
$this->height = $height;
$this->text = $text;
}
protected function init()
{
$this->_middle = (int)floor(($this->height - count($this->text)) / 2);
$this->_textParams = array();
foreach ($this->text as $text) {
$this->_textParams[] = array(
'length' => mb_strlen($text),
'pos' => (int)floor(($this->width - mb_strlen($text)) / 2),
);
}
$this->_line = str_repeat(' ', $this->width);
$this->_resetPos = `tput cup 0 0`;
for ($i = 0; $i < $this->height; $i++) $this->_positions[$i] = array();
$this->_collisions = array();
$this->clearScreen();
}
protected function clearScreen()
{
echo `tput clear`;
}
protected function renderFrame()
{
echo $this->_resetPos;
$lines = array();
for ($i = 0; $i < $this->height; $i++) {
$curLine = $this->_line;
foreach ($this->_positions[$i] as $p) {
$curLine[$p] = '/';
}
$lines[] = $curLine;
}
// Text
foreach ($this->_textParams as $i => $params) {
$lines[$this->_middle + $i] = substr_replace(
$lines[$this->_middle + $i],
$this->text[$i],
$params['pos'],
$params['length']
);
}
// Collisions
foreach ($this->_collisions as $collision) {
$lines[$collision[0]][$collision[1]] = '*';
}
echo implode("\n", $lines) . "\n";
}
protected function nextFrame()
{
// Collisions
$this->_collisions = array();
foreach ($this->_positions[$this->height - 1] as $p) {
$this->_collisions[] = array($this->height - 1, $p);
}
// Move all drops one line below and shift them to the left
for ($i = $this->height - 1; $i > 0; $i--) {
$this->_positions[$i] = array();
foreach ($this->_positions[$i - 1] as $p) {
if ($p > 0) {
$this->_positions[$i][] = $p - 1;
} else {
$this->_positions[$i][] = $p - 1 + $this->width;
}
}
}
// Add a line with random drops to the top
$this->_positions[0] = array();
$drops = mt_rand(0, 8);
while ($drops--) {
$this->_positions[0][] = mt_rand(0, $this->width - 1);
}
}
public function run()
{
$this->init();
// Initial rain lines
for ($i = 0; $i < $this->height - 10; $i++) $this->nextFrame();
while (true) {
$this->renderFrame();
$this->nextFrame();
usleep(45000);
}
}
}
$text = array(
'Rain in your terminal', '',
'Running on PHP ' . PHP_VERSION
);
$r = new Renderer(80, 25, $text);
$r->run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment