纯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
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以给你提供一个简单的贪吃蛇游戏的代码,你可以在网页上运行它。 HTML 代码: ``` <!DOCTYPE html> <html> <head> <title>贪吃蛇游戏</title> <style> canvas { border: 1px solid #000; } </style> </head> <body> <h1>贪吃蛇游戏</h1> <canvas id="gameCanvas" width="400" height="400"></canvas> <script src="snake.js"></script> </body> </html> ``` JavaScript 代码: ```javascript // 获取 canvas 元素 var canvas = document.getElementById("gameCanvas"); var ctx = canvas.getContext("2d"); // 定义游戏参数 var blockSize = 10; // 方块大小 var widthInBlocks = canvas.width / blockSize; var heightInBlocks = canvas.height / blockSize; var score = 0; // 定义绘制方块的函数 var drawBlock = function(ctx, position) { var x = position[0] * blockSize; var y = position[1] * blockSize; ctx.fillRect(x, y, blockSize, blockSize); }; // 定义绘制分数的函数 var drawScore = function() { ctx.font = "20px Arial"; ctx.fillStyle = "Black"; ctx.textAlign = "left"; ctx.textBaseline = "top"; ctx.fillText("Score: " + score, blockSize, blockSize); }; // 定义清除画布的函数 var clearCanvas = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); }; // 定义游戏结束的函数 var gameOver = function() { clearInterval(intervalId); ctx.font = "60px Arial"; ctx.fillStyle = "Black"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText("Game Over", canvas.width / 2, canvas.height / 2); }; // 定义方块的构造函数 var Block = function(col, row) { this.col = col; this.row = row; }; // 定义判断方块是否在画布内的函数 Block.prototype.insideCanvas = function() { return (this.col >= 0 && this.col < widthInBlocks && this.row >= 0 && this.row < heightInBlocks); }; // 定义判断方块是否在同一个位置的函数 Block.prototype.equal = function(otherBlock) { return (this.col === otherBlock.col && this.row === otherBlock.row); }; // 定义蛇的构造函数 var Snake = function() { this.segments = [ new Block(7, 5), new Block(6, 5), new Block(5, 5) ]; this.direction = "right"; this.nextDirection = "right"; }; // 定义绘制蛇的函数 Snake.prototype.draw = function() { for (var i = 0; i < this.segments.length; i++) { drawBlock(ctx, this.segments[i].position()); } }; // 定义移动蛇的函数 Snake.prototype.move = function() { var head = this.segments[0]; var newHead; this.direction = this.nextDirection; if (this.direction === "right") { newHead = new Block(head.col + 1, head.row); } else if (this.direction === "down") { newHead = new Block(head.col, head.row + 1); } else if (this.direction === "left") { newHead = new Block(head.col - 1, head.row); } else if (this.direction === "up") { newHead = new Block(head.col, head.row - 1); } if (this.checkCollision(newHead)) { gameOver(); return; } this.segments.unshift(newHead); if (newHead.equal(apple.position())) { score++; apple.move(); } else { this.segments.pop(); } }; // 定义检查蛇是否碰到边界或自己的函数 Snake.prototype.checkCollision = function(head) { var leftCollision = (head.col === 0); var topCollision = (head.row === 0); var rightCollision = (head.col === widthInBlocks - 1); var bottomCollision = (head.row === heightInBlocks - 1); var wallCollision = leftCollision || topCollision || rightCollision || bottomCollision; var selfCollision = false; for (var i = 0; i < this.segments.length; i++) { if (head.equal(this.segments[i])) { selfCollision = true; } } return wallCollision || selfCollision; }; // 定义改变蛇的方向的函数 Snake.prototype.setDirection = function(newDirection) { if (this.direction === "up" && newDirection === "down") { return; } else if (this.direction === "right" && newDirection === "left") { return; } else if (this.direction === "down" && newDirection === "up") { return; } else if (this.direction === "left" && newDirection === "right") { return; } this.nextDirection = newDirection; }; // 定义苹果的构造函数 var Apple = function() { this.position = function() { var col = Math.floor(Math.random() * (widthInBlocks - 2)) + 1; var row = Math.floor(Math.random() * (heightInBlocks - 2)) + 1; return new Block(col, row); }; this.move = function() { this.block = this.position(); }; this.block = this.position(); }; // 创建蛇和苹果对象 var snake = new Snake(); var apple = new Apple(); // 定义游戏循环 var intervalId = setInterval(function() { clearCanvas(); drawScore(); snake.move(); snake.draw(); apple.draw(); }, 100); // 定义键盘按下事件 var directions = { 37: "left", 38: "up", 39: "right", 40: "down" }; document.addEventListener("keydown", function(event) { var newDirection = directions[event.keyCode]; if (newDirection !== undefined) { snake.setDirection(newDirection); } }); ``` 这个代码实现了一个简单的贪吃蛇游戏,你可以在浏览器中打开 HTML 文件,就可以运行游戏了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值