jjzjj

飞机大战代码

而 已 2024-03-13 原文

飞机大战代码


设计代码:


<!DOCIYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>飞机大战</title>
	<style>
		canvas{
		border:1px solid #000;
		display:block;
		margin:auto;
		aligin:center;
		}
	</style>
</head>
<body>
	<!--整个游戏的思路使用html5中的canvas进行绘制-->
	<canvas id="canvas" width="480" height="700"></canvas>
	
  <script>
  	// 游戏使用构造函数的方式进行完成
    // 获取canvas的标签并且获取画笔
	var canvas = document.getElementById("canvas");
	var can = canvas.getContext("2d");//设置类型为2D的类型
	      // 0.初始化游戏的数据
        // 0.1 将游戏的5个阶段定义成5个常量
        const START = 0;            //游戏欢迎阶段
        const STARTTING = 1;        //游戏准备中
        const RUNNING = 2;          //游戏运行
        const PAUSE = 3;            //游戏暂停
        const GAMEOVER = 4;         //游戏结束
        // 0.2 定义自己的一个状态,时刻的和五个阶段进行比较,判定出游戏处于哪个阶段
        var state = START;
        // 0.3 画布的宽和高
        var WIDTH = 480;
        var HEIGHT = 700;
        // 0.4 定义游戏的分数
        var score = 0;
        // 0.5 定义生命值
        var life = 3;

	// 1.游戏欢迎阶段
    // 1.1 加载背景图片
    // 1.1.1 加载背景图片被标签
	var bg = new Image();
	bg.src = "images/background.png";
	// 1.1.2 初始化背景图片的数据
	var BG = {
		imgs : bg,
		width : 480,
		height : 852
	}
	// 1.1.3 背景图片的构造函数
	function Bg(config){
		this.imgs = config.imgs;
		this.width = config.width;
		this.height = config.height;
		// 定义绘制背景图片的坐标
		this.x1 = 0;
		this.y1 = 0;
		this.x2 = 0;
		this.y2 = -this.height;
		 // 定义绘制背景图片的方法
		this.paint = function(){
			can.drawImage(this.imgs,this.x1,this.y1);
			can.drawImage(this.imgs,this.x2,this.y2);
		}
		 // 运动方法
		this.step = function(){
			// 背景图片的运动就是改变y坐标
			this.y1++;
			this.y2++;
			if(this.y1 == this.height){
				this.y1 = -this.height;
			}
			if(this.y2 == this.height){
				this.y2 = -this.height;
			}
		}
	}
	 // 1.1.4 构造背景对象
	var sky = new Bg(BG);
	 // 1.2 加载LOGO图片
	var logo = new Image();
	logo.src = "images/start.png";
	// 2.游戏准备中阶段  过渡阶段
     // 第一阶段到第二阶段的过程,通过鼠标的点击事件
     // 第二阶段是加载动画
     // 2.1 加载过渡动画的图片
	var loadings = [];
	loadings[0] = new Image();
	loadings[0].src = "images/game_loading1.png";
	loadings[1] = new Image();
	loadings[1].src = "images/game_loading2.png";
	loadings[2] = new Image();
	loadings[2].src = "images/game_loading3.png";
	loadings[3] = new Image();
	loadings[3].src = "images/game_loading4.png";
	// 2.2 初始化图片的数据
	var LOADINGS = {
		imgs : loadings,
		length : loadings.length,
		width : 186,
		height : 38
	}
	// 2.3 初始化图片的构造函数
	function Loading(config){
		this.imgs = config.imgs;
		this.length = config.length;
		this.width = config.width;
		this.height = config.height;
		// 取到对应图片的索引
		this.startIndex = 0;
		// 定义绘制图片的方法
		this.paint = function(){
			can.drawImage(this.imgs[this.startIndex],0,HEIGHT-this.height);
		}
		// 因为运动的太快了,定义一个速度
		this.time = 0;
		// 定义图片的运动方法
		this.step = function(){
			this.time++;
			if(this.time%3 == 0){
				this.startIndex++;
			}
			// 判断,当索引值增加到4(数组的长度)的时候,进入下一个阶段
			if(this.startIndex == this.length){
				// 动画执行完毕,进入下一阶段
				state = RUNNING;
			}
		}
	}
	// 2.4 创建出图片运动的对象
	var loading = new Loading(LOADINGS);
	// 2.5 当游戏处于第一阶段(初始化)的时候,点击以后可以切换到第二阶段(图片运动阶段)
	canvas.onclick = function(){
		if(state == START){
			state = STARTTING;
		}
	}
        // 3.游戏运行阶段
        // 3.1 我方飞机
        // 3.1.1 我方飞机的图片
	var heros = [];
	// 正常运行的图片
	heros[0] = new Image();
	heros[0].src = "images/hero1.png";
	heros[1] = new Image();
	heros[1].src = "images/hero2.png";
	 // 发生碰撞以后的图片
	heros[2] = new Image();
	heros[2].src = "images/hero_blowup_n1.png";
	heros[3] = new Image();
	heros[3].src = "images/hero_blowup_n2.png";
	heros[4] = new Image();
	heros[4].src = "images/hero_blowup_n3.png";
	heros[5] = new Image();
	heros[5].src = "images/hero_blowup_n4.png";
	// 3.1.2 我方飞机的数据
	var HEROS = {
		imgs : heros,
		length : heros.length,
		width : 99,
		height : 124,
		frame : 2//表示状态   2种状态   1种正常运行的状态  1种发生碰撞以后的状
	}
	// 3.1.3 我方飞机的构造函数
	function Hero(config){
		this.imgs = config.imgs;
		this.length = config.length;
		this.width = config.width;
		this.height = config.height;
		this.frame = config.frame;
		// 需要对应的索引,表示获取图片
		this.startIndex = 0;
		this.x = WIDTH/2-this.width/2;
		this.y = HEIGHT-150;
		// 增加一个标识符 判断目前飞机处于什么样的状态
		this.down = false;//增加是否碰撞,false表示一直没有发生碰撞
		// 定义绘制的方法
		this.paint = function(){
			can.drawImage(this.imgs[this.startIndex],this.x,this.y);
		}
		// 定义动画方法
		this.step = function(){
			if(!this.down){//如果没有被撞击
				if(this.startIndex == 0){
					this.startIndex = 1;
				}else{
					this.startIndex = 0;
				}
			}else{
				this.startIndex++;
				if(this.startIndex == this.length){
					life--;
					if(life == 0){
						state = GAMEOVER;
						this.startIndex = this.length-1;
					}else{
						hero = new Hero(HEROS);
					}
				}
			}
		}
		 // 增加一个射击的速度
		this.time = 0;
		// 增加射击的方法
		this.shoot = function(){
			this.time++;
			if(this.time%3 == 0){
				bullets.push(new Bullet(BULLET));
			}
		}
		// 增加碰撞的方法
		this.bang = function(){
			this.down = true;
		}
	}
	// 3.1.4 创建我方飞机的对象
	var hero = new Hero(HEROS);
	// 3.1.5 绑定鼠标事件,控制飞机的移动
	canvas.onmousemove = function(event){
		if(state == RUNNING){
			var x = event.offsetX;
			var y = event.offsetY;
			hero.x = x - hero.width/2;
			hero.y = y - hero.height/2;
		}
	}

    // 3.2 绘制子弹
    // 3.2.1 加载子弹的图片
	var bullet = new Image();
	bullet.src = "images/bullet1.png";
	// 3.2.2 初始化子弹的数据
	var BULLET = {
		imgs : bullet,
		width : 9,
		height : 21
	}
	 // 3.2.3 子弹的构造函数
	function Bullet(config){
		this.imgs = config.imgs;
		this.width = config.width;
		this.height = config.height;
		this.x = hero.x + hero.width/2 - this.width/2;
		this.y = hero.y - this.height - 10;
		// 定义绘制函数
		this.paint = function(){
			can.drawImage(this.imgs,this.x,this.y);
		}
		// 定义运动函数
		this.step = function(){
			this.y-=10;
		}
		// 定义子弹的撞击属性
		this.candel = false;
		this.bang = function(){
			this.candel = true;
		}
	}
	// 3.2.4 创建数组,用于存储子弹
	var bullets = [];
	// 3.2.5 创建函数,用于绘制所有的子弹
	function bulletsPaint(){
		for(var i=0;i<bullets.length;i++){
			// 循环调用绘制的方法
			bullets[i].paint();
		}
	}
// 3.2.6 创建函数,用于运动所有的子弹
	function bulletsStep(){
		for(var i=0;i<bullets.length;i++){
			bullets[i].step();
		}
	}
// 3.2.7 创建函数,用于删除子弹
	function bulletsDel(){
		// 1.子弹出画布    2.子弹发生了撞击
		for(var i=0;i<bullets.length;i++){
			if(bullets[i].y < -bullets[i].height || bullets[i].candel){
				bullets.splice(i,1);
			}
		}
	}
	// 3.3 敌方飞机
    // 3.3.1 敌方飞机一共有三种,加载3种不同的图片
	var enemy1 = [];// 小飞机
	enemy1[0] = new Image();
	enemy1[0].src = "images/enemy1.png";
	enemy1[1] = new Image();
	enemy1[1].src = "images/enemy1_down1.png";
	enemy1[2] = new Image();
	enemy1[2].src = "images/enemy1_down2.png";
	enemy1[3] = new Image();
	enemy1[3].src = "images/enemy1_down3.png";
	enemy1[4] = new Image();
	enemy1[4].src = "images/enemy1_down4.png";
	var enemy2 = [];// 中飞机
	enemy2[0] = new Image();
	enemy2[0].src = "images/enemy2.png";
	enemy2[1] = new Image();
	enemy2[1].src = "images/enemy2_down1.png";
	enemy2[2] = new Image();
	enemy2[2].src = "images/enemy2_down2.png";
	enemy2[3] = new Image();
	enemy2[3].src = "images/enemy2_down3.png";
	enemy2[4] = new Image();
	enemy2[4].src = "images/enemy2_down4.png";
	var enemy3 = [];// 大飞机
	enemy3[0] = new Image();
	enemy3[0].src = "images/enemy3_n1.png";
	enemy3[1] = new Image();
	enemy3[1].src = "images/enemy3_n2.png";
	enemy3[2] = new Image();
	enemy3[2].src = "images/enemy3_down1.png";
	enemy3[3] = new Image();
	enemy3[3].src = "images/enemy3_down2.png";
	enemy3[4] = new Image();
	enemy3[4].src = "images/enemy3_down3.png";
	enemy3[5] = new Image();
	enemy3[5].src = "images/enemy3_down4.png";
	enemy3[6] = new Image();
	enemy3[6].src = "images/enemy3_down5.png";
	enemy3[7] = new Image();
	enemy3[7].src = "images/enemy3_down6.png";
	// 3.3.2 敌方飞机的数据
	var ENEMY1 = {
		imgs : enemy1,
		length : enemy1.length,
		width : 57,
		height : 51,
		type : 1,
		frame : 1,
		life : 1,
		score : 1
	}
	var ENEMY2 = {
		imgs : enemy2,
		length : enemy2.length,
		width : 69,
		height : 95,
		type : 2,
		frame : 1,
		life : 3,
		score : 3
	}
	var ENEMY3 = {
		imgs : enemy3,
		length : enemy3.length,
		width : 169,
		height : 258,
		type : 3,
		frame : 2,
		life : 20,
		score : 10
	}
	// 3.3.3 敌方飞机的构造函数
	function Enemy(config){
		this.imgs = config.imgs;
		this.length = config.length;
		this.width = config.width;
		this.height = config.height;
		this.type = config.type;
		this.frame = config.frame;
		this.life = config.life;
		this.score = config.score;
		this.x = Math.random() * (WIDTH - this.width);// 0 - (画布宽-飞机宽)
		this.y = -this.height;
		this.startIndex = 0;
		this.down = false;
		this.candel = false;
		// 绘制方法
		this.paint = function(){
			can.drawImage(this.imgs[this.startIndex],this.x,this.y);
		}
		// 运动方法
		this.step = function(){
			if(!this.down){//正常
				this.startIndex++;
				this.startIndex = this.startIndex%this.frame;
				this.y+=2;
			}else{
				this.startIndex++;
				if(this.startIndex == this.length){
					this.candel = true;
					this.startIndex = this.length-1;
				}
			}
		}

		//是否被撞击
		this.checkHit = function(wo){
			return wo.y + wo.height > this.y
			&& wo.x + wo.width > this.x
			&& wo.y < this.y + this.height
			&& wo.x < this.x + this.width;
		}

		// 新增方法bang() - 用于被撞击后的逻辑
		this.bang = function(){
			this.life--;
			if(this.life == 0){
				this.down = true;
				score += this.score;
			}
		}
	}

	// 3.3.4 创建数组,用于存放敌方飞机
	var enemies = [];
	// 3.3.5 创建函数,增加飞机到数组
	function enterEnemies(){
		var rand = Math.floor(Math.random()*100);
		if(rand <= 7){
			// 小飞机
			enemies.push(new Enemy(ENEMY1));
		}else if(rand == 8){
			// 中飞机
			enemies.push(new Enemy(ENEMY2));
		}else if(rand == 9){
			// 大飞机 - 只允许数组的第一个元素为大飞机
			if(enemies[0].type != 3 && enemies.length > 0){
				enemies.splice(0,0,new Enemy(ENEMY3));
			}
		}
	}
	// 3.3.6 创建函数,绘制数组中的敌方飞机
	function paintEnemies(){
		for(var i=0;i<enemies.length;i++){
			enemies[i].paint();
		}
	}
	// 3.3.7 创建函数,运动数组中的敌方飞机
	function stepEnemies(){
		for(var i=0;i<enemies.length;i++){
			enemies[i].step();
		}
	}
	// 3.3.8 创建函数,删除数组中的敌方飞机
	function delEnemies(){
		for(var i=0;i<enemies.length;i++){
			// 敌方飞机的y值 > 画布的高度
			if(enemies[i].y > HEIGHT||enemies[i].candel){
				enemies.splice(i,1);
			}
		}
	}
	// 3.3.9 创建函数,用于检测撞击敌方飞机的情况
	function hitEnemies(){
		for(var i=0;i<enemies.length;i++){
			if(enemies[i].checkHit(hero)){
				enemies[i].bang();
				hero.bang();
			}
			// 子弹撞击敌方飞机
			for(var j=0;j<bullets.length;j++){
				if(enemies[i].checkHit(bullets[j])){
					enemies[i].bang();
					bullets[j].bang();
				}
			}
		}
	}
	//游戏得分与我方飞机的生命值
	function paintText(){
		can.font = "bold 24px 微软雅黑";
		can.fillText("SCORE: "+score,10,30);
		can.fillText("LIFE: "+life,390,30);
	}
	// 4.游戏暂停阶段
	canvas.onmouseover = function(){
		//从暂停恢复到运行
		if(state == PAUSE){
			state = RUNNING;
		}
	}
	canvas.onmouseout = function(){
		//从运行切换到暂停
		if(state == RUNNING){
			state = PAUSE;
		}
	}
	var pause = new Image();
	pause.src = "images/game_pause_nor.png";
	
	// 5.游戏结束阶段
	function paintOver(){
		can.font = "bold 48px 微软雅黑";
		can.fillText("GAME OVER",100,320);
	}
// 写定时器,让整个图片开始动起来
	setInterval(function(){
		 // 1.背景图片
         // 1.1 调用背景图片的绘制方法
		sky.paint();
		// 1.2 调用背景图片的运动方法
		sky.step();
		// 分阶段进行处理
		if(state == START){
			// 第一个阶段
			can.drawImage(logo,20,0);
		}else if(state == STARTTING){
			// 第二个阶段
            // 绘制动画的图片
			loading.paint();
			loading.step();
		}else if(state == RUNNING){
			// 第三个阶段
            // 绘制我方飞机
			hero.paint();
			// 绘制我方飞机的运动状态
			hero.step();
			// 子弹
            // 绘制子弹
			hero.shoot();
			bulletsPaint();
			// 运动子弹
			bulletsStep();
			// 删除子弹
			bulletsDel();
			// 敌方飞机
            // 增加敌方飞机
			enterEnemies();
			// 绘制敌方飞机
			paintEnemies();
			// 运动敌方飞机
			stepEnemies();
			// 删除敌方飞机
			delEnemies();
			// 碰撞方法
			hitEnemies();
			paintText();
		}else if(state == PAUSE){
			hero.paint();
			bulletsPaint();
			paintEnemies();
			paintText();
			can.drawImage(pause,10,30);	
		}else if(state == GAMEOVER){
			hero.paint();
			bulletsPaint();
			paintEnemies();
			paintText();
			paintOver();
		}
	},50);
 </script>
  
 </body>
</html>

有关飞机大战代码的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  4. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  5. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  6. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  7. 程序员如何提高代码能力? - 2

    前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源

  8. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

  9. git使用常见问题(提交代码,合并冲突) - 2

    文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g

  10. ruby - 这两段代码有什么区别? - 2

    打印1:defsum(i)i=i+[2]end$x=[1]sum($x)print$x打印12:defsum(i)i.push(2)end$x=[1]sum($x)print$x后者是修改全局变量$x。为什么它在第二个例子中被修改而不是在第一个例子中?类Array的任何方法(不仅是push)都会发生这种情况吗? 最佳答案 变量范围在这里无关紧要。在第一段代码中,您仅使用赋值运算符=为变量i赋值,而在第二段代码中,您正在修改$x(也称为i)使用破坏性方法push。赋值从不修改任何对象。它只是提供一个名称来引用一个对象。方法要么是破坏性

随机推荐