美文网首页ES6前端开发那些事儿
从零开始手把手教你使用javascript+canvas开发一个

从零开始手把手教你使用javascript+canvas开发一个

作者: __豆约翰__ | 来源:发表于2020-12-29 14:13 被阅读0次

    项目演示

    项目演示地址:

    体验一下

    项目源码:

    项目源码

    代码结构

    本节做完效果

    image.png

    Enemy.js

    //敌人类
    
    function Enemy(cxt,img,type,x,y,width,height){
    
        this.cxt = cxt;
        this.img = img;
        this.x = x;//55
        this.y = y;//0
        this.width = width;
        this.height = height;
        //敌人类型
        this.type = type;
    
        this.sp = 2;
        //移动的方向
        this.dir = null;
        //下个移动位置
        this.nextPosition = null;
    
        //记录已经走过的位置
        this.hadWalk = {};
    }
    
    Enemy.prototype = {
        //敌人在图片中对应的位置
        enemyMap : [{x:0,y:0},{x:40,y:0},{x:80,y:0},{x:120,y:0},{x:160,y:0},{x:200,y:0},{x:240,y:0},{x:280,y:0},{x:320,y:0},{x:360,y:0},
            {x:400,y:0},{x:440,y:0},{x:480,y:0},{x:520,y:0},{x:560,y:0},{x:600,y:0},{x:640,y:0},{x:680,y:0},{x:720,y:0},{x:760,y:0}],
        //画出敌人
        draw : function(){
            //冰冻中,画出冰冻图
            if(this.frozenTime > 0){
    
                Canvas.drawImg(this.cxt,this.img,this.enemyMap[this.type].x,this.enemyMap[this.type].y+40,this.width,this.height,this.x,this.y,this.width,this.height);
            }
            //画出正常图
            else Canvas.drawImg(this.cxt,this.img,this.enemyMap[this.type].x,this.enemyMap[this.type].y,this.width,this.height,this.x,this.y,this.width,this.height);
            //计算血量百分比
            var persen = Math.floor(this.life / this.maxLife * 100) / 2;
            //画出血量
            Canvas.fillRect(this.cxt,this.x-5,this.y-5,persen,3,"rgba(38,223,116,0.8)");
        },
    
        //更新敌人信息
        update : function(){
            //超出坐标
            if(this.x >= 500){
                return false;
            }
    
            var xIndex = parseInt(this.x / 50,10),//1
                yIndex = parseInt(this.y / 50,10);//0
            //判断是否有下个移动位置信息,或者下哥移动位置信息是否已经走到了
            if(!this.nextPosition ||
                ((this.x >= this.nextPosition.x - 5 && this.x <= this.nextPosition.x)
                    && (this.y >= this.nextPosition.y - 5 && this.y <= this.nextPosition.y))
            ){
                //走到最右侧
                if(xIndex + 1 >= 10){
                    xIndex = -1;
                }
                else{
                    //判断往下能否走
                    if(MapData[xIndex][yIndex+1] && !this.hadWalk[xIndex+"_"+(yIndex+1)]){
    
                        this.dir = "down";
                        yIndex += 1;
                    }
                    //判断往右能否走
                    else if(MapData[xIndex+1][yIndex]  && !this.hadWalk[(xIndex+1)+"_"+yIndex]){
                        this.dir = "right";
                        xIndex += 1;
                    }
                    else if(MapData[xIndex][yIndex-1] && !this.hadWalk[xIndex+"_"+(yIndex-1)]){
                        this.dir = "up";
                        yIndex -= 1;
                    }
                    else if(MapData[xIndex-1][yIndex] && !this.hadWalk[(xIndex-1)+"_"+yIndex]){
                        this.dir = "left";
                        xIndex -= 1;
                    }
                }
                //是否走到最右侧
                if(xIndex == -1){
                    this.nextPosition = {x:500,y:yIndex*50+5};
                }
                //设置下个移动位置
                else {
                    this.nextPosition = {x:xIndex*50+5,y:yIndex*50+5};
                    //记录已经走过的位置
                    this.hadWalk[xIndex+"_"+yIndex] = true;
                }
    
            }
    
    
            //移动
            switch(this.dir){
    
                case "down":
                    this.y += this.sp;
                    break;
                case "up":
                    this.y -= this.sp;
                    break;
                case "left":
                    this.x -= this.sp;
                    break;
                case "right":
                    this.x += this.sp;
                    break;
                default:
    
                    break;
            }
    
        }
    
    }
    
    //更新所有敌人信息
    function updateEnemy(){
    
        var enemy;
    
        for(var i=0,l=Game.enemyList.length;i<l;i++){
    
            enemy = Game.enemyList[i];
    
            if(!enemy)continue;
    
            enemy.update();
        }
    
    }
    
    //画出所有敌人
    function drawEnemy(){
    
        var enemy;
    
        for(var i=0,l=Game.enemyList.length;i<l;i++){
    
            enemy = Game.enemyList[i];
    
            if(!enemy)continue;
    
            enemy.draw();
        }
    
    }
    

    game.js修改

    每50次循环出一个敌人


    tool.js新增

    自动寻路算法解析

    坐标系

    向右为x轴
    向下为y轴

    整个地图为500*500

       // 游戏对象
            var hero = {
                speed: 2, // 每秒移动的像素
                x: 55,
                y: 0,
                srcx:120,
                srcy:40,
               flood:50,
             
            //移动的方向
            dir:null,
            //下个移动位置
            nextPosition: null,
    
            //记录已经走过的位置
            hadWalk:{}
            };
    

    英雄像素转换为网格(10*10)坐标

     var xIndex = parseInt(hero.y / 50, 10),
     yIndex = parseInt(hero.x / 50, 10);
    

    最开始时,
    xIndex = 1
    yIndex = 0

    初始时满足!hero.nextPosition

      if (!hero.nextPosition ||
                     ((hero.x >= hero.nextPosition.x - 5 && hero.x <= hero.nextPosition.x) && (hero.y >= hero.nextPosition.y - 5 && hero.y <= hero.nextPosition.y))
                 ) 
    

    进入后,满足往下走

     else {
                    //判断往下能否走
                    if(MapData[xIndex][yIndex+1] && !this.hadWalk[xIndex+"_"+(yIndex+1)]){
    
                        this.dir = "down";
                        yIndex += 1;
                    }
    

    此时
    xIndex = 1
    yIndex = 1
    然后,

     //设置下个移动位置
                     else {
                         hero.nextPosition = {y: xIndex * 50 + 5, x: yIndex * 50 + 5};
                         //记录已经走过的位置
                         hero.hadWalk[xIndex + "_" + yIndex] = true;
                     }
    

    hero.nextPosition = {
    x:55,y:55
    }

    然后,

     //移动
                switch(hero.dir){
    
                    case "down":
                        hero.y += hero.speed;
                        break;
                    case "up":
                        hero.y -= hero.speed;
                        break;
                    case "left":
                        hero.x -= hero.speed;
                        break;
                    case "right":
                        hero.x += hero.speed;
                        break;
                    default:
    
                        break;
                }
    

    此时,

    hero = {
               speed: 2, // 每秒移动的像素
               x: 2,
               y: 55,
    

    循环回去:
    然后在hero.x未满足条件:

      if (!hero.nextPosition ||
                    ((hero.x >= hero.nextPosition.x - 5 && hero.x <= hero.nextPosition.x) && (hero.y >= hero.nextPosition.y - 5 && hero.y <= hero.nextPosition.y))
                ) 
    

    时,有25次(50/2),跳过上面条件里的代码,直接执行以下代码:

     //移动
                switch(hero.dir){
    
                    case "down":
                        hero.y += hero.speed;
                        break;
                    case "up":
                        hero.y -= hero.speed;
                        break;
                    case "left":
                        hero.x -= hero.speed;
                        break;
                    case "right":
                        hero.x += hero.speed;
                        break;
                    default:
    
                        break;
                }
    

    当再次hero.x满足条件:

      if (!hero.nextPosition ||
                    ((hero.x >= hero.nextPosition.x - 5 && hero.x <= hero.nextPosition.x) && (hero.y >= hero.nextPosition.y - 5 && hero.y <= hero.nextPosition.y))
                ) 
    

    时,重复之前的逻辑。
    如此循环。
    such that

    项目源码:

    项目源码

    相关文章

      网友评论

        本文标题:从零开始手把手教你使用javascript+canvas开发一个

        本文链接:https://www.haomeiwen.com/subject/knipnktx.html