html坦克游戏,HTML5+JS实现坦克大战小游戏
听了韩顺平老师的视频教程,学到了不少编程思想,原来看似简单的坦克大战小游戏写起来其实并不简单。这里总结一下这几天学到的东西。
首先是关于html5的知识了。这里我们基本上只用了画布canvas来画坦克,还有就是html5的第一行来说明这是一个使用html5写的页面,html5的特性之一就包括canvas,这是html中没有的标签。
另外一个就是js了,涉及到的语法都是最简单、最基本的用法,这在代码中进行解释。同时,韩老师在这个视频中代码有个bug就是敌人坦克在死后依然会发子弹,小弟在此进行了修正。
接下来最重要的就是我们要来分析一下坦克大战小游戏的设计思路:
1、要有作战区域,这有canvas 可以帮我们解决。
2、要有坦克,包括自己的、敌人的。
3、要能有子弹,包括自己的、敌人的。
4、要有炸弹。
5、我的坦克要能按键发射子弹,敌人的坦克要能连续自动发射子弹。
6、我的子弹打到敌人时子弹要消失,同时敌人爆炸并消失,不能再发子弹。
以上是游戏设计的简单思路,这是初步设计,接下来以代码来分析详细的设计过程:
步骤一:
组织代码,为了代码易读,而且我使用的是html5+js来实现,自不必多说,使用tankGame.js+tankGame.html来组织我的代码,js用于类以及方法的实现过程,html实现函数调用以及网页的显示。
步骤二:设计作战区域:
code 1 from tankeGame.html
//得到画布
var canvas1=document.getElementById("tankMap");
//得到绘图上下文(你可以理解是画笔)
var cxt=canvas1.getContext("2d");
步骤三:画坦克,包括自己的和敌人的:
// 基类,里面有基本的共有属性和方法
function Tank(x,y,direct,color){
this.x=x;
this.y=y;
this.speed=1;
this.isLive=true;
this.direct=direct;
//一个坦克,需要两个颜色.
this.color=color;
//上移
this.moveUp=function(){
this.y-=this.speed;
this.direct=0;
}
//向右
this.moveRight=function(){
this.x+=this.speed;
this.direct=1;
}
//下移
this.moveDown=function(){
this.y+=this.speed;
this.direct=2;
}
//左
this.moveLeft=function(){
this.x-=this.speed;
this.direct=3;
}
}
//子类Hero和EnemyTanke继承自基类。注意继承的方法。
//定义一个Hero类
//x 表示坦克的 横坐标, y 表示纵坐标, direct 方向
function Hero(x,y,direct,color){
//继承的方法和格式,tank其实就是一个对象
this.tank=Tank;
this.tank(x,y,direct,color);
//增加一个私有函数,射击敌人坦克.
this.shotEnemy=function(){
//创建子弹, 子弹的位置应该和hero有关系,并且和hero的方向有关
switch(this.direct){
case 0:
heroBullet=new Bullet(this.x+9,this.y,this.direct,3,"hero",this);
break;
case 1:
heroBullet=new Bullet(this.x+30,this.y+9,this.direct,3,"hero",this);
break;
case 2:
heroBullet=new Bullet(this.x+9,this.y+30,this.direct,3,"hero",this);
break;
case 3: //右
heroBullet=new Bullet(this.x,this.y+9,this.direct,3,"hero",this);
break;
}
//把这个子弹对象放入到数组中 -> push函数
heroBullets.push(heroBullet);
//定时器.
var timer=window.setInterval("heroBullets["+(heroBullets.length-1)+"].run()",50);
//把这个timer赋给这个子弹(js对象是引用传递!)
heroBullets[heroBullets.length-1].timer=timer;
}
//定义一个EnemyTank类
function EnemyTank (x,y,direct,color){
//继承Tank
this.tank=Tank;
this.count=0;
this.bulletIsLive=true;
this.tank(x,y,direct,color);
this.qetBullet=null;
this.run=function run(){
//判断敌人的坦克当前方向
switch(this.direct){
case 0:
if(this.y>0){
this.y-=this.speed;
}
break;
case 1:
if(this.x+30<400){
this.x+=this.speed;
}
break;
case 2:
if(this.y+30<300){
this.y+=this.speed;
}
break;
case 3:
if(this.x>0){
this.x-=this.speed;
}
break;
}
//改变方向,走50次,再改变方向
if(this.count>50){
this.direct=Math.round(Math.random()*3);//随机生成 0,1,2,3
this.count=0;
}
this.count++;
//判断敌人坦克是否还活着
//if(this.tank.isLive==true){
//判断子弹是否已经死亡,如果死亡,则增加新的一颗子弹
if(this.bulletIsLive==false){
//增子弹,这是需要考虑当前这个敌人坦克的方向,在增加子弹
switch(this.direct){
case 0:
qetBullet=new Bullet(this.x+9,this.y,this.direct,3,"enemy",this);
break;
case 1:
qetBullet=new Bullet(this.x+30,this.y+9,this.direct,3,"enemy",this);
break;
case 2:
qetBullet=new Bullet(this.x+9,this.y+30,this.direct,3,"enemy",this);
break;
case 3: //右
qetBullet=new Bullet(this.x,this.y+9,this.direct,3,"enemy",this);
break;
}
//把子弹添加到敌人子弹数组中
enemyBullets.push(qetBullet);
//启动新子弹run
var mytimer=window.setInterval("enemyBullets["+(enemyBullets.length-1)+"].run()",50);
enemyBullets[enemyBullets.length-1].timer=mytimer;
this.bulletIsLive=true;
}
}
//绘制坦克(敌人坦克和自己的坦克)
function drawTank(tank){
//说明所有的坦克都要isLive这个属性
if(tank.isLive){
//考虑方向
switch(tank.direct){
case 0: //上
case 2:// 下
//画出自己的坦克,使用前面的绘图技术
//设置颜色
cxt.fillStyle=tank.color[0];
//韩老师使用 先死--->后活 (初学者最好用这个方法)
//先画出左面的矩形
cxt.fillRect(tank.x,tank.y,5,30);
//画出右边的矩形(这时请大家思路->一定要一个参照点)
cxt.fillRect(tank.x+15,tank.y,5,30);
//画出中间矩形
cxt.fillRect(tank.x+6,tank.y+5,8,20);
//画出坦克的盖子
cxt.fillStyle=tank.color[1];
cxt.arc(tank.x+10,tank.y+15,4,0,360,true);
cxt.fill();
//画出炮筒(直线)
cxt.strokeStyle=tank.color[1];
//设置线条的宽度
cxt.lineWidth=1.5;
cxt.beginPath();
cxt.moveTo(tank.x+10,tank.y+15);
if(tank.direct==0){
cxt.lineTo(tank.x+10,tank.y);
}else if(tank.direct==2){
cxt.lineTo(tank.x+10,tank.y+30);
}
cxt.closePath();
cxt.stroke();
break;
case 1: //右和左
case 3:
//画出自己的坦克,使用前面的绘图技术
//设置颜色
cxt.fillStyle=tank.color[0];
//韩老师使用 先死--->后活 (初学者最好用这个方法)
//先画出左面的矩形
cxt.fillRect(tank.x,tank.y,30,5);
//画出右边的矩形(这时请大家思路->一定要一个参照点)
cxt.fillRect(tank.x,tank.y+15,30,5);
//画出中间矩形
cxt.fillRect(tank.x+5,tank.y+6,20,8);
//画出坦克的盖子
cxt.fillStyle=tank.color[1];
cxt.arc(tank.x+15,tank.y+10,4,0,360,true);
cxt.fill();
//画出炮筒(直线)
cxt.strokeStyle=tank.color[1];
//设置线条的宽度
cxt.lineWidth=1.5;
cxt.beginPath();
cxt.moveTo(tank.x+15,tank.y+10);
//向右
if(tank.direct==1){
cxt.lineTo(tank.x+30,tank.y+10);
}else if(tank.direct==3){ //向左
cxt.lineTo(tank.x,tank.y+10);
}
cxt.closePath();
cxt.stroke();
break;
}
}
}
步骤四:画子弹:
type表示:这颗子弹是敌人的,还是自己的
//tank表示对象,说明这颗子弹,属于哪个坦克.
function Bullet(x,y,direct,speed,type,tank){
this.x=x;
this.y=y;
this.direct=direct;
this.speed=speed;
this.timer=null;
this.isLive=true;
this.type=type;
this.tank=tank;
this.run=function run(){
//在该表这个子弹的坐标时,我们先判断子弹是否已经到边界
//子弹不前进,有两个逻辑,1.碰到边界,2. 碰到敌人坦克.
if(this.x<=0||this.x>=500||this.y<=0||this.y>=500||this.isLive==false){
//子弹要停止.
window.clearInterval(this.timer);
//子弹死亡
this.isLive=false;
if(this.type=="enemy"){
this.tank.bulletIsLive=false;
}
}else{
//坐标的移动代表子弹位置变化
switch(this.direct){
case 0:
this.y-=this.speed;
break;
case 1:
this.x+=this.speed;
break;
case 2:
this.y+=this.speed;
break;
case 3:
this.x-=this.speed;
break;
}
}
}
}
//Bullet只是一个类,并没有画坦克的方法,需要我们自己设计,draw一个
//画出自己的子弹
function drawHeroBullet(){
//现在要画出所有子弹
for( var i=0;i
var heroBullet=heroBullets[i];
if(heroBullet!=null&&heroBullet.isLive){
cxt.fillStyle="#FEF26E";
cxt.fillRect(heroBullet.x,heroBullet.y,2,2);
}
}
}
//这里我们还需要添加一个函数,用于画出敌人的子弹
function drawEnemyBullet(){
//检查坦克是否还活着
for(var j=0;j
var enemyTank=enemyTanks[j];
if(enemyTank.isLive==true){
for( var i=0;i
var etBullet=enemyBullets[i];
if(etBullet!=null&&etBullet.isLive){
cxt.fillStyle="#00FEFE";
cxt.fillRect(etBullet.x,etBullet.y,2,2);
}
}
}
}
}
步骤五:检测判断自己的坦克是否击中敌人坦克。
//编写一个函数,专门用于判断我的子弹,是否击中了某个敌人坦克
function isHitEnemyTank(){
//取出子弹
for(var i=0;i
//取出一颗子弹
var heroBullet=heroBullets[i];
if(heroBullet.isLive){ //子弹是活的,才去判断
//让这颗子弹去和遍历每个敌人坦克判断
for(var j=0;j
var enemyTank=enemyTanks[j];
if(enemyTank.isLive){
//(看看这颗子弹,是否进入坦克所在矩形)
//根据当时敌人坦克的方向来决定
switch(enemyTank.direct){
case 0: //敌人坦克向上
case 2://敌人坦克向下
if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+20
&&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+30){
//把坦克isLive 设为false ,表示死亡
enemyTank.isLive=false;
//该子弹也死亡
heroBullet.isLive=false;
//创建一颗炸弹
var bomb=new Bomb(enemyTank.x,enemyTank.y);
//然后把该炸弹放入到bombs数组中
bombs.push(bomb);
}
break;
case 1: //敌人坦克向右
case 3://敌人坦克向左
if(heroBullet.x>=enemyTank.x&&heroBullet.x<=enemyTank.x+30
&&heroBullet.y>=enemyTank.y&&heroBullet.y<=enemyTank.y+20){
//把坦克isLive 设为false ,表示死亡
enemyTank.isLive=false;
heroBullet.isLive=false;
//创建一颗炸弹
var bomb=new Bomb(enemyTank.x,enemyTank.y);
//然后把该炸弹放入到bombs数组中
bombs.push(bomb);
}
break;
}
}
}//for
}
}
步骤六:设计爆炸效果
//定义一个炸弹类
function Bomb(x,y){
this.x=x;
this.y=y;
this.isLive=true; //炸弹是否活的,默认true;
//炸弹有一个生命值
this.blood=9;
//减生命值
this.bloodDown=function(){
if(this.blood>0){
this.blood--;
}else{
//说明炸弹死亡
this.isLive=false;
}
}
}
//画出敌人炸弹
function drawEnemyBomb(){
for(var i=0;i
//取出一颗炸弹
var bomb=bombs[i];
if(bomb.isLive){
//更据当前这个炸弹的生命值,来画出不同的炸弹图片
if(bomb.blood>6){ //显示最大炸弹图
var img1=new Image();
img1.src="picture/bomb_1.gif";
var x=bomb.x;
var y=bomb.y;
img1.οnlοad=function(){
cxt.drawImage(img1,x,y,30,30);
}
}else if(bomb.blood>3){
var img2=new Image();
img2.src="picture/bomb_2.gif";
var x=bomb.x;
var y=bomb.y;
img2.οnlοad=function(){
cxt.drawImage(img2,x,y,30,30);
}
}else {
var img3=new Image();
img3.src="picture/bomb_3.gif";
var x=bomb.x;
var y=bomb.y;
img3.οnlοad=function(){
cxt.drawImage(img3,x,y,30,30);
}
}
//减血
bomb.bloodDown();
if(bomb.blood<=0){
//怎么办?把这个炸弹从数组中去掉
bombs.splice(i,1);
}
}
}
}
步骤七:响应键盘事件
function getCommand(){
//我怎么知道,玩家按下的是什么键
//说明当按下键后 事件--->event对象----->事件处理函数()
var code=event.keyCode;//对应字母的ascii码->我们看码表
switch(code){
case 87://上
hero.moveUp();
break;
case 68:
hero.moveRight();
break;
case 83:
hero.moveDown();
break;
case 65:
hero.moveLeft();
break;
case 74:
hero.shotEnemy();
break;
}
步骤八:页面刷新:
//专门写一个函数,用于定时刷新我们的作战区,把要在作战区出现的元素(自己坦克,敌人坦克,子弹,炸弹,
//障碍物...)->游戏思想
function flashTankMap(){
//把画布清理
cxt.clearRect(0,0,500,500);
//我的坦克
drawTank(hero);
//画出自己的子弹
//子弹飞效果是怎么出现的?[答 : 首先我们应该每隔一定时间(setInterval)就去刷新作战区,如果在刷新的时候,子弹坐标变换了,给人的感觉就是子弹在飞!]
drawHeroBullet();
//敌人的坦克
//判断一下敌人坦克是否击中
isHitEnemyTank();
drawEnemyBomb();
drawEnemyBullet();
//画出所有敌人坦克
for(var i=0;i<3;i++){
drawTank(enemyTanks[i]);
}
}
总结:坦克大战小游戏虽小但是涉及到的内容和思想却不少,在学习编程的过程中慢慢的体会编程思想非常重要。在此非常感谢韩顺平老师的视频!!!
html坦克游戏,HTML5+JS实现坦克大战小游戏相关推荐
- JS实现飞机大战小游戏 超详细 附源码和原图
目录 效果展示 源码 HTML CSS JS 原图 效果展示 HTML+CSS+JS做打飞机小游戏 开始界面 选择你喜欢的飞机开始游戏 按下空格键 开始/暂停 有三种敌机 可以设置飞机生命值,生命值 ...
- php 设计五子棋游戏,基于js+canvas实现五子棋小游戏
本文实例为大家分享了js+canvas实现五子棋小游戏的具体代码,供大家参考,具体内容如下 效果展示: 源码展示: 五子棋 * { margin: 0; padding: 0; } body { ma ...
- js实现飞机大战小游戏
用JavaScript来实现一个鼠标指针控制的飞机大战小程序,效果图如下. 1.进入页面阶段 2.第二载入阶段效果图 3.第三核心阶段 4.第四暂停阶段 5.第五结束阶段 实现这个项目的HTML代码只 ...
- php掷骰子小游戏代码,js实现掷骰子小游戏
本文实例为大家分享了js掷骰子小游戏的具体代码,供大家参考,具体内容如下 因为这次作业是第一个实验,比较简单,但是要求面向对象来做,而我这个时候又刚好在学JS,JS来做骰子游戏即有前端了,又省了后台处 ...
- 基于HTML5canvars的小游戏,HTML5之canvas简单射箭小游戏
最近折腾一个自己个人主页,无奈履历太渣,能放在首页的东西不多,于是想给自己的个人主页上添加一个小游戏.遂参考了各种教程,使用HTML5的canvas元素做了一个相当原始的东西出来,效果如图~ QQ截图 ...
- html+css+js实现飞机大战小游戏
前言 废话不多说,直接上源码 一.requestAnimationFrame是什么? 在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout/ se ...
- 使用Pixi.js编写JavaScript网页小游戏
Pixi.js中文网https://pixijs.huashengweilai.com/PixiJSOfficial site for PixiJS, The HTML Creation Engine ...
- html实现经典坦克大战小游戏
文章目录 1.设计来源 1.1 游戏主界面 1.2 游戏界面 2.效果和源码 2.1 动态效果 2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/w ...
- Java实现的经典坦克大战小游戏
Java实现的经典坦克大战小游戏 先看一下游戏结构: 有点多,没有耐心的可以不用看,这里先给出链接吧! 云链接:经典坦克大战 提取码:s9ai 这里就不介绍功能了,贴了一张游戏运行的截图,具体的功能自 ...
- 【JAVA程序设计】基于JAVA的坦克大战小游戏--入门级小游戏
基于JAVA的坦克大战小游戏--入门级小游戏 零.项目获取 一.项目简介 二.开发环境 三.游戏玩法 四.运行截图 零.项目获取 获取方式(点击下载):是云猿实战 项目经过多人测试运行,可以确保100 ...
最新文章
- ASP.NET MVC入门到精通——Spring.net-业务层仓储
- 用 tap/tun 做虚拟机的网卡
- javaWeb服务详解(含源代码,测试通过,注释) ——applicationContext-dao.xml
- python tkinter图片为什么要设置全局变量_为什么这里一定要设置全局变量
- 最简单的CSocket通信流程
- vasp和ms_采用MS建模的基本步骤以及vasp新手入门需要注意的十个简单问题
- 基于统计学的商务与经济数据分析知识
- CQ40 519TX不刷BIOS完美解决声卡问题方法
- Qt对象间的父子关系
- 提交网址到bing搜索引擎
- unity期末个人作品-落笔洞寻宝探险之旅(寻宝游戏)
- 小白常用的Widows10实用功能,让你更好掌控你的电脑。
- 《 指数基金投资指南 》by 银行螺丝钉 - 笔记 - 4 - 第二部分
- Windows10中Edge“嗯...无法访问此页面”,详细信息 DSN名称不存在 问题的解决方案
- 对于现在毕业之后,大部分找不到合适的工作,转行到软件开发(大部分是JAVA)的人来说,分享下自己的经验
- 【补作业】msp430单片机(一)控制LED灯的亮灭
- Maven deploy项目到私服报错
- 论文的文献综述查重吗?
- 浏览器无法访问localhost
- 珍稀资料:1950年中国高考数学真题
热门文章
- 三极管的下拉电阻作用是什么?
- 表格怎么样输入数字自己计算机,如何让EXCEL中输入数字后自动显示求和结果
- go和python哪个好就业_python就业方向哪个好?没基础学python
- 2022-2027年(新版)中国钢铁产业运行状况及需求前景预测报告
- 〖教程〗Winrm远程命令/WinrmCmd/端口复用后门/Windows密码爆破
- 掘金8000亿早教市场,启蒙APP们还面临哪些难题?
- PS完美抠取头发丝----更换证件照背景完美去白边/蓝边/红边-----超实用方法
- 微信小程序微信支付(统一支付)
- m-bom,p-bom,e-bom 这是什么意思
- gnome桌面终端程序 Guake