几点注意事项:
① 当将页面中某个对象存入数组时,对数组进行操作相当于对DOM元素操作。
② 移除页面上的某一个元素的两种方法:1) 父对象.removeChild(移除对象) 2)对象.remove()
③select对象.selectedIndx
为当前选中元素的索引。select对象.selectedOptions
为当前选中元素
④ 当移除select
标签的被选中的元素时:select对象.remove(select对象.selectedIndex)
⑤父元素对象.removeChild(移除对象)
:以 Node 对象返回被删除的节点,如果节点不存在则返回 null。
⑥对象.remove()
:jQuery方法。返回一个指向已被删除的节点的引用,这个节点元素还可以使用;该方法也会移除被选元素的数据和事件。如需移除元素,但保留数据和事件,请使用 detach() 方法代替。如只需从被选元素移除内容,请使用 empty() 方法。
简易版贪吃蛇
功能:蛇可穿墙,只能撞自己死亡。蛇在吃一个食物后得分会加一。创建的食物必须要在蛇身外部出现,食物的位置不可和蛇身任何一个位置相同。
1. 创建map:使用动态原型模式,只有当instance=null
时才创建map对象。最终将map加给body(document.body.appendChild(地图对象))
注意:将map设为绝对定位,无论是蛇还是食物都作为绝对定位在map中。
var getMap = (function getMap(){
var instance = null;
function map(){
var divele = document.createElement("div");
divele.style.width="900px";
divele.style.height="600px";
divele.style.backgroundColor="black";
divele.style.position="relative";
divele.className="map";
document.body.appendChild(divele);
}
return function () {
if(instance==null){
instance = new map();
}
return instance;
}
})();
2. 蛇对象
① 创建蛇身:createSnack方法
this.createSnack = function(ele) {
var spanEle = document.createElement("span");
spanEle.style.width="30px";
spanEle.style.height="30px";
spanEle.style.backgroundColor=ele[2];
spanEle.style.position="absolute";
spanEle.style.left=ele[0]*30+"px";
spanEle.style.top = ele[1]*30+"px";
return spanEle;
};
② getSnack方法
init数组中存储所有蛇身对象。初始时
init[i][3]
都为null,且数组长度为3(默认有三个蛇身对象)。初始时调用该方法,创建初始三个蛇身,并将其将入map
元素。之后在每次吃完食物后调用该方法,增加蛇身长度,并将其将入map
元素。
this.getSnack=function(){
for(var i=0;i<init.length;i++){
if(init[i][3]==null){
init[i][3] = this.createSnack(init[i]);
map.appendChild(init[i][3]);
}
}
};
③ 蛇移动方法:move
① 在蛇移动过程中,每个蛇身对象都取前一个对象的定位位置(即x,y值),蛇头根据当前移动方向来决定位置。
② 在蛇移动过程中,要注意蛇穿墙的情况,当当前蛇头x>30
时,设置x=0
。当前蛇头x<0
,设置x=29
(注意:此处只是init中每个对象的x和y改变,还并未改变位置),纵轴同理。
③ 在蛇移动过程中,如果蛇头的位置和蛇身任何一个对象的位置相同,则清除移动计时器,并提示游戏失败。(注意:此处只是init中每个对象的x和y改变,并未改变位置)游戏失败后直接return。
this.move = function () {
for(var i=init.length-1;i>0;i--){
init[i][0] = init[i-1][0];
init[i][1] = init[i-1][1];
}
//转换方向
switch (direction) {
case "left":
init[0][0]--;
break;
case "right":
init[0][0]++;
break;
case "up":
init[0][1]--;
break;
case "down":
init[0][1]++;
break;
}
//蛇穿墙
if(init[0][0]>=30){
init[0][0]=0;
}
if(init[0][0]<0){
init[0][0]=29;
}
if(init[0][1]>=20){
init[0][1]=0;
}
if(init[0][1]<0){
init[0][1]=19
}
for(var j=1;j<init.length;j++){
if(init[j][0]==init[0][0] && init[j][1]==init[0][1]){
clearInterval(timer);
alert("Game over!!!你最后的得分为"+count);
return;
}
}
this.setPostion();
this.eat();
complete[1] = true;
}
④ 设置蛇的位置:setPosition方法
当
init
数组变化时,DOM元素并未发生变化,故需要重新设置每一个对象的位置。将所有的位置提取成一个函数设置是因为:当蛇撞到自身时,要先判断init[0]
是否与蛇身对象位置相同,而不能在位置变化后再判断(会出现在撞到自身后继续向前移动的情况)
this.setPostion = function () {
for(var i=0;i<init.length;i++){//将所有位置提成一个函数写蛇头不会被盖住。(若先设置尾部,再设置头部,最后撞死时头部后面的元素已经取得了头部的位置,尽管头部未移动,但是头部后面的元素和头部叠加到了一起)
init[i][3].style.left=init[i][0]*30+"px";
init[i][3].style.top=init[i][1]*30+"px";
}
}
3. 创建食物:createFood方法
① 在创建食物时,要先移除已被吃掉的食物
map.removeChild(food[0])
(food数组中只有当前食物,故其长度最大为1)
② 在创建前应该先生成除蛇身位置以外的随机食物位置。此处应用一个while循环来判断。
③ 创建食物相关信息,并将食物加入map
对象中
function createFood(){
if(food.length==1){
map.removeChild(food[0]);
}
var randomX = this.getRandomX();
var randomY = this.getRandomY();
for(var i=0;i<init.length;i++)
while(randomX==init[i][0] && randomY==init[i][1]){
//判断是否食物位置与蛇的位置相同
randomX = this.getRandomX();
randomY = this.getRandomY();
i=-1;
break;
}
}
var spanEle = document.createElement("div");
foodPosition[0]=(randomX);//用foodPosition存储当前食物的位置,用来和蛇头位置作比较。若相同,则蛇吃食物
foodPosition[1]=(randomY);
spanEle.style.backgroundColor="green";
spanEle.style.width="30px";
spanEle.style.height="30px";
spanEle.style.position="absolute";
spanEle.className="food";
spanEle.style.left=randomX*30+"px";
spanEle.style.top=randomY*30+"px";
map.appendChild(spanEle);
}
4. 切换方向:body的onkeyup
事件
① 根据
key
来做限制,且存储当前方向direction
。若当前方向和即将变化的方向相反,则方向不改变,蛇依旧以当前的方向运动。若不相反,才可改变。
② 用complete
属性来判断上次移动是否完成,若complete[1]
为false,则上次移动未完成,不能进行下次移动(若当前蛇向上移动,当以很快的速度按下右下键时,会撞自己死亡:按下右键还未move便方向又变为向下。由于按了右键后方向向右,故是可以将方向改为向下的)
③ 当转变方向时,将complete[1]
值设为false。在当前方向下完成一次移动后,则将compelet[1]
变为true
。这样至少保证了蛇在该方向完成了一次移动。只有当compelet[1]
为true
时,蛇才可转变方向。
document.body.onkeyup = function (ev) {
var key = ev.key;
if(complete[0]!=key && complete[1]){
if(key=="ArrowUp"){
if(direction!="down"){
direction = "up";
}
}
else if(key=="ArrowDown"){
if(direction!="up" ){
direction="down";
}
}else if(key=="ArrowLeft"){
if(direction!="right" ){
direction="left";
}
}else{
if(direction!="left"){
direction="right";
}
}
complete = [key,false];
}
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
*{
margin:0;
padding:0;
}
.grade{
font-style: normal;
font-weight: bold;
color: red;
}
</style>
<body>
<span >
当前你的得分为:<i class="grade"></i>
</span>
<script>
var map;
var snackList;
var init = [[2,0,"red",null],[1,0,"yellow",null],[0,0,"yellow",null]];
var timer;
var food;
var count=0;
var foodPosition=[];
var direction="right";
var grade = document.getElementsByClassName("grade")[0];
grade.innerHTML = count;
var complete = ["ArrowRight",true];
var getMap = (function getMap(){
var instance = null;
function map(){
var divele = document.createElement("div");
divele.style.width="900px";
divele.style.height="600px";
divele.style.backgroundColor="black";
divele.style.position="relative";
divele.className="map";
document.body.appendChild(divele);
}
return function () {
if(instance==null){
instance = new map();
}
return instance;
}
})();
function snack(){
this.getSnack=function(){
for(var i=0;i<init.length;i++){
if(init[i][3]==null){
init[i][3] = this.createSnack(init[i]);
map.appendChild(init[i][3]);
}
}
};
this.createSnack = function(ele) {
var spanEle = document.createElement("span");
spanEle.style.width="30px";
spanEle.style.height="30px";
spanEle.style.backgroundColor=ele[2];
spanEle.style.position="absolute";
spanEle.style.left=ele[0]*30+"px";
spanEle.style.top = ele[1]*30+"px";
return spanEle;
};
this.eat = function () {
if(init[0][0]==foodPosition[0] && init[0][1] == foodPosition[1]){
foodPosition = [];
init[init.length]=[init[init.length-1][0],init[init.length-1][1],"yellow",null];
this.getSnack();
count++;
grade.innerHTML = count;
createFood();
}
};
this.setPostion = function () {
for(var i=0;i<init.length;i++){//将所有位置提成一个函数写蛇头不会被盖住。(若先设置尾部,再设置头部,最后撞死时头部后面的元素已经取得了头部的位置,尽管头部未移动,但是头部后面的元素和头部叠加到了一起)
init[i][3].style.left=init[i][0]*30+"px";
init[i][3].style.top=init[i][1]*30+"px";
}
}
this.move = function () {
for(var i=init.length-1;i>0;i--){
init[i][0] = init[i-1][0];
init[i][1] = init[i-1][1];
}
//转换方向
switch (direction) {
case "left":
init[0][0]--;
break;
case "right":
init[0][0]++;
break;
case "up":
init[0][1]--;
break;
case "down":
init[0][1]++;
break;
}
//蛇穿墙
if(init[0][0]>=30){
init[0][0]=0;
}
if(init[0][0]<0){
init[0][0]=29;
}
if(init[0][1]>=20){
init[0][1]=0;
}
if(init[0][1]<0){
init[0][1]=19
}
for(var j=1;j<init.length;j++){
if(init[j][0]==init[0][0] && init[j][1]==init[0][1]){
clearInterval(timer);
alert("Game over!!!你最后的得分为"+count);
return;
}
}
this.setPostion();
this.eat();
complete[1] = true;
}
}
//创造食物
function getRandomX() {
return Math.floor(Math.random()*30);
}
function getRandomY() {
return Math.floor(Math.random()*20);
}
function createFood(){
if(food.length==1){
map.removeChild(food[0]);
}
var randomX = this.getRandomX();
var randomY = this.getRandomY();
for(var i=0;i<init.length;i++){
while(randomX==init[i][0] && randomY==init[i][1]){
randomX = this.getRandomX();
randomY = this.getRandomY();
i=-1;
break;
}
}
var spanEle = document.createElement("div");
foodPosition[0]=(randomX);
foodPosition[1]=(randomY);
spanEle.style.backgroundColor="green";
spanEle.style.width="30px";
spanEle.style.height="30px";
spanEle.style.position="absolute";
spanEle.className="food";
spanEle.style.left=randomX*30+"px";
spanEle.style.top=randomY*30+"px";
map.appendChild(spanEle);
}
window.onload = function (ev) {
getMap();
map = document.getElementsByClassName("map")[0];
food = document.getElementsByClassName("food");
snackList = new snack();
snackList.getSnack();
timer = setInterval(function () {
snackList.move()
},250);
createFood();
document.body.onkeyup = function (ev) {
var key = ev.key;
if(complete[0]!=key && complete[1]){
if(key=="ArrowUp"){
if(direction!="down"){
direction = "up";
}
}
else if(key=="ArrowDown"){
if(direction!="up" ){
direction="down";
}
}else if(key=="ArrowLeft"){
if(direction!="right" ){
direction="left";
}
}else{
if(direction!="left"){
direction="right";
}
}
complete = [key,false];
}
}
}
</script>
</body>
</html>