在github里看到了个不错的脚本游戏,决定亲自动手来写,效果如下

下面是代码的思路分享

把整个代码理解消化确实不容易,但是如果你坚持看完相信你一定会有收获

如果没兴趣可以直接点击下面的链接 复制代码 开玩:

http://www.cnblogs.com/demonxian3/p/6241755.html

1丶首先准备好素材

游戏的元素有:飞机 敌机 子弹 背景 暂停

素材的大小可以通过drawImage()来改变其大小,因此不需要太纠结素材多少像素

创建一个html文件 和一个js文件

然后开始编辑该html文件

2.写一个画布:

  1. <canvas id="canvas" width=500 height=500 style="border:1px solid #c3c3c3"></canvas>

3.获取画布对象

  1. canvas = document.getElementById('canvas')
  2.  
  3. cxt = canvas.getContext('2d');

4.设置画布属性

  1. var boxx=0
  2.  
  3. var boxy=0
  4.  
  5. var boxwidth=500
  6.  
  7. var boxheight=500

**************************画飞机****************************

5.声明飞机相关的变量

飞机横坐标 纵坐标 宽度 高度 这些都是为下面的drawImage做准备的

  1. var planex;
  2.  
  3. var planey;
  4.  
  5. var planewidth=60;
  6.  
  7. var planeheight=60;
  8.  
  9. var planeImage = new Image();
  10.  
  11. planeImage.src="data:images/hero.jpg"; //引入图片

6.布置飞机初始位置

  1. planex = (boxwidth - planewidth) / 2 //画布的中央
  2.  
  3. planey = boxheight - planeheight     //画布的底端

因为这里的坐标(x,y)指的是飞机左上角的坐标,因此需要把飞机的长度算上

7.画出飞机

有了坐标和宽高就可以把飞机画出来了

  1. cxt.drawImage(planeImage,planex,planey,planewidth,planeheight);

现在可以打开网页测试下,看看飞机是否画出来了,

如果没有画出来,那么请别灰心,耐心的查一下有什么错误的地方

如果成功显示出飞机了那么go on!

飞机画出来了但是飞机不会动

那么怎么能让飞机动呢?

改变其坐标!

那么什么时候动呢?

按下键盘上的 ↑ ↓ ← → 键的时候

我们知道键盘有个事件驱动 onkeydown

而这个事件驱动有个属性keycode

用这个属性可以绑定上下左右键对应的函数

如下可以看到对应的keycode码

下面是四个我们需要的按键的对应码

左 : 37

上 : 38

右 : 39

下 : 40

光有事件驱动onkeydown还不够,我们还需要实时监听事件的发生

说的通俗点就是 你在任意时刻去按键盘 程序都能够及时响应

下面这个函数就可以帮我们实时监听事件

addEventListener()函数

语法

element.addEventListener(event, function, useCapture)
 
参数解释:
element    表示需要使用该方法的对象 
event        表示监听什么事件  
function    表示监听到事件后做出什么响应 
useCapture 表示在捕获或冒泡执行 默认为false 我们就按照默认来
 
 
声明一个运动跨度变量 这个变量的作用你马上就能看到了
  1. var sp=0;
 
8.监听body元素 响应事件
 
下面四个if语句用来判断飞机是否出界
 
  1. body.addEventListener('keydown',function (event){
  2. switch(event.keyCode){
  3. case 37 : if(planex>boxx){sp=8}else{sp=0}planex-=sp;break;
  4. case 38 : if(planey>boxy){sp=8}else{sp=0}planey-=sp;break;
  5. case 39 : if((planex+planewidth)<boxwidth){sp=8}else{sp=0}planex+=sp;break;
  6. case 40 : if((planey+planeheight)<boxheight){sp=8}else{sp=0}planey+=sp;break;
  7. default:break;
  8. }
  9. },false)

到这里 你可以测试一下飞机是否可以动起来了

当然我会直接告诉你结果----不能动!!

因为上面的事件监听改变的只是飞机的坐标,但是图片还在原地

为了让图片跟着坐标动起来,我们需要写一个函数

9.更新飞机图片位置函数

  1. function drawplane(){
  2.  
  3. cxt.clearRect(boxx,boxy,boxwidth,boxheight); //清除所有就元素
  4.  
  5. cxt.drawImage(planeImage,planex,planey,planewidth,planeheight);  //重新画出飞机
  6.  
  7. }
  8.  
  9. var fps                          //其实只是用来调飞机流畅度
  10.  
  11. var gameTimmer = setInterval (run,1000/fps);     //gameTimer是游戏的总驱动计时器
  12.  
  13. function run(){                    //drawplane函数自动运行
  14.  
  15. drawplane();                      
  16.  
  17. }

**************************画子弹****************************

10.设置子弹的相关变量 也是为drawImage函数的五个参数所做准备

  1. var bulletx;
  2.  
  3. var bullety;
  4.  
  5. var bulletwidth=10;
  6.  
  7. var bulletheight=10;
  8.  
  9. var bulletImage=new Image();
  10.  
  11. bulletImage.src="data:images/bullet.png"

11.存放子弹的弹夹-----数组

用数组来存放子弹方便我们访问每个子弹对象

  1. var herobullet; //用来表示单个子弹
  2.  
  3. var allbullets = new Array(); //用来表示所有子弹

12.设置子弹初始位置

我们希望 每颗子弹的起始位置是随着飞机而改变的 因此把飞机的变量引进来

  1. bulletx=planex+planewidth/2
  2.  
  3. bullety=planey+bulletheight

13.声明子弹的构造函数、

这部分有点难理解 也是本代码的难点

下面声明的构造函数是用来制作子弹的

  1. function bullet(x,y){
  2.  
  3. this.x=x; //子弹横坐标
  4.  
  5. this.y=y;          //子弹纵坐标
  6.  
  7. this.islive=true;   //子弹存活属性
  8.  
  9. this.timmer=null;     //子弹计时器 用来使得子弹自己运动
  10.  
  11. this.run = function run(){ //子弹的运动方法
  12.  
  13. if(this.islive==false||this.y<-10){ //判断子弹是否存活或出界
  14.  
  15. clearInterval(this.timmer); //停止运动
  16.  
  17.    this.islive=false;
  18.  
  19. }else{
  20.  
  21. this.y-=20       //让子弹往上飞
  22.  
  23.    }
  24.  
  25. }
  26.  
  27. }

 14.生产子弹

有了做子弹的秘方 那么就可以开始制造子弹了

在这里可以使用到我们之前定义的数组存放每颗子弹

  1. function producebullet(){
  2.  
  3. herobullet = new bullet(bulletx,bullety); //生产子弹
  4.  
  5. allbullets.push(herobullet); //存放子弹
  6.  
  7. var timmer = setInterval("allbullets[" + allbullets.length-1 +"].run()" , 50); //设置子弹子弹运行 这里用到eval可以将字符变为有效方法
  8.  
  9. allbullets[allbullets.length-1].timmer=timmer; //将自动运行的子弹方法赋予到子弹的属性
  10.  
  11. }

15.画出子弹

同飞机的道理相同:光改变坐标是看不出效果,还需要把图片位置也更新了

  1. function drawbullet(){
  2.  
  3. for (var i=0;i<allbullets.length;i++){ //遍历每颗子弹
  4.  
  5. if(allbullets[i].islive){ //如果子弹挂了 就不需要再画出来了
  6.  
  7. cxt.drawImage(bulletImage,allbullets.x,allbullets.y,bulletwidth,bulletheight);
  8.  
  9. }
  10.  
  11. }
  12.  
  13. }

16.让drawbullet函数自动运行

然后把drawbullet函数 放到之前定义的run函数里 不是子弹的方法

  1. function run(){
  2.  
  3. drawplane();
  4.  
  5. drawbullet();
  6.  
  7. }

17.让子弹自动生产

给生产子弹的函数加个计时器

  1. btimmer = setInterval(producebullet,500)

**************************画敌机****************************

我们来回顾下画子弹的步骤

设置相关属性 ->  确定初始坐标 -> 子弹构造函数 ->  生产子弹 -> 画出子弹 -> 自动生产和绘画

画敌机的步骤和上面的步骤是一样的

但是有个不同的点 那就是敌机初始的横坐标应该是随机的  而纵坐标都是0 (顶部位置)

说到随机 Math.random()函数 是不可以缺少的

但这个只能产生0~1的随机数

因此 Math.random*500   范围就是0~500范围

最后四拾伍入   Math.ceil(Math.random*500);

18.设置敌机的相关属性

  1. var enemyx;
  2. var enemyy;
  3. var enemywidth=30
  4. var enemyheight=30
  5. var allenemys = new Arr(); //和子弹一样 数组用来存放所有敌机
  6. var heroenemy; //用来表示其中单个敌机
  7. var enemyImage= new Image();
  8. enemyImage.src="data:images/enemy.png"

19.敌机构造函数

  1. //构造函数
  2. //下面基本上和子弹差不多 就不解释了
  3. function enemy(x,y){
  4.  
  5. this.x=x;
  6.  
  7. this.y=y;
  8.  
  9. this.islive=true;
  10.  
  11. this.timmer=null;
  12.  
  13. this.run = function run(){
  14.  
  15. if (this.islive==false||this.y>boxheight){
  16.  
  17. clearInterval(this.timmer);
  18.  
  19. this.islive=false;
  20.  
  21. }else{
  22.  
  23. this.y+=2.5;
  24.  
  25. }
  26.  
  27. }
  28.  
  29. }

20生产敌机

  1. //生产随机位置的敌机
  2.  
  3. function produceenemy(){
  4.  
  5. enemyx=Math.ceil(Math.random()*500); //产生随机初始位
  6.  
  7. enemyy=33; //在画布顶端产生敌机
  8.  
  9. heroenemy = new enemy(enemyx,enemyy); //生产敌机
  10.  
  11. allenemys.push(heroenemy); //加入数组
  12.  
  13. var timmer = setInterval("allenemys[" + (allenemys.length-1) + "].run()"); //启动run函数并使其自动运行
  14.  
  15. allenemys[allenemys.length-1].timmer=timmer; //run函数赋予在enemy属性
  16.  
  17. }

21画出敌机

  1. //画出敌机
  2.  
  3. function drawenemy(){
  4.  
  5. for (var i=0;i<allenemys.length;i++){
  6.  
  7. if(allenemys[i].islive){
  8.  
  9. cxt.drawImage(enemyImage,allenemys[i].x,allenemys[i].y,enemywidth,enemyheight)
  10.  
  11. }
  12.  
  13. }
  14.  
  15. }

22自动生产敌机 更新敌机

最后把 drawenemy 加入run函数里  给produeenemy 加个计时器

  1. function run(){
  2.  
  3. drawplane();
  4.  
  5. drawbullet();
  6.  
  7. drawenemy();
  8.  
  9. }
  1.  

etimmer = setInterval(produceenemy,800);

  1.  

**************************击中敌机****************************

飞机 敌机  子弹 都画好了 而且都可以动起来了 , 现在来写子弹碰到敌机时敌机消失的规则

上图可以清晰的看出子弹击中敌机的范围

击中条件:

bulletx + bulletwidth > enemyx

bulletx < enemyx + enemywidth

bullety < enemyy + enemyheight

  1. function checkbullet{
  2.  
  3.   for(var i=0;i<allenemys.length;i++){ //遍历敌机
  4.  
  5.     if (allenemys[i].islive){
  6.  
  7.     var e = allenemys[i]; //获取敌机对象
  8.  
  9.     }
  10.  
  11.     for(var j=0;j<allbullets.length;j++){ //遍历
  12.  
  13.       if(allbullets[j].islive){
  14.  
  15.         var b = allbullets[j];
  16.  
  17.         if(b.x+b.width>e.x&&b.x<e.x+e.width&&b.y<e.y+e.height){ //这里使用到上面的规则
  18.  
  19.           b.islive=false; //在构造函数里只要islive的属性为假 就会停止run函数的计时器
  20.  
  21.           e.islive=false; //因此子弹和敌机相关计时器都被clear掉了
  22.  
  23.           score+=100; //加分
  24.  
  25.         }
  26.  
  27.       }
  28.  
  29.     }
  30.  
  31.   }
  32.  
  33. }

**************************击中我机****************************

我机的死亡的规则:

击中条件:

enemyx+enemywidth > planex

enemyx < planex + planewidth

enemyy + enemyheight > planey

  1. function checkenemy(){
  2.  
  3.   for(var i=0;i<allenemys[i].length;i++){
  4.  
  5.   if(allenemys[i].islive){
  6.  
  7.       var e = allenemys[i];
  8.  
  9.       if(e.x+e.width > planex && e.x < planex + planewidth && e.y + e.height > planey){
  10.  
  11.         e.islive=false;
  12.  
  13.         stop();
  14.  
  15.       }
  16.  
  17.     }
  18.  
  19. }
  20.  
  21. }

**************************停止一切****************************

然后把stop函数写出来

  1. function stop(){
  2.  
  3. clearInterval(btimmer);    //停止生产子弹
  4.  
  5. clearInterval(etimmer);    //停止生产敌机
  6.  
  7. clearInterval(gameTimmer); //停止游戏
  8.  
  9. allenemys.length=0;      //初始化
  10.  
  11. allbullets.length=0;      //初始化
  12.  
  13. show.innerHTML=score;    //统计总分
  14.  
  15. score=0;
  16.  
  17. }

**************************启动一切****************************

然后把checkbullet函数 和checkenemy函数 放到游戏驱动run 里头

  1. function run(){
  2.  
  3. drawplane(); //画飞机
  4.  
  5. drawenemy(); //画敌机
  6.  
  7. drawbullet(); //画子弹
  8.  
  9. checkbullet(); //检查子弹
  10.  
  11. checkenemy(); //检查敌机
  12.  
  13. drawscore();  //实时加分
  14.  
  15. }

最后设置一下加分相关的标签

这个标签用来显示当前分数

  1. <div style="position: absolute;top: 90px;left: 30px;
    font-weight: bold;font-size: 40px;color:cornflowerblue">
  2. <span id="show">0</span></div>

获取标签

  1. show = document.getElementById('show');

实时计分

  1. function drawscore(){
  2.  
  3. show.innerHTML=score;
  4.  
  5. }

当然还可以加一些小细节,比如暂停按钮 弹出窗口统计得分

还可以玩好玩的,比如飞机无敌 无限子弹 超级子弹 无敌并排子弹 总之你自己想怎么改都行

源代码:http://www.cnblogs.com/demonxian3/p/6241755.html

用javascript写星际飞机大战游戏的更多相关文章

  1. 用Javascript模拟微信飞机大战游戏

    最近微信的飞机大战非常流行,下载量非常高. 利用JS进行模拟制作了一个简单的飞机大战[此源码有很多地方可以进行重构和优化] [此游戏中没有使用HTML5 任何浏览器都可以运行]. 效果图: 原理:利用 ...

  2. android:怎样用一天时间,写出“飞机大战”这种游戏!(无框架-SurfaceView绘制)

    序言作为一个android开发人员,时常想开发一个小游戏娱乐一下大家,今天就说说,我是怎么样一天写出一个简单的"飞机大战"的. 体验地址:http://www.wandoujia. ...

  3. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(下)

    在飞机大战游戏开发中遇到的问题和解决方法: 1.在添加菜单时,我要添加一个有背景的菜单,需要在菜单pMenu中添加一个图片精灵,结果编译过了但是运行出错,如下图: 查了很多资料,调试了很长时间,整个人 ...

  4. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(中)

    接<基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)> 三.代码分析 1.界面初始化 bool PlaneWarGame::init() { bool bRet = fals ...

  5. 基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(上)

    最近接触过几个版本的cocos2dx,决定每个大变动的版本都尝试一下.本实例模仿微信5.0版本中的飞机大战游戏,如图: 一.工具 1.素材:飞机大战的素材(图片.声音等)来自于网络 2.引擎:coco ...

  6. 11.pygame飞机大战游戏整体代码

    主程序 # -*- coding: utf-8 -*- # @Time: 2022/5/20 22:26 # @Author: LiQi # @Describe: 主程序 import pygame ...

  7. 一、利用Python编写飞机大战游戏-面向对象设计思想

    相信大家看到过网上很多关于飞机大战的项目,但是对其中的模块方法,以及使用和游戏工作原理都不了解,看的也是一脸懵逼,根本看不下去.下面我做个详细讲解,在做此游戏需要用到pygame模块,所以这一章先进行 ...

  8. Canvas:飞机大战 -- 游戏制作

    Canvas:飞机大战 最开始我们要初始化信息,我们有五个状态:游戏封面,加载状态,运行状态,游戏暂停,游戏结束. 我们还需要  得分--score,生命--life. var START = 1;/ ...

  9. web版canvas做飞机大战游戏 总结

    唠唠:两天的时间跟着做了个飞机大战的游戏,感觉做游戏挺好的.说是用html5做,发现全都是js.说js里一切皆为对象,写的最多的还是函数,都是函数调用.对这两天的代码做个总结,希望路过的大神指点一下, ...

随机推荐

  1. java中servlet的各种路径

    1. web.xml中<url-pattern>路径,(叫它Servlet路径!) > 要么以“*”开关,要么为“/”开头 2. 转发和包含路径 > *****以“/”开头:相 ...

  2. JSON.parse()和JSON.stringify()

    1.parse 用于从一个字符串中解析出json 对象.例如 var str='{"name":"cpf","age":"23&q ...

  3. jQuery学习之路(4)- 动画

    ▓▓▓▓▓▓ 大致介绍 通过jQuery中基本的动画方法,能够轻松地为网页添加非常精彩的视觉效果,给用户一种全新的体验 ▓▓▓▓▓▓ jQuery中的动画 ▓▓▓▓▓▓ show()和hide()方法 ...

  4. C#为IE编写BHO插件心得

    啥是BHO,其实大家都用过,没听过只是没在意而已,来张图你就知道是什么了 是不是很熟悉,就是这么个玩意~~ 先说说我要用来干嘛~我们有个库,里面数据很全面,但是某个部门需要在第三方的B/S系统录入某些 ...

  5. 马里奥AI实现方式探索 ——神经网络+增强学习

    [TOC] 马里奥AI实现方式探索 --神经网络+增强学习 儿时我们都曾有过一个经典游戏的体验,就是马里奥(顶蘑菇^v^),这次里约奥运会闭幕式,日本作为2020年东京奥运会的东道主,安倍最后也已经典 ...

  6. Entity Framework 手动使用migration里面的up 和down方法。

    add-migration -IgnoreChanges 201606100717405_201606100645298_InitialCreate 执行这一句后 ,清空使用map生成的代码,个人不太 ...

  7. 动手做第一个Chrome插件

    Chrome插件是令人惊讶的简单,一旦你弄懂它的工作和实现原理.它是由一部分HTML,一部分Js,然后混合了一个叫做manifest.json的Json文件组合而成的整体.这意味着你可以使用你最擅长的 ...

  8. 用Kotlin实现Android定制视图(KAD 06)

    作者:Antonio Leiva 时间:Dec 27, 2016 原文链接:https://antonioleiva.com/custom-views-android-kotlin/ 在我们阅读有关c ...

  9. OpenGL ES: Array Texture初体验

    [TOC] Array Texture这个东西的意思是,一个纹理对象,可以存储不止一张图片信息,就是说是是一个数组,每个元素都是一张图片.这样免了频繁地去切换当前需要bind的纹理,而且可以节省系统资 ...

  10. BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3522  Solved: 1041[Submi ...