利用pixi.js制作简单的跑酷小游戏

目录
  • 前言
    • 项目地址
    • demo地址
  • 初始化项目
  • 主要逻辑
    • useParkour
    • useScene
    • useHurdle
    • Player

前言

此项目使用pixi.js和vue实现,部分素材来自爱给网,本项目仅作用于 pixi.js 学习用途,侵权立删。

项目地址

shellingfordly/pixi-games

demo地址

pixi-games

初始化项目

使用vite初始化项目

pnpm create vite my-vue-app

安装pixi.js和pixi-tweener

pixi-tweener一个做过度动画的开源库

pnpm i pixi.js pixi-tweener

主要逻辑

useParkour

此函数用于创建pixi app,将场景,障碍物,人物添加到app中

  • containerRef canvas的容器
  • gameStart 开始游戏
  • start 开始状态
  • score 分数
  • hp 血量
export function useParkour() {
  const containerRef = ref();
  const app = new Application({
    width: BODY_HEIGHT,
    height: BODY_WIDTH,
    backgroundColor: 0xffffff,
  });
  const start = ref(false);

  Tweener.init(app.ticker);

  const container = new Container();
  app.stage.addChild(container);

  const player = new Player();
  const { scene, runScene, stopScene } = useScene();
  const { trap, runHurdle, score, hp } = useHurdle();
  container.addChild(player);
  container.addChild(scene);
  container.addChild(trap);
  container.sortChildren();

  runScene();

  function gameStart() {
    start.value = true;
    player.play();
    const timer = setTimeout(() => {
      runHurdle(player);
      clearTimeout(timer);
    }, 1000);
  }

  watch(hp, (value) => {
    if (value === 0) {
      player.stop();
      stopScene();
      start.value = false;
    }
  });

  onMounted(() => {
    if (containerRef.value) containerRef.value.appendChild(app.view);
  });

  return { containerRef, app, score, hp, gameStart, start };
}

useScene

此函数用于创建天空、地面场景

加载天空、地面纹理,创建平铺精灵(TilingSprite),这个TilingSprite类比较方便做场景的移动

创建ticker递减精灵的x坐标实现场景移动

export function useScene() {
  const loader = new Loader();
  const scene = new Container();
  scene.height = 130;
  scene.zIndex = 1;
  const ticker = new Ticker();

  loader
    .add("footer", FooterImg)
    .add("sky", SkyImg)
    .load(() => {
      const footer = new TilingSprite(
        loader.resources.footer.texture as Texture,
        BODY_HEIGHT,
        130
      );
      footer.y = BODY_WIDTH - 130;
      footer.zIndex = 2;

      const sky = new TilingSprite(
        loader.resources.sky.texture as Texture,
        BODY_HEIGHT,
        BODY_WIDTH - 80
      );
      sky.tileScale.y = 0.6;
      sky.zIndex = 1;
      sky.y = -30;

      scene.addChild(footer);
      scene.addChild(sky);
      scene.sortChildren();

      const sceneTicker = () => {
        footer.tilePosition.x -= 3;
        sky.tilePosition.x -= 3;
      };

      ticker.add(sceneTicker);
    });

  function runScene() {
    ticker.start();
  }

  function stopScene() {
    ticker.stop();
  }

  return { scene, runScene, stopScene };
}

useHurdle

此函数用于创建障碍物

和创建场景其实差不多,只是障碍物是普通的精灵类(Sprite),创建ticker移动其x

在移动时做和人物的碰撞检测,如果碰撞则减少生命值,如果没有则增加分数

export function useHurdle() {
  const loader = new Loader();
  const trap = new Container();
  const ticker = new Ticker();
  const textures: Texture[] = [];
  let player: Sprite | null = null;
  const hp = ref(100);
  const score = ref(0);
  let timer: NodeJS.Timer;

  trap.zIndex = 3;

  loader.add("trap", TrapImg).load((_, resources) => {
    TrapTexturePosition.forEach((position) => {
      const t = new Texture(
        resources.trap.texture as any,
        new Rectangle(...position)
      );
      textures.push(t);
    });
  });

  loader.load(() => {
    timer = setInterval(() => {
      const index = Math.floor(Math.random() * 2) + 1;
      const item = new Sprite(textures[index]);
      item.width = 80;
      item.height = 40;
      item.x = BODY_HEIGHT;
      item.y = BODY_WIDTH - 120;
      trap.addChild(item);
      let scoreFlag = true;
      let hpFlag = true;
      let isHit = false;

      function itemTicker() {
        item.x -= 8;

        if (player && !isHit) {
          isHit = hitTestRectangle(player, item);
          if (hpFlag && isHit) {
            hp.value -= 10;
            hpFlag = false;
            if (hp.value === 0) stopGame();
          } else if (scoreFlag && item.x < player.x) {
            score.value++;
            scoreFlag = false;
          }
        }

        if (item.x < -item.width) {
          ticker.remove(itemTicker);
          trap.removeChild(item);
        }
      }

      ticker.add(itemTicker);
    }, 2000);
  });

  function runHurdle(target: Sprite) {
    player = target;
    ticker.start();
  }

  function stopGame() {
    timer && clearInterval(timer);
    ticker.stop();
  }

  return { trap, runHurdle, score, hp };
}

Player

玩家类:实现跑动、上跳、滑铲、入场的效果

通过变换Sprite的texture实现跑动效果,监听键盘事件,上键时减y,下键时更换滑铲纹理

export class Player extends Sprite {
  defaultY = BODY_WIDTH - 160;
  textures: Texture[] = [];
  status: "run" | "jump" | "slide" = "run";
  ticker = new Ticker();

  constructor() {
    super();
    this.width = 80;
    this.height = 80;
    this.x = -120;
    this.y = this.defaultY;
    this.zIndex = 10;
    this.loader();
    this.watchEvent();
  }

  private loader() {
    const loader = new Loader();
    loader.add("player", PlayerImg).load((_, resources) => {
      PlayerTexturePosition.forEach((position, i) => {
        const texture = new Texture(
          resources.player.texture as any,
          new Rectangle(...position)
        );
        this.textures.push(texture);
      });
    });
  }

  private watchEvent() {
    document.addEventListener("keydown", this.keydown);
    document.addEventListener("keyup", this.keyup);
  }

  private clearEvent() {
    document.removeEventListener("keyup", this.keydown);
    document.removeEventListener("keydown", this.keyup);
  }

  private keydown = (e: any) => {
    if (e.code === "ArrowUp") {
      this.status = "jump";
      if (this.y === this.defaultY) {
        Tweener.add(
          { target: this, duration: 0.3, ease: Easing.easeInOutQuint },
          { y: this.y - 120 }
        );
      }
    } else if (e.code === "ArrowDown") {
      this.status = "slide";
      this.texture = this.textures[10];
    }
  };

  private keyup = () => {
    this.status = "run";
  };

  stop() {
    this.ticker.stop();
    this.clearEvent();
  }

  play() {
    this.ticker.autoStart = true;
    const runTicker = () => {
      this.down();
      this.entrance();
      if (this.status === "run") this.run();
      else if (this.status === "jump") this.jump();
    };
    this.ticker.add(runTicker);
  }

  // 跑
  run() {
    this.texture = this.textures[Math.floor(Date.now() / 100) % 8];
  }

  jump() {
    this.texture = this.textures[(Math.floor(Date.now() / 100) % 5) + 11];
  }

  // 下落
  down() {
    if (this.y < this.defaultY) {
      this.status = "jump";
      this.y += 5;
    } else {
      if (this.status === "jump") {
        this.status = "run";
      }
    }
  }

  // 入场
  entrance() {
    if (this.x < 120) this.x += 5;
  }
}

到此这篇关于利用pixi.js制作简单的跑酷小游戏的文章就介绍到这了,更多相关pixi.js跑酷游戏内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Phaser.js实现简单的跑酷游戏附源码下载

    采用的物理引擎是Phaser.js 官网地址:http://phaser.io/ 在这里对此引擎不做过多介绍(因为我也是小白,嘿嘿) 效果展示: 源码(详细源码图片资源可点击文章下方或屏幕右上方的github链接进行clone) 1.创建游戏舞台 var config = { type: Phaser.AUTO, width: 800, height: 400, physics: { default: 'arcade', arcade: { gravity: { y: 300 }, debug:

  • 使用webpack搭建pixi.js开发环境

    本文介绍怎么使用webpack搭建pixi.js游戏的开发环境,怎么配置babel将ES6+代码最终转换为ES5,怎么利用gulp将webpack和其他脚本粘合一起优化项目并最终发布项目. 前提 需要会简单使用nodejs,了解package.json,会简单使用npm init,npm install,npm run命令. 需要稍微了解webpack和gulp. 需要有google chrome浏览器. 最好会一点git,demo项目pixi-webpack-demo托管在github上,通过

  • 基于PixiJS实现react图标旋转动效

    目录 什么是PixiJS PixiJS初探 PIXI.Application PIXI.Sprite sprite.x | sprite.y | sprite.anchor 旋转起来 什么是PixiJS PixiJS是一个开源的基于web的渲染系统,为游戏.数据可视化和其他图形密集型项目提供了极快的性能.具体细节可移步PixiJS官网 PixiJS初探 首先我们在html中引入pixijs,打印PIXI看看都暴露了哪些API <!doctype html> <html> <h

  • 利用pixi.js制作简单的跑酷小游戏

    目录 前言 项目地址 demo地址 初始化项目 主要逻辑 useParkour useScene useHurdle Player 前言 此项目使用pixi.js和vue实现,部分素材来自爱给网,本项目仅作用于 pixi.js 学习用途,侵权立删. 项目地址 shellingfordly/pixi-games demo地址 pixi-games 初始化项目 使用vite初始化项目 pnpm create vite my-vue-app 安装pixi.js和pixi-tweener pixi-tw

  • 利用Vue.js制作一个拼图华容道小游戏

    目录 游戏介绍 核心思路 核心代码 html games 类 生成随机图片数量 移动图片 键盘事件 拼图完成 结语 游戏介绍 先看看界面 这是一个拼图游戏,可以自选难度和自选闯关图片 游戏开始后根据不同难度,生成与所选主图 对应的 不同张数的 随机顺序的小图,然后只要把乱序的小图片还原成完整的图片就闯关成功 游戏区域有一个空白位置,可以用鼠标点击空白位相邻的图片完成替换,也就是移动,也可以用键盘上下左右操作 游戏好玩,可不要贪杯哦,学习也不能落下,不管什么游戏都一样 这个虽然用到的技术很一般很简

  • 利用原生JS实现欢乐水果机小游戏

    简介: 玩家点击某个押注物品则在该物品上下注.点击开始则游戏开始,如果没有下注则不能开始游戏. 游戏中的物品有八中,分别为:苹果.西瓜.柠檬.橙子.铃铛.77.双星.BAR. 在放行游戏区左右方为押注区,每种物品下方有加减号按钮,每次点 击加号增加一个筹码注金,反之减号就减少一个筹码注金 开始: 开始键 奖励:GOOD LUCK 由于这个时低配版的,我就没有按照原版的写进去,就是中了GOOD LUCK直接获得15分. 出于好耍,本人想起了小时候玩过的水果机,js也学了一会儿了,就想用它写一个简单

  • js实现简单掷骰子小游戏

    本文实例为大家分享了js掷骰子小游戏的具体代码,供大家参考,具体内容如下 实现方法: 方法一:通过background-position.background-image.backg-repeat三个属性以及jquery animate()方法改变背景骰子图来实现图片切换. PS:调整background-position比较麻烦,由于背景是一张包含各个点数以及旋转时骰子的整图 方法二:设置定时调整css样式background-image. PS:实现简单,但是视觉效果不佳 <!DOCTYPE

  • 原生js实现简单贪吃蛇小游戏

    本文实例为大家分享了js实现贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 先上图 话不多说,代码奉上,喜欢的请留下你的小星星♥(ˆ◡ˆԅ) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial

  • JS实现简单贪吃蛇小游戏

    本文实例为大家分享了JS实现简单贪吃蛇游戏的具体代码,供大家参考,具体内容如下 1.使用语言 HTML+CSS+JavaScript 2.使用工具 visual studio code 3.GitHub项目地址:贪吃蛇 4.项目运行截图: 5.项目功能分析:主要使用数组来存储蛇的位置,地图和蛇都是一个二维数组,对于有蛇的地方,地图的CSS就会发生改变,同时添加了添加了一个音乐播放按钮,通过CSS动画实现旋转. 6.项目代码:(项目代码有详细的注释) snake.html <!-- * @Auth

  • 利用css+原生js制作简单的钟表

    利用css+原生js制作简单的钟表.效果如下所示 实现该效果,分三大块:html.javascript.css html部分 html部分比较简单,定义一个clock的div,内部有原点.时分秒针.日期以及时间,至于钟表上的刻度.数字等元素,因为量比较多,采用jvascript生成 <!doctype html> <html> <head> <meta charset="UTF-8"> <link rel='stylesheet'

  • 利用Three.js制作一个新闻联播开头动画

    目录 这里才是引言 技术选型 场景分解 代码逻辑分解 创建背景图和背景音乐 背景图 背景音乐 在线体验地址:点我预览 代码地址:点我github 这里才是引言 五一居家隔离,闲着也是闲着,想着整个活儿,于是就有了这个项目. 项目本身不是很难,但是中间确实是遇到了一些小问题,断断续续也是花费了三四天时间才写完,还有一些需要优化的地方,后续有时间再整. 我会从脚手架开始,按照场景中出现的物体顺序逐条进行讲解制作,每个物体将分为独立的一篇文章,方便理解.Go. 技术选型 选用vite作为构建工具: 选

  • Js制作简单弹出层DIV在页面居中 中间显示遮罩的具体方法

    这两天要用到正好练练手,比想象中碰到的问题要多,比如: ie6背景透明 ie6居中显示 还有对js对象的理解 openID=显示按钮,conID=需要显示的div,closeID=关闭按钮 解决了: 1.可以遮挡ie6下的select元素 但是在ie6下div没有透明度 2.弹出的div可以一直在浏览器屏幕中间显示 问题: 1.目前不支持.class 只支持#id 2.需要显示的div需要自己设置css 3.在ie6下需要设置css 例如div {_position: absolute;_top

随机推荐