前言

本课程是通过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贪吃蛇游戏实战开发笔记的更多相关文章

  1. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

  2. JS贪吃蛇游戏

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  3. Android快乐贪吃蛇游戏实战项目开发教程-02虚拟方向键(一)自定义控件概述

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.自定义控件简介 在本项目中,无论是游戏主区域还是虚拟方向键都是通过自定义控件 ...

  4. Android快乐贪吃蛇游戏实战项目开发教程-06虚拟方向键(五)绘制方向键箭头

    本系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html本系列教程项目源码GitHub地址:https://github.com/jack ...

  5. Android快乐贪吃蛇游戏实战项目开发教程-05虚拟方向键(四)四个三角形按钮

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.如何判断点击的是哪个方向键按钮 在上篇教程中我们实现了左边的三角形按钮效果, ...

  6. Android快乐贪吃蛇游戏实战项目开发教程-04虚拟方向键(三)三角形按钮效果

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.知识点讲解 当我们点击系统自带的按钮时,按钮的外观会发生变化.上篇博文中我们 ...

  7. Android快乐贪吃蛇游戏实战项目开发教程-03虚拟方向键(二)绘制一个三角形

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.绘制三角形 在上一篇文章中,我们已经新建了虚拟方向键的自定义控件Direct ...

  8. 原生js贪吃蛇

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="u ...

  9. 一个原生JS实现的不太成熟的贪吃蛇游戏

    一个初初初初级前端民工 主要是记录一下写过的东西,复习用 大佬们如果看到代码哪里不符合规范,或者有更好写法的,欢迎各位批评指正 十分感谢 实现一个贪吃蛇游戏需要几步? 1.有地图 2.有蛇 3.有食物 ...

随机推荐

  1. HDU - 1962 二分图最大匹配模板(扑克牌得分最大)

    题意: 直接说数据,第一行给定几组数据,每一组数据的第一行是两个人扑克牌分别的数量,第一行是亚当的扑克牌,第二行是夏娃的扑克牌,每一个扑克牌的大小用两个字符来表示,第一个表示是几号扑克牌,第二个表示扑 ...

  2. 模块 序列化 json pickle shelv xml

    序列化 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes. json 模块 json.dump(d,f) json.load(f ...

  3. 使用 Visual Studio 开发、测试和部署 Azure Functions(二)测试,部署

    1,引言 上一篇介绍了使用使用 Visual Studio 开发 "Azure Functions" 函数,此篇介绍 “Azure Functions” 的测试以及直接从 Vist ...

  4. 使用 Visual Studio 开发、测试和部署 Azure Functions(一)开发

    1,什么是Azure functions Azure Functions 是 Microsoft Azure 提供的完全托管的 PaaS 服务,用于实现无服务器体系结构. Azure Function ...

  5. 《Three.js 入门指南》3.1.2 - 一份整齐的代码结构以及使用ORBIT CONTROLS插件(轨道控制)实现模型控制

    3.1.2 正式代码结构 & ORBIT CONTROLS插件(轨道控制) 说明 本节内容属于插入节,<Three.js入门指南>这本书中,只是简单的介绍了一些概念,是一本基础的入 ...

  6. 深入理解== 和 equals 的本质区别

    简介 初学者常常被"= =“和‘equals ’所折磨,为什么,因为他们的大概意思相同,都是比较两个对象是否相等,而又不搞不清他们的具体比较两个对象相等的原理是什么,所以经常搞混淆,接下来我 ...

  7. 37 net 网络编程

    InetAddress:此类表示互联网协议 (IP) 地址. Stringbuilder getHostAddress() 返回 IP 地址. Stringbuilder getHostName() ...

  8. bit/byte/ascii/unicode

    bit(位).byte(字节).ASCII.Unicode 和 UTF-8位和字节的关系bit 电脑记忆体中最小的单位,在二进位电脑系统中,每一bit 可以代表0 或 1 的数位讯号byte一个byt ...

  9. String 对象-->fromCharCode() 方法

    1.定义和用法 将ASCII码转换成对应的字符 语法: String.fromCharCode(n1, n2, ..., nX) 参数: n1, n2, ..., nX:一个或多个 Unicode 值 ...

  10. python3(十一)generator

    # 只要把一个列表生成式的[]改成() L = [x * x for x in range(10)] print(L) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] g ...