鸿蒙Arkts开发飞机大战小游戏,包含无敌模式,自动射弹,暂停和继续

news2025/4/16 23:21:34

飞机大战可以把飞机改成图片,目前包含无敌模式,自动射弹,暂停和继续的功能
请添加图片描述
代码如下:

// 定义位置类
class GamePosition {
  x: number
  y: number

  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }
}

@Entry
@Component
struct PlaneGame {
  @State isPaused: boolean = false // 添加暂停状态
  @State playerX: number = 180
  @State playerY: number = 400  // 降低初始Y位置
  @State bullets: GamePosition[] = []
  @State enemies: GamePosition[] = []
  @State score: number = 0
  @State isGameOver: boolean = false
  @State isInvincible: boolean = false  // 添加无敌状态
  @State autoFire: boolean = false  // 添加自动发射状态
  // 修改移动速度从8提高到15
  private speed: number = 15      // 大幅提高移动速度
  private bulletSpeed: number = 15
  private enemySpeed: number = 3
  private enemySpawnRate: number = 45
  private fireInterval: number = 10  // 自动发射间隔(帧数)
  private frameCount: number = 0
  private planeSize: number = 40  // 减小尺寸
  private bulletSize: number = 8
  private enemySize: number = 40
  private isLeftPressed: boolean = false
  private isRightPressed: boolean = false
  private isFirePressed: boolean = false
  private gameInterval: number = 0 // 添加游戏循环引用

  // 添加togglePause方法
  togglePause() {
    this.isPaused = !this.isPaused
    // 强制状态更新
    this.score = this.score + 0
    console.log(`游戏已${this.isPaused ? '暂停' : '继续'}`)
  }

  aboutToAppear() {
    this.gameInterval = setInterval(() => {
      if (!this.isPaused && !this.isGameOver) {
        this.updateGame()
        this.handleContinuousInput()
      }
    }, 16)
  }

  handleContinuousInput() {
    if (this.isLeftPressed) {
      this.movePlayer('left')
    }
    if (this.isRightPressed) {
      this.movePlayer('right')
    }
    if (this.isFirePressed || (this.autoFire && this.frameCount % this.fireInterval === 0)) {
      this.fireBullet()
    }
  }

  updateGame() {
    if (this.isGameOver) {
      return;
    }
    
    this.frameCount++;
    
    // Update bullet positions
    this.bullets = this.bullets.map(bullet => 
      new GamePosition(bullet.x, bullet.y - this.bulletSpeed)
    ).filter(bullet => bullet.y > 0);
    
    // Update enemy positions
    this.enemies = this.enemies.map(enemy => 
      new GamePosition(enemy.x, enemy.y + this.enemySpeed)
    ).filter(enemy => enemy.y < 1000);
    
    // Spawn new enemies
    if (this.frameCount % this.enemySpawnRate === 0) {
      this.enemies.push(new GamePosition(
        Math.random() * (360 - this.enemySize),
        -this.enemySize
      ));
    }
    
    // Check collisions
    this.checkCollisions();
    
    // Check game over condition
    if (!this.isInvincible && this.enemies.some(enemy => 
        enemy.y + this.enemySize > this.playerY &&
        enemy.x + this.enemySize > this.playerX &&
        enemy.x < this.playerX + this.planeSize)) {
      this.isGameOver = true;
    }
  }

  checkCollisions() {
    this.bullets.forEach(bullet => {
      this.enemies.forEach((enemy, index) => {
        if (bullet.x + this.bulletSize > enemy.x &&
            bullet.x < enemy.x + this.enemySize &&
            bullet.y + this.bulletSize > enemy.y &&
            bullet.y < enemy.y + this.enemySize) {
          this.score += 10;
          this.enemies.splice(index, 1);
        }
      });
    });
  }

  fireBullet() {
    this.bullets.push(new GamePosition(
      this.playerX + this.planeSize / 2 - this.bulletSize / 2,
      this.playerY - this.bulletSize
    ));
  }

  movePlayer(direction: string) {
    if (direction === 'left' && this.playerX > 0) {
      this.playerX -= this.speed;
    } else if (direction === 'right' && this.playerX < 360 - this.planeSize) {
      this.playerX += this.speed;
    }
  }

  toggleInvincible() {
    this.isInvincible = !this.isInvincible;
  }

  toggleAutoFire() {
    this.autoFire = !this.autoFire;
  }

  restartGame() {
    this.playerX = 180;
    this.playerY = 350;  // 将初始Y坐标从400改为350
    this.bullets = [];
    this.enemies = [];
    this.score = 0;
    this.isGameOver = false;
    this.frameCount = 0;
    this.isPaused = false;
  }

  build() {
    Column() {
      // 游戏标题和状态栏
      Row() {
        Text('飞机大战')
          .fontSize(24)  // 缩小标题字号
          .fontColor(Color.White)
          .margin({ left: 10 })  // 减小左边距
        Blank()
        Text(`得分: ${this.score}`)
          .fontSize(20)  // 缩小得分显示字号
          .fontColor(Color.White)
          .margin(5)  // 减小边距
        Text(`无敌: ${this.isInvincible ? 'ON' : 'OFF'}`)
          .fontSize(20)  // 缩小无敌状态字号
          .fontColor(this.isInvincible ? Color.Green : Color.Gray)
          .margin(5)  // 减小边距
      }
      .width('100%')
      .height(40)  // 减小标题栏高度
      .backgroundColor('#333333')

      // 游戏主区域
      Stack() {
        // 游戏区域背景
        Rect()
          .width('100%')
          .height(450)  // 将高度从400增加到450
          .backgroundColor('#000033')
  
        // 玩家飞机
        Rect()
          .width(this.planeSize)
          .height(this.planeSize)
          .fill(Color.Blue)
          .position({ x: this.playerX, y: this.playerY })
  
        // 子弹
        ForEach(this.bullets, (bullet: GamePosition) => {
          Rect()
            .width(this.bulletSize)
            .height(this.bulletSize * 2)  // 加长子弹
            .fill(Color.Yellow)
            .position({ x: bullet.x, y: bullet.y })
        }, (bullet: GamePosition) => `${bullet.x},${bullet.y}`)
  
        // 敌机
        ForEach(this.enemies, (enemy: GamePosition) => {
          Rect()
            .width(this.enemySize)
            .height(this.enemySize)
            .fill(Color.Red)
            .position({ x: enemy.x, y: enemy.y })
        }, (enemy: GamePosition) => `${enemy.x},${enemy.y}`)
      }
      .width('100%')
      .height(450)  // 同步修改高度
      .margin({ top: 5, bottom: 5 })  // 调整上下边距
      .borderRadius(10)
      .border({ width: 2, color: '#555555' })

      // 游戏控制按钮区域
      Row() {
        Button(this.isInvincible ? '关闭无敌' : '开启无敌')
          .onClick(() => this.toggleInvincible())
          .width(100)
          .height(40)
          .fontSize(16)
          .backgroundColor('#4A4A4A')
          .fontColor(Color.White)
        Button(this.autoFire ? '关闭自动' : '开启自动')
          .onClick(() => this.toggleAutoFire())
          .width(100)
          .height(40)
          .fontSize(16)
          .backgroundColor(this.autoFire ? '#FFA500' : '#4A4A4A')
          .fontColor(Color.White)
        Button(this.isPaused ? '继续' : '暂停')
          .onClick(() => this.togglePause())
          .width(100)
          .height(40)
          .fontSize(16)
          .backgroundColor(this.isPaused ? '#00AA00' : '#AA0000')
          .fontColor(Color.White)
        // 添加重新开始按钮
        Button('重新开始')
          .onClick(() => this.restartGame())
          .width(100)
          .height(40)
          .fontSize(16)
          .backgroundColor('#4A4A4A')
          .fontColor(Color.White)
      }
      .width('95%')  // 减小宽度
      .justifyContent(FlexAlign.SpaceAround)
      .margin({ top: 5, bottom: 5 })  // 调整上下边距

      // 方向控制区域
      Column() {
        // 上方向按钮
        Button('↑')
          .onTouch((event: TouchEvent) => {
            if (event.type === TouchType.Down) {
              this.isFirePressed = true
            } else if (event.type === TouchType.Up) {
              this.isFirePressed = false
            }
          })
          .onClick(() => this.fireBullet())  // 上按钮用于发射子弹
          .width(60)
          .height(60)
          .fontSize(20)
          .margin(5)
        
        // 左右方向按钮
        Row() {
          Button('←')
            .onTouch((event: TouchEvent) => {
              if (event.type === TouchType.Down) {
                this.isLeftPressed = true
              } else if (event.type === TouchType.Up) {
                this.isLeftPressed = false
              }
            })
            .onClick(() => this.movePlayer('left'))
            .width(60)
            .height(60)
            .fontSize(20)
            .margin(5)
          Button('→')
            .onTouch((event: TouchEvent) => {
              if (event.type === TouchType.Down) {
                this.isRightPressed = true
              } else if (event.type === TouchType.Up) {
                this.isRightPressed = false
              }
            })
            .onClick(() => this.movePlayer('right'))
            .width(60)
            .height(60)
            .fontSize(20)
            .margin(5)
        }
        .justifyContent(FlexAlign.Center)
        
        // 下方向按钮(可留空或用作其他功能)
        // Button('↓')
        //   .width(60)
        //   .height(60)
        //   .fontSize(20)
        //   .margin(5)
        //   .opacity(0.5)  // 半透明表示不可用
      }
      .margin({ top: 20, bottom: 20 })
      .alignItems(HorizontalAlign.Center)
      .backgroundColor('#333333')
      .width('90%')
      .borderRadius(20)
      .padding(10)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#222222')
    .onClick(() => {
      console.log('游戏区域点击')
    })
    .onKeyEvent((event: KeyEvent) => {
      switch (event.keyCode) {
        case 2038: // 左箭头
        case 21: 
          this.isLeftPressed = (event.type === KeyType.Down)
          break
        case 2039: // 右箭头
        case 22: 
          this.isRightPressed = (event.type === KeyType.Down)
          break
        case 2040: // 空格
        case 23: 
        case 2037: // 上箭头
        case 19: 
          this.isFirePressed = (event.type === KeyType.Down)
          break
      }
    })
  }
} // 这是PlaneGame结构体的闭合

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

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

相关文章

从基础算力协作到超智融合,超算互联网助力大语言模型研习

一、背景 大语言模型&#xff08;LLMs&#xff09;的快速发展释放出了AI应用领域的巨大潜力。同时&#xff0c;大语言模型作为 AI领域的新兴且关键的技术进展&#xff0c;为 AI 带来了全新的发展方向和应用场景&#xff0c;给 AI 注入了新潜力&#xff0c;这体现在大语言模型独…

M1使用docker制作镜像xxl-job,供自己使用

很苦逼一个情况,m1的docker假如不翻墙&#xff0c;我们找不到xxl-job,所以我们要自己制作 首先先去下载xxl-job源码https://gitee.com/xuxueli0323/xxl-job 你把它拉去到idea中 拉去成功后&#xff0c;进入这个xxl-job目录 执行 mvn clean package -Dmaven.test.skiptrue(这一步…

第一个简易SSM框架项目

引言 这是一个简易SSM整合项目&#xff0c;适合后端入门的练习项目&#xff0c;其中没有太多的业务操作&#xff0c;主要是这个框架&#xff0c;以及编码的顺序&#xff0c;希望大家有所收获 首先需要先配置环境 数据库环境 创建一个存放书籍的数据库表 create database s…

golang 计时器内存泄露问题 与 pprof 性能分析工具

&#xff08;上图用 go tool pprof 工具分析生成&#xff09; 这种会造成内存泄露 因为每次for都会新建一个time对象&#xff0c;只有到期后会被回收。 解决方法&#xff1a;用time.NewTimer与time.Reset每次重新激活定时器 背景 我先贴一下会发生内存泄漏的代码段&#xff0c…

深度学习的下一个突破:从图像识别到情境理解

引言 过去十年&#xff0c;深度学习在图像识别领域取得了惊人的突破。从2012年ImageNet大赛上的AlexNet&#xff0c;到后来的ResNet、EfficientNet&#xff0c;再到近年来Transformer架构的崛起&#xff0c;AI已经能在许多任务上超越人类&#xff0c;比如人脸识别、目标检测、医…

深入解析Spring Boot自动装配:原理、设计与最佳实践

引言 Spring Boot作为现代Java开发中的一股清流&#xff0c;凭借其简洁、快速和高效的特性&#xff0c;迅速赢得了广大开发者的青睐。而在Spring Boot的众多特性中&#xff0c;自动装载&#xff08;Auto-configuration&#xff09;无疑是最为耀眼的明珠之一。本文将深入剖析Sp…

【USRP】srsRAN 开源 4G 软件无线电套件

srsRAN 是SRS开发的开源 4G 软件无线电套件。 srsRAN套件包括&#xff1a; srsUE - 具有原型 5G 功能的全栈 SDR 4G UE 应用程序srsENB - 全栈 SDR 4G eNodeB 应用程序srsEPC——具有 MME、HSS 和 S/P-GW 的轻量级 4G 核心网络实现 安装系统 Ubuntu 20.04 USRP B210 sudo …

《从零搭建Vue3项目实战》(AI辅助搭建Vue3+ElemntPlus后台管理项目)零基础入门系列第二篇:项目创建和初始化

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 《从零搭建Vue3项目实战》&#xff08;AI辅助…

简单线程池实现

线程池的概念 线程池内部可以预先去进行创建出一批线程&#xff0c;对于每一个线程&#xff0c;它都会周期性的进行我们的任务处理。 线程内部在维护一个任务队列&#xff0c;其中我们外部可以向任务队列里放任务&#xff0c;然后内部的线程从任务队列里取任务&#xff0c;如…

CentOS7 安装 LLaMA-Factory

虚拟机尽量搞大 硬盘我配置了80G&#xff0c;内存20G 下载源码 git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git 如果下载不了&#xff0c;可以进入github手动下载&#xff0c;然后在传入服务器。 也可以去码云搜索后下载 安装conda CentOS7安装conda…

最新扣子(Coze)案例教程:最新抖音视频文案提取方法替代方案,音频视频提取文案插件制作,手把手教学,完全免费教程

&#x1f468;‍&#x1f4bb; 星球群同学反馈&#xff0c;扣子平台的视频提取插件已下架&#xff0c;很多智能体及工作流不能使用&#xff0c;斜杠君这里研究了一个替代方案分享给大家。 方案原理&#xff1a;无论是任何视频或音频转文案&#xff0c;我们提取的方式首先都是要…

adb检测不到原来的设备List of devices attached解决办法

进设备管理器-通用串行总线设备 卸载无法检测到的设备驱动 重新拔插数据线

案例分享(七):实现Apache-sharding-proxy的监控

案例分享(七):实现Apache-sharding-proxy的监控 背景部署流程背景 因业务需求,实现Apache-sharding-proxy的监控(基于Apache-sharding-agent)。 部署流程 1.下载agent的包,选择与sharding版本一致,要不然无法启动sharding 2.点击5.3.0之后可以看到有sharding,proxy…

docker 安装 awvs15

安装好 docker bash <(curl -sLk https://www.fahai.org/aDisk/Awvs/check.sh) xrsec/awvs:v15等待完成后访问即可 地址: https://server_ip:3443/#/login UserName: awvsawvs.lan PassWord: Awvsawvs.lan修改密码 docker ps -a //查看容器&#xff0c;找到相应id d…

Flutter:Flutter SDK版本控制,fvm安装使用

1、首先已经安装了Dart&#xff0c;cmd中执行 dart pub global activate fvm2、windows配置系统环境变量 fvm --version3、查看本地已安装的 Flutter 版本 fvm releases4、验证当前使用的 Flutter 版本&#xff1a; fvm flutter --version5、切换到特定版本的 Flutter fvm use …

碰一碰发视频源头开发技术服务商

碰一碰发视频系统 随着短视频平台的兴起&#xff0c;用户的创作与分享需求日益增长。而如何让视频分享更加便捷、有趣&#xff0c;则成为各大平台优化的重点方向之一。抖音作为国内领先的短视频平台&#xff0c;在2023年推出了“碰一碰”功能&#xff0c;通过近距离通信技术实…

Oracle 23ai Vector Search 系列之4 VECTOR数据类型和基本操作

文章目录 Oracle 23ai Vector Search 系列之4 VECTOR数据类型和基本操作VECTOR 数据类型基本语法Vector 维度限制和向量大小向量存储格式&#xff08;DENSE vs SPARSE&#xff09;1. DENSE存储2. SPARSE存储3. 内部存储与空间计算 Oracle VECTOR数据类型的声明格式VECTOR基本操…

C++day8

思维导图 牛客练习 练习 #include <iostream> #include <cstring> #include <cstdlib> #include <unistd.h> #include <sstream> #include <vector> #include <memory> using namespace std; class user{ public: …

MySQL的进阶语法8(SQL优化——insert、主键、order by、group by、limit、count和update)

目录 一、插入数据 1.1 insert 1.2 大批量插入数据 二、主键优化 2.1 数据组织方式 2.2 页分裂 2.2.1 主键顺序插入效果 2.2.2 主键乱序插入效果 2.3 页合并 2.4 索引设计原则 三、order by优化 3.1 执行以下两条语句&#xff08;无索引&#xff09; 3.2 创建索引…

自然语言处理利器NLTK:从入门到核心功能解析

文章目录 一、NLP领域的基石工具包二、NLTK核心模块全景解析1 数据获取与预处理2 语言特征发现3 语义与推理 三、设计哲学与架构优势1 四维设计原则2 性能优化策略 四、典型应用场景1 学术研究2 工业实践 五、生态系统与未来演进 一、NLP领域的基石工具包 自然语言工具包&…