PHP dasturlash tilida otishma o'yini
o'yinni ishga tushirish uchun buyruqlar satrida
$: php shooterGame.php
<?php | |
class Entity { | |
public $positionX = 0; | |
public $positionY = 0; | |
public function __construct( $x, $y ) { | |
$this->positionX = $x; | |
$this->positionY = $y; | |
} | |
} | |
class Spaceship extends Entity { | |
public $movementX = 0; | |
public $movementY = 0; | |
public $fire = FALSE; | |
} | |
class Enemy extends Entity {} | |
class Bullet extends Entity {} | |
class Scene { | |
public $height; | |
public $width; | |
public $ship; | |
public $enemies = []; | |
public $bullets = []; | |
public $score = 0; | |
public function __construct( $width, $height ) { | |
$this->width = $width; | |
$this->height = $height; | |
$this->ship = new Spaceship( 2, round( $this->height / 2 ) ); | |
} | |
public function moveShip() { | |
$this->ship->positionX += $this->ship->movementX; | |
$this->ship->positionY += $this->ship->movementY; | |
$this->ship->movementX = 0; | |
$this->ship->movementY = 0; | |
if ( $this->ship->positionX < 0 ) { | |
$this->ship->positionX = 0; | |
} | |
if ( $this->ship->positionX >= $this->height ) { | |
$this->ship->positionX = $this->height - 1; | |
} | |
if ( $this->ship->positionY < 0 ) { | |
$this->ship->positionY = 0; | |
} | |
if ( $this->ship->positionY > $this->width / 4 ) { | |
$this->ship->positionY = $this->width / 4; | |
} | |
} | |
public function shoot() { | |
if ( $this->ship->fire == TRUE ) { | |
$this->bullets[] = new Bullet( $this->ship->positionX, $this->ship->positionY + 1 ); | |
$this->ship->fire = FALSE; | |
} | |
} | |
public function action( $stdin ) { | |
$key = fgets( $stdin ); | |
if ( $key ) { | |
$key = $this->translateKeypress( $key ); | |
switch ( $key ) { | |
case "UP": | |
$this->ship->movementX = -1; | |
$this->ship->movementY = 0; | |
break; | |
case "DOWN": | |
$this->ship->movementX = 1; | |
$this->ship->movementY = 0; | |
break; | |
case "RIGHT": | |
$this->ship->movementX = 0; | |
$this->ship->movementY = 1; | |
break; | |
case "LEFT": | |
$this->ship->movementX = 0; | |
$this->ship->movementY = -1; | |
break; | |
case "ENTER": | |
case "SPACE": | |
$this->ship->fire = TRUE; | |
break; | |
case "ESC": | |
exit(); | |
} | |
} | |
} | |
private function translateKeypress( $string ) { | |
switch ( $string ) { | |
case "\033[A": | |
return "UP"; | |
case "\033[B": | |
return "DOWN"; | |
case "\033[C": | |
return "RIGHT"; | |
case "\033[D": | |
return "LEFT"; | |
case "\n": | |
return "ENTER"; | |
case " ": | |
return "SPACE"; | |
case "\e": | |
return "ESC"; | |
} | |
return $string; | |
} | |
public function moveBullets() { | |
foreach ( $this->bullets as $bullet ) { | |
$bullet->positionY++; | |
} | |
} | |
public function spawnEnemies() { | |
if ( count( $this->enemies ) < 15) { | |
$y = rand( $this->width, $this->width * 2 ); | |
$x = rand( 0, $this->height - 1 ); | |
$this->enemies[] = new Enemy( $x, $y ); | |
} | |
} | |
public function moveEnemies() { | |
foreach ( $this->enemies as $enemyId => $enemy ) { | |
$enemy->positionY--; | |
if ( $enemy->positionY == 0 ) { | |
// Dushman sahnaning chap tomoniga taqalgan bo'lsa uni hech qanday hodisasiz olib tashlash lozim. | |
unset( $this->enemies[ $enemyId ] ); | |
continue; | |
} | |
foreach ( $this->bullets as $bulletId => $bullet ) { | |
if ( $bullet->positionX == $enemy->positionX && ( $bullet->positionY == $enemy->positionY || $bullet->positionY == $enemy->positionY - 1 ) ) { | |
unset( $this->enemies[ $enemyId ] ); | |
unset( $this->bullets[ $bulletId ] ); | |
$this->score++; | |
} | |
} | |
} | |
} | |
public function gameOver() { | |
foreach ( $this->enemies as $enemy ) { | |
if ( $this->ship->positionX == $enemy->positionX && $this->ship->positionY == $enemy->positionY ) { | |
exit('O\'yin tugadi, dushman kemasi sizni mag\'lub qildi'); | |
} | |
} | |
} | |
public function renderGame() { | |
$output = ''; | |
for ( $i = 0; $i < $this->height; $i++ ) { | |
for ( $j = 0; $j < $this->width; $j++ ) { | |
$cell = ( $this->ship->positionX == $i && $this->ship->positionY == $j ) ? '>' : ' '; | |
foreach( $this->enemies as $enemy ) { | |
if ( $enemy->positionX == $i && $enemy->positionY == $j ) $cell = 'X'; | |
} | |
foreach( $this->bullets as $bullet ) { | |
if ( $bullet->positionX == $i && $bullet->positionY == $j ) $cell = '-'; | |
} | |
$output .= $cell; | |
} | |
$output .= PHP_EOL; | |
} | |
$output .= PHP_EOL. 'Ochkolar: ' . $this->score . PHP_EOL; | |
return $output; | |
} | |
} | |
$scene = new Scene( 50, 10 ); // kenglik, balandlik | |
system( 'stty cbreak -echo' ); // strdan alohida belgilarni o'qishni belgilash | |
$stdin = fopen( 'php://stdin', 'r' ); // kiritish oqimini ochish | |
stream_set_blocking( $stdin, 0 ); // oqimni to'xtovsiz o'qish uchun kiritish satriga to'siq o'rnatish | |
while ( 1 ) { | |
system( 'clear' ); // satrni tozalash | |
$scene->action( $stdin ); // Kema uchun harakatlarni belgilash | |
$scene->moveShip(); // Kemani harakatga keltirish | |
$scene->shoot(); // Otish | |
$scene->moveEnemies(); // Dushmanlarni harakatlantirish | |
$scene->moveBullets(); // O'qlarni harakatlantirish | |
echo $scene->renderGame(); // O'yin sahnasini chop etish | |
$scene->gameOver(); // O'yindagi kema holatini kuzatish (O'yinni tugatish jarayoni) | |
$scene->spawnEnemies(); // Dushmanlarni generatsiya qilib borish | |
usleep(100000); | |
} |