头图

给大家安利一个免费且实用的前端刷题(面经大全)网站,👉点击跳转到网站

本节教程我会带大家使用 HTML 、CSS和 JS 来制作一个 水果忍者游戏

本节示例将会实现如下所示的效果:

在线演示地址:https://code.haiyong.site/moyu/shuiguorenzhe/
源码也可在文末进行获取

🕹️ 本文已收录于🎖️100个HTML小游戏专栏:100个HTML小游戏
🎮 目前已有100+小游戏,源码在持续更新中,前100位订阅免费,先到先得。
🐬 订阅专栏后可阅读100个HTML小游戏文章;还可私聊进前端/游戏制作学习交流群;领取一百个小游戏源码。
在这里插入图片描述

✨ 项目基本结构

大致目录结构如下(共92个子文件):

├── images
│   ├── background.jpg
│   │   ...
│   └── xf.png
├── sound
│   ├── start.ogg
│   │   ...
│   └── boom.mp3
├── scripts
│   ├── factory
│   │   ├── rotate.js
│   │   ├── fruit.js
│   │   ...
│   │   └── juice.js
│   ├── timeline.js
│   ...
│   └── control.js
└── index.html

在这里插入图片描述

场景展示

 title=
 title=
 title=

HTML源码

<div id="extra"></div>
<canvas id="view" width="640" height="480"></canvas>
<div id="desc">
    <div>用鼠标滑动水果开始游戏</div>
    <div id="browser"></div>
</div>
<a href="https://code.haiyong.site/moyu" target="_blank" class="btn btn_left">更多游戏</a>
<a href="https://code.haiyong.site/ziyuan/game/" target="_blank" class="btn btn_right" id="fullscr">游戏源码</a>

CSS 源码

html,body

html, body{
    width: 100%;
    height: 100%;
    background: #484848;
}

body{
    position: relative;
}

extra,view,layer

#extra, #view{
    position: absolute;
    left: 50%;
    top: 50%;
    width: 640px;
    height: 480px;
    margin: -280px auto auto -320px;
    text-align: left;
    background: #fff;
}

#view{
    display: block;
    background: transparent url(blank.gif) repeat 0 0;
    cursor: default;
    z-index: 20;
}

#extra{
    background: #000;
}

#extra .layer{
    position: absolute;
    left: 0;
    top: 0;
    width: 640px;
    height: 480px;
    z-index: 10;
}

fork

#fork{
    display: block;
    position: absolute;
    right: 0;
    top: 0;
    width: 356px;
    height: 92px;
    cursor: pointer;
    background-image: url(fork.gif);
    z-index: 0;
}

desc

#desc{
    width: 100%;
    position: absolute;
    left: 0;
    top: 50%;
    height: 80px;
    color: #ccc;
    line-height: 40px;
    margin-top: 200px;
    text-align: center;
    font-size: 14px;
}

#desc a{
    color: #318fe1;
}

browser

#browser{
    font-size: 14px;
    line-height: 16px;
}

#browser .b{
    color: #fff;
    font-weight: 700;
}

JS 源码

js 代码较多,这里提供部分,完整源码可以在文末下载

碰撞检测

exports.check = function( knife ){
    var ret = [], index = 0;

    fruits.forEach(function( fruit ){
        var ck = lineInEllipse(
            knife.slice( 0, 2 ), 
            knife.slice( 2, 4 ), 
            [ fruit.originX, fruit.originY ],
            fruit.radius
        );
        if( ck )
            ret[ index ++ ] = fruit;
    });
    return ret;
};

function sqr(x){
    return x * x;
}

function sign(n){
    return n < 0 ? -1 : ( n > 0 ? 1 : 0 );
}

function equation12( a, b, c ){
    if(a == 0)return;

    var delta = b * b - 4 * a * c;
    if(delta == 0)
        return [ -1 * b / (2 * a), -1 * b / (2 * a) ];
    else if(delta > 0)
        return [ (-1 * b + Math.sqrt(delta)) / (2 * a),  (-1 * b - Math.sqrt(delta)) / (2 * a) ];
}

返回线段和椭圆的两个交点,如果不相交,返回 null

function lineXEllipse( p1, p2, c, r, e ){
    // 线段:p1, p2    圆心:c    半径:r    离心率:e
    if (r <= 0) return;
    e = e === undefined ? 1 : e;
    var t1 = r, t2 = r * e, k;

    a = sqr( t2) * sqr(p1[0] - p2[0]) + sqr(t1) * sqr(p1[1] - p2[1]);

    if (a <= 0) return;
    
    b = 2 * sqr(t2) * (p2[0] - p1[0]) * (p1[0] - c[0]) + 2 * sqr(t1) * (p2[1] - p1[1]) * (p1[1] - c[1]);
    c = sqr(t2) * sqr(p1[0] - c[0]) + sqr(t1) * sqr(p1[1] - c[1]) - sqr(t1) * sqr(t2);
    
    if (!( k = equation12(a, b, c, t1, t2) )) return;
    
    var result = [
        [ p1[0] + k[0] * (p2[0] - p1[0]), p1[1] + k[0] * (p2[1] - p1[1]) ],
        [ p1[0] + k[1] * (p2[0] - p1[0]), p1[1] + k[1] * (p2[1] - p1[1]) ]
    ];
    
    if ( !( ( sign( result[0][0] - p1[0] ) * sign( result[0][0] - p2[0] ) <= 0 ) &&
        ( sign( result[0][1] - p1[1] ) * sign( result[0][1] - p2[1] ) <= 0 ) ) )
        result[0] = null;

    if ( !( ( sign( result[1][0] - p1[0] ) * sign( result[1][0] - p2[0] ) <= 0 ) &&
        ( sign( result[1][1] - p1[1] ) * sign( result[1][1] - p2[1] ) <= 0 ) ) )
        result[1] = null;

    return result;
}

判断计算线段和椭圆是否相交

function lineInEllipse( p1, p2, c, r, e ){
    var t = lineXEllipse( p1, p2, c, r, e );
    return t && ( t[0] || t[1] );
};

图片资源

一共两百多张图片,全都打包放在文末的下载链接里了。

在这里插入图片描述
在这里插入图片描述

源码下载

1.CSDN资源下载(需要VIP):https://download.csdn.net/download/qq_44273429/86922040
2.从海拥资源网下载(更优惠):https://code.haiyong.site/25/
3.也可关注我思否(海拥)后私信简易版英雄联盟获取


海拥
13 声望5 粉丝