纯php写的贪吃蛇游戏,膜拜了

有朋友说php无法实现贪吃蛇游戏,忙里偷闲尝试一下,试写了个纯php版的贪吃蛇,不包含一句JavaScript代码,其实php也有写桌面应用的接口的

d5ee6eea046dc7cd02d8ac2bc3c193f4.jpeg

不过今天我们这个demo就是我们常见的写增删改查的服务端php,下面还是先上效果图,再上代码。

0542cdc6e9c0a7dedf0f6f82d28b7c2a.jpeg

以下是代码示例

<?php
namespace snake;
/**
 * php贪吃蛇
 */
class snake{
  /**
   * 构造方法
   */
  public function __construct(){
    $this->app="http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
  }
  /**
   * 读取session模拟的虚拟缓存显示到屏幕上
   * @return [type] [description]
   */
  public function print(){
    $score=!$this->get("score")?0:$this->get("score");//得分
    //html长字符串
    $html=<<<MAP_STRING
    <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>snake</title>
<style>
table{
    background-color:#000;
  }
  table td{
    padding:1px 1px 1px 1px;
    width:16px;height:12px;
    color:red;
  }
  table tr{
    background-color:#000;
  }
  .sn{
    background:#fff;
  }
  .bright{background:#fff;}
  button{font-size:20px;}
  marquee{width:400px;height:400px;font-size:50px;color:red;background:#000;text-align:center;}
</style>
<p>php贪吃蛇->[分数:{$score}]</p>
MAP_STRING;
    $map="<table>";
    //初始化高亮区域$bright,包括蛇体和食物
    if(!$this->get("snake")){
      $bright=[];
    }else{
      $bright=array_merge($this->get("snake"),[$this->get("food")]);
    }
    //标记蛇体和食物高亮
    for($i=0;$i<30;$i++){
      $map.="<tr>";
      for($j=0;$j<30;$j++){
        if(in_array([$j,$i],$bright)){
          $map.="<td class='bright'></td>";
        }else{
          $map.="<td></td>";
        }
      }
      $map.="</tr>";
    }
    $map.="</table>";
    //控制区域长字符串
    $controll=<<<CONTROLL
    <a href="{$this->app}?isOn=on"><button>start</button></a>
    ........................
    <a href="{$this->app}?isOn=on&direction=up"><button>up</button></a>
    <br><a href="{$this->app}?isOn=off"><button>stop</button></a>
    ...............
    <a href="{$this->app}?isOn=on&direction=left"><button>left</button></a>
    <a href="{$this->app}?isOn=on&direction=right"><button>right</button></a>
    <br>............................................
    <a href="{$this->app}?isOn=on&direction=down"><button>down</button></a>
CONTROLL;
    if(isset($_GET["isOn"])&&$_GET["isOn"]=="on"){
      header("refresh: 1");//每一秒刷新一次页面
    }
    if(isset($_GET["msg"])){
      //收到游戏结束的消息
      echo $html."<marquee direction=up>{$_GET["msg"]}</marquee>".$controll;
    }else{
      //游戏画面显示
      echo $html.$map.$controll;
    }
  }
  /**
   * 设置虚拟显存session中的数据
   * @param [type] $k [description]
   * @param [type] $v [description]
   */
  public function set($k,$v){
    $_SESSION[$k]=$v;
  }
  /**
   * 读取虚拟缓存session中的数据
   * @param  [type] $k [description]
   * @return [type]    [description]
   */
  public function get($k){
    return isset($_SESSION[$k])?$_SESSION[$k]:false;
  }
  /**
   * 贪吃蛇算法,添头去尾、吃食物、撞墙判断、咬自己判断
   * @return [type] [description]
   */
  public function cpu(){
    session_start();
    //游戏若暂停状态则不需计算不需修改虚拟缓存
    if(!(isset($_GET["isOn"])&&$_GET["isOn"]=="on")){
      return;
    }
    //初始化蛇体和食物
    if(!$this->get("snake")){
      $this->set("snake",[
        [29,29]
      ]);
      $this->set("score",0);
      $this->getFood();
      return;
    }
    //初始化运动方向
    if(!isset($_GET["direction"])){
      $this->set("direction","left");
    }else{
      $this->set("direction",$_GET["direction"]);
    }
    $snake=$this->get("snake");
    //计算蛇头坐标
    switch($this->get("direction")){
      case "up":{
        $snakeHead=[
          $snake[0][0],
          $snake[0][1]-1
        ];
        break;
      }
      case "down":{
        $snakeHead=[
          $snake[0][0],
          $snake[0][1]+1
        ];
        break;
      }
      case "left":{
        $snakeHead=[
          $snake[0][0]-1,
          $snake[0][1]
        ];
        break;
      }
      case "right":{
        $snakeHead=[
          $snake[0][0]+1,
          $snake[0][1]
        ];
        break;
      }
    }
    //咬到自己,游戏结束
    if(in_array($snakeHead,$snake)){
      $this->gameOver();
      return;
    }
    //添加蛇头坐标
    array_unshift($snake,$snakeHead);
    //撞墙,游戏结束
    if($snake[0][0]<0||$snake[0][1]<0||$snake[0][0]>29||$snake[0][1]>29){
      $this->gameOver();
      return;
    }
    //咬到食物得一分
    if(in_array($this->get("food"),$snake)){
      $this->getFood();
      $this->set("score",$this->get("score")+1);
    }else{
      unset($snake[count($snake)-1]);
    }
    $this->set("snake",$snake);
  }
  /**
   * 取得食物
   * @return [type] [description]
   */
  public function getFood(){
    $food=[mt_rand(1, 29),mt_rand(1, 29)];
    $this->set("food",$food);
    if(in_array($food,$this->get("snake"))){
      $this->getFood();
    }
  }
  /**
   * 游戏结束
   * @return [type] [description]
   */
  public function gameOver(){
    session_unset();
    header("location:".$this->app."?msg=gameover");
  }
  /**
   * 程序入口
   * @return [type] [description]
   */
  public function main(){
    $this->cpu();
    $this->print();
  }
}
(new snake())->main();

贪吃蛇无非就是添头去尾,撞墙判断和吃自己判断,通过二维数组就能实现,主要是php不像JavaScript那样常驻内存,页面生成了php就停止运行了,也没有定时器。

因此这个贪吃蛇是靠不断地刷新页面实现的的,控制方向啥的靠链接跳转挂参数实现的,$_GET变量存储方向等参数,蛇体数组和食物数组存储在$_SESSION里,这样通过header("refresh: 1")不断刷新页面,每次刷新的页面都根据$_SESSION中存储的数组进行调整,这样就完成了游戏的基本流程。

  • $this->cpu()方法负责计算蛇体位置数组和食物以及方向控制和得分情况

  • $this->print()方法负责通过页面自动刷新把数据显示在屏幕上

游戏结束的动画是通过html原生标签<marquee>实现的。

最后,这个代码都是在手机上写的,最近发现ios上新出了个phpwin的app,可以写php代码也可以运行。

9c5ae64094f17a6d2f6773d3cf123c2d.jpeg

👇👇最新2024IDEA永久激活(支持全家桶)👇👇
关注上面公众号回复“激活码”,获取2024年最新激活码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值