vue3——pixi初学,编写一个简单的小游戏,复制粘贴可用学习

pixi官网

小游戏效果
在这里插入图片描述![在这里插入图片描述](https://img-blog.csdnimg.cn/a28bad4e64294c88ae10d764378d2091.png

两个文件夹 一个index.html 一个data.js

//data.js
import { reactive } from "vue";
import { Sprite, utils, Rectangle, Application, Text, Graphics } from "pixi.js";

//首先 先创建一个舞台
export const app = new Application({
  resizeTo: window, //自适应页面大小 铺满页面 其他参数可以查看文档
  backgroundColor: 0x061639, // 背景颜色
  transparent: true,//背景是否透明,默认false
});

// 计算分数 舞台上面分数文本
let scroe = 0;
const scroeText = new Text(`分数: ${scroe}`, {
  fontFamily: "Arial",
  fontSize: 24,
  fill: 0xffffff,
});

// 创建一个文本对象来显示当前帧数
 const fpsText = new Text("FPS: 0", {
    fontFamily: "Arial",
    fontSize: 24,
    fill: 0xffffff,
 }); 
// 文本创建
export function createText() {
  scroeText.position.set(100, 10); // 位置  x 100  y 10
  // scroeText.anchor.set(0.5); //以自己中心设置了锚点来计算 x y
  scroeText.zIndex = 999; // 层级
  fpsText.position.set(250, 10);
  fpsText.zIndex = 999;
  app.stage.addChild(fpsText);
  app.stage.addChild(scroeText);
   
   // 创建一个Ticker对象来处理动画循环
  app.ticker.add(update);
  // 定义一个update函数来更新帧数
  function update() {
    // 计算当前帧数
     const fps = Math.round(app.ticker.FPS);
    // 更新文本内容
     fpsText.text = `FPS: ${fps}`;
    // console.log(`FPS: ${fps}`);
   }
}

// 创建精灵  
let sprites = []; // 存储精灵图对象的数组
const maxSprites = 8; // 最大精灵图数量
let s_data = reactive({
  vx: 0,
  vy: 1, //初始速度
  maxX: 0,//边界
  maxY: 0,
  minX: 0,
  minY: 0,
  // 设置精灵图的初始移动方向
  directionX: 1,
  directionY: 1,
});
// 创建精灵图  从雪碧图里面抠出方块
export function createRocket() {
   // 超过8个就不再创建
  if (sprites.length >= maxSprites) return;
  
 // 扣雪碧图 将雪碧图存储在TextureCache缓存中的texture变量中。
  let texture = utils.TextureCache[require("../../assets/tileset.png")];
  
  // 创建了一个新的Rectangle对象,该对象表示了从纹理中提取的一个矩形区域
  let rectangle = new Rectangle(96, 128, 32, 32);
  
  // 将之前创建的矩形区域赋值给纹理的frame属性。
  texture.frame = rectangle;
  
  // 创建了一个新的精灵图对象,名称为rocket,并将之前创建的纹理对象赋值给它的texture属性。
  // 这样,精灵图将根据纹理显示相应的图像。
  let sprite = new Sprite(texture);
  
  // 设置精灵图的初始位置
  sprite.x = Math.random() * app.renderer.width; // 随机 X轴坐标
  sprite.y = 0; // Y轴坐标
  
  // 运动边界
  s_data.maxX = app.screen.width - sprite.width;
  s_data.maxY = app.screen.height - sprite.height;
  
  // 初始位置边界
  if (sprite.x < 0) sprite.x = 0;
  if (sprite.x > s_data.maxX) sprite.x = app.screen.width - sprite.width;
  
  app.stage.addChild(sprite); // 添加到舞台
  sprites.push(sprite);
  

}
// 精灵图——方块 运动判断
function gameLoop() {
  for (let i = sprites.length - 1; i >= 0; i--) {
    const sprite = sprites[i];
    const nextX = sprite.x + s_data.vx;
    const nextY = sprite.y + s_data.vy;
    // 检查碰撞并采取相应行动
    // if (nextX < s_data.minX || nextX > s_data.maxX) {
    // 在X轴方向上与边界碰撞
    // s_data.directionX *= -1; // 反转运动方向
   //  }
    if (nextY < s_data.minY || nextY > s_data.maxY) {
      // 在Y轴方向上与边界碰撞
      // s_data.directionY *= -1; // 反转运动方向
      // app.stage.removeChild(rocket); // 移除
      // return;
      // scroe += 10;
      scroeText.text = `FPS: ${scroe}`;
      app.stage.removeChild(sprite);
      sprites.splice(i, 1);
    }
    // 检测碰撞
    if (detectCollision(box, sprite)) {
      // 发生碰撞
      console.log("碰撞发生!");
      scroe += 10;
      scroeText.text = `FPS: ${scroe}`;
      app.stage.removeChild(sprite); // 从舞台移除精灵图
      sprites.splice(i, 1);
    }
    // 更新精灵图的位置
    sprite.x += s_data.vx * s_data.directionX;
    sprite.y += s_data.vy * s_data.directionY;
  }
}
// 创建动画循环 会一直频繁触发gameLoop
app.ticker.add(() => gameLoop());

// 暂停创建
export function stopTimer(timer) {
  if (scroe > 200) {
    clearInterval(timer);
  }
}

// 创建 底部方块 限制:左右运动
let boxData = reactive({
  minX: 0,// 运动边界
  maxX: 0,
});
const boxWidth = 100;
const boxHeight = 50;
const box = new Graphics();
export function createBox() {
  box.beginFill(0x0000ff); // 方块的填充颜色为蓝色,可以根据需要修改颜色值
  box.drawRect(0, 0, boxWidth, boxHeight); // 绘制方块
  box.endFill();
  box.x = (app.screen.width - boxWidth) / 2; // 将方块定位在水平居中位置
  box.y = app.screen.height - boxHeight; // 将方块定位在底部
  boxData.maxX = app.screen.width - boxWidth;
  // 启用交互
  box.interactive = true;

  // 监听触摸或鼠标按下事件,开始拖动
  box.on("pointerdown", onDragStart);

  // 监听触摸或鼠标释放事件,停止拖动
  box.on("pointerup", onDragEnd);
  box.on("pointerupoutside", onDragEnd);

  // 监听触摸或鼠标移动事件,移动方块
  box.on("pointermove", onDragMove);

  let isDragging = false; // 记录是否正在拖动
  let startPosition; // 拖动开始时的位置

  // 拖动开始
  function onDragStart(event) {
    isDragging = true;
    startPosition = event.data.global.x;
  }

  // 拖动停止
  function onDragEnd() {
    isDragging = false;
  }

  // 拖动移动
  function onDragMove(event) {
    if (isDragging) {
      const currentPosition = event.data.global.x;
      const deltaX = currentPosition - startPosition;
      console.log(deltaX, box.x, s_data.maxX);
      // 移动方块
      box.x += deltaX;
      // 检查碰撞并采取相应行动 // 在X轴方向上与边界碰撞
      if (box.x > boxData.maxX) box.x = boxData.maxX;
      if (box.x < boxData.minX) box.x = boxData.minX;
      startPosition = currentPosition;
    }
  }
  app.stage.addChild(box); // 将方块添加到舞台上
}

// 检测碰撞
function detectCollision(box, sprite) {
  // getBounds 方法获取方块和精灵图的边界矩形,然后判断两个矩形是否相交,如果相交,则说明发生了碰撞。
  const boxBounds = box.getBounds();
  const spriteBounds = sprite.getBounds();

  return (
    boxBounds.x + boxBounds.width > spriteBounds.x &&
    boxBounds.x < spriteBounds.x + spriteBounds.width &&
    boxBounds.y + boxBounds.height > spriteBounds.y &&
    boxBounds.y < spriteBounds.y + spriteBounds.height
  );
}
// index.html

<template>
  <div id="pixi"></div>
</template>
<script>
import { Loader } from "pixi.js";
import { onMounted } from "vue";
import { createRocket, app, createText, stopTimer, createBox } from "./index";

export default {
  name: "Game",
  setup() {
  	//初始化
    function init() {
      createText();
      // 定时创建精灵图
      let timer = setInterval(() => {
        createRocket();
      }, 1000); // 每秒创建一个精灵图
      stopTimer(timer);
      createBox();
    }

    onMounted(() => {
      let box = document.getElementById("pixi");
      box.appendChild(app.view);
      Loader.shared.add([require("../../assets/tileset.png")]).load(init);
    });
    return {};
  },
  components: {},
};
</script>
<style scoped lang="scss">
#pixi {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("../../assets/bg.png"); /* 替换为你的背景图路径 */
  background-size: cover;
}
</style>

package.josn

 "dependencies": {
    "core-js": "^3.6.5",
    "pixi.js": "^6.2.1",
    "vue": "^3.0.0-0",
    "vue-router": "^4.0.0-0",
    "vuex": "^4.0.0-0"
  },

该页面素材
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值