<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Canvas02_贪吃蛇</title>
</head>
<style type="text/css">
#ca {
border: 1px solid red;
display: block;
margin: 20px auto;
}
</style>
<body>
<canvas id="ca" width="600" height="600"></canvas>
<script type="text/javascript">
//1.获取canvas标签
var canvasE = document.getElementById("ca");
//2.通过canvas标签获取2D渲染对象(画笔)
var pen = canvasE.getContext("2d");
//声明一个变量记录分数
let score = 0;
//声明一个产生随机数的函数
function randomNum(x, y) {
return Math.floor(Math.random() * (y - x + 1) + x);
}
//声明一个方块类
class Block {
//列
col;
//行
row;
//尺寸
size;
//绘制方块
draw() {
pen.fillRect(this.col * this.size, this.row * this.size, this.size, this.size);
}
//构造方法
constructor(col, row, size) {
this.col = col;
this.row = row;
this.size = size;
}
}
//声明食物类
class Food {
//列
col;
//行
row;
//尺寸
fSize;
//初始化食物
constructor() {
//调用食物的赋值方法
this.initFood();
}
initFood() {
this.col = Math.floor(Math.random() * 60);
this.row = Math.floor(Math.random() * 60);
this.fSize = 5;
}
draw() {
//设置食物颜色
pen.fillStyle = "red";
//画食物
pen.beginPath();
pen.arc(this.col * this.fSize * 2 + this.fSize, this.row * this.fSize * 2 + this.fSize, this.fSize, 0, Math.PI * 2, false);
pen.fill();
//把颜色改回来
pen.fillStyle = "black";
}
}
//声明🐍类
class Snake {
//身体
body = [new Block(20, 20, 10), new Block(20, 21, 10), new Block(20, 22, 10)];
//初始方向
direction = "up";
//食物
food;
//初始化蛇
constructor(food) {
this.food = food;
}
//绘制🐍身体的方法
draw() {
//循环绘制每一个小块
for (var i = 0; i < this.body.length; i++) {
this.body[i].draw();
}
}
//移动方法
move() {
//新建蛇头,新蛇头由当前方向和当前蛇头的位置共同决定
let oldHead = this.body[0];
let newHead;
//判断移动的方向(WASD)
switch (this.direction) {
case "up":
{
newHead = new Block(oldHead.col, oldHead.row - 1, oldHead.size);
break;
}
case "down":
{
newHead = new Block(oldHead.col, oldHead.row + 1, oldHead.size);
break;
}
case "left":
{
newHead = new Block(oldHead.col - 1, oldHead.row, oldHead.size);
break;
}
case "right":
{
newHead = new Block(oldHead.col + 1, oldHead.row, oldHead.size);
break;
}
}
//新的头部放进数组的第一位
this.body.unshift(newHead);
//判断是否吃到食物
if (newHead.col == this.food.col && newHead.row == this.food.row) {
while (true) {
this.food.initFood();
//判断生成的食物是否在蛇的身体上
for (var i = 0; i < this.body.length; i++) {
if (this.food.col == this.body[i].col && this.food.row == this.body[i].row) {
//如果真的在蛇身上,重新生成食物
this.food.initFood();
}
}
//结束循环
break;
}
//吃一个加一分
score++;
} else {
//移除数组里的最后一个值
this.body.pop();
}
}
//碰撞检测
snakeDeath() {
//获取蛇头
let snakeHead = this.body[0];
//判断是否碰壁
if (snakeHead.col < 0 || snakeHead.col > 59 || snakeHead.row < 0 || snakeHead.row > 59) {
alert("你无了.");
//重新开始游戏
score = 0;
this.body = [new Block(20, 20, 10), new Block(20, 21, 10), new Block(20, 22, 10)];
}
//判断蛇头是否碰到自己
for (let i = 1; i < this.body.length; i++) {
if (snakeHead.col == this.body[i].col && snakeHead.row == this.body[i].row) {
alert("游戏结束!");
//重新开始游戏
score = 0;
this.body = [new Block(20, 20, 10), new Block(20, 21, 10), new Block(20, 22, 10)];
}
}
}
}
let food = new Food();
let snake = new Snake(food);
//开始游戏
var count = 0;
startGame();
function startGame(argument) {
count++;
pen.clearRect(0, 0, canvasE.width, canvasE.height);
//绘制分数
pen.font = "normal 30px 黑体";
pen.fillText("分数" + score, 10, 40);;
snake.draw();
food.draw();
snake.snakeDeath();
if (count == 3) {
snake.move();
count = 0;
}
requestAnimationFrame(startGame);
}
//绑定键盘事件
window.onkeydown = function(e) {
var even = e || event;
switch (even.keyCode) {
case 65:
{
//左
if (snake.direction != "right") {
snake.direction = "left";
}
break;
}
case 87:
{
//上
if (snake.direction != "down") {
snake.direction = "up";
}
break;
}
case 68:
{
//右
if (snake.direction != "left") {
snake.direction = "right";
}
break;
}
case 83:
{
//下
if (snake.direction != "up") {
snake.direction = "down";
}
break;
}
}
}
</script>
</body>
</html>