h5仿大炮炮彈飛行
html5仿大炮炮彈的自由落體實現
html5的魅力相信大家不會陌生,希望各位大大瀏覽器們早點支援這個特性哦,,還有先吐槽一句,微信的那個broser簡直弱爆了就簡單的動畫,比如滑動,就jquery的show(1000),hide(1000)都卡的不行,還是qq瀏覽器的核心,qq瀏覽器,,,算了,,我先冷靜下。。。。
還有就是前幾天看到的這個!!!
都不支援要他幹嘛?????
迴歸主題大炮
整體思路就是將每個打出來的炮彈看做一個物件,他的x,y轉換成canvas的x,y,其中vecior就是個控制力度的一個選項後文會提到。
var cannonBall = function (x,y,vector){
var gravity=0,
that={
x: x,
y: y,
removeMe:false,
move: function (){
vector.vy += gravity;
gravity += 0.1;
//模擬加速度
that.x+=vector.vx;
that.y+=vector.vy;
if(that.y > canvas.height -150){
that.removeMe=true;
}
},
draw: function (){
ctx.beginPath();
ctx.arc(that.x,that.y,5,0,Math.PI * 2);
ctx.fill();
ctx.closePath();
}
};
其中大炮炮彈的物件勢必涉及到了向量計算,自己封裝了個個方法,,有現成的Vector.js,但覺得太重(對於我們後端每次前端說不用模板,說太重,我們心裡都默想重你妹呀,,哈哈哈),很簡單,實現簡單功能可以,大型遊戲強烈建議使用現成的。
var vector2d= function (x,y){
var vec={
vx:x,
vy:y,
scale: function (scale){
vec.vx*=scale;
vec.vy*=scale;
},
add:function (vec2){
vec.vx+=vec2.vx;
vec.vy+=vec2.vy;
},
sub:function (vec2){
vec.vx-=vec2.vx;
vec.vy-=vec2.vy;
},
negate: function(){
vec.vx=-vec.vx;
vec.vy=-vec.vy;
},
length:function (){
return Math.sqrt(vec.vx * vec.vx + vec.vy * vec.vy);
},
normalize:function (){
var len=this.length();
if(len){
vec.vx /=len;
vec.vy /=len;
}
return len;
},
rotate:function (angle){
var vx = vec.vx;
var vy = vec.vy;
vec.vx = vx * Math.cos(angle) - vy * Math.sin(angle)
vec.vy = vx * Math.sin(angle) + vy * Math.cos(angle);
},
toString:function(){
return '(' + vec.vx.toFixed(3) + ',' + vec.vy.toFixed(3) + ')' ;
}
};
return vec;
};
好了,接著就是個計算角度再加上setInterval了,,其他沒啥說的,這裡我著重說下canvas.save();和canvas.restore();這裡稍微解釋一下,
當我們對畫布進行旋轉,縮放,平移等操作的時候其實我們是想對特定的元素進行操作,比如圖片,一個矩形等,但是當你用canvas的方法來進行這些操作的時候,其實是對整個畫布進行了操作,那麼之後在畫布上的元素都會受到影響,所以我們在操作之前呼叫canvas.save()來儲存畫布當前的狀態,當操作之後取出之前儲存過的狀態,這樣就不會對其他的元素進行影響
全部程式碼
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta author='gongbangwei'>
<title>大炮</title>
</head>
<body>
<div id='lidu'>
<span>選擇大炮的</span>
<input type="radio" checked='checked' value='25'>大
<input type="radio" value='20'>中
<input type="radio" value='15'>小
</div>
<canvas id='can' width="640" height="480" style=" border:2px solid">no support html5</canvas>
<script src='vector2d.js'></script>
<script src='jquery/jquery-1.7.2.min.js'></script>
<script>
var gameObj=[],
canvas=document.getElementById('can'),
ctx=canvas.getContext('2d');
var cannonBall = function (x,y,vector){
var gravity=0,
that={
x: x,
y: y,
removeMe:false,
move: function (){
vector.vy += gravity;
gravity += 0.1;
//模擬加速度
that.x+=vector.vx;
that.y+=vector.vy;
if(that.y > canvas.height -150){
that.removeMe=true;
}
},
draw: function (){
ctx.beginPath();
ctx.arc(that.x,that.y,8,0,Math.PI * 2);
ctx.fill();
ctx.closePath();
}
};
return that;
}
var cannon= function (x,y,lidu){
var mx=0,
my=0,
angle=0,
that={
x: x,
y: y,
lidu:lidu,
angle:0,
removeMe:false,
move:function (){
angle=Math.atan2(my-that.y,mx-that.x);
},
draw:function(){
ctx.save();
ctx.lineWidth=2;
ctx.translate(that.x,that.y);
//平移,將畫布的座標原點向左右方向移動x,向上下方向移動y.canvas的預設位置是在(0,0)
ctx.rotate(angle);
//畫布旋轉
ctx.strokeRect(0,-5,50,10);
ctx.moveTo(0,0);
ctx.beginPath();
ctx.arc(0,0,15,0,Math.PI * 2 );
ctx.fill();
ctx.closePath();
ctx.restore();
}
};//end that
canvas.onmousedown = function(){
//在這裡呼叫向量的那個js
var vec = vector2d(mx-that.x,my-that.y);
vec.normalize();
//console.log(lidu);
vec.scale(lidu);
gameObj.push(cannonBall(that.x,that.y,vec));
}
canvas.onmousemove = function (event){
var bb= canvas.getBoundingClientRect();
mx=(event.clientX - bb.left);
my=(event.clientY - bb.top);
};
return that;
};
//畫藍田和草地
var drawSkyAndGrass = function (){
ctx.save();
ctx.globalAlpha= 0.4;
var linGrad=ctx.createLinearGradient(0,0,0,canvas.height);
linGrad.addColorStop(0,'#00BFFF');
linGrad.addColorStop(0.5,'white');
linGrad.addColorStop(0.5,'#55dd00');
linGrad.addColorStop(1,'white');
ctx.fillStyle=linGrad;
ctx.fillRect(0,0,canvas.width, canvas.height);
ctx.restore();
}
///////main/////////////
var lidu=$('#lidu').find("input:checked").val();
gameObj.push(cannon(50,canvas.height-150,lidu));
$('#lidu').click(function (event){
var cl=event.target;
$(this).find('input').each(function(){
$(this).attr('checked',false)
});
$(cl).attr('checked',true);
lidu=$(cl).val();
gameObj.splice(0,gameObj.length);
gameObj.push(cannon(50,canvas.height-150,lidu));
})
setInterval( function (){
drawSkyAndGrass();
var gameObj_fresh=[];
for (var i = 0; i < gameObj.length; i++) {
gameObj[i].move();
gameObj[i].draw();
if(gameObj[i].removeMe === false){
gameObj_fresh.push(gameObj[i]);
}
}
gameObj=gameObj_fresh;
},50);
</script>
</body>
</html>
結束語
一個真正的前端絕不是ui,一個前端遊戲工程師也絕對是個數學家。
相關文章
- 仿IOS底部彈框iOS
- 射擊遊戲裡的子彈是如何飛行的遊戲
- js+canvas仿微信《彈一彈》小遊戲JSCanvas遊戲
- vue3仿windows彈窗VueWindows
- unity3D 兩點拋物線模擬炮彈Unity3D
- 讓前端的子彈飛-TypeScript前端TypeScript
- vue仿layer.js彈層元件vlayerVueJS元件
- 仿微信打飛機小遊戲GamePlane(1)----概述遊戲GAM
- h5單頁面彈出彈窗背景滾動問題H5
- ios 仿android的popupwindow彈出選單iOSAndroid
- Android仿微信支付密碼彈出層Android密碼
- react-native 仿原生自定義彈窗|iOS/Android 彈窗效果ReactiOSAndroid
- H5移動端彈幕動畫實現H5動畫
- h5監聽手機鍵盤彈起H5
- swift實現仿知乎搖一搖彈出框Swift
- 高仿微信聊天介面長按彈框樣式
- 仿QQ右下角彈窗新聞_原始碼分享原始碼
- 小技巧|H5禁止手機虛擬鍵盤彈出H5
- C#——飛行棋C#
- Webpack飛行手冊Web
- 仿“螢火蟲”通訊無人機:無懼電磁壓制,被干擾下也能協同飛行!無人機
- 四軸飛行器實踐教程1.1.2飛行器的發展
- 專案需求討論-仿ios底部彈框實現及分析iOS
- 防止“被黑飛”,大疆推出飛行安全系統GEO
- 飛行器的分類四軸飛行器實踐教程大學霸
- 對飛豬H5端API介面sign簽名逆向實驗H5API
- spring cloud 微信掃碼H5飛鳥程式搭建環境配置SpringCloudH5
- 開源飛行器 HEX
- 四軸飛行器實踐教程第1章什麼是飛行器
- python 打飛機專案 ( 讓敵機發射子彈 )Python
- h5鍵盤彈出收回導致位置錯亂解決方案H5
- H5頁面遮罩彈框下層還能滾動的問題H5遮罩
- 中文OCR超越GPT-4V,引數量僅2B,面壁小鋼炮拿出了第二彈GPT
- 彈指間,網頁灰飛煙滅——Google滅霸彩蛋實現網頁Go
- Infinity Wing Drive個人飛行翼:戴上它就能飛起來
- Vue H5微信瀏覽器外進行支付 H5支付VueH5瀏覽器
- Flutter | 可能是目前最好用的仿微信聊天長按彈出框 WPopupMenuFlutter
- react.js自定義pc桌面端對話方塊|react仿layer彈窗ReactJS