第五周周记

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42018459/article/details/88959829

一个老师指导我制作的H5小游戏,一次随机生成5个圆形目标,当鼠标点击界面时,会有圆形子弹沿着鼠标的方向发射,当子弹击中圆形目标,会减少目标上方的血条,每消灭一个圆形目标,会自动生成一个目标,当消灭目标时,有概率出现大型目标,大型目标更难消灭,需要被击中多次,当消灭小型目标时会获得2积分,消灭大型目标时会获得10积分,子弹发射有冷血时间,冷却缓冲标志显示在左上角。
效果图如下(效果动态图有些卡顿,制作的时候帧数没设置好,运行代码之后的网页效果不会那么卡顿):
在这里插入图片描述

spirit.js

// spirit
function Spirit() {
    this.speed = 1.0;
    this.direction = 30 * (Math.PI / 180);

    this.lastframe = 0;
    this.lastx = 0;
    this.lasty = 0;
    this.radius = 50;

    // 游戏属性
    this.maxhp = 100;
    this.hp = 100;

    this.update = function () {
        var time = framecount - this.lastframe;
        var distance = this.speed * time;
        var x = distance * Math.cos(this.direction) + this.lastx;
        var y = distance * Math.sin(this.direction) + this.lasty;
        //
        if((x - this.radius) < 0 || (x + this.radius) > mapwidth){
            this.direction = 180 * (Math.PI / 180) - this.direction;
            x = this.lastx;
            y = this.lasty;
        }
        else if( (y- this.radius) < 0 || (y + this.radius) > mapheight){
            this.direction = - this.direction;
            x = this.lastx;
            y = this.lasty;
        }

        this.lastframe = framecount;
        this.lastx = x;
        this.lasty = y;
    };

    this.render = function () {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.arc(this.lastx,this.lasty,this.radius,0,Math.PI*2);
        ctx.fill();

        var hpwidth = this.radius * 2;
        var hpheight = this.radius/4;

        var hpx = this.lastx - this.radius;
        var hpy = this.lasty - this.radius;

        var hppercent = this.hp/this.maxhp;
        ctx.fillStyle = "red";
        ctx.fillRect(hpx,hpy,hpwidth * hppercent,hpheight);
        ctx.strokeStyle = "black";
        ctx.strokeRect(hpx,hpy,hpwidth,hpheight);
    }
}

function Bullet(){
    this.createframe = 0;
    this.lifetime = 500;

    this.speed = 2.0;
    this.direction = 60 * (Math.PI / 180);

    this.lastframe = 0;
    this.lastx = 0;
    this.lasty = 0;

    this.radius = 20;

    this.damage = 25;

    this.update = function () {
        var time = framecount - this.lastframe;
        var distance = this.speed * time;
        var x = distance * Math.cos(this.direction) + this.lastx;
        var y = distance * Math.sin(this.direction) + this.lasty;

        this.lastframe = framecount;
        this.lastx = x;
        this.lasty = y;
    };

    this.render = function () {
        if(framecount <= (this.createframe + this.lifetime)){
            ctx.fillStyle="#00000080";
            ctx.beginPath();
            ctx.arc(this.lastx,this.lasty,this.radius,0,Math.PI*2);
            ctx.fill();
        }
    }
}

render.js

var mousex = 0;
var mousey = 0;
var framecount = 0;
var mapwidth = 800;
var mapheight = 600;
var spiritlimit = 5;

var lastusetime = 0;
var cooldown = 20;

var score=0;
var grade;
// 目标的属性
// 普通:颜色深灰色,HP50,大小25
// BOSS:颜色黑色,HP200,大小50

function onMouseMove() {
    mousex = event.pageX - c.offsetLeft;
    mousey = event.pageY - c.offsetTop;
}

function onClick() {
    mousex = event.pageX - c.offsetLeft;
    mousey = event.pageY - c.offsetTop;

    if(framecount > (lastusetime + cooldown)) {
        var b = new Bullet();

        var startx = mapwidth/2;
        var starty = mapheight;

        var dx = mousex - startx;
        var dy = mousey - starty;
        var angle = Math.atan2(dy,dx);

        b.createframe = framecount;
        b.lastframe = framecount;
        b.lastx = startx;
        b.lasty = starty;
        b.direction = angle;
        mgr.addBullet(b);

        lastusetime = framecount;
    }

}

function ObjectManager() {
    this.idgen = 0;
    this.spirits = [];
    this.bullets = [];

    this.addSpirit = function (s) {
        this.idgen++;
        s.id = this.idgen;
        this.spirits.push(s);
        return s.id;
    };

    this.hitTest = function (x,y) {
        for(var i = 0; i < this.spirits.length; ++i){
            var s = this.spirits[i];
            if( x >= s.lastx && x <= (s.lastx + s.width) && y >= s.lasty && y <=(s.lasty+s.height)){
                return s.id;
            }
        }
        return null;
    };
    this.delSpirit = function (id) {
        for(var i = 0; i < this.spirits.length; ++i){
            var s = this.spirits[i];
            if(s.id == id)
            {
                if(s.maxhp>100)
                    score=score+10;
                else
                    score=score+2;
                this.spirits.splice(i,1);
                break;
            }
        }
    };

    // bullet
    this.addBullet = function (b) {
        this.idgen++;
        b.id = this.idgen;
        this.bullets.push(b);
        return b.id;
    };

    this.delBullet = function (id) {
        for(var i = 0; i < this.bullets.length; ++i){
            var b = this.bullets[i];
            if(b.id == id){
                this.bullets.splice(i,1);
                break;
            }
        }
    };

    this.update = function () {
        for(var i = 0; i < this.spirits.length; ++i){
            var s = this.spirits[i];
            s.update();
        }
        for(i = this.bullets.length - 1; i >= 0; --i){
            var b = this.bullets[i];
            if(framecount <= (b.createframe + b.lifetime)) {
                b.update();
                // 检查碰撞
                for(var index = this.spirits.length -1; index >= 0; --index  ){
                    s = this.spirits[index];
                    var dx = s.lastx - b.lastx;
                    var dy = s.lasty - b.lasty;
                    var distance = Math.sqrt(dx*dx + dy*dy);
                    if(distance < (s.radius + b.radius)){
                        s.hp -= b.damage;
                        if(s.hp <= 0){
                            this.delSpirit(s.id);
                        }
                        this.delBullet(b.id);
                        break;
                    }
                }
            }
            else{
                this.bullets.splice(i,1);
            }
        }
    };

    this.render = function () {
        for(var i = 0; i < this.spirits.length; ++i){
            var s = this.spirits[i];
            s.render();
        }
        for(i = 0; i < this.bullets.length; ++i){
            var b = this.bullets[i];
            b.render();
        }

        // cooldown
        var current = framecount - lastusetime;
        var percent = 1.0;
        if(current < cooldown){
            percent =  current/cooldown;
        }
        ctx.beginPath();
        ctx.moveTo(50,50);
        ctx.fillStyle = "gray";
        ctx.arc(50,50,30,0,Math.PI*2 * percent);
        ctx.fill();

        grade="Score:"+score;
        ctx.font="25px null";
        ctx.fillText(grade.toString(),360,30);
    }
}
var mgr = new ObjectManager();

function render() {
    requestAnimationFrame(render);
    framecount++;
    if(framecount % 60 == 0){
        if(mgr.spirits.length < spiritlimit){
            var rand = Math.random();
            if(rand < 0.1){
                var obj = new Spirit();
                obj.radius = 50;
                obj.lastx = Math.random() * (mapwidth - obj.radius * 2) + obj.radius;
                obj.lasty = Math.random() * (mapheight - obj.radius * 2) + obj.radius;
                obj.lastframe = framecount;
                obj.direction = Math.random() * 360 *(Math.PI/180);
                obj.color = "#000000FF";
                obj.maxhp = 200;
                obj.hp = 200;
                mgr.addSpirit(obj);
            }
            else{
                var obj = new Spirit();
                obj.radius = 25;
                obj.lastx = Math.random() * (mapwidth - obj.radius * 2) + obj.radius;
                obj.lasty = Math.random() * (mapheight - obj.radius * 2) + obj.radius;
                obj.lastframe = framecount;
                obj.direction = Math.random() * 360 *(Math.PI/180);
                obj.color = "#404040FF";
                obj.maxhp = 50;
                obj.hp = 50;
                mgr.addSpirit(obj);
            }
        }
    }

    mgr.update();
    ctx.clearRect(0,0,c.width,c.height);
    mgr.render();
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<canvas onclick="onClick();" onmousemove="onMouseMove();" id="rendertarget" width="800px" height="600px" style="border: solid 1px blue;background-color: #3F647FFF">
</canvas>
<script src="spirit.js"></script>
<script src="render.js"></script>
<script type="text/javascript">
    var c=document.getElementById("rendertarget");
    var ctx=c.getContext("2d");
    render();
</script>

</body>
</html>

将普通目标和大型目标分别用两种图片代替,将子弹同样替换为图片,并设置好角度、射出的方向,增加一个猫炮台,同时隐藏血条,当子弹击中目标才会显示血条。

效果图如下:
在这里插入图片描述
然后做了一些小小的修改,看起来奇怪了点,不过也是一种尝试

在这里插入图片描述
两个页面的源代码:
链接:https://pan.baidu.com/s/1lGtbo_g3qHAvSMdYTHWlDg
提取码:nxra

展开阅读全文

没有更多推荐了,返回首页