html5利用canvas寫的一個js版本的捕魚,有積分統計,魚可以全方位移動,炮會跟著鼠標移動,第一次打開需要鼠標移出背景圖,再移入的時候就可以控制炮的轉動,因為是用的mouseover觸發的。
在線試玩:
http://hovertree.com/texiao/html5/33/
手機掃描二維碼試玩:
效果圖:
源碼下載:http://hovertree.com/h/bjaf/buyuyuanma.htm
代碼如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>捕魚達人 - 何問起</title>
<style>
* {
margin: 0px;
padding: 0px;
}
body {
background: black;
}
#hovertreefish {
background-image: url(http://hovertree.com/texiao/html5/33/Images/hovertreefishbg.jpg);
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
}
#hovertreeinfo{position:fixed;top:0px;left:0px;font-size:16px;}
#hovertreeinfo{
padding: 5px;
background-color: rgba(0,0,0,0.3);/* IE9、標准浏覽器、IE6和部分IE7內核的浏覽器(如QQ浏覽器)會讀懂 */
}
#hovertreeinfo p{
color: #FFFFFF;
}
@media \0screen\,screen\9 {/* 只支持IE6、7、8 */
#hovertreeinfo{
background-color:#000000;
filter:Alpha(opacity=30);
position:static; /* IE6、7、8只能設置position:static(默認屬性) ,否則會導致子元素繼承Alpha值 */
*zoom:1; /* 激活IE6、7的haslayout屬性,讓它讀懂Alpha */
}
#hovertreeinfo p{
position: relative;/* 設置子元素為相對定位,可讓子元素不繼承Alpha值 */
}
}
/*參考: http://hovertree.com/hvtart/bjae/q3etb2qv.htm
http://hovertree.com/h/bjaf/8mj7gsk6.htm
*/
</style>
</head>
<body>
<canvas id="hovertreefish" width="900" height="800">
何問起提示:請使用新版浏覽器!
</canvas>
<div id="hovertreeinfo"><p>移動鼠標控制方向,點擊鼠標放子彈<br />何問起提示:無法控制請點擊這裡。</p></div>
<script>
function loadImg(arr, fn) {
var result = {};
var iNow = 0;
for (var i = 0; i < arr.length; i++) {
var oImage = new Image();
var tmp = arr[i].split('.');
result[tmp[0]] = oImage;
oImage.onload = function () {
iNow++;
if (iNow >= arr.length) {
fn(result);
}
}
oImage.src = 'Images/' + arr[i];
}
}
window.onload = function () {
var oCans = document.getElementById('hover' + 'treefish');
var curW = document.documentElement.clientWidth || document.body.clientWidth;
var curH = document.documentElement.clientHeight || document.body.clientHeight;
var intger = '000000';
var intgerArr = getInteger(0);
var i = 0;
oCans.width = curW - 10;
oCans.height = curH - 10;
var oGc = oCans.getContext('2d');
loadImg(['pig.png', 'gun.png', 'zidan.png', 'gold.png', 'fish1.png', 'fish1_1.png', 'fish2.png', 'fish2_1.png', 'fish3.png', 'fish3_1.png', 'integer.png', 'bottom.jpg'], function (result) {
//炮的運動
oGc.drawImage(result['gun'], 0, 0, 64, 64, oCans.offsetWidth / 2 - 32, oCans.offsetHeight - 70, 64, 64);
var gun = {};
var pig = {};
var goldArr = [];
var goldRun = [];
var zidanArr = [];
var bottomL = intgerArr.length * 80;
gun.x = oCans.offsetWidth / 2;
gun.y = oCans.offsetHeight - 70;
pig.arcX = result['pig'].width / 2;
pig.arcY = (oCans.offsetHeight - result['pig'].height / 2);
pig.curPoy = 0.5;
oCans.onmouseover = function () {
this.onmousemove = function (ev) {
var oEvent = ev || event;
var iMx = oEvent.layerX;
var iMy = oEvent.layerY;
gun.hudu = -(Math.atan2(iMx - gun.x, iMy - gun.y) + 180 * Math.PI / 180);
//炮
oGc.save();
oGc.translate(gun.x, gun.y + 32);//設置原點
oGc.rotate(gun.hudu);
oGc.drawImage(result['gun'], 0, 0, 64, 64, -32, -32, 64, 64);
oGc.restore();
}
this.onmousedown = function (ev) {
var oEvent = ev || event;
var iCx = oEvent.layerX;
var iCy = oEvent.layerY;
zidanArr.push(
{
x: gun.x,
y: gun.y,
startX: iCx,
startY: iCy,
iRatio: 0,
hudu: gun.hudu,
curPoy: 1
}
);
}
}
//畫
setInterval(function () {
oGc.clearRect(0, 0, oCans.offsetWidth, oCans.offsetHeight);
// document.title = zidanArr.length+'/'+fashArr.length+'/'+goldArr.length+'/'+goldRun.length;
//子彈
for (i = 0; i < zidanArr.length; i++) {
var theY = Math.floor(24 - Math.cos(zidanArr[i].hudu) * 24 - 10);
var theX = Math.ceil(Math.sin(zidanArr[i].hudu) * 24);
var arcX = zidanArr[i].x + theX;
var arcY = zidanArr[i].y + theY;
zidanArr[i].iRatio = (zidanArr[i].startX - arcX) / (zidanArr[i].startY - arcY);
oGc.save();
oGc.translate(arcX, arcY);//設置原點
oGc.rotate(zidanArr[i].hudu);
oGc.drawImage(result['zidan'], 0, parseInt(zidanArr[i].curPoy) * 48, 30, 48, theX - 15, theY - 24, 30, 48);
oGc.restore();
zidanArr[i].y -= 6;
zidanArr[i].x -= 6 * zidanArr[i].iRatio.toFixed(2);
zidanArr[i].curPoy += 0.3;
if (zidanArr[i].curPoy > 3) {
zidanArr[i].curPoy = 0;
}
if (zidanArr[i].x <= 0 || zidanArr[i].x >= oCans.offsetWidth || zidanArr[i].y <= 0 || zidanArr[i].y >= oCans.offsetHeight) {
zidanArr.splice(i, 1);
i--;
}
}
//炮
oGc.save();
oGc.translate(gun.x, gun.y + 32);//設置原點
oGc.rotate(gun.hudu);
oGc.drawImage(result['gun'], 0, 0, 64, 64, -32, -32, 64, 64);
oGc.restore();
//魚
for (i = 0; i < fashArr.length; i++) {
var speedX = 2;
if (fashArr[i].type == 1) {
speedX = -2;
}
var speedY = parseFloat(speedX * Math.tan(fashArr[i].hudu));
fashArr[i].x = fashArr[i].x + speedX;
fashArr[i].y = fashArr[i].y + speedY;
oGc.save();
oGc.translate(fashArr[i].x, fashArr[i].y);
oGc.rotate(fashArr[i].hudu);
oGc.drawImage(result[fashArr[i].name], 0, parseInt(fashArr[i].curPoy) * fashArr[i].h, fashArr[i].w, fashArr[i].h, speedX, speedY, fashArr[i].w, fashArr[i].h);
oGc.restore();
fashArr[i].curPoy += fashArr[i].step;
if (fashArr[i].curPoy > fashArr[i].endPoy) {
fashArr[i].curPoy = 0;
}
if (fashArr[i].type == 0 && fashArr[i].x > oCans.offsetWidth) {
fashArr.splice(i, 1);
i--;
} else if (fashArr[i].x < -fashArr[i].w) {
fashArr.splice(i, 1);
i--;
}
}
// 底邊 試玩地址: http://hovertree.com/h/bjaf/html5buyu.htm
oGc.drawImage(result['bottom'], 0, 0, result['bottom'].width, result['bottom'].height, bottomL, 0, (intgerArr.length - 1) * result['integer'].height / 10, result['integer'].height / 10 + 5);
//打中
for (i = 0; i < zidanArr.length; i++) {
for (var n = 0; n < fashArr.length; n++) {
if (collideTest(zidanArr[i].x, zidanArr[i].y, 30, 46, fashArr[n].x, fashArr[n].y, fashArr[n].w, fashArr[n].h)) {
var goldTmp = {
x: fashArr[n].x,
y: fashArr[n].y,
curPoy: 0,
};
intgerArr = getInteger(fashArr[n].intger);//設置積分
goldArr.push(goldTmp);
fashArr.splice(n, 1);
zidanArr.splice(i, 1);
i--;
break;
}
}
}
//金幣
for (i = 0; i < goldArr.length; i++) {
oGc.drawImage(result['gold'], 0, parseInt(goldArr[i].curPoy) * 51, 49, 51, goldArr[i].x, goldArr[i].y, 49, 51);
if (goldArr[i].curPoy >= 5) {
goldRun.push({
curX: goldArr[i].x,
curY: goldArr[i].y,
});
goldArr.splice(i, 1);
} else {
goldArr[i].curPoy += 0.5;
}
}
//金幣運動
if (pig.curPoy > 0.5) {
pig.curPoy -= 0.08;
} else {
pig.curPoy = 0;
}
for (i = 0; i < goldRun.length; i++) {
oGc.drawImage(result['gold'], 0, 0, 49, 51, goldRun[i].curX, goldRun[i].curY, 49, 51);
var speedX = parseInt((pig.arcX - goldRun[i].curX) * 0.2);
var speedY = parseInt((pig.arcY - 20 - goldRun[i].curY) * 0.2);
goldRun[i].curX += speedX;
goldRun[i].curY += speedY;
if (speedX == 0) {
goldRun.splice(i, 1);
i--;
pig.curPoy = 1;
}
}
//pig
oGc.drawImage(result['pig'], 0, Math.round(pig.curPoy) * 90, 90, 90, 0, oCans.offsetHeight - 90, 90, 90);
//積分
for (i = 0; i < intgerArr.length; i++) {
oGc.drawImage(result['integer'], 0, intgerArr[i].old, result['integer'].width, result['integer'].height / 10, bottomL + (i * result['integer'].width), 5, result['integer'].width, result['integer'].height / 10);
var intSpeed = (intgerArr[i].number - intgerArr[i].old) / 8;
intSpeed = intSpeed > 0 ? Math.ceil(intSpeed) : Math.floor(intSpeed);
intgerArr[i].old += intSpeed;
}
}, 1000 / 60);
});
var fashArr = [];
var arr = [
{
name: 'fish1',
endPoy: 12,
step: 0.1,
w: 80,
h: 80,
intger: 2
},
{
name: 'fish2',
endPoy: 8,
step: 0.1,
w: 60,
h: 64,
intger: 3
},
{
name: 'fish3',
endPoy: 9,
step: 0.1,
w: 50,
h: 56,
intger: 1
}
]
setInterval(function () {
var rand = Math.round(Math.random() * (arr.length - 1));
var iType = Math.round(Math.random() * 1);
var tmp = {
x: -arr[rand].w,
y: oCans.offsetHeight / 2 - 150,
hudu: (Math.PI / 180) * (parseInt(Math.random() * 60 - 20)),
curPoy: 0,
step: arr[rand].step,
endPoy: arr[rand].endPoy,
name: arr[rand].name,
w: arr[rand].w,
h: arr[rand].h,
intger: arr[rand].intger,
type: 0
};
if (iType === 1) {
tmp.type = 1;
tmp.x = oCans.offsetWidth + tmp.w;
tmp.name = tmp.name + '_1';
}
fashArr.push(tmp);
}, 800);
//碰撞檢測
function collideTest(x1, y1, w1, h1, x2, y2, w2, h2) {
var r1 = x1 + w1;
var b1 = y1 + h1;
var r2 = x2 + w2;
var b2 = y2 + h2;
if (x1 > r2 || r1 < x2 || b1 < y2 || y1 > b2) {
return false;
} else {
return true;
}
}
function getInteger(num) {
var intgerArr = [];
for (var i = 0; i < String(intger).length; i++) {
intgerArr.push({
old: Number(String(intger)[i]) * 53,
curPoy: 0
});
}
intger = parseFloat(intger) + num;
for (i = String(intger).length; i < 6; i++) {
intger = '0' + intger;
}
for (i = 0; i < intgerArr.length; i++) {
intgerArr[i].number = Number(String(intger)[i]) * 53;
}
return intgerArr;
}
}
</script>
</body>
</html>