前言

本课程是通过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. Soldier and Number Game CodeForces - 546D 素因子数打表(素数筛的改造)

    题意: 输入 a 和 b(a>b),求a! / b!的结果最多能被第二个士兵给的数字除多少次. 思路: a! / b!肯定能把b!约分掉,只留下b+1~a的数字相乘,所以我们求b+1 ~ a的所 ...

  2. 初步进入linux世界

    [Linux 系统启动过程] Linux的启动其实和windows的启动过程很类似,不过windows我们是无法看到启动信息的,而linux启动时我们会看到许多启动信息,例如某个服务是否启动. Lin ...

  3. 干净直接安装+PS下载

    PS CS6 https://www.cr173.com/soft/247727.html 直接一键安装,很方便干净. 不要去华军软件下,广告浪费时间. 链接:https://pan.baidu.co ...

  4. 将java中Map对象转为有相同属性的类对象(json作为中间转换)

    java中Map对象转为有相同属性的类对象(json作为中间转换) 准备好json转换工具类 public class JsonUtil { private static ObjectMapper o ...

  5. markdown怎么上传图片

    将图片转为base64格式 , 在线转换地址link 语法格式 // 方式1 ![picture](base64密钥) // 方式2 ![picture][img] [img]:base64密钥

  6. react axios 跨域访问一个或多个域名

    1.react + axios 跨域访问一个域名 配置非常简单,只需要在当前的 package.json 文件里面配置: "proxy":"http://iot-demo ...

  7. PTA | 1020. 月饼 (25)

    月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样 ...

  8. python工业互联网监控项目实战2—OPC

    OPC(OLE for Process Control)定义:指为了给工业控制系统应用程序之间的通信建立一个接口标准,在工业控制设备与控制软件之间建立统一的数据存取规范.它给工业控制领域提供了一种标准 ...

  9. 34.1 字符流-- FileRead FileWrite

    一次读取一个字符 FileReader fr = new FileReader("aa.txt"); // System.out.println(fr.read()); // Sy ...

  10. Js异步机制的实现

    Js异步机制 JavaScript是一门单线程语言,所谓单线程,就是指一次只能完成一件任务,如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推.这种模式的好处是实现起来比较简单 ...