纯php实现贪吃蛇游戏(不使用JavaScript)

        好久不写php了,最近有朋友说php只能写写增删改查,无法实现贪吃蛇游戏,忙里偷闲,写了个纯php版的贪吃蛇,不包含一句JavaScript代码,其实php也有写桌面应用的接口,不过今天我们这个demo就是我们常见的写增删改查的服务端php,下面还是先上效果图,再上代码。

 然后是代码

<?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代码也可以运行。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值