一篇博文:带你用Typescript实现飞机大战,附(详细思路注释),建议收藏!
Posted 贪吃ღ大魔王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇博文:带你用Typescript实现飞机大战,附(详细思路注释),建议收藏!相关的知识,希望对你有一定的参考价值。
站点结构:😉
图片素材:
地图:经典原图
飞机图片:
由于图片太多,这里用的是精灵图。为了方便,精灵图的数据存在json中。
json文件:
arts.json:
开发思路:
- 创建地图
- 发送请求将所有图片信息请求回来
- 创建自己飞机
- 发送子弹
- 创建敌机
- 处理击中和被击中
环境配置:
这里用的AMD 引入require.js
源码附注释见末尾 🌈
创建地图: 🌞
background.ts
- 背景div盒子
- 让背景图动起来,设置中间放两个图的div
- 单例的实例对象,地图背景相当于创建一个div,放到网页中间
- 设置地图样式
实现代码:
export default class Background
public bgWidth:number = 320
public bgHeight:number = 568
// 背景div盒子
public bg:htmlDivElement;
// 让背景图动起来需要的top值
public bgImageTop:number = -this.bgHeight;
// 设置中间放两个图的div
public imgContainer:HTMLDivElement;
// 单例的实例对象
public static _instance:Background;
private constructor()
// 地图背景相当于创建一个div,放到网页中间就好了
this.bg = document.createElement('div')
// 设置样式
Tool.getInstance().setStyle(this.bg,
width:this.bgWidth + "px",
height:this.bgHeight + "px",
border:"1px solid #000",
margin:"100px auto",
position:"relative",
overflow:"hidden",
as CSSStyleDeclaration)
// 将背景插入到body中
this.appendTo(this.bg,'body')
// 创建一个大盒子 - 高度是背景盒子的一倍
this.imgContainer = document.createElement('div')
// 设置样式
Tool.getInstance().setStyle(this.imgContainer,
width:this.bgWidth + "px",
height:this.bgHeight * 2 + "px",
position:"absolute",
top:-this.bgHeight + "px",
left:"0",
fontSize:"0",
zIndex:"-1"
as CSSStyleDeclaration)
// 放入背景图
this.setbg()
this.bgMove()
发送请求将所有图片信息请求回来:
imageData.ts
- 发送请求
- 获取响应的内容
- 根据数据中的 x y w h 创建div,图片定位
- 重新设置div样式
实现代码:
export default class ImageData extends MyTarget
private static _instance:ImageData;
public imgdata:imgData|null = null;
private constructor()
super()
// 发送请求
var xhr = new XMLHttpRequest()
xhr.addEventListener('load',(e:Event)=>this.loadHandler(e))
xhr.open('get','../../json/arts.json')
xhr.send()
static getInstance():ImageData
if(!this._instance) this._instance = new ImageData();
return this._instance;
// 处理ajax回调
loadHandler(e:Event):void
// 获取ajax对象并获取响应的内容
// console.log(e.currentTarget.response);
var data = JSON.parse((e.currentTarget as XMLHttpRequest).response);
this.imgdata = data;
var evt = new MyEvent('readEnd')
this.dispatchEvent(evt)
// 根据名称创建一个div
createDiv(imgname:string):HTMLDivElement|null
var frame = this.searchData(imgname);
if(!frame) return null;
// 根据数据中的 x y w h 创建div
var div:HTMLDivElement = document.createElement('div')
this.setImgStyle(div,frame)
return div;
// 替换图片定位
replaceImgPosition(ele:HTMLDivElement,imgname:string):void
var frame = this.searchData(imgname)
if(!frame) return;
this.setImgStyle(ele,frame)
// 根据名称找对应数据
searchData(imgname:string):Frame|undefined
// 创建div - 根据名称
var frames:Array<Frame> = (this.imgdata as imgData).frames // 数组
// 遍历数组找到 名称 对应的那一个对象
var frame:Frame|null = null;
for(var i=0;i<frames.length;i++)
if(frames[i].filename === imgname)
frame = frames[i]
if(!frame) return;
return frame
// 给div设置样式
setImgStyle(ele:HTMLDivElement,frame:Frame):void
// 给div重新创建样式
Tool.getInstance().setStyle(ele,
width:frame.frame.w + "px",
height:frame.frame.h + "px",
position:"absolute",
// left:"0",
// top:"0",
backgroundImage:"url('../../images/arts.png')",
backgroundPosition:`-$frame.frame.xpx -$frame.frame.ypx`
as CSSStyleDeclaration)
创建飞机: 🎯
Mypalne.ts
- 创建飞机,设置飞机状态的图片下标切换
- 改变飞机的状态
- 设置飞机喷火
private static _instance:MyPlane;`在这里插入代码片`
// 自己飞机
public myplane:HTMLDivElement;
// 自己飞机的状态
public myplaneStatus:FlyOrDie = FlyOrDie.FLY;
// 存活状态飞机的图片名称集合
public myplaneLiveImgList:Array<string> = ['hero_fly_1','hero_fly_2'];
public myplaneDieImgList:Array<string> = ['hero_blowup_1','hero_blowup_2','hero_blowup_3','hero_blowup_4'];
// 设置切换图片的下标
public index:number = 0;
public timer:number = 0
public speed:number = 0;
private constructor()
// 创建自己飞机
this.myplane = ImageData.getInstance().createDiv(this.myplaneLiveImgList[0]) as HTMLDivElement;
// 创建自己飞机
var myPlane:HTMLDivElement = ImageData.getInstance().createDiv('hero_fly_1') as HTMLDivElement;
myPlane.style.zIndex = '9999'
改变飞机状态:
setStatus(status:string)
switch(status)
case "fly":
this.myplaneStatus = FlyOrDie.FLY
this.firePen()
break;
case "die":
this.myplaneStatus = FlyOrDie.DIE
clearInterval(this.timer)
this.speed = 200
this.index = -1
this.firePen()
break;
飞机喷火:
firePen()
clearInterval(this.timer)
this.timer = setInterval(()=>
this.index++;
// 判断自己飞机状态
switch(this.myplaneStatus)
case "fly":
if(this.index===this.myplaneLiveImgList.length)
this.index = 0
// 调用替换图片名称的方法
ImageData.getInstance().replaceImgPosition(this.myplane,this.myplaneLiveImgList[this.index])
break;
case "die":
if(this.index===this.myplaneDieImgList.length-1)
// 清除定时器
clearInterval(this.timer)
ImageData.getInstance().replaceImgPosition(this.myplane,this.myplaneDieImgList[this.index])
break;
,this.speed)
子弹模块:
Bullet:
创建子弹,设置样式
实现代码:
public bullet:HTMLDivElement;
static bulletList:Array<Bullet> = [];
public num:number = 0
public startTop:number = 0
public speed:number = 2;
public time:number = 20
constructor()
this.bullet = ImageData.createDiv('bullet1')
Bullet.bulletList.push(this)
TimeManager.getInstance().add(this)
this.setstyle()
setstyle()
Tool.getInstance().setStyle(this.bullet,
left:-10 + "px",
top:-20 + "px"
as CSSStyleDeclaration)
子弹移动
实现代码:
move()
this.num++;
if(this.num===1)
Tool.getInstance().setStyle(this.bullet,
left:MyPlane.myplane.offsetLeft + MyPlane.myplane.offsetWidth/2 - this.bullet.offsetWidth/2 + "px",
top:MyPlane.myplane.offsetTop + "px"
as CSSStyleDeclaration)
this.startTop = MyPlane.myplane.offsetTop;
// this.time--;
// if(this.time>0) return;
// this.time = 20
this.startTop -= this.speed;
this.bullet.style.top = this.startTop + "px"
if(this.startTop<-this.bullet.offsetHeight)
var index:number = Bullet.bulletList.indexOf(this)
if(index<0) return;
Bullet.bulletList.splice(index,1)
Background.bg.removeChild(this.bullet)
TimeManager.getInstance().remove(this)
敌机模块:
Enemy.ts:
创建敌机
- 三种敌机,每种敌机都有不同的爆炸状态
创建敌机
public enemy:HTMLDivElement;
public enemyStatus:EnemyStatus = EnemyStatus.EnemyLive;
public enemyImg:Array<IEnemy> = [
fly:['enemy1_fly_1'],
hit:[],
die:['enemy1_blowup_1','enemy1_blowup_2','enemy1_blowup_3','enemy1_blowup_4']
,
fly:['enemy2_fly_1'],
hit:['enemy2_hit_1'],
die:['enemy2_blowup_1','enemy2_blowup_2','enemy2_blowup_3','enemy2_blowup_4','enemy2_blowup_5','enemy2_blowup_6','enemy2_blowup_7']
,
fly:['enemy3_fly_1'],
hit:['enemy3_hit_1','enemy3_hit_2'],
die:['enemy3_blowup_1','enemy3_blowup_2','enemy3_blowup_3','enemy3_blowup_4']
,
]
static enemyList:Array<Enemy> = []
public startTop:number = 0
public speed = 1
public type:number = 0
public index:number = 0
constructor()
var index:number = Math.floor(Math.random() * this.enemyImg.length)
this.type = index;
this.enemy = ImageData.createDiv(this.enemyImg[this.type]['fly'][this.index])
TimeManager.getInstance().add(this)
Enemy.enemyList.push(this)
setStatus(status:EnemyStatus)
this.enemyStatus = status
敌机移动,检测碰撞
move()
this.startTop += this.speed
this.enemy.style.top = this.startTop + "px"
// 检测碰撞
Bullet.bulletList.forEach(item=>
if(this.collide(item.bullet,this.enemy))
switch(this.enemyStatus)
case EnemyStatus.EnemyLive:
this.setStatus(EnemyStatus.EnemyHit)
var index:number = Bullet.bulletList.indexOf(item)
if(index<0) return;
Bullet.bulletList.splice(index,1)
Background.bg.removeChild(item.bullet)
TimeManager.getInstance().remove(item)
this.index = 0
break;
case EnemyStatus.EnemyHit:
break;
case EnemyStatus.EnemyDie:
break;
)
this.index++
switch(this.enemyStatus)
case EnemyStatus.EnemyLive:
break;
case EnemyStatus.EnemyHit:
if(!this.enemyImg[this.type一篇博文:带你TypeScript入门,两万字肝爆,建议收藏!
一篇博文:带你TypeScript入门,两万字肝爆,建议收藏!
canvas入门,一篇博文带你学会用代码绘画,直击实战案例!