从零开始手把手教你使用javascript+canvas开发一个塔防游戏05拖拽塔到地图上

简介: 从零开始手把手教你使用javascript+canvas开发一个塔防游戏05拖拽塔到地图上

项目演示


image.png


项目演示地址:

体验一下

项目源码:

项目源码

代码结构


image.png

本节做完效果


image.png


新增tower.js

//塔类
 function Tower(cxt,img,type,x,y,width,height){
    this.cxt = cxt;
    this.img = img;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    //塔的类型
    this.type = type;
    //塔的级别
    this.level = 1;
    //塔的攻击冷却时间
    this.cd = 0;
}
Tower.prototype = {
    //塔的图片位置
    towerMap : [{x:0,y:0},{x:50,y:0},{x:100,y:0},{x:150,y:0},{x:200,y:0}],
    //画塔
    draw : function(){
        Canvas.drawImg(this.cxt,this.img,this.towerMap[this.type].x,this.towerMap[this.type].y,this.width,this.height,this.x,this.y,this.width,this.height);
    },
}
var TowerType = [
    {
        level_1:{
            scope:100,buyIt:50,bullet:1,cd:20
        },
        level_2:{
            scope:110,buyIt:50,bullet:1,cd:18
        },
        level_3:{
            scope:120,buyIt:50,bullet:1,cd:15
        }
    },
    {
        level_1:{
            scope:120,buyIt:75,bullet:1,cd:18
        },
        level_2:{
            scope:130,buyIt:75,bullet:1,cd:15
        },
        level_3:{
            scope:140,buyIt:75,bullet:2,cd:12
        }
    },
    {
        level_1:{
            scope:140,buyIt:100,bullet:3,cd:18
        },
        level_2:{
            scope:150,buyIt:100,bullet:4,cd:15
        },
        level_3:{
            scope:160,buyIt:100,bullet:5,cd:12
        }
    },
    {
        level_1:{
            scope:130,buyIt:125,bullet:1,cd:50
        },
        level_2:{
            scope:140,buyIt:125,bullet:1,cd:40
        },
        level_3:{
            scope:150,buyIt:125,bullet:1,cd:30
        }
    },
    {
        level_1:{
            scope:150,buyIt:150,bullet:1,cd:20
        },
        level_2:{
            scope:160,buyIt:150,bullet:1,cd:15
        },
        level_3:{
            scope:170,buyIt:150,bullet:1,cd:12
        }
    }
]
//更新塔
function updateTower(){
    var tower;
    for(var i=0,l=Game.towerList.length;i<l;i++){
        tower = Game.towerList[i];
        if(!tower)continue;
        tower.update(Game.enemyList);
    }
}


tool.js


新增


image.png


以及

var T = {
    //判断一个点是否在一个矩形中
    pointInRect : function(point,rect){
        if(point.x >= rect.x && point.x <= (rect.x+rect.width)
            && point.y >= rect.y && point.y <= (rect.y + rect.height))
        return true;
        return false;
    },
    //判断两个圆是否相交
    circleInCircle : function(cir1,cir2){
        if(Math.sqrt(Math.pow(cir1.x-cir2.x,2)+Math.pow(cir1.y-cir2.y,2)) < (cir1.radius+cir2.radius))return true;
        return false;
    },
    //判断矩形与圆相交
    rectInCircle : function(rect,cir){
        var x1 = rect.x,y1 = rect.y,
            x2 = rect.x+rect.width,y2= rect.y+rect.height;
        if(Math.sqrt(Math.pow(x1-cir.x,2)+Math.pow(y1-cir.y,2)) < cir.radius ||
            Math.sqrt(Math.pow(x1-cir.x,2)+Math.pow(y2-cir.y,2)) < cir.radius ||
            Math.sqrt(Math.pow(x2-cir.x,2)+Math.pow(y2-cir.y,2)) < cir.radius ||
            Math.sqrt(Math.pow(x2-cir.x,2)+Math.pow(y1-cir.y,2)) < cir.radius)
            return true;
        return false;
    }
 }


game.js


image.png


info.js


新增

//绑定右侧塔的事件
    bindEvent : function(){
        var self = this,info = document.getElementById("info"),
            select = document.getElementById("select"),
            main = Game.canvasList.tower,
            cxt = Game.canvasList.select;
        //鼠标按下
        info.onmousedown = function(e){
            var x = e.offsetX || e.layerX,
                y = e.offsetY || e.layerY,
                xIndex,yIndex;
            //遍历右侧的塔位置
            for(var i=0;i<self.towerPosition.length;i++){
                //点击的是塔
                if(T.pointInRect({x:x,y:y},self.towerPosition[i])){
                    //金钱不够,推出
                    if(self.score - TowerType[i]["level_1"].buyIt < 0)break;
                    //绑定移动移动事件,也可以说是拖动
                    select.onmousemove = function(e){
                        x = e.offsetX || e.layerX;
                        y = e.offsetY || e.layerY;
                        xIndex = Math.floor(x / 50);
                        yIndex = Math.floor(y / 50);
                        Canvas.clear(cxt,500,500);
                        //画出塔在左侧区域
                        Canvas.drawImg(cxt,self.towerImg,i*50,0,50,50,x-25,y-25,50,50);
                        //画出范围,如果当前位置没有塔而且是可放塔的
                        if(MapData[xIndex][yIndex] == 0 && !self.installTower[xIndex+"_"+yIndex])Canvas.fillArc(cxt,x,y,TowerType[i]["level_1"].scope,"rgba(25,174,70,0.5)");
                        else Canvas.fillArc(cxt,x,y,TowerType[i]["level_1"].scope,"rgba(252,82,7,0.5)");
                        //画出塔具体的放置位置
                        Canvas.drawRect(cxt,xIndex*50,yIndex*50,50,50,'black');
                    }
                    //绑定鼠标释放事件,就是拖动结束
                    select.onmouseup = function(e){
                        Canvas.clear(cxt,500,500);
                        //此位置可以放塔
                        if(MapData[xIndex][yIndex] == 0 && !self.installTower[xIndex+"_"+yIndex]){
                            //新增一个塔
                            var img = document.getElementById("tower_img");
                            var tower = new Tower(main,img,i,xIndex*50,yIndex*50,50,50);
                            tower.draw();
                            //标记当前位置有塔
                            self.installTower[xIndex+"_"+yIndex] = i+"";
                            //加入塔的列表中
                            Game.towerList.push(tower);
                            //更新金钱
                            self.updateScore(TowerType[i]["level_1"].buyIt * -1);
                        }
                        //取消绑定
                        this.onmousemove = null;
                        this.onmouseup = null;
                    }
                    break;
                }
            }
        }
        //如果鼠标释放的位置还在左侧,则取消此次操作
        info.onmouseup = function(){
            Canvas.clear(cxt,500,500);
            select.onmousemove = null;
            select.onmousedown = null;
        }
    },
    //更新金钱
    updateScore : function(score){
        this.score += score;
        this.redraw();
    },

并在init中调用

......
this.bindEvent();


项目源码:

项目源码

目录
相关文章
|
2月前
|
JavaScript 前端开发 异构计算
兼容移动手机的js拖拽插件Draggin.js
兼容移动手机的js拖拽插件Draggin.js
63 1
|
2月前
|
Web App开发 JavaScript 前端开发
Node.js开发
Node.js开发
78 13
|
3月前
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
本文将带你领略Node.js的魅力,从基础概念到实践应用,一步步深入理解并掌握Node.js在后端开发中的运用。我们将通过实例学习如何搭建一个基本的Web服务,探讨Node.js的事件驱动和非阻塞I/O模型,以及如何利用其强大的生态系统进行高效的后端开发。无论你是前端开发者还是后端新手,这篇文章都会为你打开一扇通往全栈开发的大门。
|
2月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
本文将带领读者从零基础开始,一步步深入到Node.js后端开发的精髓。我们将通过通俗易懂的语言和实际代码示例,探索Node.js的强大功能及其在现代Web开发中的应用。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的见解和技巧,让你的后端开发技能更上一层楼。
|
3月前
|
JavaScript 前端开发 API
深入理解Node.js事件循环及其在后端开发中的应用
本文旨在揭示Node.js的核心特性之一——事件循环,并探讨其对后端开发实践的深远影响。通过剖析事件循环的工作原理和关键组件,我们不仅能够更好地理解Node.js的非阻塞I/O模型,还能学会如何优化我们的后端应用以提高性能和响应能力。文章将结合实例分析事件循环在处理大量并发请求时的优势,以及如何避免常见的编程陷阱,从而为读者提供从理论到实践的全面指导。
|
JavaScript 定位技术 API
ArcGIS API for JavaScript4.x 之加载2D、3D地图
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gisdoer/article/details/81545607 ArcGIS AP...
1544 0
|
3月前
|
JavaScript 前端开发
JavaScript中的原型 保姆级文章一文搞懂
本文详细解析了JavaScript中的原型概念,从构造函数、原型对象、`__proto__`属性、`constructor`属性到原型链,层层递进地解释了JavaScript如何通过原型实现继承机制。适合初学者深入理解JS面向对象编程的核心原理。
50 1
JavaScript中的原型 保姆级文章一文搞懂
|
7月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
138 2
|
3月前
JS+CSS3文章内容背景黑白切换源码
JS+CSS3文章内容背景黑白切换源码是一款基于JS+CSS3制作的简单网页文章文字内容背景颜色黑白切换效果。
34 0
|
7月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
196 4

热门文章

最新文章

  • 1
    当面试官再问我JS闭包时,我能答出来的都在这里了。
    49
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    29
  • 3
    Node.js 中实现多任务下载的并发控制策略
    34
  • 4
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    26
  • 5
    【JavaScript】深入理解 let、var 和 const
    49
  • 6
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    47
  • 7
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    57
  • 8
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    57
  • 9
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    72
  • 10
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    57