原生javascript开发仿微信打飞机小游戏-程序员宅基地

技术标签: ViewUI  游戏  javascript  xhtml  

今天闲来无事,于是就打算教一个初学javascript的女童鞋写点东西,因此为了兼顾趣味性与简易程度,果断想到了微信的打飞机小游戏。。

本来想用html5做的,但是毕竟人家才初学,连jquery都还不会,所以最终还是决定用原生的javascript。虽说相对于园内的高手们而言代码算不上优雅,效率算不上高,不过对于初学者来练手还是足以。。

 

   三个文件,main.js(主函数),entity.js(实体类与工厂类),util.js(工具类),基本原理就是把位置信息保存在对象里面,然后在setInterval里面统一对所有对象进行更新显示。程序所用到的飞机与子弹图片都是从微信上截屏得来的。

 

先上图:

 

再上代码:

index.html:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>打飞机</title>
<script type="text/javascript" src="js/util.js"></script>
<script type="text/javascript" src="js/entity.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script type="text/javascript">
window.onload=function(){
 Main.init();
 Util.g("startBtn").onclick=function(){
  Main.start();
  this.style.display="none";
 }
}
</script>
</head>
<body>
<div id="parent" style="
        margin: 0 auto; 
        width:350px; height:480px; 
        background-color:#c3c9c9; 
        position: relative;
        overflow:hidden;">
 <div style="
     position:absolute;
        left:5px;
        top:5px;">积分:<span id="score">0</span></div>
    <button 
     style=" 
      position:absolute; 
         left:150px;
            top:240px;
            display:block;" 
        id="startBtn">
    点击开始
    </button>
</div>
</body>
</html>

main.js:

 // JavaScript Document
var Main={
 init:function(){
  Util.init();
 },
 _totalEnemies:8,
 start:function(){
  //初始化敌机
  enemyPlaneFactory.creatEnemyPlane(this._totalEnemies);
  
  //初始化自己
  selfPlane.init();
  
  //初始化子弹
  bulletFactory.creatBullet(100);
  //开始渲染画面
  this._render();
  //开始射击子弹
  this._startShoot();
  
  //初始化键盘事件响应
  this._initEvent();
 },
 
 //渲染定时器
 _render_t:null,
 _render:function(){
  this._render_t=setInterval(function(){
   //渲染敌机
   var enemys=enemyPlaneFactory.enemys;
   for(var i in enemys){
    var enemy=enemys[i];
    enemy.move(0,enemy.speed);
    
    //判断自己是否被敌机击中
    if(enemy.x+enemy.e.width>selfPlane.x+10
     &&enemy.x<selfPlane.x+selfPlane.e.width-10
     &&enemy.y+enemy.e.height>selfPlane.y+selfPlane.e.height/2
     &&enemy.y<selfPlane.y+selfPlane.e.height-40){
      enemy.isDied=true;
      clearInterval(Main._render_t);
      clearInterval(Main._startShoot_t);
      var b=window.confirm("对不起,您已经挂了,是否重玩?")
      if(b){
       window.location.reload();
      }
    }
    
    //判断敌机是否已经消失或者已死
    if(enemy.y>Util.windowHeight||enemy.isDied){
     enemy.restore();
    }
   }
   
   //渲染子弹
   var bullets=bulletFactory.bullets;
   for(var i in bullets){
    var bullet=bullets[i];
    bullet.move(0,-bullet.speed);
    
    for(var i in enemys){
     var enemy=enemys[i];
     //判断子弹是否击中敌机,如果击中则隐藏子弹,杀死敌机,增加积分..
     if(bullet.y>10
      &&bullet.x>enemy.x
      &&bullet.x<enemy.x+enemy.e.width
      &&bullet.y<enemy.y+enemy.e.height){
       enemy.isDied=true;
       bullet.moveTo(0,-bullet.e.height);
       selfPlane.score+=50;
       Util.scoreSpan.innerHTML=selfPlane.score+"";
     }
    }
   }
   
   
  },1000/15);
 },
 //射击定时器
 _startShoot_t:null,
 _startShoot:function(){
  var i=0;
  var bullets=bulletFactory.bullets;
  var bulletsCount=bullets.length;
  this._startShoot_t=setInterval(function(){
   if(i>=bulletsCount){
    i=0;
   }
   var bullet=bullets[i];
   bullet.moveTo(selfPlane.x+selfPlane.e.width/2-bullet.e.width/2,selfPlane.y-bullet.e.height-3);
   i++;
  },300);
 },
 keyMove:10,
 _initEvent:function(){
  window.onkeydown=function(e){
   /*
   37:左
   38:上
   39:右
   40:下
   */
   var keynum;
   var left=37,up=38,right=39,down=40;
   if(window.event){// IE
     keynum = window.event.keyCode;
   }else if(e.which) {// Netscape/Firefox/Opera
     keynum = e.which
   }
   
   switch(keynum){
    case left:
    selfPlane.move(-Main.keyMove,0);
    break;
    case up:
    selfPlane.move(0,-Main.keyMove);
    break;
    case right:
    selfPlane.move(Main.keyMove,0);
    break;
    case down:
    selfPlane.move(0,Main.keyMove);
    break;
    
    default:
    break;
   }
   
   //console.log(keynum);
  }
  
 }
 
 
}

entity.js:

 //自身的对象
var selfPlane={
 x:0,
 y:0,
 score:0,
 e:null,
 init:function(){
  this.x=(Util.windowWidth-Util.selfPlaneElement.width)/2;//相对于父窗体的x偏移(css:left)
  this.y=Util.windowHeight-Util.selfPlaneElement.height;//相对于父窗体的y偏移(css:top)
  this.e=Util.selfPlaneElement;//对应的dom元素
  Util.selfPlaneElement.style.left=this.x+"px";
  Util.selfPlaneElement.style.top=this.y+"px";
  Util.parentElement.appendChild(this.e);
 },
 move:function(moveX,moveY){
  var x=this.x+moveX;
  var y=this.y+moveY;
  
  if(x<0-this.e.width/2||x>Util.windowWidth-this.e.width/2){
   return ;
  }
  if(y<0-this.e.height/2||y>Util.windowHeight-this.e.height/2){
   return ;
  }
  this.x=x;
  this.y=y;
  
  this.e.style.left=this.x+"px";
  this.e.style.top=this.y+"px";
 },
 moveTo:function(x,y){
  
  if(x<0-this.e.width/2||x>Util.windowWidth-this.e.width/2){
   return ;
  }
  if(y<0-this.e.height/2||y>Util.windowHeight-this.e.height/2){
   return ;
  }
  this.x=x;
  this.y=y;
  
  this.e.style.left=this.x+"px";
  this.e.style.top=this.y+"px";
 }
}

//敌机的类
var enemyPlane=function(x,y,speed){
 this.x=x;
 this.y=y;
 this.e=Util.enemyPlaneElement.cloneNode(true);
 this.e.style.left=x;
 this.e.style.top=y;
 this.e.style.display="none";
 Util.parentElement.appendChild(this.e);
 this.e.style.display="block";
 this.speed=speed;
 this.isDied=false;
}
//prototype:原型
enemyPlane.prototype.move=function(moveX,moveY){
 this.x+=moveX;
 this.y+=moveY;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}
//敌人复活
enemyPlane.prototype.restore=function(){
 this.x=Math.random()*(Util.windowWidth-Util.enemyPlaneElement.width);
 this.y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
 this.speed=2+Math.random()*4;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
 this.isDied=false;
}
//敌机工厂
var enemyPlaneFactory={
 enemys:[],
 creatEnemyPlane:function(n){
  for(var i=0;i<n;i++){
   //0~1 乘以窗口宽度,得到的就是从0~窗口宽度的一个随机x值
   var x=Math.random()*(Util.windowWidth-Util.enemyPlaneElement.width);
   var y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
   var speed=2+Math.random()*4;
   var ep=new enemyPlane(x,y,speed);
   this.enemys.push(ep);
  }
 }
}
//子弹
var bullet=function(x,y,speed){
 this.x=x;
 this.y=y;
 this.speed=speed;
 this.e=Util.bulletElement.cloneNode(true);
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
 Util.parentElement.appendChild(this.e);
 this.isUsed=false;
}
bullet.prototype.move=function(moveX,moveY){
 this.x+=moveX;
 this.y+=moveY;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}
bullet.prototype.moveTo=function(X,Y){
 this.x=X;
 this.y=Y;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}

//子弹恢复
bullet.prototype.restore=function(){
 this.x=Main.self
 this.y=-Math.random()*Util.windowHeight-Util.enemyPlaneElement.height;
 this.speed=2+Math.random()*4;
 this.e.style.left=this.x+"px";
 this.e.style.top=this.y+"px";
}
//子弹工厂
var bulletFactory={
 bullets:[],
 creatBullet:function(n){
  for(var i=0;i<n;i++){
   var b=new bullet(0,-Util.bulletElement.height,20);
   this.bullets.push(b);
  }
 }
}

util.js:

 // JavaScript Document
var Util={
 windowWidth:350,
 windowHeight:480,
 selfPlaneElement:null,
 enemyPlaneElement:null,
 bulletElement:null,
 parentElement:null,
 scoreSpan:null,
 g:function(id){
  return document.getElementById(id);
 },
 
 init:function(){
  this.parentElement=this.g("parent");
  //http://sandbox.runjs.cn/uploads/rs/222/crfsjcjp/boss.gif
  this.selfPlaneElement=this._loadImg("images/self.gif");
  
  this.enemyPlaneElement=this._loadImg("images/boss.gif");
  
  this.bulletElement=this._loadImg("images/bullet.jpg");
  
  this.scoreSpan=this.g("score");
 },
 
 _loadImg:function(src){
  var e=document.createElement("img");
  e.style.position="absolute";
  e.src=src;
  return e;
 }
}

 在线预览:预览

源码下载地址:打飞机小游戏原生javascript版

转载于:https://my.oschina.net/ZaneYoung/blog/197265

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34365635/article/details/92040755

智能推荐

C# System.ArgumentException “参数无效“ 的详细解决方法(图文)-程序员宅基地

文章浏览阅读2.6w次,点赞3次,收藏14次。情况:解决方法:_system.argumentexception

Hive分桶概念_hive分桶的概念及作用-程序员宅基地

文章浏览阅读1.5k次。相较于分区,分桶的粒度更小,而且与分区不同的是,分区是人为设定分区字段建立一个用于管理的“伪列”,而分桶是按照某列的属性值的Hash计算结果进行区分。_hive分桶的概念及作用

灰度发布专题---3、Nginx+Lua灰度发布_lua结合nginx 灰度发布-程序员宅基地

文章浏览阅读1.7k次,点赞25次,收藏13次。上一章已经讲解了配置文件灰度发布、应用版本灰度发布、API网关灰度发布实现,但如果用户这时候在代理层如何做灰度发布呢?_lua结合nginx 灰度发布

Java 正则表达式 短横线"-"转义_正则表达式短横线-程序员宅基地

文章浏览阅读8.2k次,点赞2次,收藏5次。过滤特殊字符的正则如下: /** * 过滤特殊字符串正则(含中英文字符) */ public static final String STR_SPECIAL = "[`~!@#$%^&amp;*()_+=|{}':;'\",\\[\\].&lt;&gt;/?·~!@#¥%……&amp;*()——+|{}《》【】‘;:”“’。,、?]";可以发现上面的字符中..._正则表达式短横线

数字货币支付和电子支付一样吗?-程序员宅基地

文章浏览阅读1.2k次。数字货币支付和电子支付一样吗?相信大多数人都知道数字货币和电子支付说的不是一回事儿,但其实还是会有人把两者搞混。看完下面这篇文章,你就明白二者的区别到底在哪里了。相信大家应该还记得,大约是在两年前,我国央行召开了一场关于数字货币的研讨会,这次研讨会可以看成是我国数字货币研发的起点。众所周知,数字货币和我们日常生活中见到的实体货币不一样,它是和密码学及互联网技术有关的新一代的货币。于是我们要问,数..._电子货币和电子支付工具可以等同吗?

hadoop05-HDFS的api操作_hdfs api 操作 centos hadoop-程序员宅基地

文章浏览阅读195次。环境配置eclipse配置hdfs的环境hadoop的插件hadoop-eclipse-plugin,放在eclipse的安装目录的plugins下配置本地hadoop的环境解压hadoop安装包配置windows下hadoop的环境变量 新建:HADOOP_HOME=hadoop的解压路径,我的是:HADOOP_HOME=C:\soft\hadoop-2.7.6..._hdfs api 操作 centos hadoop

随便推点

excel 瀵煎叆mysql,src/czy/Score.java · 陈志杨/personal - Gitee.com-程序员宅基地

文章浏览阅读61次。package czy;import java.util.regex.Matcher;import java.util.regex.Pattern;import org.jsoup.*;import org.jsoup.nodes.*;import org.jsoup.select.Elements;import java.io.File;import java.io.FileInputStrea...

iMindMap12如何利用思维导图学习C语言的数组经验分享_imindmap12序列号-程序员宅基地

文章浏览阅读332次。C语言是一门非常基础的编程语言,学习它的难点不在于语言的理解,而在于繁琐的记忆点,而当我们使用思维导图将细碎的知识点拉到框架中去后,C语言的难度就大大降低了。接下来就为大家介绍一下我使用iMindMap制作的用来树立C语言数组相关知识的思维导图。一、一维数组1.定义和举例数组是一种C语言中聚合类的语言,其中包含的元素类型相同、个数确定。一维数组就是元素一个接一个地排列在一行内,格式定义为“类型定义符数组名[常量表达式]”,这里的“常量表达式”用来示意数组的元素个数,可以是常数也可以是表达式。举一_imindmap12序列号

Java缓存简介-程序员宅基地

文章浏览阅读762次,点赞17次,收藏24次。Java 缓存

struct sockaddr_in, struct sockaddr,struct in_addr_client_len = sizeof(struct sockaddr_in);-程序员宅基地

文章浏览阅读1.9k次。一、结构体 struct sockaddr_in, struct sockaddr, struct in_addrstruct sockaddr_in, struct sockaddr,struct in_addr,这是网络编程中常用的结构体,每次都记不住它们各自的成员是啥,需要临时查,为方便以后的查看,在这里总结下。struct sockaddr {unsigned short sa_family; /* 地址族, AF_xxx */

屏幕录像软件camtasia2022汉化版好用的录屏软件_录屏ca-程序员宅基地

文章浏览阅读1.4k次。TechSmith Camtasia Studio是由美国TechSmith公司出品的一款简单实用,功能强大的屏幕录像和编辑的软件套装应用。它不仅能在任何颜色模式下轻松地记录屏幕动作,包括影像、音效、鼠标移动的轨迹,解说声音等等。_录屏ca

如何讲解自己开发的程序_如何说程序是自己写的-程序员宅基地

文章浏览阅读2.2k次。在很多人的潜意识里,程序员就是一群口头表达能力欠缺的技术人。作为程序员,我们必须用实际行动去反驳。首先我们得学会展示自己的工作,自己开发出一个软件,要怎样想其他人进行讲解,偶然看到这么一篇文章,觉得非常不错,转载之,顺便附上自己的一些阅读笔记。采用PPT展示自己的软件采用以下思路做ppt分享:   1、首先预估好分享用的时间,一开始就要告诉自己时间有限,_如何说程序是自己写的

推荐文章

热门文章

相关标签