一、简介
还记得许多年前的春天,你我一起“打飞机”。
那就一起写个打飞机游戏吧:
二、HTML内容
HTML内容把需要的图片资源以相应标签格式写出即可,分为以下几部分:
-
- 背景图片
- 自己战机的图片
- 子弹的图片
- 敌机的图片
- 敌机挂了的图片
- 计算分数的位置预留
<base href="http://images.cnblogs.com/cnblogs_com/suoning/860380/" /> <div class="bg"> <div class="me-plan"></div> <div id="play_num"></div> <div class="bullet"> <img src="o_cartridge.png"> </div> <div class="x"> <img class="lift" src="o_plain1.png"> <img class="die" src="o_die1.png"> </div> <div class="x2"> <img class="lift" src="o_plain2.png"> <img class="die" src="o_die2.png"> </div> </div>
三、CSS布局
CSS代码块只需把HTML代码块的图片进程简单布局,分以下几部分:
-
- 背景图片的宽与高、居中、边框、超出边界隐藏、relative相对定位
- 自己战机的宽与高、absolute相对父级定位与z-index优先级最高
- 自己战机默认隐藏,游戏开始则滑出
- 子弹、敌机的absolute相对父级定位
- 子弹、敌机的默认隐藏,游戏开始则通过克隆展示
- 敌机死亡的图片定位与隐藏
- 分数的字体大小设置及定位
<base href="http://images.cnblogs.com/cnblogs_com/suoning/860380/" /> <style> .bg { background-image: url("o_bg.jpg"); height: 500px; width: 300px; position: relative; margin-left: 40%; margin-top: 5%; overflow: hidden; border: 1px; } .me-plan { width: 99px; height: 112px; background-image: url("o_me.png"); position: absolute; top: 80%; left: 35%; display: none; z-index: 666; } .bullet { position: absolute; display: none; left: -10px; } .x, .x2 { position: absolute; display: none; } .lift { position: absolute; top: -110px; } .die { display: none; } #play_num { font-size: 30px; } </style>
四、jQuery 代码块
JavaScript基础知识戳这,DOM相关戳这,jQuery全套戳这
jQuery代码块是程序的主要实现部分:
-
- 自己战机得需要跟着鼠标移动
- 自己战机移动的同时子弹也需要同时做相对定位的移动
- 敌机随机从上到下移动
- 敌机若与子弹相碰,则炸毁,相应分数增加
1、程序所需值与预定义
程序在一开始就必须获取相应的值,以便之后调用:
背景的宽与高 :判断自己战机是否超出边界,如果超出则固定在边界内某一块;
自己战机的宽与高:也做超出边界固定的作用,加上这个值更精确;
背景图片相对父元素的距离:这个值也可以说背景图片相对body的距离,因为需要不断获取鼠标的坐标,来确定自己战机的位置,鼠标的坐标减去这个值即是元素相对父级元素的距离;
还需要预定义一些值:
play_num:游戏的得分,默认定位0;
FD = {}:定义一个"字典",存放每个敌机的对象与对于标签,用于判断碰撞。
var dwidth = $('.bg').width(); // 背景的宽与高 var dheight = $('.bg').height(); var fwidth = $('.me-plan').width(); // 自己战机的宽与高 var fheight = $('.me-plan').height(); var zwidth = $('.bullet').width(); // 子弹的宽与高 var zheight = $('.bullet').height(); var t = $('.bg').offset().top; // 背景相对父元素的距离 var l = $('.bg').offset().left; var FD = {}; // 存放敌的的对象,封装坐标及标签 var play_num = 0; // 计算分数
2、鼠标移动事件
自己战机需要不断跟着鼠标走,所有必须定义鼠标移动事件;
event.clientX与event.clientY分别为鼠标的x和y轴距离;
判断如果超出边界,则战机固定位置;
鼠标位置坐相应处理就是战机的位置(实时)。
$(".me-plan").mousemove(function m(event) { /* 鼠标移动事件 */ var x = event.clientX - fwidth / 2; var y = event.clientY - fheight / 2; MovePlanM(x - l, y - t); }) function MovePlanM(x, y) { /* 战机随鼠标移动 */ if (x >= dwidth) { x = dwidth - fwidth; } else if (y >= dheight) { y = dheight - fheight; } $('.me-plan').css({ "top": y + "px", "left": x + "px", }); }
3、随机值
每次敌机出现的x轴位置是不同的,所有需要写一个随机数函数;
可以以做为出现敌机的类型,小飞机与大飞机。
function Randmon() { /* 用于随机生成x轴与敌机型号 */ var num_one = Math.random(); var num_two = num_one * 100; if (num_two < 80) { num_two += 100; } num_stree = Math.round(Math.abs(num_two)); return num_stree }
4、敌机类
一次可以出现一个以上敌机,而敌机属性都类似,所有需要写一个类;
三个参数,分别为x轴,y轴,还有敌机的类型;
通过克隆再插入对应标签实现多个敌机;
通过定时器使y轴自加,使敌机不断向下移动;
判断如果超出背景,则停止定时器,删除对应标签;
把对象都加入FD字典中;
注意:定时器为单独函数,不属于类,所以需要用到继承。
function FoePlan(x, y, BB) { /* 克隆及移动敌机 */ this.x = x; this.y = y; this.BB = BB; this.Clone = function () { var objj = $(this.BB).first().clone(true).appendTo(".bg").css("display", "block"); var s2 = setInterval(MovePlanFirst, 100); function MovePlanFirst() { FoePlan.call(this, x, y, BB); // 类的继承 var dic = [this.x, this.y, objj]; FD[this] = dic; RemovePlan(this.y, s2, objj); y += 20; objj.css({ "top": this.y + "px", "left": this.x + "px", }) } } } function RemovePlan(y, s2, objj) { /* 用于删除出镜的敌机 */ if (y > 600) { clearInterval(s2); $(objj).remove(); } }
5、子弹相关
两个参数,分别为自己战机x轴与y轴坐标,用于跟着战机相对移动;
定时器让y轴坐标自减,对应的子弹会一直上升;
子弹超出边界则删除定时器与对应标签;
循环读取FD字典,得到每个敌机的坐标,判断碰撞则爆炸效果,并淡出;
如果击落敌机对应分数增加;
击落敌机删除对应标签与FD中的值。
function MoveBullet(x, y) { /* 克隆及移动子弹、判断子弹是否射到敌机 */ var obj = $('.bullet').first().clone(true).appendTo(".bg").css("display", "block"); var s1 = setInterval(function () { for (var item in FD) { // 判断子弹是否射到敌机 var xx = FD[item][0]; var yy = FD[item][1]; var objj = FD[item][2]; var flag = false; if ((xx < x) && (x < (xx + 60)) && (yy < y) && ( y < (yy + 60))) { $(objj).children().first().css("display", "none"); $(objj).children().last().css("display", "block").fadeOut("1600").fadeTo("slow", 0); play_num += 10; $('#play_num').text(play_num); } if (flag) { $(objj).remove(); flag = false; } } RemoveBullet(y, s1, obj); y -= 20; obj.css({ "top": (y) + "px", "left": x + "px", }) }, 100); } function RemoveBullet(y, s1, obj) { /* 删除超出边界的子弹 */ if (y < 0) { clearInterval(s1); $(obj).remove(); } }
6、运行程序
页面加载完成则开始运行游戏;
定时器获取自己战机的坐标,并传给子弹,让子弹不断开炮;
定时器获取随机值,并传给敌机类,让敌机不断涌现。
$(function () { /* 页面加载完成初始化开始游戏 */ $(".me-plan").slideDown("900"); setInterval(function () { var x = $(".me-plan").position().left + fwidth / 2; var y = $(".me-plan").position().top; MoveBullet(x, y); }, 200); setInterval(function () { var n = Randmon(); if (n > 130) { var shape = '.x'; } else { var shape = '.x2'; } var obj = new FoePlan(n, 0, shape); obj.Clone(); }, 1500); });
五、完整代码
注:访问代码里图片路径需加前缀:
http://images.cnblogs.com/cnblogs_com/suoning/860380/ + 图片名字
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>外挂版打飞机 Nick Suo</title> <base href="http://images.cnblogs.com/cnblogs_com/suoning/860380/"/> <style> .bg { background-image: url("o_bg.jpg"); height: 500px; 300px; position: relative; margin-left: 40%; margin-top: 5%; overflow: hidden; border: 1px; } .me-plan { 99px; height: 112px; background-image: url("o_me.png"); position: absolute; top: 80%; left: 35%; display: none; z-index: 666; } .bullet { position: absolute; display: none; left: -10px; } .x, .x2 { position: absolute; display: none; } .lift { position: absolute; top: -110px; } .die { display: none; } #play_num { font-size: 30px; } </style> </head> <body> <div class="bg"> <div class="me-plan"></div> <div id="play_num"></div> <div class="bullet"> <img src="o_cartridge.png"> </div> <div class="x"> <img class="lift" src="o_plain1.png"> <img class="die" src="o_die1.png"> </div> <div class="x2"> <img class="lift" src="o_plain2.png"> <img class="die" src="o_die2.png"> </div> </div> <script src="../jquery-1.12.4.js"></script> <script> /* build time: Jul 28,2016 23:59 author: Nick Suo email: 630571017@qq.com */ var dwidth = $('.bg').width(); // 背景的宽与高 var dheight = $('.bg').height(); var fwidth = $('.me-plan').width(); // 自己战机的宽与高 var fheight = $('.me-plan').height(); var zwidth = $('.bullet').width(); // 子弹的宽与高 var zheight = $('.bullet').height(); var t = $('.bg').offset().top; // 背景相对父元素的距离 var l = $('.bg').offset().left; var FD = {}; // 存放敌的的对象,封装坐标及标签 var play_num = 0; // 计算分数 $(".me-plan").mousemove(function m(event) { /* 鼠标移动事件 */ var x = event.clientX - fwidth / 2; var y = event.clientY - fheight / 2; MovePlanM(x - l, y - t); }) function MovePlanM(x, y) { /* 战机随鼠标移动 */ if (x >= dwidth) { x = dwidth - fwidth; } else if (y >= dheight) { y = dheight - fheight; } $('.me-plan').css({ "top": y + "px", "left": x + "px", }); } $(function () { /* 页面加载完成初始化开始游戏 */ $(".me-plan").slideDown("900"); setInterval(function () { var x = $(".me-plan").position().left + fwidth / 2; var y = $(".me-plan").position().top; MoveBullet(x, y); }, 200); setInterval(function () { var n = Randmon(); if (n > 130) { var shape = '.x'; } else { var shape = '.x2'; } var obj = new FoePlan(n, 0, shape); obj.Clone(); }, 1500); }); function MoveBullet(x, y) { /* 克隆及移动子弹、判断子弹是否射到敌机 */ var obj = $('.bullet').first().clone(true).appendTo(".bg").css("display", "block"); var s1 = setInterval(function () { for (var item in FD) { // 判断子弹是否射到敌机 var xx = FD[item][0]; var yy = FD[item][1]; var objj = FD[item][2]; var flag = false; if ((xx < x) && (x < (xx + 60)) && (yy < y) && ( y < (yy + 60))) { $(objj).children().first().css("display", "none"); $(objj).children().last().css("display", "block").fadeOut("1600").fadeTo("slow", 0); play_num += 10; $('#play_num').text(play_num); } if (flag) { $(objj).remove(); flag = false; } } RemoveBullet(y, s1, obj); y -= 20; obj.css({ "top": (y) + "px", "left": x + "px", }) }, 100); } function RemoveBullet(y, s1, obj) { /* 删除超出边界的子弹 */ if (y < 0) { clearInterval(s1); $(obj).remove(); } } function FoePlan(x, y, BB) { /* 克隆及移动敌机 */ this.x = x; this.y = y; this.BB = BB; this.Clone = function () { var objj = $(this.BB).first().clone(true).appendTo(".bg").css("display", "block"); var s2 = setInterval(MovePlanFirst, 100); function MovePlanFirst() { FoePlan.call(this, x, y, BB); // 类的继承 var dic = [this.x, this.y, objj]; FD[this] = dic; RemovePlan(this.y, s2, objj); y += 20; objj.css({ "top": this.y + "px", "left": this.x + "px", }) } } } function RemovePlan(y, s2, objj) { /* 用于删除出镜的敌机 */ if (y > 600) { clearInterval(s2); $(objj).remove(); } } function Randmon() { /* 用于随机生成x轴与敌机型号 */ var num_one = Math.random(); var num_two = num_one * 100; if (num_two < 80) { num_two += 100; } num_stree = Math.round(Math.abs(num_two)); return num_stree } </script> </body> </html>
持续更新中...