功能说明:

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

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

推荐用chrome浏览器查看。

效果预览:

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

实现分析:

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

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

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

首先,每个游戏元素都对应两个游戏对象,一个游戏对象为左边地图上的对象,另一个则为右边屏幕上的对象。例如,一个敌人的位置,是否射击状态等信息都由左边的地图对象来表示,而敌人在屏幕上的显示,则是根据在左边地图上对象的信息进行绘制。简而言之,左边的地图对象负责游戏元素位置,状态的判别,它真正存储游戏信息。而右边的屏幕对象则只负责游戏元素的呈现。newEnemy.relatedObj= 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跳出循环,停止检测,防止击中在该敌人后面的敌人。

html5 如何实现自动射击,HTML5第一人称射击游戏实现的代码分享相关推荐

  1. 【转】HTML5第一人称射击游戏发布

    [CSON原创]HTML5第一人称射击游戏发布 功能说明: 游戏中在躲避敌人攻击的同时,需要收集三种不同的钥匙,开启对应的门,最后到达目的地. 该游戏同样基于自己开发的HTML5游戏框架cnGameJ ...

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

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

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

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

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

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

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

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

  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. 以太坊RLP机制分析
  2. crontab、chkconfig、systemd、unit、targ
  3. rocketmq queue_RocketMQ在面试中那些常见问题及答案+汇总
  4. shell输出没有换行符
  5. 循环链表:魔术师发牌问题
  6. Fiddler如何查找登陆的可用cookie用于其他请求?方式一
  7. 李彦宏告诫年轻人:向前看两年
  8. c++win32项目 如何显示后再删除一个绘图_sai绘图软件中文版
  9. 2018中国云原生用户大会:网易云深度解析微服务框架
  10. ios定位权限plist_iOS(定位一)后台定位和前台定位权限设置
  11. 三、判断三元一次方程组是否有解及求解——(计算糖果)
  12. web开发设为首页、添加到收藏夹实现方法
  13. [Linux] 添加清华镜像
  14. 期货反跟单-侃侃人工反跟单那些事儿
  15. ios键盘弹起页面被顶上去的问题
  16. uni-app注册全局组件
  17. [EOS源码分析]7.EOS智能合约开发实践之合约调用合约(inline action)
  18. c语言中i++与++i的区别
  19. 私有云服务器搭建及ssh连接
  20. php ppt转视频教程,如何制作ppt转换视频新手教程操作指南

热门文章

  1. vue中阻止事件冒泡
  2. 广西计算机一级机试考试试题,2014广西高校计算机联合考试一级机试模拟试题(有素材)win7+office2010...
  3. 因为我是科研废物所以每天翘课摸鱼准备去打工这件事
  4. 国际财务报告准则(IFRS)
  5. 效率爆表的创作小工具
  6. 独孤思维:从《狂飙》高启强身上获得的赚钱机会
  7. c++获取屏幕像素点的颜色值
  8. OLAP和OLTP以及HTAP的区别
  9. 智能教育之电子积木的评测实验
  10. 轻巧的编辑器:Sublime Text3 user设置