当前位置: 首页 > news >正文

做本地团购网站做一个网站

做本地团购网站,做一个网站,wordpress 公司网站,基于.net的个人网站开发实录文章目录 引言项目初始化游戏设计和结构游戏程序实现Vue页面嵌入PhaserPreloader 场景加载游戏场景功能实现功能类定义Boom爆炸类Bullet子弹类Enemy敌军类Player玩家类End游戏结束类 总结 更多相关内容可查看 引言 飞机大战(也被称为射击游戏或空战游戏&#xff09…

在这里插入图片描述

文章目录

  • 引言
  • 项目初始化
  • 游戏设计和结构
  • 游戏程序实现
    • Vue页面嵌入Phaser
    • Preloader 场景加载
    • 游戏场景功能实现
    • 功能类定义
      • Boom爆炸类
      • Bullet子弹类
      • Enemy敌军类
      • Player玩家类
      • End游戏结束类
  • 总结

更多相关内容可查看

引言

飞机大战(也被称为射击游戏或空战游戏)是一种非常受欢迎的休闲游戏类型。在这个博客中,我们将探讨如何使用 Vue.js 框架来构建一个简单的飞机大战游戏。我们将从基本的游戏逻辑开始,逐步增加游戏元素和交互性,代码详解可参考注释,最终展示画面在文章底部

项目初始化

git地址:https://gitee.com/its-a-little-bad/vue-project—aircraft-battle.git
node版本:20.8.1

游戏设计和结构

在 Vue.js 中,我们通常将游戏的各个部分分解为不同的场景。

主场景

Game.vue:游戏的主界面,包含背景、飞机、敌机、子弹等。
Plane.vue:玩家的飞机,可以移动和发射子弹。
Enemy.vue:敌机,从屏幕上方随机出现并向下移动。
Bullet.vue:子弹,从玩家飞机发射并向上移动。

游戏场景
在这里插入图片描述

游戏程序实现

Vue页面嵌入Phaser

在 Vue 应用中嵌入一个 Phaser 游戏

<template><!-- Phaser 游戏的容器 --><div id="container"></div>
</template>
<script setup lang="ts">
import { onMounted, onUnmounted } from "vue";
import { Game, AUTO, Scale } from "phaser";
import { Preloader } from "./game/Preloader";
import { Main } from "./game/Main";
import { End } from "./game/End";// 使用正则表达式检测当前设备是否为移动设备
let isMobile = /(iPhone|iPad|Android)/i.test(navigator.userAgent);// 定义了一个 game 变量来存储 Phaser 游戏实例
let game: Game;
onMounted(() => {game = new Game({parent: "container",type: AUTO,width: 375,//游戏的大小根据设备类型进行调整。如果设备是移动设备,则高度会根据设备的纵横比计算得出。height: isMobile ? (window.innerHeight / window.innerWidth) * 375 : 667,//游戏的缩放模式也根据设备类型进行设置。移动设备使用 Scale.FIT,这意味着游戏将尽可能地适应屏幕大小,//而不会保持其原始纵横比。非移动设备则使用 Scale.NONE,这意味着游戏将保持其原始大小。scale: {mode: isMobile ? Scale.FIT : Scale.NONE,},physics: {default: "arcade",arcade: {debug: false,},},scene: [Preloader, Main, End],});
});onUnmounted(() => {game.destroy(true);
});
</script><style>
body {margin: 0;
}
#app {height: 100%;
}
</style>

Preloader 场景加载

创建一个 Preloader 场景来加载游戏所需的资源和设置一些基本的游戏元素,示例如下
在这里插入图片描述
程序实现:

import { Scene } from "phaser";  
import backgroundImg from "../assets/images/background.jpg";  
import enemyImg from "../assets/images/enemy.png";  
import playerImg from "../assets/images/player.png";  
import bulletImg from "../assets/images/bullet.png";  
import boomImg from "../assets/images/boom.png";  
import spritesImg from "../assets/images/sprites.png";  
import spritesJson from "../assets/json/sprites.json?url";  
import bgmAudio from "../assets/audio/bgm.mp3";  
import boomAudio from "../assets/audio/boom.mp3";  
import bulletAudio from "../assets/audio/bullet.mp3";  export class Preloader extends Scene {  // 构造函数,定义场景名称为 "Preloader"  constructor() {  super("Preloader");  }  // 预加载资源的方法  preload() {  // 加载背景图片  this.load.image("background", backgroundImg);  // 加载敌人图片  this.load.image("enemy", enemyImg);  // 加载玩家图片  this.load.image("player", playerImg);  // 加载子弹图片  this.load.image("bullet", bulletImg);  // 加载爆炸动画的精灵表(spritesheet)  this.load.spritesheet("boom", boomImg, {  frameWidth: 64,  frameHeight: 48,  });  // 加载精灵图集(atlas)  this.load.atlas("sprites", spritesImg, spritesJson);  // 加载背景音乐  this.load.audio("bgm", bgmAudio);  // 加载爆炸音效  this.load.audio("boom", boomAudio);  // 加载子弹音效  this.load.audio("bullet", bulletAudio);  }  // 创建场景的方法  create() {  const { width, height } = this.cameras.main;  // 显示背景(通常在Preloader场景中不展示实际游戏内容,这里仅为示例)  this.add.tileSprite(0, 0, width, height, "background").setOrigin(0, 0);  // 播放背景音乐(在Preloader场景中播放通常是为了给玩家一个等待的反馈)  this.sound.play("bgm", { loop: true }); // 循环播放背景音乐  // 添加标题(通常也不在Preloader场景中,但可以作为加载提示)  this.add  .text(width / 2, height / 4, "飞机大战", {  fontFamily: "Arial",  fontSize: 60,  color: "#e3f2ed",  stroke: "#203c5b",  strokeThickness: 6,  })  .setOrigin(0.5);  // 添加开始按钮(通常用于在加载完成后切换到主场景)  let button = this.add  .image(width / 2, (height / 4) * 3, "sprites", "button") // 假设"sprites"图集中有名为"button"的帧  .setScale(3, 2)  .setInteractive()  .on("pointerdown", () => {  // 当按钮被点击时,切换到主场景(这里主场景名为'Main')  this.scene.start('Main');  });  // 按钮文案this.add.text(button.x, button.y, "开始游戏", {fontFamily: "Arial",fontSize: 20,color: "#e3f2ed",}).setOrigin(0.5); }  // 创建动画,命名为 boom,后面使用this.anims.create({key: "boom",frames: this.anims.generateFrameNumbers("boom", { start: 0, end: 18 }),repeat: 0,});
}

在Phaser 3框架中,从一个场景(如Preloader)切换到另一个场景(如Main)通常使用this.scene.start(‘Main’)这样的代码来实现。这是Phaser场景管理系统的一部分,它允许你动态地加载、创建、运行和销毁游戏的不同部分。

游戏场景功能实现

在这里插入图片描述

程序实现

// 定义 Main 场景类,继承自 Phaser 的 Scene 类  
import { Scene, Physics, GameObjects } from "phaser";
import { Player } from "./Player";
import { Bullet } from "./Bullet";
import { Enemy } from "./Enemy";
import { Boom } from "./Boom";// 场景元素
let background: GameObjects.TileSprite;
let player: Player;
let enemys: Physics.Arcade.Group;
let bullets: Physics.Arcade.Group;
let booms: GameObjects.Group;
let scoreText: GameObjects.Text;// 场景数据
let score: number;export class Main extends Scene {constructor() {super("Main");}create() {let { width, height } = this.cameras.main;// 创建背景background = this.add.tileSprite(0, 0, width, height, "background").setOrigin(0, 0);// 创建玩家,调用Player类player = new Player(this);// 创建敌军组// 注解:enemys 是一个 Phaser 的物理组,用于存储和管理多个 Enemy 对象// frameQuantity 表示从 enemy 纹理集中加载的帧数,key 是纹理集的名称// enable, active, visible 分别是启用物理、激活和可见性标志// classType 指示组中新创建对象的类型enemys = this.physics.add.group({frameQuantity: 30,key: "enemy",enable: false,// 在此初始状态下不启用物理 active: false,// 在此初始状态下不激活  visible: false,// 在此初始状态下不可见classType: Enemy,// 当组中添加新对象时使用的类});// 创建子弹// 注解:与敌军组类似,但用于存储和管理多个 Bullet 对象 bullets = this.physics.add.group({frameQuantity: 15,key: "bullet",enable: false,active: false,visible: false,classType: Bullet,});// 创建爆炸// 注解:booms 组用于存储和管理多个 Boom 对象,可能是用于显示爆炸动画booms = this.add.group({frameQuantity: 30,key: "boom",active: false,visible: false,classType: Boom,});// 分数// 注解:score 变量用于跟踪玩家的分数,scoreText 是显示分数的文本对象 score = 0;scoreText = this.add.text(10, 10, "0", {fontFamily: "Arial",fontSize: 20,});// 注册事件this.addEvent();}// 注册事件addEvent() {// 定时器// 注解:此定时器每 400 毫秒触发一次回调,生成敌军和发射子弹 this.time.addEvent({delay: 400,callback: () => {// 生成2个敌军for (let i = 0; i < 2; i++) {enemys.getFirstDead()?.born();}// 发射1颗子弹bullets.getFirstDead()?.fire(player.x, player.y - 32);},callbackScope: this,repeat: -1,});// 子弹和敌军碰撞,会调用 hit 方法this.physics.add.overlap(bullets, enemys, this.hit, null, this);// 玩家和敌军碰撞,会调用 gameOver 方法this.physics.add.overlap(player, enemys, this.gameOver, null, this);}// 子弹击中敌军hit(bullet, enemy) {// 子弹和敌军隐藏enemy.disableBody(true, true);bullet.disableBody(true, true);// 显示爆炸booms.getFirstDead()?.show(enemy.x, enemy.y);// 分数增加scoreText.text = String(++score);}// 游戏结束gameOver() {// 暂停当前场景,并没有销毁this.sys.pause();// 保存分数this.registry.set("score", score);// 打开结束场景this.game.scene.start("End");}update() {// 设置背景瓦片不断移动background.tilePositionY -= 1;}
}

功能类定义

Boom爆炸类

import { GameObjects, Scene } from "phaser";export class Boom extends GameObjects.Sprite {constructor(scene: Scene, x: number, y: number, texture: string) {// 创建对象super(scene, x, y, texture);// 爆炸动画播放结束事件this.on("animationcomplete-boom", this.hide, this);}/*** 显示爆炸* @param x 爆炸x坐标* @param y 爆炸y坐标*/show(x: number, y: number) {this.x = x;this.y = y;this.setActive(true);this.setVisible(true);// 爆炸动画this.play("boom");// 爆炸音效this.scene.sound.play("boom");}/*** 隐藏爆炸*/hide() {this.setActive(false);this.setVisible(false);}
}

Bullet子弹类

import { Physics, Scene } from "phaser";export class Bullet extends Physics.Arcade.Sprite {constructor(scene: Scene, x: number, y: number, texture: string) {super(scene, x, y, texture);// 设置属性this.setScale(0.25);}/*** 发射子弹* @param x 子弹x坐标* @param y 子弹y坐标*/fire(x: number, y: number) {this.enableBody(true, x, y, true, true);this.setVelocityY(-300);this.scene.sound.play("bullet");}preUpdate(time: number, delta: number) {super.preUpdate(time, delta);// 子弹走到头,销毁if (this.y <= -14) {this.disableBody(true, true);}}
}

Enemy敌军类

import { Physics, Math, Scene } from "phaser";export class Enemy extends Physics.Arcade.Sprite {constructor(scene: Scene, x: number, y: number, texture: string) {// 创建对象super(scene, x, y, texture);scene.add.existing(this);scene.physics.add.existing(this);// 设置属性this.setScale(0.5);this.body.setSize(100, 60);}/*** 生成敌军*/born() {let x = Math.Between(30, 345);let y = Math.Between(-20, -40);this.enableBody(true, x, y, true, true);this.setVelocityY(Math.Between(150, 300));}preUpdate(time: number, delta: number) {super.preUpdate(time, delta);let { height } = this.scene.cameras.main;// 敌军走到头,销毁if (this.y >= height + 20) {this.disableBody(true, true)}}
}

Player玩家类

import { Physics, Scene } from "phaser";export class Player extends Physics.Arcade.Sprite {isDown: boolean = false;downX: number;downY: number;constructor(scene: Scene) {// 创建对象let { width, height } = scene.cameras.main;super(scene, width / 2, height - 80, "player");scene.add.existing(this);scene.physics.add.existing(this);// 设置属性this.setInteractive();this.setScale(0.5);this.setCollideWorldBounds(true);this.body.setSize(120, 120);// 注册事件this.addEvent();}/*** 注册事件*/addEvent() {// 手指按下我方飞机this.on("pointerdown", () => {this.isDown = true;this.downX = this.x;this.downY = this.y;});// 手指抬起this.scene.input.on("pointerup", () => {this.isDown = false;});// 手指移动this.scene.input.on("pointermove", (pointer) => {if (this.isDown) {this.x = this.downX + pointer.x - pointer.downX;this.y = this.downY + pointer.y - pointer.downY;}});}
}

End游戏结束类

import { Scene } from "phaser";export class End extends Scene {constructor() {super("End");}create() {let { width, height } = this.cameras.main;// 结束面板this.add.image(width / 2, height / 2, "sprites", "result").setScale(2.5);// 标题this.add.text(width / 2, height / 2 - 85, "游戏结束", {fontFamily: "Arial",fontSize: 24,}).setOrigin(0.5);// 当前得分let score = this.registry.get("score");this.add.text(width / 2, height / 2 - 10, `当前得分:${score}`, {fontFamily: "Arial",fontSize: 20,}).setOrigin(0.5);// 重新开始按钮let button = this.add.image(width / 2, height / 2 + 50, "sprites", "button").setScale(3, 2).setInteractive().on("pointerdown", () => {// 点击事件:关闭当前场景,打开Main场景this.scene.start("Main");});// 按钮文案this.add.text(button.x, button.y, "重新开始", {fontFamily: "Arial",fontSize: 20,}).setOrigin(0.5);}
}

总结

通过使用 Vue.js 框架,我们可以轻松地构建出一个简单而有趣的飞机大战游戏。从基本的游戏逻辑开始,逐步增加游戏元素和交互性,最终得到一个完整且吸引人的游戏作品。希望这个博客能对你有所启发,并鼓励你尝试使用 Vue.js 来开发更多有趣的游戏和应用程序!

http://www.15wanjia.com/news/20390.html

相关文章:

  • 酒店网站建设的构思手机访问另一部手机访问文件
  • 建立一个公司网站大约多少钱免费行情网站
  • 国外网站空间租用费用电商平台有哪些?
  • 网站改版的意义福州短视频seo获客
  • 做gif表情包网站企业网站营销优缺点
  • 天津设计公司招聘上海网站seo
  • 广安做网站公司域名大全
  • 外贸网站自建站百度竞价点击一次多少钱
  • 杨幂做的网站广告网页链接制作生成
  • 互联网建网站如何交换友情链接
  • 企业网站的好处哈尔滨百度搜索排名优化
  • 有特效的网站最新黑帽seo教程
  • 帝国 只做网站地图武汉今日头条最新消息
  • 怎么做销售网站免费做网站的平台
  • 网页美工设计脚本seo在哪可以学
  • 怎么样自己建立网站360推广怎么收费
  • 网页制作与网站建设作业全国31省市疫情最新消息今天
  • 做网站要幕布干啥呢链接是什么意思
  • 最专业的网站建设团队营销型网站建设公司价格
  • 成都设计公司装修seo培训课程
  • 海口seo快速排名优化长沙seo网站
  • 做期货都看哪个网站东莞网站快速排名提升
  • 网站需求分析模板正规代运营公司排名
  • 哪里做网站排名软文大全500篇
  • 公司网站运营方案怎么创建网站快捷方式
  • 石家庄网站建设优化北京网站seo
  • 做母婴的网站百中搜优化
  • 常州网站建设智博百度指数搜索热度
  • .net简单网站开发视频教程百度seo推广怎么收费
  • 微信小程序开发文档 菜鸟教程洛阳网站seo