Python学习笔记:5.2.8 javascript打飞机实战练习

本文是学习陆老师的《python全栈工程师 - web开发前端基础》课程的笔记,欢迎学习交流。同时感谢陆老师的精彩传授!

一、课程目标
  • 打飞机场景构建
  • 利用js实现动画
  • 构造函数及原型继承实例使用
  • 键盘鼠标事件
  • 元素碰撞检测
  • 文件管理
二、详情解读
2.1.打飞机场景
2.1.1.游戏场景-使用css实现飞机动画

1.css背景复习
2.css动画
3.元素动态创建

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>01-游戏场景-使用css实现飞机动画</title>
		<style>
			.container {
				position: relative;
				margin: 0;
				width: 600px;
				height: 800px;
				background: url(image/background.png) repeat-y;
				animation: background-move 10s linear infinite;
			}
			@-webkit-keyframes background-move {
				from {background-position: 0 0;}
				to {background-position: 0 852px;}
			}
			.plane {
				position: absolute;
				left: 0;
				top: 0;
				width: 100px;
				height: 122px;
				border: 0px solid #f0f;
				background: url(image/hero/hero1.png);
				animation: plane_engine 0.1s linear infinite;
			}
			@-webkit-keyframes plane_engine {
				from {background: url(image/hero/hero1.png)}
				to {background: url(image/hero/hero2.png)}				
			}
		</style>
	</head>
	<body>
		<div class="container">
			
		</div>
		<script type="text/javascript">
			container = document.querySelector('.container');
			
			function createPlane() {
				myplane = document.createElement('div');
				myplane.style.top = 0;
				myplane.style.left = 0;
				myplane.className = 'plane';
				container.appendChild(myplane);
			}
			myplane = createPlane()
		</script>
	</body>
</html>

运行结果:
在这里插入图片描述

2.2.js动画

动画原理:动画其实就是利用人的视觉停留输入关键字,快速切换图片形成的。
在这里插入图片描述

2.2.1.游戏场景-使用工厂函数创建飞机
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>02.游戏场景-使用工厂函数创建飞机</title>
		<style>
			.container {
				position: relative
				margin: 0;
				width: 400px;
				height: 600px;
				background: url(image/background.png);
			}
			.plane{
				position: absolute;
				left: 0;
				top: 0;
				width: 100px;
				height; 122px;
				border: 0px solid #f0f;
			}
		</style>
	</head>
	<body>
		<div class="container">
			
		</div>
		<script>
			container = document.querySelector('.container');
			// 创建飞机节点元素函数
			function createPlane() {
				plane = document.createElement('div');
				container.appendChild(plane);
				img = document.createElement('img');
				plane.appendChild(img);
				plane.style.top = 0;
				plane.style.left = 0;
				plane.image = img;
				return plane;
			}
			/* 工厂方法
			 创建飞机对象,定义飞机的图片,加载,变化等属性与方法
			 */
			function Plane() {
				var myPlane = {
					plane: createPlane(), // 飞机节点,是包含飞机的div
					// 飞机各种状态的图片文件
					image_files: ['hero1.png', 'hero2.png', "hero_blowup_n1.png","hero_blowup_n2.png","hero_blowup_n3.png","hero_blowup_n4.png"],
					images: [],
					first_frame: 0, // 动画首帧下标
					last_frame: 1, // 动画尾帧下标
					current_frame: 0, // 动画当前帧下标
					// 加载飞机图片
					load: function() {
						for (i = 0;i < this.image_files.length - 1;i++) {
							// 预加载图片
							this.images[i] = new Image()
							this.images[i].src = 'image/hero/' + this.image_files[i]
						}
						this.plane.image.src = this.images[this.current_frame].src
					},
					
					// 飞机的变化
					movies: function() {
						this.current_frame += 1
						// 当前帧大于尾帧时,重新回到首帧
						if (this.current_frame > this.last_frame) {
							this.current_frame = 0
						}
						this.plane.image.src = this.images[this.current_frame].src;
					}
				}
				return myPlane
			}
			
			// 初始化飞机
			function init() {
				myplane = Plane()
				myplane.load()
			}
			// 使飞机“动”起来
			function run() {
				myplane.movies()
			}
			
			init()
			// 每50毫秒执行一次
			setInterval(run, 50)
		</script>
	</body>
</html>

运行结果与css实现的运行结果一致

2.3.通过构造函数实现对象
2.3.1.定义构造函数

1.构造函数本身就是对象
2.实例化使用 new 关键字

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>03.游戏场景-使用构造函数创建对象</title>
		<style>
			.container {
				position: relative;
				margin: 0;
				width: 400px;
				height: 600px;
				background: url(image/background.png);
			}
			.plane{
				position: relative;
				top: 0;
				left: 0;
				width: 100px;
				height: 122px;
				border: 0px solid #f0f;
			}
		</style>
	</head>
	<body>
		<div class="container">
			
		</div>
		<script>
			container = document.querySelector('.container');
			/* 创建飞机节点元素函数 */
			function createPlane() {
				plane = document.createElement('div');
				container.appendChild(plane);
				img = document.createElement('img');
				plane.appendChild(img)
				plane.style.top = 0;
				plane.style.left = 0;
				plane.image =img;
				return plane;
			}
			/* 构造函数
			 创建飞机对象,定义飞机的图片,加载,变化等属性与方法
			 */
			function Plane() {
			   
				this.plane = createPlane();
				this.image_files = ["hero1.png","hero2.png","hero_blowup_n1.png","hero_blowup_n2.png","hero_blowup_n3.png","hero_blowup_n4.png"];
				this.images = []
				this.first_frame = 0
				this.last_frame = 1
				this.current_frame = 0
				this.load = function() {
					for (i = 0;i < this.image_files.length - 1;i++) {
						this.images[i] = new Image()
						this.images[i].src = 'image/hero/' + this.image_files[i]
					}
					this.plane.image.src = this.images[this.current_frame].src
				}
				this.movies = function() {
					this.current_frame += 1
					if (this.current_frame > this.last_frame) {
						this.current_frame = 0
					}
					this.plane.image.src = this.images[this.current_frame].src
				}
			}
			function init() {
				myplane = new Plane()
				myplane.load()
			}
			function run() {
				myplane.movies()
			}
			
			init()
			setInterval(run, 50)
		</script>
	</body>
</html>

运行结果与css实现的运行结果一致

2.4.利用原型继承实现多种类型飞机
2.4.1.为什么要使用继承

1.所有的动画他们的基本属性与方法都是一样的,比如需要一组图片,都需要定义第一帧位置,当前帧位置,最后一帧位置,以及load方法,movies方法
2.各种飞机实现不同的就是图片不一样,飞行控制不一样
3.通过继承就可以精简代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>04.游戏场景-使用原型继承</title>
		<style>
			.container{
				position: relative;
				margin: 0;
				width: 400px;
				height: 600px;
				background: url(image/background.png);
			}
			.plane {
				position: absolute;
				top: 0;
				left: 0;
				border: 0px solid #f0f;
			}
			.hero {
				width: 100px;
				height: 122px;
			}
			.enemy1{
				width: 51px;
				height: 39px;
			}
		</style>
	</head>
	<body>
		<div class="container">
			
		</div>
		<script>
			container = document.querySelector('.container')
			enemy1_array = []
			enemy1_count = 3
			/* 
			构造函数
			 创建飞机对象,定义飞机的图片,加载,变化等属性与方法
			*/
			function Sprite() {
				this.init = function() {
					div = document.createElement('div')
					container.appendChild(div)
					img = document.createElement('img')
					div.image = img
					div.appendChild(img)
					this.div = div 
					div = null 
					this.div.style.left = init_data.x + 'px'
					this.div.style.top = init_data.y + 'px'
					this.div.className = init_data.className
					this.path = init_data.path
					this.image_files = init_data.image_files
					this.first_frame = init_data.first_frame
					this.last_frame = init_data.last_frame
					this.current_frame = init_data.current_frame
					this.speed = init_data.speed
					this.images = []
					
					this.load()					
				}
				this.load = function() {
					for (i = 0;i < this.image_files.length - 1;i++) {
						this.images[i] = new Image()
						this.images[i].src = this.path+this.image_files[i]
					}
					this.div.image.src = this.images[this.current_frame].src
				}
				this.movies = function() {
					this.current_frame += 1
					if (this.current_frame > this.last_frame) {
						this.current_frame = 0
					}
					this.div.image.src = this.images[this.current_frame].src
				}
			}
			
			function HeroPlane() {
				init_data = {
					x: 300,
					y: 300,
					className: 'plane hero',
					path: 'image/hero/',
					image_files: ["hero1.png","hero2.png","hero_blowup_n1.png","hero_blowup_n2.png","hero_blowup_n3.png","hero_blowup_n4.png"],
					first_frame: 0,
					last_frame: 1,
					current_frame: 0
				}
				HeroPlane.prototype.constructor.call(this, init_data)
				this.init()
			}
			
			HeroPlane.prototype = new Sprite()
			HeroPlane.prototype.fly = function() {
				this.div.style.top = this.div.offsetTop + this.speed + 'px'
				this.div.style.left = this.div.offsetLeft + 'px'
			}
			
			function Enemy1Plane(x, y) {
				init_data = {
					x: x,
					y: x,
					className: 'plane enemy1',
					path: 'image/enemy1/',
					image_files: ["enemy1.png","enemy1_down1.png","enemy1_down2.png","enemy1_down3.png","enemy1_down4.png"],
					first_frame: 0,
					last_frame: 0,
					current_frame: 0,
					speed: 5
				}
				Enemy1Plane.prototype.constructor.call(this, init_data)
				this.init()
			}
			
			Enemy1Plane.prototype = new Sprite()
			Enemy1Plane.prototype.fly = function() {
				console.log(this.div.offsetTop, this.speed)
				this.div.style.top = (this.div.offsetTop + this.speed) + 'px'
				if (this.div.offsetTop > container.clientHeight) {
					this.div.style.top = '-20px'					
				}				
			}
			
			function init() {
				// 创建一架我方飞机
				myplane = new HeroPlane()
				// 根据游戏规则,创建多架敌机enemy1_count
				for (var i = 0;i < enemy1_count;i++){
					x = getRand(50, 400)
					y = getRand(0, 100) - 100
					enemy1_array[i] = new Enemy1Plane(x, y)
				}
			}
			
			function run() {
				myplane.movies()
				enemy1_array.forEach(function(obj){
					obj.movies()
					obj.fly()
				})
				setTimeout(run, 30)
			}
			
			init()
			run()
			
			/* 通过Math对象生成随机数,将生成的敌机随机分布在画面中 */
			function getRand(min, max) {
				return Math.round((max-min)*Math.random())
			}
		</script>
	</body>
</html>

运行结果:
在这里插入图片描述

2.5.利用键盘控制飞机
2.5.1.如何通过键盘控制飞机飞行

1.要实现一个fly方法,根据按键来进行不同的方向移动
2.要给飞机对象一个speed属性,控制飞机的移动速度
3.通过keydown事件监测用户的操作
4.keyup事件取消控制

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>05.利用键盘控制控制己方飞机</title>
		<style>
			.container {
				position: relative;
				margin: 0;
				width: 400px;
				height: 600px;
				background: url(image/background.png);
				overflow: hidden;
			}
			.plane{
				position: absolute;
				left: 0;
				top: 0;
				border: 0px solid #f0f;
			}
			.hero {
				width: 100px;
				height: 122px;
			}
			.enemy1 {
				width: 51px;
				height: 39px;
			}
		</style>
	</head>
	<body>
		<div class="container">
			
		</div>
		<script>
			container = document.querySelector('.container')
			enemy1_array = []
			enemy1_count = 3
			/* 
			构造函数
			 创建飞机对象,定义飞机的图片,加载,变化等属性与方法
			 */
			function Sprite() {
				this.init = function() {
					div = document.createElement('div')
					container.appendChild(div)
					img = document.createElement('img')
					div.image = img
					div.appendChild(img)
					this.div = div
					div = null
					this.div.style.left = init_data.x + 'px'
					this.div.style.top = init_data.y + 'px'
					this.div.className = init_data.className
					this.path = init_data.path
					this.image_files = init_data.image_files
					this.first_frame = init_data.first_frame
					this.last_frame = init_data.last_frame
					this.current_frame = init_data.current_frame
					this.speed = init_data.speed
					this.images = []
				}
				this.load = function() {
					for (i=0;i<this.image_files.length - 1;i++){
						this.images[i] = new Image()
						this.images[i].src = this.path + this.image_files[i]
					}
					this.div.image.src = this.images[this.current_frame].src
				},
				
				this.movies = function() {
					this.current_frame += 1
					if (this.current_frame > this.last_frame) {
						this.current_frame = 0
					}
					this.div.image.src = this.images[this.current_frame].src
				}
			}
			
			function HeroPlane() {
				init_data = {
					x: 300,
					y: 300,
					className: 'plane heor',
					path: 'image/hero/',
					image_files: ["hero1.png","hero2.png","hero_blowup_n1.png","hero_blowup_n2.png","hero_blowup_n3.png","hero_blowup_n4.png"],
					first_frame : 0,
					last_frame : 1,
					current_frame : 0,
					speed : 10
				}
				HeroPlane.prototype.constructor.call(this,init_data)
			    this.init()
				this.load()
											
			}
				
			HeroPlane.prototype = new Sprite()
				
			HeroPlane.prototype.fly = function(){
			    plane = this.div
		        if (this.key == "ArrowLeft"){
					plane.style.left =( plane.offsetLeft - this.speed) +"px"
				}
				if (this.key == "ArrowRight"){
					 plane.style.left = ( plane.offsetLeft + this.speed) + "px"
				}
				if (this.key == "ArrowUp"){
					 plane.style.top = ( plane.offsetTop - this.speed) + "px"
				}
				if (this.key == "ArrowDown"){
					 plane.style.top = ( plane.offsetTop + this.speed) + "px"
				}
						
				
			}
			function Enemy1Plane(x,y){
				
				init_data = {
					x:x, 
					y:y, 
					className:"plane enemy1",
					path : "image/enemy1/",
					image_files : ["enemy1.png","enemy1_down1.png","enemy1_down2.png","enemy1_down3.png","enemy1_down4.png"],
					first_frame : 0,
					last_frame : 0,
					current_frame : 0,
					speed : 5
					}
				HeroPlane.prototype.constructor.call(this, init_data)
				this.init()
				this.load()
			
			}
			Enemy1Plane.prototype = new Sprite()
			Enemy1Plane.prototype.fly = function(){
				// console.log(this.div.offsetTop , this.speed )
				this.div.style.top = (this.div.offsetTop + this.speed )+ "px"		
				if (this.div.offsetTop > container.clientHeight){
					this.div.style.top = "-20px"
				}				
			}
			
			function init(){
				myplane = new HeroPlane()
				for (var i=0;i<enemy1_count;i++){
					x = getRand(50, 400)
					y = getRand(0, 100)-100
					enemy1_array[i] = new Enemy1Plane(x,y)
				}
				
			
			}
			
			function run(){
				myplane.movies()
				myplane.fly()
				enemy1_array.forEach(function(obj){
					obj.movies()
					obj.fly()
					})
				setTimeout(run,30)
			}
			
			init()
			run()
			/* 
			setInterval(run, 30)
			 */
			/* 
			 通过Math对象生成随机数,将生成的敌机随机分布在画面中
			 */
						 
			function getRand(min, max){
				return Math.round((max-min)*Math.random())
			}
			
			window.onload = function() {
				document.onkeydown = function(event) {
					if (event.key in {ArrowLeft:1, ArrowRight:1, ArrowUp:1, ArrowDown: 1}) {
						myplane.key = event.key
					}
				}
				document.onkeyup = function(event) {
					console.log('key:' + event.key)
					if (event.key in {ArrowLeft: 1, ArrowRight: 1, ArrowUp: 1, ArrowDown: 1}) {
						myplane.key = ''
					}
				}
			}
			
		</script>
	</body>
</html>

运行结果:
在这里插入图片描述

2.6.碰撞测试

在这里插入图片描述
代码实现:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
		    .container{
		        position: relative;
		        margin: 0;
		        /*padding: 0;*/
		        width: 400px;
		        height: 600px;
		        background: url(image/background.png);
		    }
			.plane{
			    position: absolute;
			    left: 0;
			    top:0;
			    border: 0px solid #f0f;	    
			}
			.hero {
				width: 100px;
				height: 122px;
			}
			.enemy1{
				width: 51px;
				height: 39px;
			}
			
		</style>
	</head>
	<body>
	   <div class="container">
	   	   
        </div>
	   </div>
	    
	    <script type="text/javascript">
	        
				container = document.querySelector(".container")
				enemy1_array = []
				enemy1_count = 3
                /* 
				构造函数
				创建飞机对象,定义飞机的图片,加载,变化等属性与方法
				*/
				function Sprite(){
					        
					this.init = function(){
						// console.log(init_data)
						div = document.createElement("div")
						container.appendChild(div)
						img = document.createElement("img")
						div.image = img 
						div.appendChild(img);
						this.div = div
						div = null
						this.div.style.left = init_data.x + "px"
						this.div.style.top  = init_data.y + "px"
						this.div.className  = init_data.className
						this.path = init_data.path
						this.image_files = init_data.image_files
						this.first_frame = init_data.first_frame
						this.last_frame = init_data.last_frame
						this.current_frame = init_data.current_frame
						this.speed = init_data.speed
						this.images = []
					}
					this.load = function(){
						// console.log(this.image_files)
						for (i=0;i<this.image_files.length-1;i++){
						   this.images[i] = new Image()
						   this.images[i].src = this.path+this.image_files[i]
						}
						
						this.div.image.src = this.images[this.current_frame].src
						
					},
							
					this.movies = function(){
						// console.log(this)
						this.current_frame += 1
						if (this.current_frame > this.last_frame){
							this.current_frame = 0
						}
						this.div.image.src = this.images[this.current_frame].src					
					}							
				}
				
				function HeroPlane(){
					 init_data = {
						x:300, 
						y:300, 
						className:"plane hero",
						path : "image/hero/",
						image_files : ["hero1.png","hero2.png","hero_blowup_n1.png","hero_blowup_n2.png","hero_blowup_n3.png","hero_blowup_n4.png"],
						first_frame : 0,
						last_frame : 1,
						current_frame : 0,
						speed : 3
						}
					HeroPlane.prototype.constructor.call(this,init_data)
				    this.init()
					this.load()					
				}
				
				HeroPlane.prototype = new Sprite()
				
				HeroPlane.prototype.fly = function(){
					plane = this.div
					if (this.key == "ArrowLeft"){
						 plane.style.left =( plane.offsetLeft - this.speed) +"px"
					}
					if (this.key == "ArrowRight"){
						 plane.style.left = ( plane.offsetLeft + this.speed) + "px"
					}
					if (this.key == "ArrowUp"){
						 plane.style.top = ( plane.offsetTop - this.speed) + "px"
					}
					if (this.key == "ArrowDown"){
						 plane.style.top = ( plane.offsetTop + this.speed) + "px"
					}						
				
				}
				function Enemy1Plane(x,y){
					
					init_data = {
						x:x, 
						y:y, 
						className:"plane enemy1",
						path : "image/enemy1/",
						image_files : ["enemy1.png","enemy1_down1.png","enemy1_down2.png","enemy1_down3.png","enemy1_down4.png"],
						first_frame : 0,
						last_frame : 0,
						current_frame : 0,
						speed : 5
						}
					HeroPlane.prototype.constructor.call(this, init_data)
					this.init()
					this.load()

				}
				Enemy1Plane.prototype = new Sprite()
				Enemy1Plane.prototype.fly = function(){
					// console.log(this.div.offsetTop , this.speed )
					this.div.style.top = (this.div.offsetTop + this.speed )+ "px"		
					if (this.div.offsetTop > container.clientHeight){
						this.div.style.top = "-20px"
					}					
				}				
				
				function init(){
					myplane = new HeroPlane()
					for (var i=0;i<enemy1_count;i++){
						x = getRand(50, 400)
						y = getRand(0, 100)-100
						enemy1_array[i] = new Enemy1Plane(x,y)
					}
				}
				
				function run(){
					myplane.movies()
					// enemy1plane.movies()
					setTimeout(run,30)
				}
				
				init()
				setTimeout(run, 30)
	    	    setInterval(function(){
					myplane.fly()
					enemy1_array.forEach(function(obj){
						obj.movies()
						obj.fly()
						if (isConflict(obj, myplane)){
							console.log("conflict")
						}
						})
				}, 30)
				
				function getRand(min, max){
					return Math.round((max-min)*Math.random())
				}
				
				function isConflict(obj1, obj2){
					// obj1在obj2的左上角原点左侧
					rect1 = obj1.div
					rect2 = obj2.div
					x_conflict_left = rect2.offsetLeft - rect1.offsetLeft <= rect1.offsetWidth  ? true : false,
					
					// obj1在obj2的左上角原点右侧
					x_conflict_right = rect1.offsetLeft - rect2.offsetLeft <= rect2.offsetWidth  ? true : false,
					
					// obj1在obj2的左上角原点上方
					y_conflict_top = rect2.offsetTop - rect1.offsetTop <= rect1.offsetHeight
					
					// obj1在obj2的左上角原点下方
					y_conflict_bottom = rect1.offsetTop - rect2.offsetTop <= rect2.offsetHeight
					console.log(x_conflict_left , x_conflict_right,y_conflict_top , y_conflict_bottom)
					return (x_conflict_left || x_conflict_right) && (y_conflict_top || y_conflict_bottom)
				}
				
				  
				window.onload=function(){
					document.onkeydown = function(event){
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=event.key
					  }
					}
					document.onkeyup=function(event){
					  console.log("key:"+event.key)
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=""
					  }
					}
				}
	    </script>
	</body>
</html>

2.7.爆炸效果

1.飞机如果相撞,那么生命值就会减值,可以设定一个伤害值
2.如果一个飞机的生命值为0了,那么他的状态就是死亡状态,应该播放爆炸效果
3.爆炸效果通过播放后面的爆炸帧实现
4.飞机爆炸后,需要将这个节点移除
5.创建新的飞机实例

添加碰撞爆炸效果

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
		    .container{
		        position: relative;
		        margin: 0;
		        /*padding: 0;*/
		        width: 400px;
		        height: 600px;
		        background: url(image/background.png);
		    }
			.plane{
			    position: absolute;
			    left: 0;
			    top:0;
			    border: 0px solid #f0f;	    
			}
			.hero {
				width: 100px;
				height: 122px;
			}
			.enemy1{
				width: 51px;
				height: 39px;
			}
			
		</style>
	</head>
	<body>
	   <div class="container">
	   	   
        </div>
	   </div>
	    
	    <script type="text/javascript">
	        
				container = document.querySelector(".container")
				myplane = null
				enemy1_array = []
				enemy1_count = 3
                /* 
				构造函数
				创建飞机对象,定义飞机的图片,加载,变化等属性与方法
				*/
				function Sprite(){}
				Sprite.prototype.init = function(){
					// console.log(init_data)
					div = document.createElement("div")
					container.appendChild(div)
					img = document.createElement("img")
					div.image = img 
					div.appendChild(img);
					this.div = div
					div = null
					this.div.style.left = init_data.x + "px"
					this.div.style.top  = init_data.y + "px"
					this.div.className  = init_data.className
					this.path = init_data.path
					this.image_files = init_data.image_files
					this.first_frame = init_data.first_frame
					this.last_frame = init_data.last_frame
					this.current_frame = init_data.current_frame
					this.speed = init_data.speed
					this.images = []
					this.life = init_data.life
					this.dead = false
					this.remove = function(){
						this.div.remove()
					}
					this.load = function(){
						// console.log(this.image_files)
								for (i=0;i<this.image_files.length-1;i++){
								   this.images[i] = new Image()
								   this.images[i].src = this.path+this.image_files[i]
								}
								
								this.div.image.src = this.images[this.current_frame].src
								
							},
							
					this.movies = function(){
					    // console.log(this)
						if (this.life<=0){
							this.last_frame = this.images.length-1
						}
						if (this.life<=0 && this.current_frame >= this.last_frame){
							this.dead = true
						}
						this.current_frame += 1
						if (this.current_frame > this.last_frame){
							this.current_frame = 0
						}
						
						this.div.image.src = this.images[this.current_frame].src
						
					
					}
				}
				
				
				
				function HeroPlane(){
					 init_data = {
						x:300, 
						y:300, 
						className:"plane hero",
						path : "image/hero/",
						image_files : ["hero1.png","hero2.png","hero_blowup_n1.png","hero_blowup_n2.png","hero_blowup_n3.png","hero_blowup_n4.png"],
						first_frame : 0,
						last_frame : 1,
						current_frame : 0,
						speed : 3,
						life: 10,
						dead:false
						}
					HeroPlane.prototype.constructor.call(this,init_data)
				    this.init()
					this.load()					
				}
				
				HeroPlane.prototype = new Sprite()				
				
				HeroPlane.prototype.fly = function(){
					    this.movies()
					    plane = this.div
						
                        if (this.key == "ArrowLeft"){
							 plane.style.left =( plane.offsetLeft - this.speed) +"px"
                        }
                        if (this.key == "ArrowRight"){
							 plane.style.left = ( plane.offsetLeft + this.speed) + "px"
                        }
                        if (this.key == "ArrowUp"){
							 plane.style.top = ( plane.offsetTop - this.speed) + "px"
                        }
                        if (this.key == "ArrowDown"){
							 plane.style.top = ( plane.offsetTop + this.speed) + "px"
                        }			
				}
				function Enemy1Plane(x,y){					
					init_data = {
						x: getRand(50, 400),
						y: getRand(0, 100)-400, 
						className:"plane enemy1",
						path : "image/enemy1/",
						image_files : ["enemy1.png","enemy1_down1.png","enemy1_down2.png","enemy1_down3.png","enemy1_down4.png"],
						first_frame : 0,
						last_frame : 0,
						current_frame : 0,
						speed : 5,
						life: 1,
						dead: false
						}
					Enemy1Plane.prototype.constructor.call(this, init_data)
					this.init()
					this.load()
				}
				Enemy1Plane.prototype = new Sprite()
				
				Enemy1Plane.prototype.fly = function(){
				        // console.log(this.div.offsetTop , this.speed )
						this.movies()
						this.div.style.top = (this.div.offsetTop + this.speed )+ "px"		
					    if (this.div.offsetTop > container.clientHeight){
							this.div.style.top = "-20px"
						}					
				}				
				
				function init(){
					myplane = new HeroPlane()
					for (var i=0;i<enemy1_count;i++){
						x = getRand(50, 400)
						y = getRand(0, 100)-100
						enemy1_array[i] = new Enemy1Plane(x,y)
					}
				}
				
				function run(){					
					if (myplane.dead){
						myplane.remove()
						myplane = null
					}
					
					for (i=0;i<enemy1_count; i++){
						if (enemy1_array[i].dead){
							enemy1_array[i].remove()
							enemy1_array[i] = null
							enemy1_array[i] = new Enemy1Plane(x,y)
						}
					}
					
					if (myplane == null){
						myplane = new HeroPlane()
					}					
				
					myplane.fly()
					
					enemy1_array.forEach(function(obj){
						obj.fly()
						if (obj.dead){
							obj.remove()
						}
						if (isConflict(obj, myplane)){
							// console.log("conflict")
							obj.life -= 1
							myplane.life -= 1
						}
						})
					setTimeout(run,30)					
				}
				
				init()
				run()	    	    
				
				function getRand(min, max){
					return Math.round((max-min)*Math.random())
				}
				
				function isConflict(obj1, obj2){					
					rect1 = obj1.div
					rect2 = obj2.div
					if (rect2.offsetLeft >= rect1.offsetLeft){
						// obj1在obj2的左上角原点左侧
						x_conflict = rect2.offsetLeft - rect1.offsetLeft <= rect1.offsetWidth  ? true : false
					} else {
						// obj1在obj2的左上角原点右侧
						x_conflict = rect1.offsetLeft - rect2.offsetLeft <= rect2.offsetWidth  ? true : false						
					}					
					
					if (rect2.offsetTop - rect1.offsetTop){	
						// obj1在obj2的左上角原点上方
						y_conflict = rect2.offsetTop - rect1.offsetTop <= rect1.offsetHeight
					} else {
						// obj1在obj2的左上角原点下方
						y_conflict = rect1.offsetTop - rect2.offsetTop <= rect2.offsetHeight
					}
					// console.log(x_conflict ,y_conflict)
					
					return x_conflict && y_conflict
				}				
				  
				window.onload=function(){
					document.onkeydown = function(event){
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=event.key
					  }
					}
					document.onkeyup=function(event){
					  console.log("key:"+event.key)
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=""
					  }
					}
				}
	    </script>
	</body>
</html>

运行结果:
在这里插入图片描述

2.8.子弹发射

子弹发射与飞机飞行的不同:

1.飞机是根据飞机数量,判定是否要创建新的飞机实例
2.子弹只要用户触发相关事件就发射,比如按下键盘空格键
3.子弹的数量是动态变化的
4.子弹撞上飞机或者飞出可视化区域就表示这颗子弹生命期结束,需要移除。

添加子弹发射:

 <!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
		    .container{
		        position: relative;
		        margin: 0;
		        /*padding: 0;*/
		        width: 400px;
		        height: 600px;
		        background: url(image/background.png);
		    }
			.plane{
			    position: absolute;
			    left: 0;
			    top:0;
			    border: 0px solid #f0f;	    
			}
			.hero {
				width: 100px;
				height: 122px;
			}
			.enemy1{
				width: 51px;
				height: 39px;
			}
			.bullet {
				width: 9px;
				height: 21px;
			}
		</style>
		<script type="text/javascript" src="js/helper.js"></script>
		<script type="text/javascript" src="js/sprite.js"></script>
	</head>
	<body>
	   <div class="container">
	   	   
        </div>
	   </div>	    
	    <script type="text/javascript">	        
				container = document.querySelector(".container")
				myplane = null
				enemy1_array = []
				enemy1_count = 3
                bullet_array = []
				//子弹构造函数
				function Bullet(x,y){
					init_data = {
						x: x,
						y: y, 
						className:"plane bullet",
						path : "image/bullet/",
						image_files : ["bullet1.png","bullet2.png"],
						first_frame : 0,
						last_frame : 1,
						current_frame : 0,
						speed : 10,
						life: 1,
						dead: false
					}
					this.init()
					this.load()
				}
				
				Bullet.prototype = new Sprite()
				Bullet.prototype.fly = function(){
					this.movies()
					this.div.style.top = (this.div.offsetTop - this.speed )+ "px"
					if (this.div.offsetTop <= 0){
						this.dead = true
					}
				}
				
				function init(){
					myplane = new HeroPlane()
					for (var i=0;i<enemy1_count;i++){
						x = getRand(50, 400)
						y = getRand(0, 100)-100
						enemy1_array[i] = new Enemy1Plane(x,y)
					}
				}
				
				function run(){					
					if (myplane.dead){
						myplane.remove()
						myplane = null
					}
					
					for (i=0;i<enemy1_count; i++){
						if (enemy1_array[i].dead){
							enemy1_array[i].remove()
							enemy1_array[i] = null
							enemy1_array[i] = new Enemy1Plane(x,y)
						}
					}
					
					for (i=0;i<bullet_array.length; i++){
						if (bullet_array[i].dead){
							bullet_array[i].remove()
							bullet_array[i] = null
							bullet_array.splice(i,1)							
						}
					}
					if (myplane == null){
						myplane = new HeroPlane()
					}			
				
					myplane.fly()
					
					enemy1_array.forEach(function(obj){
						obj.fly()
						
						if (obj.dead){
							obj.remove()
						}
						if (isConflict(obj, myplane)){
						
							obj.life -= 1
							myplane.life -= 1
						}
						})
						
					bullet_array.forEach(function(bullet, index, bullet_array){
						bullet.fly()
							enemy1_array.forEach(function(enemy){
								if (isConflict(bullet, enemy)){

									bullet.life -= 1
									enemy.life -= 1
								}
							})
						})
					setTimeout(run,30)					
				}
				
				function shot(){
				
					bullet = new Bullet(myplane.div.offsetLeft+myplane.div.offsetWidth/2,
					                    myplane.div.offsetTop
					                   )
				 
					bullet_array.push(bullet)
					
				}
				
				init()
				run()
				  
				window.onload=function(){
					document.onkeydown = function(event){
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=event.key
					  }
					  if (event.key == " "){
						  shot()
					  }
					}
					document.onkeyup=function(event){
					  console.log("key:"+event.key)
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=""
					  }
					}
				}
	    </script>
	</body>
</html>

运行结果:
在这里插入图片描述

2.9.代码整理

代码越来越多,就需要管理:

1.一般的前端会有这些文件夹:js,img,css,media,upload
2.将自己的文件分门别类放置,通过外部加载方式,可以让主页结构比较简洁
3.由于外部加载可能存在缓存,需要注意缓存,如果修改后没有变化,就清除浏览器缓存看看

整理后的全部代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
		    .container{
		        position: relative;
		        margin: 0;
		        /*padding: 0;*/
		        width: 400px;
		        height: 600px;
		        background: url(image/background.png) repeat-y;
		    	animation:background-move 10s  linear infinite;
				overflow: hidden;
		    }
		    
		    @-webkit-keyframes background-move{
		    	from{background-position: 0 0;}
		    	to{background-position: 0 852px;}
		    }
			
			.plane{
			    position: absolute;
			    left: 0;
			    top:0;
			    border: 0px solid #f0f;	    
			}
			.hero {
				width: 100px;
				height: 122px;
			}
			.enemy1{
				width: 51px;
				height: 39px;
			}
			.bullet {
				width: 9px;
				height: 21px;
			}
			#start {
				margin: -webkit-calc(50%)
			}
		</style>
		<script type="text/javascript" src="js/helper.js"></script>
		<script type="text/javascript" src="js/sprite.js"></script>
	</head>
	<body>
	   <div class="container">
	   	   <input type="image" src="image/game_resume_pressed.png" id="start" />
        </div>
	   </div>
	    <audio src="sound/game_music.wav"  id="game_music" loop="loop">
	    	当前浏览器不支持audio
	    </audio>
	    <script type="text/javascript">
	        
				container = document.querySelector(".container")
				start_btn = document.querySelector("#start")
				game_music = document.querySelector("#game_music")
				myplane = null
				enemy1_array = []
				enemy1_count = 3
                bullet_array = []
				
				function init(){
					myplane = new HeroPlane()
					for (var i=0;i<enemy1_count;i++){
						x = getRand(50, 400)
						y = getRand(0, 100)-100
						enemy1_array[i] = new Enemy1Plane(x,y)
					}
				}
				
				function run(){
					
					if (myplane.dead){
						myplane.remove()
						myplane = new HeroPlane()
					}
					
					for (i=0;i<enemy1_count; i++){
						if (enemy1_array[i].dead){
							enemy1_array[i].remove()
							enemy1_array[i] = new Enemy1Plane(x,y)
						}
					}
					
					for (i=0;i<bullet_array.length; i++){
						if (bullet_array[i].dead){
							bullet_array[i].remove()
							bullet_array[i] = null
							bullet_array.splice(i,1)
						}
					}

					myplane.fly()
					
					enemy1_array.forEach(function(obj){
						obj.fly()
						
						if (obj.dead){
							obj.remove()
						}
						if (isConflict(obj, myplane)){
							obj.life -= 1
							myplane.life -= 1
						}
						})
						
					bullet_array.forEach(function(bullet, index, bullet_array){
							bullet.fly()
							enemy1_array.forEach(function(enemy){
								if (isConflict(bullet, enemy)){
									bullet.life -= 1
									enemy.life -= 1
								}
							})
						})
						
					setTimeout(run,30)
					
				}
				
				function shot(){
					
					bullet = new Bullet(myplane.div.offsetLeft+myplane.div.offsetWidth/2,
					                    myplane.div.offsetTop
					                   )
				 
					bullet_array.push(bullet)
					
				}
				
				
				function play(){
					init()
					run()
	    	    }
				
				  
				window.onload=function(){
					document.onkeydown = function(event){
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=event.key
					  }
					  if (event.key == " "){
						  shot()
					  }
					}
					document.onkeyup=function(event){
					  if (event.key in {ArrowLeft:1,ArrowRight:1,ArrowUp:1,ArrowDown:1}){
							myplane.key=""
					  }
					}
					
					start_btn.onclick = function(){
						this.style.display = "none"
						game_music.play()
						play()
					}
				}
	    </script>
	</body>
</html>

运行结果:(运行是有声音效果的)
在这里插入图片描述
完整代码等我整理好上传到github后再分享给同学们哈 ^_^

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值