js原生捕鱼达人(三)--完结
先给分享下我写完的效果,github有点卡,我没有压缩代码,不过效果可以看到
https://jasonwang911.github.io/
转载请注明‘转载于Jason齐齐的博客http://www.cnblogs.com/jasonwang2y60/’
继续昨天的进行
11》添加金币 相同的创建了coin.js的文件
//添加金币的构造含函数
function Coin(type){
this.type=type;
this.x=0;
this.y=0;
this.cur=0;
this.move();
}
//Coin的方法有draw move ,暂时想到这两个
Coin.prototype.draw=function(gd){
gd.save();
gd.translate(this.x,this.y);
if(this.type<3){
gd.drawImage(JSON['coinAni1'],
0,this.cur*60,60,60,
-30,-30,60,60
);
}else{
gd.drawImage(JSON['coinAni2'],
0,this.cur*60,60,60,
-30,-30,60,60
);
}
gd.restore();
};
//coin是从碰撞的点移动到画布左下角的金币存储中 就是想办法让金币的x移动到0,y的位置移动到oC.height
Coin.prototype.move=function(){
var _this=this;
setInterval(function(){
//这里速度的减小使用了一种很巧妙的方法,让this.x(碰撞的x)分10次减小到0,同样的y的值也相同
_this.x+=-_this.x/10;
_this.y+=(630-_this.y)/10;
//在运动的过程中还要旋转金币,也就是更换金币的图片,设置一个cur,使cur++,同时关联draw方法中金币图片的高度来更换图片
_this.cur++;
if(_this.cur==10){
_this.cur=0;
}
},30);
}; document.addEventListener('DOMContentLoaded',function(){
var oC=document.getElementById('c1');
var gd=oC.getContext('2d');
var rule=0.05; //开始画炮台 画炮台需要先加载资源,然后再画,这里没有使用面向对象的概念
loadImage(resource,function(){
//设置炮的初始位置,初始位置在资源文件中已经写明
var c=new Cannon(4);
c.x=431;
c.y=570;
//存放炮弹的数组
var arrBullet=[];
//存放鱼的数组
var arrFish=[];
//存放金币的数组
var arrCoin=[]; setInterval(function(){
gd.clearRect(0,0,oC.width,oC.height);
//画鱼 鱼从左右两边同时随机出现 实现这个的原理是Math.random()是0-1的数,定时器的触发时间是30ms一秒钟30多条鱼的诞生有些多,所以在这里我们需要修改规则rule来降低鱼出现的概率,当rule=0.05(概率为原来的20%),再加入一个参数decoration,然后用Math.random()-0.5得出的这个值的范围时0.5到-0.5,这样正负的概率分别为50%,这样我们就能继续进行鱼诞生的方向了;
var decoration=Math.random()-0.5;
if(Math.random()<rule){
if(decoration<0){
var f1=new Fish(rnd(1,6));
f1.x=oC.width+50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(91,269);
}else{
var f1=new Fish(rnd(1,6));
f1.x=-50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(-89,89);
}
arrFish.push(f1);
}
for(var i=0;i<arrFish.length;i++){
arrFish[i].draw(gd);
}
//和炮弹一样,对鱼进行性能优化,再鱼游出屏幕一定范围之后,便将鱼从鱼的数组中清除
for(var i=0;i<arrFish.length;i++){
if(arrFish[i].x<-50 || arrFish[i].x>(oC.width+50) || arrFish[i].y<0 || arrFish[i].y>(oC.height+50)){
arrFish.splice(i,1);
i--;
}
}
//炮是在炮台上的,可以在画炮台的时候一起画出来,画之前为了避免重绘,需要先清除画布
gd.drawImage(JSON['bottom'],
0,0,765,70,
0,532,765,70
);
//调用炮的方法draw来画炮 和鱼的转动相同,当点击画布的时候,炮需要跟随鼠标的指向来转动,这里在转动的时候我们改改变炮的转动角度,然后重新不停的删除,再画炮 这个效果思路和画鱼相同,需要配合定时器来实现
c.draw(gd);
//将当次点击所产生的炮弹画出来
for(var i=0;i<arrBullet.length;i++){
arrBullet[i].draw(gd);
}
//这里由于炮弹不停的被创造,数组中也变得越来越大,当炮弹到达一定位置(移出屏幕)的时候,应该清除前面没用的炮弹,避免性能的浪费。注意,我们需要检测每个鱼和炮弹的位置(外层循环鱼,内层循环子弹),有我就是整个数组所有参数身上的x y
for(var i=0;i<arrBullet.length;i++){
if(arrBullet[i].x<0 || arrBullet[i].x>oC.width || arrBullet[i].y>oC.height || arrBullet[i].y<0){
arrBullet.splice(i,1);
i--;
}
}
//进行碰撞检测,这里只做了简单的碰撞检测,我们把每个模型(鱼和子弹)都考虑成了原型,当两个物体的距离小于两个物体的半径之和的时候表明两个物体碰撞,注意,需要循环检测存在的所有的鱼,我们可以提前做一个函数来判断这个距离,当得到碰撞距离的时候函数返回true,当得到没有碰撞的距离的时候,函数返回的是false,这个函数是每条鱼身上的一个方法,每条鱼在游动的时候都在不停的计算这个值,并不停的返回真或者假来供我们判断是否和子弹碰撞
for(var i=0;i<arrFish.length;i++){
for(var j=0;j<arrBullet.length;j++){
if(arrFish[i].isIn(arrBullet[j].x, arrBullet[j].y)){
//金币生成的起始坐标就是碰撞时候的鱼的坐标,注意代码位置,不能放到删除鱼之后
var x=arrFish[i].x;
var y=arrFish[i].y;
//鱼的类型关系到金币的类型,在这里存鱼的类型,下面创造金币的时候用
var type=arrFish[i].type;
//在鱼碰到了之后,我们需要做的是让相互碰撞的鱼和子弹都消失,也就是从鱼和子弹的数组中删除
arrFish.splice(i,1);
i--;
arrBullet.splice(j,1);
j--;
//碰撞之后生成金币
var coin=new Coin(type);
coin.x=x;
coin.y=y;
arrCoin.push(coin);
}
}
}
//画金币
for(var i=0;i<arrCoin.length;i++){
arrCoin[i].draw(gd);
}
console.log(arrCoin.length);
},30);
//当点击画布的时候炮的角度对着鼠标点击的位置,并进行重绘
oC.onclick=function(ev){
//这里需要梳理鼠标点击的位置和炮旋转角度之间的关系(附图说明--炮的旋转角度.png)
var x=ev.clientX-oC.offsetLeft- c.x;
var y= c.y-(ev.clientY-oC.offsetTop);
//计算角度,注意角度的公式tan是临边比对边,和数学公式的有所不同 Math.atan2(y,x);并且这里是弧度转角度,需要在com.js中添加a2d的函数
var d=90-a2d(Math.atan2(y,x));
c.rotate=d;
//当点击的时候生成炮弹,所以在点击事件中添加炮弹
var bullet=new Bullet(c.type);
//炮弹的位置和旋转角度和炮的位置和旋转角度相同,
bullet.x= c.x;
bullet.y= c.y;
bullet.rotate = c.rotate;
//注意炮弹不能画在这里,如果画在这里会被画炮和炮台时所清空,当然潘丹并不是只画一个,可以用一个数组来存储所画出来的炮弹,然后在炮旋转重绘的时候同时添加炮弹,为了让点击事件和定时器都能用到这个数组,这个数组应该写到事件和定时器的父级的变量空间中
/*bullet.draw(gd);*/
//讲当次点击画布所创建的炮弹存入arrBullet中
arrBullet.push(bullet);
};
});
},false);
</script>
13》添加死鱼 创建了diefish.js的文件
/**
* Created by Jason on 2016/11/3.
*/
//构造死鱼的构造函数 死鱼的属性有type x y cur翻转 rotate move
function DieFish(type){
this.type=type;
this.x=0;
this.y=0;
this.rotate=0;
this.cur=0;
this.move();
}
//死鱼的方法有draw move 注意,鱼死的时候的方向和隐形需要修正,如果不修正则都会成为默认方向
DieFish.prototype.draw=function(gd){
var w=FISH_SIZE[this.type].w;
var h=FISH_SIZE[this.type].h;
gd.save();
gd.translate(this.x,this.y);
gd.rotate(d2a(this.rotate));
//修复阴影
if(this.rotate>90&&this.rotate<270){
gd.scale(1,-1);
}
gd.drawImage(JSON['fish'+this.type],
0,(this.cur+4)*h,w,h,
-w/2,-h/2,w,h
);
gd.restore();
};
//死鱼的move方法 是更换图片翻肚皮,思路和鱼摆尾巴相似
DieFish.prototype.move=function(){
var _this=this;
setInterval(function(){
_this.cur++;
//当死鱼的图片换一遍以后,停止更换图片,以便后面死鱼消失,注意定时器的时间,控制图片的更换
if(_this.cur==4){
_this.cur=0;
}
},250);
};
index.html文件
<script src="js/resource.js"></script>
<script src="js/com.js"></script>
<script src="js/fish.js"></script>
<script src="js/cannon.js"></script>
<script src="js/bullet.js"></script>
<script src="js/coin.js"></script>
<script src="js/diefish.js"></script>
<script>
document.addEventListener('DOMContentLoaded',function(){
var oC=document.getElementById('c1');
var gd=oC.getContext('2d');
var rule=0.05; //开始画炮台 画炮台需要先加载资源,然后再画,这里没有使用面向对象的概念
loadImage(resource,function(){
//设置炮的初始位置,初始位置在资源文件中已经写明
var c=new Cannon(4);
c.x=431;
c.y=570;
//存放炮弹的数组
var arrBullet=[];
//存放鱼的数组
var arrFish=[];
//存放金币的数组
var arrCoin=[];
//存放死鱼的数组
var arrDieFish=[]; setInterval(function(){
gd.clearRect(0,0,oC.width,oC.height);
//画鱼 鱼从左右两边同时随机出现 实现这个的原理是Math.random()是0-1的数,定时器的触发时间是30ms一秒钟30多条鱼的诞生有些多,所以在这里我们需要修改规则rule来降低鱼出现的概率,当rule=0.05(概率为原来的20%),再加入一个参数decoration,然后用Math.random()-0.5得出的这个值的范围时0.5到-0.5,这样正负的概率分别为50%,这样我们就能继续进行鱼诞生的方向了;
var decoration=Math.random()-0.5;
if(Math.random()<rule){
if(decoration<0){
var f1=new Fish(rnd(1,6));
f1.x=oC.width+50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(91,269);
}else{
var f1=new Fish(rnd(1,6));
f1.x=-50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(-89,89);
}
arrFish.push(f1);
}
for(var i=0;i<arrFish.length;i++){
arrFish[i].draw(gd);
}
//和炮弹一样,对鱼进行性能优化,再鱼游出屏幕一定范围之后,便将鱼从鱼的数组中清除
for(var i=0;i<arrFish.length;i++){
if(arrFish[i].x<-50 || arrFish[i].x>(oC.width+50) || arrFish[i].y<0 || arrFish[i].y>(oC.height+50)){
arrFish.splice(i,1);
i--;
}
}
//炮是在炮台上的,可以在画炮台的时候一起画出来,画之前为了避免重绘,需要先清除画布
gd.drawImage(JSON['bottom'],
0,0,765,70,
0,532,765,70
);
//调用炮的方法draw来画炮 和鱼的转动相同,当点击画布的时候,炮需要跟随鼠标的指向来转动,这里在转动的时候我们改改变炮的转动角度,然后重新不停的删除,再画炮 这个效果思路和画鱼相同,需要配合定时器来实现
c.draw(gd);
//将当次点击所产生的炮弹画出来
for(var i=0;i<arrBullet.length;i++){
arrBullet[i].draw(gd);
}
//这里由于炮弹不停的被创造,数组中也变得越来越大,当炮弹到达一定位置(移出屏幕)的时候,应该清除前面没用的炮弹,避免性能的浪费。注意,我们需要检测每个鱼和炮弹的位置(外层循环鱼,内层循环子弹),有我就是整个数组所有参数身上的x y
for(var i=0;i<arrBullet.length;i++){
if(arrBullet[i].x<0 || arrBullet[i].x>oC.width || arrBullet[i].y>oC.height || arrBullet[i].y<0){
arrBullet.splice(i,1);
i--;
}
}
//进行碰撞检测,这里只做了简单的碰撞检测,我们把每个模型(鱼和子弹)都考虑成了原型,当两个物体的距离小于两个物体的半径之和的时候表明两个物体碰撞,注意,需要循环检测存在的所有的鱼,我们可以提前做一个函数来判断这个距离,当得到碰撞距离的时候函数返回true,当得到没有碰撞的距离的时候,函数返回的是false,这个函数是每条鱼身上的一个方法,每条鱼在游动的时候都在不停的计算这个值,并不停的返回真或者假来供我们判断是否和子弹碰撞
for(var i=0;i<arrFish.length;i++){
for(var j=0;j<arrBullet.length;j++){
if(arrFish[i].isIn(arrBullet[j].x, arrBullet[j].y)){
//金币生成的起始坐标就是碰撞时候的鱼的坐标,注意代码位置,不能放到删除鱼之后
var x=arrFish[i].x;
var y=arrFish[i].y;
//鱼的类型关系到金币的类型,在这里存鱼的类型,下面创造金币的时候用
var type=arrFish[i].type;
//在鱼碰到了之后,我们需要做的是让相互碰撞的鱼和子弹都消失,也就是从鱼和子弹的数组中删除
//鱼死的时候的rotate也要存一下,供后面死鱼使用,来确保活鱼和死鱼的方向相同
var rotate=arrFish[i].rotate;
arrFish.splice(i,1);
i--;
arrBullet.splice(j,1);
j--;
//碰撞之后生成金币
var coin=new Coin(type);
coin.x=x;
coin.y=y;
arrCoin.push(coin);
//碰撞之后生成死鱼
var dieFish=new DieFish(type);
dieFish.x=x;
dieFish.y=y;
dieFish.rotate=rotate;
arrDieFish.push(dieFish);
//清除死鱼,注意死鱼不是一直在清除,使用的一次性定时器,每隔一段时间便清除最前面的一条死鱼
setTimeout(function(){
arrDieFish.shift();
i--;
},1000)
}
}
}
//画金币
for(var i=0;i<arrCoin.length;i++){
arrCoin[i].draw(gd);
}
//画死鱼
for(var i=0;i<arrDieFish.length;i++){
arrDieFish[i].draw(gd);
} console.log(arrDieFish.length);
},30);
//当点击画布的时候炮的角度对着鼠标点击的位置,并进行重绘
oC.onclick=function(ev){
//这里需要梳理鼠标点击的位置和炮旋转角度之间的关系(附图说明--炮的旋转角度.png)
var x=ev.clientX-oC.offsetLeft- c.x;
var y= c.y-(ev.clientY-oC.offsetTop);
//计算角度,注意角度的公式tan是临边比对边,和数学公式的有所不同 Math.atan2(y,x);并且这里是弧度转角度,需要在com.js中添加a2d的函数
var d=90-a2d(Math.atan2(y,x));
c.rotate=d;
//当点击的时候生成炮弹,所以在点击事件中添加炮弹
var bullet=new Bullet(c.type);
//炮弹的位置和旋转角度和炮的位置和旋转角度相同,
bullet.x= c.x;
bullet.y= c.y;
bullet.rotate = c.rotate;
//注意炮弹不能画在这里,如果画在这里会被画炮和炮台时所清空,当然潘丹并不是只画一个,可以用一个数组来存储所画出来的炮弹,然后在炮旋转重绘的时候同时添加炮弹,为了让点击事件和定时器都能用到这个数组,这个数组应该写到事件和定时器的父级的变量空间中
/*bullet.draw(gd);*/
//讲当次点击画布所创建的炮弹存入arrBullet中
arrBullet.push(bullet);
};
});
},false);
</script>
/**
* Created by Jason on 2016/11/4.
*/
//网的尺寸
var WEB_SIZE=[
null,
{x:332,y:373,w:87,h:86},
{x:13,y:413,w:108,h:106},
{x:177,y:369,w:125,h:124},
{x:252,y:179,w:149,h:149},
{x:1,y:244,w:160,h:154},
{x:21,y:22,w:198,h:199},
{x:241,y:0,w:180,h:179}
];
//构造渔网的构造函数 思路和死鱼的相同 渔网的方法有type x y scal move
function Web(type){
this.type=type;
this.x=0;
this.y=0;
this.scale=1;
}
//渔网的方法有 draw 思路和子弹相同,因为都是在一张图上,所以需要先把长宽位置x y获取
Web.prototype.draw=function(gd){
var x=WEB_SIZE[this.type].x;
var y=WEB_SIZE[this.type].y;
var w=WEB_SIZE[this.type].w;
var h=WEB_SIZE[this.type].h;
gd.save();
gd.translate(this.x,this.y);
gd.scale(this.scale,this.scale);
gd.drawImage(JSON['web'],
x,y,w,h,
-w/2,-h/2,w,h
);
gd.restore();
};
index.js文件 index文件调整了生成鱼,死鱼,金币,渔网的位置,越靠前越向下层,炮弹打中鱼先有死鱼再有渔网,然后生成金币,活鱼在最上层
<script src="js/resource.js"></script>
<script src="js/com.js"></script>
<script src="js/fish.js"></script>
<script src="js/cannon.js"></script>
<script src="js/bullet.js"></script>
<script src="js/coin.js"></script>
<script src="js/diefish.js"></script>
<script src="js/web.js"></script>
<script> document.addEventListener('DOMContentLoaded',function(){
var oC=document.getElementById('c1');
var gd=oC.getContext('2d');
var rule=0.05; //开始画炮台 画炮台需要先加载资源,然后再画,这里没有使用面向对象的概念
loadImage(resource,function(){
//设置炮的初始位置,初始位置在资源文件中已经写明
var c=new Cannon(4);
c.x=431;
c.y=570;
//存放炮弹的数组
var arrBullet=[];
//存放鱼的数组
var arrFish=[];
//存放金币的数组
var arrCoin=[];
//存放死鱼的数组
var arrDieFish=[];
//放渔网的数组
var arrWeb=[]; setInterval(function(){
gd.clearRect(0,0,oC.width,oC.height);
//画死鱼
for(var i=0;i<arrDieFish.length;i++){
arrDieFish[i].draw(gd);
}
//画渔网
for(var i=0;i<arrWeb.length;i++){
arrWeb[i].draw(gd);
}
//画金币
for(var i=0;i<arrCoin.length;i++){
arrCoin[i].draw(gd);
}
//画鱼 鱼从左右两边同时随机出现 实现这个的原理是Math.random()是0-1的数,定时器的触发时间是30ms一秒钟30多条鱼的诞生有些多,所以在这里我们需要修改规则rule来降低鱼出现的概率,当rule=0.05(概率为原来的20%),再加入一个参数decoration,然后用Math.random()-0.5得出的这个值的范围时0.5到-0.5,这样正负的概率分别为50%,这样我们就能继续进行鱼诞生的方向了;
var decoration=Math.random()-0.5;
if(Math.random()<rule){
if(decoration<0){
var f1=new Fish(rnd(1,6));
f1.x=oC.width+50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(91,269);
}else{
var f1=new Fish(rnd(1,6));
f1.x=-50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(-89,89);
}
arrFish.push(f1);
}
for(var i=0;i<arrFish.length;i++){
arrFish[i].draw(gd);
}
//和炮弹一样,对鱼进行性能优化,再鱼游出屏幕一定范围之后,便将鱼从鱼的数组中清除
for(var i=0;i<arrFish.length;i++){
if(arrFish[i].x<-50 || arrFish[i].x>(oC.width+50) || arrFish[i].y<0 || arrFish[i].y>(oC.height+50)){
arrFish.splice(i,1);
i--;
}
}
//炮是在炮台上的,可以在画炮台的时候一起画出来,画之前为了避免重绘,需要先清除画布
gd.drawImage(JSON['bottom'],
0,0,765,70,
0,532,765,70
);
//调用炮的方法draw来画炮 和鱼的转动相同,当点击画布的时候,炮需要跟随鼠标的指向来转动,这里在转动的时候我们改改变炮的转动角度,然后重新不停的删除,再画炮 这个效果思路和画鱼相同,需要配合定时器来实现
c.draw(gd);
//将当次点击所产生的炮弹画出来
for(var i=0;i<arrBullet.length;i++){
arrBullet[i].draw(gd);
}
//这里由于炮弹不停的被创造,数组中也变得越来越大,当炮弹到达一定位置(移出屏幕)的时候,应该清除前面没用的炮弹,避免性能的浪费。注意,我们需要检测每个鱼和炮弹的位置(外层循环鱼,内层循环子弹),有我就是整个数组所有参数身上的x y
for(var i=0;i<arrBullet.length;i++){
if(arrBullet[i].x<0 || arrBullet[i].x>oC.width || arrBullet[i].y>oC.height || arrBullet[i].y<0){
arrBullet.splice(i,1);
i--;
}
}
//进行碰撞检测,这里只做了简单的碰撞检测,我们把每个模型(鱼和子弹)都考虑成了原型,当两个物体的距离小于两个物体的半径之和的时候表明两个物体碰撞,注意,需要循环检测存在的所有的鱼,我们可以提前做一个函数来判断这个距离,当得到碰撞距离的时候函数返回true,当得到没有碰撞的距离的时候,函数返回的是false,这个函数是每条鱼身上的一个方法,每条鱼在游动的时候都在不停的计算这个值,并不停的返回真或者假来供我们判断是否和子弹碰撞
for(var i=0;i<arrFish.length;i++){
for(var j=0;j<arrBullet.length;j++){
if(arrFish[i].isIn(arrBullet[j].x, arrBullet[j].y)){
//金币生成的起始坐标就是碰撞时候的鱼的坐标,注意代码位置,不能放到删除鱼之后
var x=arrFish[i].x;
var y=arrFish[i].y;
//鱼的类型关系到金币的类型,在这里存鱼的类型,下面创造金币的时候用
var type=arrFish[i].type;
//在鱼碰到了之后,我们需要做的是让相互碰撞的鱼和子弹都消失,也就是从鱼和子弹的数组中删除
//鱼死的时候的rotate也要存一下,供后面死鱼使用,来确保活鱼和死鱼的方向相同
var rotate=arrFish[i].rotate;
arrFish.splice(i,1);
i--;
arrBullet.splice(j,1);
j--;
//碰撞之后生成渔网
var web=new Web(type);
web.x=x;
web.y=y;
arrWeb.push(web);
//和死鱼相同,渔网生成一段时间后也需要消失
setTimeout(function(){
arrWeb.shift();
i--;
},1000);
//碰撞之后生成金币
var coin=new Coin(type);
coin.x=x;
coin.y=y;
arrCoin.push(coin);
//碰撞之后生成死鱼
var dieFish=new DieFish(type);
dieFish.x=x;
dieFish.y=y;
dieFish.rotate=rotate;
arrDieFish.push(dieFish);
//清除死鱼,注意死鱼不是一直在清除,使用的一次性定时器,每隔一段时间便清除最前面的一条死鱼
setTimeout(function(){
arrDieFish.shift();
i--;
},1000)
}
}
}
console.log(arrDieFish.length);
},30);
//当点击画布的时候炮的角度对着鼠标点击的位置,并进行重绘
oC.onclick=function(ev){
//这里需要梳理鼠标点击的位置和炮旋转角度之间的关系(附图说明--炮的旋转角度.png)
var x=ev.clientX-oC.offsetLeft- c.x;
var y= c.y-(ev.clientY-oC.offsetTop);
//计算角度,注意角度的公式tan是临边比对边,和数学公式的有所不同 Math.atan2(y,x);并且这里是弧度转角度,需要在com.js中添加a2d的函数
var d=90-a2d(Math.atan2(y,x));
c.rotate=d;
//当点击的时候生成炮弹,所以在点击事件中添加炮弹
var bullet=new Bullet(c.type);
//炮弹的位置和旋转角度和炮的位置和旋转角度相同,
bullet.x= c.x;
bullet.y= c.y;
bullet.rotate = c.rotate;
//注意炮弹不能画在这里,如果画在这里会被画炮和炮台时所清空,当然潘丹并不是只画一个,可以用一个数组来存储所画出来的炮弹,然后在炮旋转重绘的时候同时添加炮弹,为了让点击事件和定时器都能用到这个数组,这个数组应该写到事件和定时器的父级的变量空间中
/*bullet.draw(gd);*/
//讲当次点击画布所创建的炮弹存入arrBullet中
arrBullet.push(bullet);
};
});
},false);
</script>
//碰撞的时候添加金币的声音文件
var oA=new Audio();
oA.src='snd/coin.wav';
oA.play(); //当点击的时候发射炮弹,所以在点击的时候创造炮弹发射声音文件
var oA=new Audio();
oA.src='snd/cannon.mp3';
oA.play();
15》大炮的后坐力前面忘记写了,现在补上 其实就是大炮的一个方法
//构建炮的后坐力方法 使用this.cur和draw的时候图片的位置相关联,通过更换图片来实现炮的运动,
Cannon.prototype.emitChange=function(){
var _this=this;
//注意当图片更换一轮的时候,需要清除定时器来保证大炮不是一直在那里动,所以大炮的有个定时器的属性需要添加
clearInterval(_this.timer);
_this.timer=setInterval(function(){
_this.cur++;
if(_this.cur==5){
_this.cur=0;
clearInterval(_this.timer);
}
},30);
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
padding: 0;
margin: 0;
}
body{
background:#000;
text-align:center;
overflow:hidden;
}
#c1{
background:url(img/game_bg_2_hd.jpg);
margin:40px auto;
}
</style>
<script src="js/resource.js"></script>
<script src="js/com.js"></script>
<script src="js/fish.js"></script>
<script src="js/cannon.js"></script>
<script src="js/bullet.js"></script>
<script src="js/coin.js"></script>
<script src="js/diefish.js"></script>
<script src="js/web.js"></script>
<script src="js/init.js"></script>
</head>
<body>
<canvas id="c1" width="800" height="600"></canvas>
</body>
</html>
fish.js
/**
* Created by Jason on 2016/11/2.
*/
//各种不同的鱼的图片的数据
var FISH_SIZE=[
null,
{w: 55, h: 37, collR: 17},
{w: 78, h: 64, collR: 24},
{w: 72, h: 56, collR: 20},
{w: 77, h: 59, collR: 22},
{w: 107, h: 122, collR: 29}
];
//使用面向对象的思想创建对象的属性和方法,属性写在构造函数中,方法放在原型上
//先画一条鱼,鱼的属性有鱼的种类type 位置x,y 游动时候尾巴运动cur 游动的方向rotate 游动的速度iSpeed 向前运动move 先创建鱼的构造函数
function Fish(type){
this.type=type;
this.x=0;
this.y=0;
this.cur=0;
this.rotate=0;
this.iSpeed=1;
this.collR=FISH_SIZE[this.type].collR;
this.move();
}
//在添加鱼的方法 画鱼draw 鱼的运动move
Fish.prototype.draw=function(gd){
//鱼的图片的宽高,不同鱼的不同宽高不相同,先把鱼的宽高存入一个提前量好的数组FISH_SIZE中,再根据不同种类的鱼来获取不同的宽高
var w=FISH_SIZE[this.type].w;
var h=FISH_SIZE[this.type].h;
//开始画鱼 注意画鱼先要save,结束以后restore 鱼的出场时可以改变方向的,所以画鱼的时候注意提前准备好角度
gd.save();
gd.translate(this.x,this.y);
gd.rotate(d2a(this.rotate));
//鱼是有阴影的,当鱼从左面出来的时候,阴影是在鱼的右下面,当鱼从左面出来的时候,阴影是在鱼的左下面,在旋转完角度后鱼可能从左面出来也可能从右面出来,当鱼从右面出来的时候,需要scale图片,使图片翻转来修正阴影的位置
if(this.rotate>90 && this.rotate<270){
gd.scale(1,-1);
}
//利用drawImage这个函数来画鱼,JSON['fish'+this.type]可以选择不同种类的鱼,注意鱼的rotate是根据头部的位置来改变的
gd.drawImage(JSON['fish'+this.type],
//使用this.cur 来变换鱼的图片的位置
0,h*this.cur,w,h,
-w/2,-h/2,w,h
);
gd.restore();
};
//鱼的move的方法
Fish.prototype.move=function(){
//鱼的运动分为向前游动和尾巴的摆动两个运动
//向前游动 向前游动是改变的鱼的this.x 和 this.y 的值 不停的往前游动需要配合定时器的实现
//注意事件中套定时器,定时器的this的指向不准确,解决办法是 提前存储一个正确的this
var _this=this;
setInterval(function(){
//将this.x this.y分解到斜线坐标上
_this.x+=Math.cos(d2a(_this.rotate))*_this.iSpeed;
_this.y+=Math.sin(d2a(_this.rotate))*_this.iSpeed;
},30);
//鱼尾巴的摆动 鱼尾巴的摆动是在不停的更换鱼的图片来实现的 相同的是定时器配合this.cur的加减
setInterval(function(){
//图片的位置是改变鱼的精灵图上的鱼的起始位置x y来实现 这里用这个cur的值来关联这组坐标
_this.cur++;
//循环这组数字
if(_this.cur==4){
_this.cur=0;
}
},200);
};
//传入的两个参数x y是子弹的实时位置
Fish.prototype.isIn=function(x,y){
var a=this.x-x;
var b=this.y-y;
var c=Math.sqrt(a*a+b*b);
//这里需要提前在鱼的构造函数中添加this.collR的属性this.collR=FISH_SIZE[this.type].collR;
if(c<=this.collR){
return true;
}else{
return false;
}
};
bullet.js
/**
* Created by Jason on 2016/11/3.
*/
//开始构造炮弹
//炮弹具体尺寸
var BULLET_SIZE=[
null,
{x: 86, y: 0, w: 24, h: 26},
{x: 62, y: 0, w: 25, h: 29},
{x: 30, y: 0, w: 31, h: 35},
{x: 32, y: 35, w: 27, h: 31},
{x: 30, y: 82, w: 29, h: 33},
{x: 0, y: 82, w: 30, h: 34},
{x: 0, y: 0, w: 30, h: 44}
];
//炮弹的构造函数,同样先在resource.js中加载炮弹的资源, 炮弹的属性有 type 位置x y rotate iSpeed move
function Bullet(type){
this.type=type;
this.x=0;
this.y=0;
this.rotate=0;
this.iSpeed=this.type*2;
this.move();
}
//暂时想到的炮弹原型上的方法有draw move ,先写,后面出现其他的再补充
Bullet.prototype.draw=function(gd){
//同样的炮弹的尺寸数据表中已经量好并且给出
var w=BULLET_SIZE[this.type].w;
var h=BULLET_SIZE[this.type].h;
//这里与前面不同的是需要定义不同尺寸炮弹的起始位置,数据表中已经给出,直接获取
var x=BULLET_SIZE[this.type].x;
var y=BULLET_SIZE[this.type].y;
//开始画炮弹,
gd.save();
gd.translate(this.x,this.y);
gd.rotate(d2a(this.rotate));
gd.drawImage(JSON['bullet'],
x,y,w,h,
-w/2,-h/2,w,h
);
gd.restore();
};
//添加炮弹move的方法,和fish运动的思路相同
Bullet.prototype.move=function(){
//开启定时器不停的改变炮弹的位置并且重绘,同样,注意事件中的定时器里的this有问题,需要提前存正确的this的指向
var _this=this;
setInterval(function(){
//和鱼的move有些不同的是炮弹的y轴的方向不同炮弹都是是向上射出的
_this.x+=Math.sin(d2a(_this.rotate))*_this.iSpeed;
_this.y-=Math.cos(d2a(_this.rotate))*_this.iSpeed;
},30);
}; cannon.js /**
* Created by Jason on 2016/11/2.
*/
//炮
var CANNON_SIZE=[
null,
{w: 74, h: 74},
{w: 74, h: 76},
{w: 74, h: 76},
{w: 74, h: 83},
{w: 74, h: 85},
{w: 74, h: 90},
{w: 74, h: 94}
];
//构建炮的构造函数 炮弹的属性有位置x y type rotate 添加的同时注意在resource.js文件中添加需要加载的资源
function Cannon(type){
this.type=type;
this.x=0;
this.y=0;
this.cur=0;
this.rotate=0;
this.timer=null;
}
//构建炮的原型,炮的原型上面有draw的方法
Cannon.prototype.draw=function(gd){
//和鱼的原型相同,先要设置炮台的尺寸w h,同样的再2中的尺寸表中
var w=CANNON_SIZE[this.type].w;
var h=CANNON_SIZE[this.type].h;
//开始画炮台,注意先save最后再restore,炮台是可以旋转的
gd.save();
gd.translate(this.x,this.y);
gd.rotate(d2a(this.rotate));
gd.drawImage(JSON['cannon'+this.type],
0,this.cur*h,w,h,
-w/2,-h/2,w,h
);
gd.restore();
};
//构建炮的后坐力方法 使用this.cur和draw的时候图片的位置相关联,通过更换图片来实现炮的运动,
Cannon.prototype.emitChange=function(){
var _this=this;
//注意当图片更换一轮的时候,需要清除定时器来保证大炮不是一直在那里动,所以大炮的有个定时器的属性需要添加
clearInterval(_this.timer);
_this.timer=setInterval(function(){
_this.cur++;
if(_this.cur==5){
_this.cur=0;
clearInterval(_this.timer);
}
},30);
};
coin.js
/**
* Created by Jason on 2016/11/3.
*/
//添加金币的构造含函数
function Coin(type){
this.type=type;
this.x=0;
this.y=0;
this.cur=0;
this.move();
}
//Coin的方法有draw move ,暂时想到这两个
Coin.prototype.draw=function(gd){
gd.save();
gd.translate(this.x,this.y);
if(this.type<3){
gd.drawImage(JSON['coinAni1'],
0,this.cur*60,60,60,
-30,-30,60,60
);
}else{
gd.drawImage(JSON['coinAni2'],
0,this.cur*60,60,60,
-30,-30,60,60
);
}
gd.restore();
};
//coin是从碰撞的点移动到画布左下角的金币存储中 就是想办法让金币的x移动到0,y的位置移动到oC.height
Coin.prototype.move=function(){
var _this=this;
setInterval(function(){
//这里速度的减小使用了一种很巧妙的方法,让this.x(碰撞的x)分10次减小到0,同样的y的值也相同
_this.x+=-_this.x/10;
_this.y+=(630-_this.y)/10;
//在运动的过程中还要旋转金币,也就是更换金币的图片,设置一个cur,使cur++,同时关联draw方法中金币图片的高度来更换图片
_this.cur++;
if(_this.cur==10){
_this.cur=0;
}
},30);
};
com.js
/**
* Created by Jason on 2016/11/2.
*/
function d2a(n){
return n*Math.PI/180;
}
function a2d(n){
return n*180/Math.PI;
}
function rnd(m,n){
return parseInt(Math.random()*(n-m)+m);
}
var JSON={};
function loadImage(arr,fnSucc){
//为了测试是否加载完成,设置count,在加载的时候使count++,判断count的值来判断是否加载完成
var count=0;
for(var i=0;i<arr.length;i++){
var oImg=new Image();
//加载所有鱼的资源
(function(index){
oImg.onload=function(){
//把所有资源加载,并且存到JSON中,注意,循环中有事件,事件里的i值不对,解决用封闭空间
JSON[arr[index]]=this;
count++;
//当count的值和需要加载的资源的数组相同的时候,资源加载完毕
if(count==arr.length){
fnSucc && fnSucc();
}
};
})(i); oImg.src='img/'+arr[i]+'.png';
}
}
diefish.js
/**
* Created by Jason on 2016/11/3.
*/
//构造死鱼的构造函数 死鱼的属性有type x y cur翻转 rotate move
function DieFish(type){
this.type=type;
this.x=0;
this.y=0;
this.rotate=0;
this.cur=0;
this.move();
}
//死鱼的方法有draw move 注意,鱼死的时候的方向和隐形需要修正,如果不修正则都会成为默认方向
DieFish.prototype.draw=function(gd){
var w=FISH_SIZE[this.type].w;
var h=FISH_SIZE[this.type].h;
gd.save();
gd.translate(this.x,this.y);
gd.rotate(d2a(this.rotate));
//修复阴影
if(this.rotate>90&&this.rotate<270){
gd.scale(1,-1);
}
gd.drawImage(JSON['fish'+this.type],
0,(this.cur+4)*h,w,h,
-w/2,-h/2,w,h
);
gd.restore();
};
//死鱼的move方法 是更换图片翻肚皮,思路和鱼摆尾巴相似
DieFish.prototype.move=function(){
var _this=this;
setInterval(function(){
_this.cur++;
//当死鱼的图片换一遍以后,停止更换图片,以便后面死鱼消失,注意定时器的时间,控制图片的更换
if(_this.cur==4){
_this.cur=0;
}
},250);
};
resource.js
/**
* Created by Jason on 2016/11/2.
*/
//把所有资源放到一个resource的数组中,方便加载资源的函数loadImage调用
var resource=['fish1','fish2','fish3','fish4','fish5','bottom','cannon1','cannon2','cannon3','cannon4','cannon5','cannon6','cannon7','bullet','coinAni1','coinAni2','web'];
web.js
/**
* Created by Jason on 2016/11/4.
*/
//网的尺寸
var WEB_SIZE=[
null,
{x:332,y:373,w:87,h:86},
{x:13,y:413,w:108,h:106},
{x:177,y:369,w:125,h:124},
{x:252,y:179,w:149,h:149},
{x:1,y:244,w:160,h:154},
{x:21,y:22,w:198,h:199},
{x:241,y:0,w:180,h:179}
];
//构造渔网的构造函数 思路和死鱼的相同 渔网的方法有type x y scal move
function Web(type){
this.type=type;
this.x=0;
this.y=0;
this.scale=1;
}
//渔网的方法有 draw 思路和子弹相同,因为都是在一张图上,所以需要先把长宽位置x y获取
Web.prototype.draw=function(gd){
var x=WEB_SIZE[this.type].x;
var y=WEB_SIZE[this.type].y;
var w=WEB_SIZE[this.type].w;
var h=WEB_SIZE[this.type].h;
gd.save();
gd.translate(this.x,this.y);
gd.scale(this.scale,this.scale);
gd.drawImage(JSON['web'],
x,y,w,h,
-w/2,-h/2,w,h
);
gd.restore();
};
init.js
/**
* Created by Jason on 2016/11/4.
*/
document.addEventListener('DOMContentLoaded',function(){
var oC=document.getElementById('c1');
var gd=oC.getContext('2d');
var rule=0.05; //开始画炮台 画炮台需要先加载资源,然后再画,这里没有使用面向对象的概念
loadImage(resource,function(){
//设置炮的初始位置,初始位置在资源文件中已经写明
var c=new Cannon(rnd(1,8));
c.x=431;
c.y=570;
//存放炮弹的数组
var arrBullet=[];
//存放鱼的数组
var arrFish=[];
//存放金币的数组
var arrCoin=[];
//存放死鱼的数组
var arrDieFish=[];
//放渔网的数组
var arrWeb=[]; setInterval(function(){
gd.clearRect(0,0,oC.width,oC.height);
//画死鱼
for(var i=0;i<arrDieFish.length;i++){
arrDieFish[i].draw(gd);
}
//画渔网
for(var i=0;i<arrWeb.length;i++){
arrWeb[i].draw(gd);
}
//画金币
for(var i=0;i<arrCoin.length;i++){
arrCoin[i].draw(gd);
}
//画鱼 鱼从左右两边同时随机出现 实现这个的原理是Math.random()是0-1的数,定时器的触发时间是30ms一秒钟30多条鱼的诞生有些多,所以在这里我们需要修改规则rule来降低鱼出现的概率,当rule=0.05(概率为原来的20%),再加入一个参数decoration,然后用Math.random()-0.5得出的这个值的范围时0.5到-0.5,这样正负的概率分别为50%,这样我们就能继续进行鱼诞生的方向了;
var decoration=Math.random()-0.5;
if(Math.random()<rule){
if(decoration<0){
var f1=new Fish(rnd(1,6));
f1.x=oC.width+50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(91,269);
}else{
var f1=new Fish(rnd(1,6));
f1.x=-50;
f1.y=rnd(0,oC.height);
//
f1.rotate=rnd(-89,89);
}
arrFish.push(f1);
}
for(var i=0;i<arrFish.length;i++){
arrFish[i].draw(gd);
}
//和炮弹一样,对鱼进行性能优化,再鱼游出屏幕一定范围之后,便将鱼从鱼的数组中清除
for(var i=0;i<arrFish.length;i++){
if(arrFish[i].x<-50 || arrFish[i].x>(oC.width+50) || arrFish[i].y<0 || arrFish[i].y>(oC.height+50)){
arrFish.splice(i,1);
i--;
}
}
//炮是在炮台上的,可以在画炮台的时候一起画出来,画之前为了避免重绘,需要先清除画布
gd.drawImage(JSON['bottom'],
0,0,765,70,
0,532,765,70
);
//调用炮的方法draw来画炮 和鱼的转动相同,当点击画布的时候,炮需要跟随鼠标的指向来转动,这里在转动的时候我们改改变炮的转动角度,然后重新不停的删除,再画炮 这个效果思路和画鱼相同,需要配合定时器来实现
c.draw(gd);
//将当次点击所产生的炮弹画出来
for(var i=0;i<arrBullet.length;i++){
arrBullet[i].draw(gd);
}
//这里由于炮弹不停的被创造,数组中也变得越来越大,当炮弹到达一定位置(移出屏幕)的时候,应该清除前面没用的炮弹,避免性能的浪费。注意,我们需要检测每个鱼和炮弹的位置(外层循环鱼,内层循环子弹),有我就是整个数组所有参数身上的x y
for(var i=0;i<arrBullet.length;i++){
if(arrBullet[i].x<0 || arrBullet[i].x>oC.width || arrBullet[i].y>oC.height || arrBullet[i].y<0){
arrBullet.splice(i,1);
i--;
}
}
//进行碰撞检测,这里只做了简单的碰撞检测,我们把每个模型(鱼和子弹)都考虑成了原型,当两个物体的距离小于两个物体的半径之和的时候表明两个物体碰撞,注意,需要循环检测存在的所有的鱼,我们可以提前做一个函数来判断这个距离,当得到碰撞距离的时候函数返回true,当得到没有碰撞的距离的时候,函数返回的是false,这个函数是每条鱼身上的一个方法,每条鱼在游动的时候都在不停的计算这个值,并不停的返回真或者假来供我们判断是否和子弹碰撞
for(var i=0;i<arrFish.length;i++){
for(var j=0;j<arrBullet.length;j++){
if(arrFish[i].isIn(arrBullet[j].x, arrBullet[j].y)){
//碰撞的时候添加金币的声音文件
var oA=new Audio();
oA.src='snd/coin.wav';
oA.play();
//金币生成的起始坐标就是碰撞时候的鱼的坐标,注意代码位置,不能放到删除鱼之后
var x=arrFish[i].x;
var y=arrFish[i].y;
//鱼的类型关系到金币的类型,在这里存鱼的类型,下面创造金币的时候用
var type=arrFish[i].type;
//在鱼碰到了之后,我们需要做的是让相互碰撞的鱼和子弹都消失,也就是从鱼和子弹的数组中删除
//鱼死的时候的rotate也要存一下,供后面死鱼使用,来确保活鱼和死鱼的方向相同
var rotate=arrFish[i].rotate;
arrFish.splice(i,1);
i--;
arrBullet.splice(j,1);
j--;
//碰撞之后生成渔网
var web=new Web(type);
web.x=x;
web.y=y;
arrWeb.push(web);
//和死鱼相同,渔网生成一段时间后也需要消失
setTimeout(function(){
arrWeb.shift();
i--;
},1000);
//碰撞之后生成金币
var coin=new Coin(type);
coin.x=x;
coin.y=y;
arrCoin.push(coin);
//碰撞之后生成死鱼
var dieFish=new DieFish(type);
dieFish.x=x;
dieFish.y=y;
dieFish.rotate=rotate;
arrDieFish.push(dieFish);
//清除死鱼,注意死鱼不是一直在清除,使用的一次性定时器,每隔一段时间便清除最前面的一条死鱼
setTimeout(function(){
arrDieFish.shift();
i--;
},1000)
}
}
}
},30);
//当点击画布的时候炮的角度对着鼠标点击的位置,并进行重绘
oC.onclick=function(ev){
//当点击的时候发射炮弹,所以在点击的时候创造炮弹发射声音文件
var oA=new Audio();
oA.src='snd/cannon.mp3';
oA.play();
//这里需要梳理鼠标点击的位置和炮旋转角度之间的关系(附图说明--炮的旋转角度.png)
var x=ev.clientX-oC.offsetLeft- c.x;
var y= c.y-(ev.clientY-oC.offsetTop);
//计算角度,注意角度的公式tan是临边比对边,和数学公式的有所不同 Math.atan2(y,x);并且这里是弧度转角度,需要在com.js中添加a2d的函数
var d=90-a2d(Math.atan2(y,x));
c.rotate=d;
//炮的后坐力方法存入
c.emitChange();
//当点击的时候生成炮弹,所以在点击事件中添加炮弹
var bullet=new Bullet(c.type);
//炮弹的位置和旋转角度和炮的位置和旋转角度相同,
bullet.x= c.x;
bullet.y= c.y;
bullet.rotate = c.rotate;
//注意炮弹不能画在这里,如果画在这里会被画炮和炮台时所清空,当然潘丹并不是只画一个,可以用一个数组来存储所画出来的炮弹,然后在炮旋转重绘的时候同时添加炮弹,为了让点击事件和定时器都能用到这个数组,这个数组应该写到事件和定时器的父级的变量空间中
//讲当次点击画布所创建的炮弹存入arrBullet中
arrBullet.push(bullet);
};
});
},false);
js原生捕鱼达人(三)--完结的更多相关文章
- js原生捕鱼达人(一)
捕鱼达人的游戏大家都很熟悉吧,接下来的两三天,我会将整个游戏的原生js写法详细的写出来,整个游戏应用了面向对象的写法:创建构造函数,在构造函数上面添加对象的属性,然后在构造函数的原型上添加方法,当然这 ...
- js原生捕鱼达人(二)
昨天写到构造炮弹,有点小bug不知道大家发现没有,今天继续昨天的步骤 7>构造炮弹 思路和前面都是一样一样的 注意构造函数中需要考虑的属性 和 构造函数的原型上面的方法 <sc ...
- html5 canvas简易版捕鱼达人游戏源码
插件描述:html5利用canvas写的一个js版本的捕鱼,有积分统计,鱼可以全方位移动,炮会跟着鼠标移动,第一次打开需要鼠标移出背景图,再移入的时候就可以控制炮的转动,因为是用的mouseover触 ...
- js原生的url操作函数,及使用方法。(附:下边还有jquery对url里的中文解码函数)
js原生的url操作函数,完善的. /*****************************/ /* 动态修改url */ /*****************************/ var ...
- 图片轮播(淡入淡出)--JS原生和jQuery实现
图片轮播(淡入淡出)--js原生和jquery实现 图片轮播有很多种方式,这里采用其中的 淡入淡出形式 js原生和jQuery都可以实现,jquery因为封装了很多用法,所以用起来就简单许多,转换成j ...
- 基于HTML5的捕鱼达人游戏网页版
之前给大家分享了html5实现的水果忍者,愤怒的小鸟,中国象棋游戏.今天给大家分享一款捕鱼达人(fishjoy)网页版游戏的源码.可以在线玩也可以下载到本地.它使用html5技术和javascript ...
- TOP30专访:捕鱼达人陈昊芝
原文:http://www.csdn.net/article/2012-04-04/313919/1 编者按:3月31日,第四届CocoaChina游戏开发者大会暨Cocos2D-X技术研讨会在北京举 ...
- 手把手教你js原生瀑布流效果实现
手把手教你js原生瀑布流效果实现 什么是瀑布流效果 首先,让我们先看一段动画: 在动画中,我们不难发现,这个动画有以下特点: 1.所有的图片的宽度都是一样的 2.所有的图片的高度是不一样的 3.图片一 ...
- 利用ZjDroid对 <捕鱼达人3> 脱壳及破解过程-转
http://blog.sina.com.cn/zihao2015 <捕鱼达人3> 刚出来不久,就被鬼哥Dump出来dex,随之破解也就轻而易举.一开始我用ZjDroid神器试验过,但是没 ...
随机推荐
- CSS3边框温故
1.简介:border属性在CSS1中就已经定义了,用来设置元素边框风格,设置不同的边框.颜色.粗细 2.基本属性,包括三个类型值:(1)border-width:设置元素边框的粗细,默认3~4px( ...
- c++中string的常用函数说明
string可以说是是字符数组的升级版,使用更加啊方便,不容易出错.本文对string的常用函数进行简单介绍,做到会用即可. string中的常用函数分为四类,即赋值,添加,比较和删除. 一.赋值 1 ...
- Uploading Files in SharePoint 2013 using CSOM and REST
http://www.shillier.com/archive/2013/03/26/uploading-files-in-sharepoint-2013-using-csom-and-rest.as ...
- 【读书笔记】iOS-类别
一,类别是一种为现有的类添加新方法的方式. 二,类别的局限性. 1,无法向类中添加新的实例变量.类别没有位置容纳实例变量. 2,名称冲突,即类别中的方法与现有的方法重名.当发生名称冲突时,类别具有更高 ...
- NSNumber和NSValue
在进行数据处理的时候,因为对象类型的不同, 并不能进行相应的数据处理,所以必须要进行数据类型的转换,这也就是NSNumber,NSValue这两类值对象出现的原因. 简而言之,NSNumber就是实现 ...
- Oracle递归查询
一.创建数据 1.1.建立表与插入数据 CREATE TABLE DISTRICT ( ID ) NOT NULL, PARENT_ID ), NAME BYTE) NOT NULL ); ALTER ...
- IOS CALayer(一)
对于一个app的好坏,我们首要判断的便是app的界面,而界面的建立则是在图形的处理基础上的,说到图形处理又不得不提及Quartz2D,CALayer. 在iOS系统中,你能看得见摸得着的东西基本上都是 ...
- 【转】一个非常常见但容易被忽略的c++问题——用IPML模式可以解决
pimpl (the pointer-to-implementation idiom)手法在 C++ 里已是“高手”们广泛运用的成熟方法之一,它的优点很多,诸如降低编译依赖.提高重编译速度之类的工具性 ...
- iOS 准确计算某个时间点距现在的时间差的代码 如"几分钟,几小时,几秒之前" ,
利用时间戳来进行计算 ,需要给它一个时间: NSString *countTime = [self intervalSinceNow:@"2015-10-29 17:00:00" ...
- 转载:sql关联查询
inner join(等值连接)只返回两个表中联结字段相等的行 left join(左联接)返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接)返回包括右表中的所有记录和 ...