JS实现——贪吃蛇
把以下代码保存成Snake.html文件,使用Google或360浏览器打开
<!DOCTYPE HTML>
<html> <head>
<meta charset="utf-8" />
<title>Snake</title>
<style>
</style>
</head> <body>
<div style="position: relative"> <div style="width: 400px; font-size: 22px; border: 3px solid black;">
分数:<span id="score"></span>
</div> <canvas id="myCanvas">your browser does not support the canvas</canvas> <div id="help" style="position: absolute; left: 420px; top: 40px;">
Esc: 重新开始</br>
Enter: 开始/暂停/继续</br>
方向键: 改变蛇的移动方向</br>
Ctrl: 切换控制模式(影响手感)</br>
数字1: 加速</br>
数字2: 减速</br>
</div> <div id="gameStates" style="position: absolute; left: 420px; top: 200px; color: red">
控制模式: <span id="controlMode"></span></br>
运动状态: <span id="pause"></span></br>
蛇的方向: <span id="snakeDir"></span></br>
蛇的速度: <span id="snakeSpeed"></span></br>
蛇的长度: <span id="snakeLength"></span></br>
<span id="info"></span>
</div> </div>
</body> <script type="text/javascript">
/*
By Problue,2015.10.15
*/
var KEY_L = 37;
var KEY_U = 38;
var KEY_R = 39;
var KEY_D = 40;
var KEY_RESET = 27
var KEY_PAUSE = 13;
var KEY_CHANGE_CONTROL_MODE = 17;
var KEY_INC_SPEED = 49;
var KEY_DEC_SPEED = 50;
var MAP_R = 20;
var MAP_C = 20;
var SNAKE_LENGTH_MAX = MAP_R * MAP_C;
var OBJ_SIZE = 20;
var OBJ = {
EMPTY: 0,
SNAKE_HEAD: 1,
SNAKE_BODY: 2,
SNAKE_TAIL: 3,
FOOD: 4,
STONE: 5
};
var colors = ['white', 'midnightblue', 'darkblue', 'mediumblue', 'midnightblue', 'dimgray']; var mapData = "\
00000000000000000000\
00000000000000000000\
00000000000000000000\
50000000500000055000\
00000000000000005000\
00055000000005500000\
00050000000000500000\
00000550000550000000\
00000500000050000000\
00000000000000000000\
00000000000000000000\
00000005000050000000\
00000005500550000000\
00000500000000500000\
00000550000005500000\
00050000000000000000\
00055000000000050005\
00000000000000000000\
00000000000000000000\
00000000000000000000"; var map = []; var snake = new Snake();
var food = new Point(0, 0);
//var time; var pause;
var over;
var controlQueueMode;
var controlQueue = new Queue();
var score; function Snake() {
this.nodes = [];
this.dir = 0;
this.msSpeed = 0;
} function Point(x, y) {
this.x = x;
this.y = y;
} Point.prototype.clone = function() {
return new Point(this.x, this.y);
} Point.prototype.equals = function(other) {
if(other === this)
return true;
if(!(other instanceof Point))
return false;
return this.x == other.x && this.y == other.y;
} function Queue() {
this.arr = [];
this.head = 0;
this.tail = 0;
} Queue.prototype.enQueue = function(elem) {
this.tail++;
this.arr[this.tail] = elem;
} Queue.prototype.deQueue = function() {
this.head++;
return this.arr[this.head];
} Queue.prototype.empty = function() {
return this.head >= this.tail;
} Queue.prototype.clear = function() {
this.arr.length = 0;
this.head = 0;
this.tail = 0;
} start(); function start() {
initGame();
initMap();
initSnake();
drawMap();
showGameStates();
updateScore();
drawSnake();
randFood();
drawObj(food, OBJ.FOOD);
} function initGame() {
canvas = document.getElementById('myCanvas');
cxt = canvas.getContext('2d');
canvas.width = MAP_C * OBJ_SIZE;
canvas.height = MAP_R * OBJ_SIZE;
canvas.style.border = '3px solid black';
document.onkeydown = keydown;
//time = +new Date;
pause = true;
over = 0;
controlQueueMode = true;
score = 0;
} function initMap() {
for(var r = 0; r < MAP_R; r++) {
map.push([]);
for(var c = 0; c < MAP_C; c++) {
var obj = mapData[r * MAP_C + c] - 0;
map[r][c] = obj;
}
}
} function initSnake() {
snake.nodes.length = 0;
snake.nodes.push(new Point(2, 0));
snake.nodes.push(new Point(1, 0));
snake.nodes.push(new Point(0, 0));
snake.dir = KEY_R;
snake.msSpeed = 150;
} function keydown(event) {
var key = window.event ? event.keyCode : event.which;
switch(key) {
case KEY_U:
if(snake.dir != KEY_D) {
snake.dir = key;
controlQueue.enQueue(snake.dir);
}
break;
case KEY_D:
if(snake.dir != KEY_U) {
snake.dir = key;
controlQueue.enQueue(snake.dir);
}
break;
case KEY_L:
if(snake.dir != KEY_R) {
snake.dir = key;
controlQueue.enQueue(snake.dir);
}
break;
case KEY_R:
if(snake.dir != KEY_L) {
snake.dir = key;
controlQueue.enQueue(snake.dir);
}
break;
case KEY_RESET:
start();
break;
case KEY_PAUSE:
pause = !pause;
if(!pause) {
controlQueue.clear();
move();
}
break;
case KEY_CHANGE_CONTROL_MODE:
controlQueueMode = !controlQueueMode;
controlQueue.clear();
break;
case KEY_INC_SPEED:
snake.msSpeed -= 10;
break;
case KEY_DEC_SPEED:
snake.msSpeed += 10;
break;
default: ;
}
showGameStates();
} function moveStep() {
showGameStates();
var newHead = snake.nodes[0].clone();
var oldTail = snake.nodes[snake.nodes.length - 1].clone(); switch(snake.dir) {
case KEY_U:
newHead.y--;
break;
case KEY_R:
newHead.x++;
break;
case KEY_L:
newHead.x--;
break;
case KEY_D:
newHead.y++;
break;
} var coord = '坐标(' + snake.nodes[0].x + ',' + snake.nodes[0].y + ')是';
info(coord + '空');
if((newHead.x > MAP_C - 1 || newHead.x < 0) ||
(newHead.y > MAP_R - 1 || newHead.y < 0)) {
info(coord + '墙壁');
over = 1;
return;
} if(isInSnake(newHead)) {
info(coord + '自己');
over = 2;
return;
} var thing = map[newHead.y][newHead.x]; if(thing == OBJ.STONE) {
info(coord + '石头');
over = 3;
return;
} if(thing == OBJ.FOOD) {
info(coord + '食物');
snake.nodes.push(new Point(0, 0));
map[newHead.y][newHead.x] = OBJ.EMPTY;
randFood();
drawObj(food, OBJ.FOOD);
updateScore();
showGameStates();
} for(var i = snake.nodes.length - 1; i >= 1; i--)
snake.nodes[i] = snake.nodes[i - 1].clone();
snake.nodes[0] = newHead;
drawObj(oldTail, OBJ.EMPTY);
drawSnake();
} function move() {
if(pause)
return; if(controlQueueMode && !controlQueue.empty())
snake.dir = controlQueue.deQueue(); moveStep(); if(over) {
over = 0;
var turn = [];
turn[KEY_U] = KEY_R;
turn[KEY_D] = KEY_L;
turn[KEY_L] = KEY_U;
turn[KEY_R] = KEY_D;
snake.dir = turn[snake.dir];
} setTimeout(move, snake.msSpeed);
} function isInSnake(point) {
for(var i = 0; i < snake.nodes.length; i++)
if(snake.nodes[i].equals(point))
return true;
return false;
} function randFood() {
function randInt(n, m) {
return Math.floor(Math.random() * (m - n)) + n;
}
function smart(pt) {
if(pt.x == snake.nodes[0].x) {
if(snake.dir == KEY_U)
return pt.x - snake.nodes[0].x < 0;
if(snake.dir == KEY_D)
return pt.x - snake.nodes[0].x > 0;
}
if(pt.y == snake.nodes[0].y) {
if(snake.dir == KEY_L)
return pt.y - snake.nodes[0].y < 0;
if(snake.dir == KEY_R)
return pt.y - snake.nodes[0].y > 0;
}
return false;
}
do
{
food.x = randInt(0, MAP_C);
food.y = randInt(0, MAP_R);
} while(isInSnake(food) || smart(food) ||
map[food.y][food.x] != OBJ.EMPTY);
map[food.y][food.x] = OBJ.FOOD;
} function info(str) {
$('info').innerHTML = str;
} function showGameStates() {
$('pause').innerHTML = pause ? '静止' : '移动';
$('controlMode').innerHTML = controlQueueMode ? '队列' : '普通';
var toText = [];
toText[KEY_L] = '左';
toText[KEY_U] = '上';
toText[KEY_R] = '右';
toText[KEY_D] = '下';
$('snakeDir').innerHTML = toText[snake.dir];
$('snakeSpeed').innerHTML = snake.msSpeed + 'ms/' + OBJ_SIZE + 'px';
$('snakeLength').innerHTML = snake.nodes.length;
} function updateScore() {
$('score').innerHTML = score++;
} function drawMap() {
var pt = new Point(0, 0);
for(var r = 0; r < MAP_R; r++) {
for(var c = 0; c < MAP_C; c++) {
if(map[r][c] == OBJ.STONE) {
pt.x = c;
pt.y = r;
drawObj(pt, OBJ.STONE);
}
}
}
} function drawSnake() {
drawObj(snake.nodes[0], OBJ.SNAKE_HEAD);
for(var i = 1; i < snake.nodes.length - 1; i++)
drawObj(snake.nodes[i], OBJ.SNAKE_BODY);
drawObj(snake.nodes[snake.nodes.length - 1], OBJ.SNAKE_TAIL);
} function drawObj(point, type) {
cxt.fillStyle = colors[type];
cxt.fillRect(point.x * OBJ_SIZE, point.y * OBJ_SIZE,
OBJ_SIZE, OBJ_SIZE);
} function $(id) {
return document.getElementById(id);
}
</script> </html>
出处:qq群--编程算法&思想 459909287
JS实现——贪吃蛇的更多相关文章
- js版贪吃蛇
之前没有写博客的习惯,这是我的第一个博客,有些的不好的地方,希望大家多多提意见 js版的贪吃蛇相对比较简单,废话不多说直接上代码,有需要注意的地方我会标红,github源码地址https://gith ...
- 前端笔记之JavaScript面向对象(三)初识ES6&underscore.js&EChart.js&设计模式&贪吃蛇开发
一.ES6语法 ES6中对数组新增了几个函数:map().filter().reduce() ES5新增的forEach(). 都是一些语法糖. 1.1 forEach()遍历数组 forEach() ...
- JS仿贪吃蛇:一串跟着鼠标的Div
贪吃蛇是一款80后.90后比较熟悉的经典游戏,下面通过简单的JS代码来实现低仿版贪吃蛇效果:随着鼠标的移动,在页面中呈现所有Div块跟随鼠标依次移动,效果如下图所示. <!DOCTYPE htm ...
- 原生JS制作贪吃蛇小游戏
感情都在代码里,来,干了!... <!doctype html> <html> <head> <meta http-equiv="Content-T ...
- 用Js写贪吃蛇
使用Javascript做贪吃蛇小游戏, 1.自定义地图宽高,蛇的初始速度 2.食物随机出现 3.蛇的样式属性 4.贪吃蛇玩法(吃食物,碰到边界,吃食物后加速,计分,) <!DOCTYPE ht ...
- 用js实现贪吃蛇
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- OC版贪吃蛇
昨天写了一个js版贪吃蛇,今天突然想写一个OC版的,来对比一下两种语言的区别 oc版功能,适配所有尺寸iphone,可暂停,可设置地图和蛇的比例,可加速 对比一下会发现js版的相对OC版的会简单一些, ...
- 原生js写的贪吃蛇网页版游戏特效
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <bo ...
- 100行JS实现HTML5的3D贪吃蛇游戏
js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...
随机推荐
- Unity3d中3D Text对模型的穿透显示
昨晚,好友在电话里问我在Unity3d中使用3D Text,不想让其穿透模型显示,即想让场景中的3D Text与模型有正确的遮挡关系,怎么解? 今早谷歌上查了查,明白了原因,因为3D Text的默认材 ...
- Echarts的重点
官网中,主要看文档的”教程“和”配置项手册“这两部分 1 下载 引入js 页面放一个容器,一定要设宽高 创建对象:var myChart = echarts.init(document.getElem ...
- vue2.0:(七)、vue-resource
本篇文章开始前,先介绍下什么是vue-resource,并且现在还有一个axios. Vue.js是数据驱动的,这使得我们并不需要直接操作DOM,如果我们不需要使用jQuery的DOM选择器,就没有必 ...
- 《移动Web前端高效开发实战》笔记4--打造单页应用SPA
路由是一个单页应用的核心,大部分前端框架都实现了一个复杂的路由库,包括动态路由,路由钩子,组件生命周期甚至服务器端渲染等复杂的功能.但是对于前端开发者而言,路由组件的核心是URL路径到函数的映射,了解 ...
- ABAP自定义功能函数
1.实现计算器中阶乘函数 FUNCTION zfun_mm_001. *"---------------------------------------------------------- ...
- O2O创业团队,遇到生死悠关的问题,希望大家支招?
简单概括下情况:公司名下有两个内部创业团队,A团队成立3年以上,现在模式基本成熟稳定,有固定营收,但是还未收支平衡:B团队O2O项目,成立5个月左右,还处于萌芽阶段,技术+运营+市场共计9名成员,现总 ...
- 会写网页 就会写手机APP #2-- 范例修正 , Hybrid Mobile Apps for ASP.NET Developers (Apache Cordova)
原文出处:会写网页 就会写手机APP #2-- 范例修正 , Hybrid Mobile Apps for ASP.NET Developers (Apache Cordova) 这是我的文章备份 ...
- Android(java)学习笔记118:BroadcastReceiver之 外拨电话的广播接收者
1. 外拨电话的广播接收者: 首先我们示例工程一览表如下: (2)首先我们还是买一个收音机,定义一个OutCallReceiver继承自BroadcastReceiver,onReceive()方法中 ...
- 换个语言学一下 Golang (3)——数据类型
在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...
- 交叉熵cross entropy和相对熵(kl散度)
交叉熵可在神经网络(机器学习)中作为损失函数,p表示真实标记的分布,q则为训练后的模型的预测标记分布,交叉熵损失函数可以衡量真实分布p与当前训练得到的概率分布q有多么大的差异. 相对熵(relativ ...