原生Js贪吃蛇游戏实战开发笔记
前言
本课程是通过JavaScript结合WebAPI DOM实现的一版网页游戏---贪吃蛇的开发全过程,采用面向以象的思想设计开发。通过这个小游戏的开发, 不仅可以掌握JS的语法的应用,还可以学会DOM的使用, 更重要的是可以学习程序开发的业务逻辑,和项目开发过程,以及一些常用的游戏算法。
代码和课程来源:https://www.bilibili.com/video/BV1aE411K7Ga?from=search&seid=11376138008125697092
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>贪吃蛇桌面版小游戏</title>
<link rel="icon" href="https://www.meitubk.com/my/avator.jpg" type="image/x-icon"/>
<style type="text/css">
body{margin: 0; padding: 0;}
div#main{margin: 40px;}
input.btn{width: 100px;height: 40px;}
span.gtitle{font-size: 25px;font-weight: bold;}
span#gnum, span#glen, span#gspeed{color:red}
</style>
</head>
<body>
<div id="main">
<h1>贪吃蛇桌面版 -- 需 <span id="glen">1</span> 节 -- 第 <span id="gnum">1</span> 关 -- 速度间隔 <span id="gspeed">1</span></h1>
<input class="btn" type="button" value="开始游戏" id="begin"/>
<input class="btn" type="button" value="暂停游戏" id="pause"/>
<input class="btn" type="button" value="我的博客" id="myblog"/>
<input class="btn" type="button" value="视频教程" id="video"/>
<script type="text/javascript">
var main = document.getElementById("main");
//是否开启画布格子
var showcanvas = false;
//地图对象构造方法
function Map(atom, xnum, ynum){
//原子、像素点
this.atom = atom;
//地图宽度
this.xnum = xnum;
//地图高度
this.ynum = ynum;
this.canvas = null;
//创建画布函数
this.create = function(){
this.canvas = document.createElement("div");
this.canvas.style.cssText = "position:absolute;top:170px;border:1px solid darkred;background:#FAFAFA;"
this.canvas.style.width = this.atom * this.xnum + 'px';
this.canvas.style.height = this.atom * this.ynum + 'px';
main.appendChild(this.canvas);
if(showcanvas){
for(var y=0; y<ynum; y++){
for(var x=0; x<xnum; x++){
var item = document.createElement("div");
item.style.cssText = "border:1px solid yellow;"
item.style.width = this.atom + 'px';
item.style.height = this.atom + 'px';
item.style.backgroundColor = "green";
this.canvas.appendChild(item);
item.style.position = "absolute";
item.style.left = x * this.atom + 'px';
item.style.top = y * this.atom + 'px';
}
}
}
}
}
//创建食物函数
function Food(map){
this.width = map.atom;
this.height = map.atom;
this.bgColor = "rgb("+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+")";
//食物放在第几格
this.x = Math.floor(Math.random() * map.xnum);
this.y = Math.floor(Math.random() * map.ynum);
//设置食物的样式
this.flag = document.createElement("div");
this.flag.style.width = this.width + 'px';
this.flag.style.height = this.height + 'px';
this.flag.style.backgroundColor = this.bgColor;
this.flag.style.position = "absolute";
this.flag.style.left = this.x * this.width + 'px';
this.flag.style.top = this.y * this.height + 'px';
map.canvas.appendChild(this.flag);
}
//创建蛇对象
function Snake(map){
//设置宽、高
this.width = map.atom;
this.height = map.atom;
//设置起始方向
this.direction = 'right';
this.body = [
{x: 2, y: 0}, //头
{x: 1, y: 0}, //身
{x: 0, y: 0} //尾
]
//显示蛇
this.display = function(){
for(var i=0;i < this.body.length; i++){
//当吃到食物时,要把x设置为null
if(this.body[i].x != null){
var item = document.createElement('div');
//将节点保存到一个状态变量中,以便以后删除使用
this.body[i].flag = item;
//设置蛇的样式
item.style.width = this.width + 'px';
item.style.height = this.height + 'px';
item.style.backgroundColor = "rgb("+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+","+Math.floor(Math.random()*200)+")";
item.style.position = "absolute";
item.style.left = this.body[i].x * this.width + 'px';
item.style.top = this.body[i].y * this.height + 'px';
map.canvas.appendChild(item);
}
}
}
//让蛇运动
this.run = function(){
for(var i=this.body.length-1; i>0 ; i--){
this.body[i].x = this.body[i-1].x;
this.body[i].y = this.body[i-1].y;
}
//判断方向
switch(this.direction){
case "left": this.body[0].x -= 1; break;
case "right": this.body[0].x += 1; break;
case "up": this.body[0].y -=1; break;
case "down": this.body[0].y += 1; break;
}
//判断蛇头吃到食物
if(this.body[0].x == food.x && this.body[0].y == food.y){
//蛇加一节,根据最后节点
this.body.push({x: null, y:null, flag: null});
//判断下一级别
if(this.body.length >= level.slength){
level.setlevel();
}
map.canvas.removeChild(food.flag);
food = new Food(map);
}
//判断是否出界
if(this.body[0].x < 0 || this.body[0].x > map.xnum - 1 || this.body[0].y < 0 || this.body[0].y > map.ynum - 1){
clearInterval(timer);
alert("真笨呀,活活的撞墙死掉了!");
//重新开始游戏
restart(map, this, level);
return false;
}
//判断是否吃到自己
for(var i=4; i<this.body.length;i++){
if(this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y){
alert("哎,把自己给咬死了!");
//重新开始游戏
restart(map, this, level);
return false;
}
}
for(var i=0; i < this.body.length; i++){
if(this.body[i].flag != null){
map.canvas.removeChild(this.body[i].flag);
}
}
this.display();
}
}
//重新开始游戏
function restart(map, snake, level){
for(var i=0; i<snake.body.length;i++){
map.canvas.removeChild(snake.body[i].flag);
}
snake.body = [
{x: 2, y: 0}, //头
{x: 1, y: 0}, //身
{x: 0, y: 0} //尾
]
snake.direction = 'right';
snake.display();
map.canvas.removeChild(food.flag);
food = new Food(map);
level.num = 1;
level.speed = 100;
level.slength = 6;
level = new Level();
level.display();
}
//设置级别对象
function Level(){
this.num = 1;
this.speed = 100;
this.slength = 6; //通过目标长度
this.setlevel = function(){
this.num++;
if(this.speed <= 20){
this.speed = 20;
}else{
this.speed -= 20;
}
this.slength += 3;
this.display();
start();
}
this.display = function(){
document.getElementById("gnum").innerHTML = this.num;
document.getElementById("gspeed").innerHTML = this.speed;
document.getElementById("glen").innerHTML = this.slength;
}
}
var level = new Level();
level.display();
var map = new Map(20, 40, 20);
map.create()
var food = new Food(map);
var snake = new Snake(map);
snake.display();
//键盘监听
window.onkeydown = function(e){
var event = e || window.event;
//上下左右
switch(event.keyCode){
case 38:
if(snake.direction != "down"){
snake.direction = "up";
}
break;
case 40:
if(snake.direction != "up"){
snake.direction = "down";
}
break;
case 37:
if(snake.direction != "right"){
snake.direction = "left";
}
break;
case 39:
if(snake.direction != "left"){
snake.direction = "right";
}
break;
}
}
function start(){
clearInterval(timer);
timer = setInterval(function(){
snake.run();
}, level.speed);
}
var timer;
document.getElementById('begin').onclick=function(){
start();
}
document.getElementById('pause').onclick=function(){
clearInterval(timer);
}
document.getElementById('myblog').onclick=function(){
location.href = "https://www.meitubk.com/";
}
document.getElementById('video').onclick=function(){
location.href = "https://www.bilibili.com/video/BV1aE411K7Ga";
}
</script>
</div>
</body>
</html>
预览
请访问 https://www.meitubk.com/my/demo2/
原生Js贪吃蛇游戏实战开发笔记的更多相关文章
- Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录
一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...
- JS贪吃蛇游戏
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- Android快乐贪吃蛇游戏实战项目开发教程-02虚拟方向键(一)自定义控件概述
该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.自定义控件简介 在本项目中,无论是游戏主区域还是虚拟方向键都是通过自定义控件 ...
- Android快乐贪吃蛇游戏实战项目开发教程-06虚拟方向键(五)绘制方向键箭头
本系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html本系列教程项目源码GitHub地址:https://github.com/jack ...
- Android快乐贪吃蛇游戏实战项目开发教程-05虚拟方向键(四)四个三角形按钮
该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.如何判断点击的是哪个方向键按钮 在上篇教程中我们实现了左边的三角形按钮效果, ...
- Android快乐贪吃蛇游戏实战项目开发教程-04虚拟方向键(三)三角形按钮效果
该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.知识点讲解 当我们点击系统自带的按钮时,按钮的外观会发生变化.上篇博文中我们 ...
- Android快乐贪吃蛇游戏实战项目开发教程-03虚拟方向键(二)绘制一个三角形
该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.绘制三角形 在上一篇文章中,我们已经新建了虚拟方向键的自定义控件Direct ...
- 原生js贪吃蛇
<!DOCTYPE html> <html> <head> <title></title> <meta charset="u ...
- 一个原生JS实现的不太成熟的贪吃蛇游戏
一个初初初初级前端民工 主要是记录一下写过的东西,复习用 大佬们如果看到代码哪里不符合规范,或者有更好写法的,欢迎各位批评指正 十分感谢 实现一个贪吃蛇游戏需要几步? 1.有地图 2.有蛇 3.有食物 ...
随机推荐
- Tensorboard 详解(上篇)
花间提壶华小厨 1. Tensorboard简介 对大部分人而言,深度神经网络就像一个黑盒子,其内部的组织.结构.以及其训练过程很难理清楚,这给深度神经网络原理的理解和工程化带来了很大的挑战.为了解决 ...
- SVM多核学习方法简介
作者:Walker SVM是机器学习有监督学习的一种方法,常用于解决分类问题,其基本原理是:在特征空间里寻找一个超平面,以最小的错分率把正负样本分开.因为SVM既能达到工业界的要求,机器学习研究者又能 ...
- 从零开始实现穿衣图像分割完整教程(附python代码演练)
时装业是人工智能领域很有前景的领域.研究人员可以开发具有一定实用价值的应用.我已经在这里展示了我对这个领域的兴趣,在那里我开发了一个来自Zalando在线商店的推荐和标记服装的解决方案. 在这篇文章中 ...
- MATLAB——时间,日期及显示格式
一.日期和时间 1.生成指定格式日期和时间 标准日期格式 2.获取当前时间的数值 >> datestr(now,) ans = -- :: >> datestr(now,'yy ...
- linux压缩及归档
一.解析 压缩:把大文件,通过压缩成一个比之前小的文件. 归档(打包):把多个文件,归档成一个文件. 二.压缩 1.zip(归档压缩,可以压缩目录,要保存源文件) 压缩:zip 压缩后的文件名 压缩 ...
- CentOS 编译安装 Emacs 并配置
Linux 中 CentOS 系列一向以稳定为目标,然而也会存在版本太旧的问题,Emacs 就是其中的一个,目前 Emacs 都发行到 25.2 了,而 CentOS 上的 Emacs 版本却还是 2 ...
- ThinkPHP6.0学习笔记-模型操作
ThinkPHP模型 模型定义 在app目录下创建Model目录,即可创建模型文件 定义一个和数据库表相匹配的模型 use think\Model; class User extends Model ...
- python 终端带颜色的打印文本
import sys from termcolor import colored, cprint text = colored('Hello, World!', 'red', attrs=['reve ...
- 并发——深入分析CountDownLatch的实现原理
一.前言 最近在研究java.util.concurrent包下的一些的常用类,之前写了AQS.ReentrantLock.ArrayBlockingQueue以及LinkedBlockingQu ...
- 数据科学 R语言速成
文章更新于:2020-03-07 按照惯例,需要的文件附上链接放在文首: 文件名:R-3.6.2-win.exe 文件大小:82.4M 下载链接:https://www.lanzous.com/i9c ...