【CSON原创】HTML5第一人称射击游戏发布

功能说明:

  游戏中在躲避敌人攻击的同时,需要收集三种不同的钥匙,开启对应的门,最后到达目的地。

  该游戏同样基于自己开发的HTML5游戏框架cnGameJS。

  推荐用chrome浏览器查看。

效果预览:

  方向键控制移动,空格键射击,shift键打开门。

  

请用支持HTML5 canvas的浏览器查看请用支持HTML5 canvas的浏览器查看

实现分析:

  在上一篇文章《HTML5实现3D迷宫》中,通过放射线法模拟出3D场景的效果,而本文则在3D效果的基础上,添加更多的游戏元素,构建成一个较完整的第一人称射击游戏。

  关于如何模拟出3D场景效果上文中已经有较详细的描述,本文则主要介绍如何实现游戏互动部分。

  1.游戏元素在地图上的对象和在屏幕上的对象的对应关系?

  首先,每个游戏元素都对应两个游戏对象,一个游戏对象为左边地图上的对象,另一个则为右边屏幕上的对象。例如,一个敌人的位置,是否射击状态等信息都由左边的地图对象来表示,而敌人在屏幕上的显示,则是根据在左边地图上对象的信息进行绘制。简而言之,左边的地图对象负责游戏元素位置,状态的判别,它真正存储游戏信息。而右边的屏幕对象则只负责游戏元素的呈现。

  

        newEnemy.relatedObj=new enemy2({src:srcObj.enemy,context:screenContext});        newEnemy.relatedObj.relatedParent=newEnemy;
复制代码

  如上,地图上的对象和屏幕上的对象保持互相引用的关系,这样就可以轻易通过地图对象访问屏幕对象,反之亦然。

  2.如何使敌人在发现玩家后进行射击?

  要实现该功能,我们需要知道玩家相对于敌人的角度,该参数我们可以根据敌人到玩家的距离和它们x,y的差值求出。之后我们就可以在敌人对象的位置向该方向发射出一条射线,如果该射线能在不触碰墙壁的时候触碰到玩家,就证明敌人可以看到玩家。这时候敌人就可以向玩家射击了。

  

            nextX = enemyCenter[0];            nextY = enemyCenter[1];while (this.map.getPosValue(nextX, nextY) == 0) {                distant += 1;                x = nextX;                y = nextY;if (cnGame.collision.col_Point_Rect(x, y, playerRect)&&!spriteList[i].relatedObj.isCurrentAnimation("enemyDie")) {//如果地图上敌人能看到玩家,则向玩家射击                    spriteList[i].isShooting = true;if (spriteList[i].lastShootTime > spriteList[i].shootDuration) {//检查是否超过射击时间间隔,超过则射击玩家                                    spriteList[i].shoot(player);                        spriteList[i].relatedObj.setCurrentImage(srcObj.enemy1);                                spriteList[i].lastShootTime = 0;

                    }else {if (spriteList[i].lastShootTime > 0.1) {                            spriteList[i].relatedObj.setCurrentImage(srcObj.enemy);                        }                        spriteList[i].lastShootTime += duration;                    }break;                }else {                    spriteList[i].isShooting = false;                }                nextX = distant * Math.cos(angle) + enemyCenter[0];                nextY = enemyCenter[1] - distant * Math.sin(angle);            }

        }
复制代码

  3.如何检测是否获得钥匙?

  检测钥匙获取其实就是简单地检测玩家对象和钥匙对象是否产生碰撞,产生碰撞则获取到钥匙。碰撞检测同样发生在左边的地图对象。

  

/*  检测是否获得钥匙    */var checkGetKeys = function() {var list = cnGame.spriteList;var playerRect= this.player.getRect();for (var i = 0, len = list.length; i < len; i++) {if (list[i] instanceof key) {if (cnGame.collision.col_Between_Rects(list[i].getRect(),playerRect)) {this.keysValue.push(list[i].keyValue);                list.remove(list[i]);                i--;                len--;            }        }    }

}
复制代码

4.如何同时把游戏元素和游戏场景同时绘制在屏幕上并且保持正确的先后关系?

  在css里,我们可以使用z-Index使元素保持正确的层级关系,但是我们现在需要在canvas上绘制图形,因此只能模拟出z-Index效果。

  在之前那篇文章中说过,3D场景是由一条条不同长短的像素线的绘制而成,因此在加入了其他游戏元素之后,若要保持正确的层级关系,就需要为每个元素和像素线自定义zIndex属性,并存放在数组中。每次绘制的时候数组根据zIndex排序,使绘制有一个先后顺序,从而保证层级正确。zIndex的值根据玩家到该元素或像素线的距离计算所得:

  

zIndex= Math.floor(1 / distant * 10000)

  之后每次绘制就可以产生近的图像覆盖在远的图像上的效果:

  排序:

  

        colImgsArray.sort(function(obj1, obj2) {

if (obj1.zIndex > obj2.zIndex) {return 1;            }else if (obj1.zIndex < obj2.zIndex) {return -1;            }else {return 0;            }        });
复制代码

  绘制:

  

        //画出每条像素线和游戏元素        for (var i = 0, len = colImgsArray.length; i < len; i++) {var obj = colImgsArray[i];if(obj.draw){                obj.draw();            }else{                context.drawImage(obj.img, obj.oriX, obj.oriY, obj.oriWidth, obj.oriHeight, obj.x, obj.y, obj.width, obj.height);            }        }    
复制代码

  5.如何判断玩家击中敌人?

  玩家击中敌人的判别其实也是利用碰撞检测,不过这次是利用元素在屏幕上的对象进行碰撞检测。我们只需要检测准星(屏幕中点)与敌人对象所形成的矩形是否产生碰撞,就可以检测到是否击中了敌人。

  

    for (var i = list2.length - 1; i >= 0; i--) {if (list2[i] instanceof enemy2 && list2[i].relatedParent.isShooting) {var obj = list2[i];var enemyRect = obj.getRect();//构造敌人在屏幕上形成的矩形对象            if (cnGame.collision.col_Point_Rect(starPos[0], starPos[1], enemyRect)) {                obj.setCurrentAnimation("enemyDie");    break;            }        }    }
复制代码

  击中敌人之后,需要break跳出循环,停止检测,防止击中在该敌人后面的敌人。

  最后给出所有源码下载:点击下载

  欢迎转载,请标明出处:http://www.cnblogs.com/Cson/archive/2012/03/05/2380963.html

转载于:https://www.cnblogs.com/xsmhero/archive/2012/03/06/2381535.html

【转】HTML5第一人称射击游戏发布相关推荐

  1. html5 如何实现自动射击,HTML5第一人称射击游戏实现的代码分享

    功能说明: 游戏中在躲避敌人攻击的同时,需要收集三种不同的钥匙,开启对应的门,最后到达目的地. 该游戏同样基于自己开发的HTML5游戏框架cnGameJS. 推荐用chrome浏览器查看. 效果预览: ...

  2. 【历史上的今天】12 月 10 日:世界上第一位程序员诞生;Ada 语言发布;第一人称射击游戏的开拓者

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2021 年 12 月 10 日,在 120 年前的今天,瑞典国王和挪威诺贝尔基金会首次颁发了诺贝尔奖.根据诺贝尔 ...

  3. UE4创建第一人称射击游戏学习教程

    Unreal Engine 4: Create Your Own First-Person Shooter MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言 ...

  4. UE4创建第一人称射击游戏学习教程 Unreal Engine 4: Create Your Own First-Person Shooter

    UE4创建第一人称射击游戏学习教程 本课程包含38节视频课,将逐步指导您完成以下主题: 云桥网络 平台获取课程! 如何创建6种可定制的武器(包括手枪.突击步枪.猎枪.狙击枪.榴弹发射器和火箭发射器) ...

  5. Unity VR学习:第一人称射击游戏(1)

    Unity VR学习:第一人称射击游戏(1) 1.封装标签和场景淡入淡出效果实现 (1) 封装标签 1.标签有Player,Enemy,GameController,Fader(画布),MainCam ...

  6. 【UE4 第一人称射击游戏】12-全自动步枪并显示剩余弹药量

    上一篇: [UE4 第一人称射击游戏]11-武器跟随鼠标移动并添加开火音效 本篇效果: 步骤: 1.打开"Weapon_Base",添加一个整数类型,名为"Ammo&qu ...

  7. 【UE4 第一人称射击游戏】08-使用“AK47”发射子弹

    上一篇: [UE4 第一人称射击游戏]07-添加"AK47"武器 本节效果: 步骤: 1.在"Blueprints"文件夹内添加一个Actor蓝图,命名为&qu ...

  8. 【UE4 第一人称射击游戏】22-拾取弹药

    上一篇: [UE4 第一人称射击游戏]21-添加动态扩散准心 本篇效果: 当角色触碰到弹药箱后,玩家的后备弹夹就会多50发子弹,并且触碰到弹药箱后,会播放相应的声音和粒子特效. 步骤: 新建一个蓝图类 ...

  9. 【UE4 第一人称射击游戏】13-瞄准开火

    上一篇: [UE4 第一人称射击游戏]12-全自动步枪并显示剩余弹药量 本篇效果: 步骤: 1.打开"ThirdPersonCharacter",添加一个骨架网格体组件 将其作为M ...

最新文章

  1. 离不开深度学习的自动驾驶
  2. 我佛了!用KNN实现验证码识别,又 Get 到一招!
  3. 「多图」图解10大CNN架构
  4. 解决方案需求提升 安防工程细节化事项要了解
  5. 史上最经典的数据库面试题之二
  6. Python 面向对象编程基础
  7. EF调用存储过程实现分页
  8. ParameterizedTypeImpl
  9. JavaScript 专题之函数柯里化
  10. oracle 中此处列不允许,oracle-序列 ora-02287 此处不允许序号
  11. 四.川.木.里-2020-03-28火灾遥感数据下载汇总
  12. GBK/GBK2312字库寻址及使用原理
  13. 【STM32H7教程】第39章 STM32H7的DMAMUX基础知识(重要)
  14. python微信自动发朋友圈_Python自制微信机器人:群发消息、自动接收好友
  15. 资源篇(一)-在线抠图神器
  16. 八种语言最新毕业文献参考
  17. PACS系统源码 影像管理系统源码(PACS)
  18. python上楼梯问题_python解决上楼梯问题
  19. 数据分析师成长路径-第一阶段
  20. atari游戏模型_在Atari.com免费玩经典街机游戏

热门文章

  1. Python模块: 命令行解析optionparser
  2. Luogu T16048 会议选址
  3. CentOS系统下Hadoop 2.4.1集群安装配置(简易版)
  4. phpMyAdmin开发人员访谈——4个人支持整个项目
  5. 发现asp.net 2.0 在MSDN中的多个BUG 关于无刷新窗体的
  6. C/C++不同文件夹下包含头文件的方法及#include的使用
  7. logo是啥_乐夏2开播,33支乐队的Logo设计,凭啥一个塑料袋最火?
  8. ttf能改成gfont吗_中国废弃轮胎,被非洲人买去做成凉鞋!15元一双,至少能穿10年...
  9. docker安装测试及问题解决
  10. php正则表达式应用,PHP 正则表达式应用