Skip to content
此页目录
本文总阅读量

Pixi.js 做一个谷歌恐龙小游戏

素材图片

一个谷歌恐龙小游戏素材图片

demo 代码

ts
import * as PIXI from "pixi.js"
import img from "./小恐龙素材图片/全部.png"

const app = new PIXI.Application({
  width: window.innerWidth,
  height: window.innerHeight,
  background: "#fff",
  resolution: window.devicePixelRatio || 1,
  antialias: true,
})

document.documentElement.appendChild(app.view as any)

// 配置
// 恐龙大小
const dinoSize = {
  width: 44,
  height: 47,
}
// 恐龙位置
const dinoPosition = {
  x: 50,
  y: app.screen.height - dinoSize.height,
}
// 地面高度
const groundHeight = 14

// 创建容器
const container = new PIXI.Container()

// 将容器添加到舞台
app.stage.addChild(container)

// 导入基础纹理
const baseTexture = PIXI.BaseTexture.from(img)

// 创建恐龙纹理
const dinoTexture = new PIXI.Texture(
  baseTexture,
  new PIXI.Rectangle(40, 1, dinoSize.width, dinoSize.height)
)

// 创建恐龙精灵
const dino = new PIXI.Sprite(dinoTexture)
dino.x = dinoPosition.x
dino.y = dinoPosition.y - groundHeight
container.addChild(dino)

// 恐龙跑步动画
const runTexture = []
// 取 6 张恐龙的第 2、3 张
for (let i = 2; i < 4; i++) {
  runTexture.push(
    // 纹理
    new PIXI.Texture(
      baseTexture,
      new PIXI.Rectangle(
        // 每一帧恐龙图片的起点
        677 + i * dinoSize.width,
        0,
        dinoSize.width,
        dinoSize.height
      )
    )
  )
}

// 创建动画精灵
const runAnimation = new PIXI.AnimatedSprite(runTexture)
runAnimation.animationSpeed = 0.1 // 动画速度
runAnimation.x = dinoPosition.x
runAnimation.y = dinoPosition.y - groundHeight
runAnimation.visible = false
runAnimation.play() // 播放

container.addChild(runAnimation)

// 创建恐龙跳跃动画
const jumpTexture = new PIXI.Texture(
  baseTexture,
  new PIXI.Rectangle(677, 0, 44, 47)
)
const jumpDino = new PIXI.Sprite(jumpTexture)
jumpDino.x = dinoPosition.x
jumpDino.y = dinoPosition.y - groundHeight
jumpDino.visible = false
container.addChild(jumpDino)

// 创建地面
const groundTexture = new PIXI.Texture(
  baseTexture,
  new PIXI.Rectangle(2, 54, 1202, groundHeight)
)
// 平铺精灵
const groundSprite = new PIXI.TilingSprite(groundTexture)
groundSprite.width = app.screen.width
groundSprite.height = groundHeight
groundSprite.position.set(0, app.screen.height - 20)
container.addChild(groundSprite)

// 创建仙人掌
const cactusTexture = new PIXI.Texture(
  baseTexture,
  new PIXI.Rectangle(228, 2, 17, 34)
)
const cactusSprite = new PIXI.Sprite(cactusTexture)
cactusSprite.x = app.screen.width
cactusSprite.y = app.screen.height - 15 - 35
container.addChild(cactusSprite)

// 创建文字
const startText = new PIXI.Text("开始游戏", {
  fontFamily: "arial",
  fontSize: 36,
  fill: "#333",
  align: "center",
})
startText.x = app.screen.width / 2
startText.y = app.screen.height / 2
startText.anchor.set(0.5)
startText.cursor = "pointer"
container.addChild(startText)

startText.interactive = true

startText.on("click", () => {
  playGame()
})

// 是否正在游戏中
let isGameing = false
// 是否游戏结束
let isGameOver = false

// 开始游戏
function playGame() {
  isGameing = true
  isGameOver = false
  score = 0
  jumpValocity = 20
  startText.visible = false
  dino.visible = false

  cactusSprite.x = app.screen.width
  // 显示恐龙的跑步动画
  runAnimation.visible = true
}

// 游戏得分
let score = 0

const scoreText = new PIXI.Text("得分:0", {
  fill: "#666",
})
scoreText.position.x = app.screen.width
scoreText.position.y = 10
scoreText.anchor.x = 1.2
container.addChild(scoreText)

// 初始化跳跃速度
let jumpValocity = 20
// 初始化重力
let gravity = 1
// 游戏循环
app.ticker.add(() => {
  if (isGameing) {
    // 地面背景向左移动
    groundSprite.tilePosition.x -= 10

    // 仙人掌循环
    cactusSprite.x -= 10
    if (cactusSprite.x < -30) {
      cactusSprite.x = app.screen.width
      score++
      scoreText.text = `得分:${score}`
    }
  }

  // 跳跃状态
  if (jumpDino.visible) {
    jumpValocity -= gravity // 速度减去重力
    jumpDino.y -= jumpValocity // y 值减去速度,向上跳跃
    if (jumpDino.y > runAnimation.y) {
      jumpDino.visible = false
      runAnimation.visible = true
      jumpValocity = 20
    }
  }

  // 碰撞检测
  if (
    jumpDino.y + jumpDino.height > cactusSprite.y &&
    jumpDino.x + jumpDino.width > cactusSprite.x &&
    jumpDino.x < cactusSprite.x + cactusSprite.width &&
    !isGameOver
  ) {
    isGameing = false
    isGameOver = true
    dino.visible = true
    runAnimation.visible = false
    // 创建游戏结束
    const gameOverTexture = new PIXI.Texture(
      baseTexture,
      new PIXI.Rectangle(484, 15, 191, 11)
    )
    const gameOverSprite = new PIXI.Sprite(gameOverTexture)
    gameOverSprite.position.set(app.screen.width / 2, app.screen.height / 2)
    gameOverSprite.anchor.x = 0.5
    gameOverSprite.scale.set(2)
    container.addChild(gameOverSprite)
    // 创建重新开始
    const restartTexture = new PIXI.Texture(
      baseTexture,
      new PIXI.Rectangle(2, 2, 36, 32)
    )
    const restartSprite = new PIXI.Sprite(restartTexture)
    restartSprite.position.set(
      app.screen.width / 2,
      app.screen.height / 2 + gameOverSprite.height + 30
    )
    restartSprite.anchor.x = 0.5
    restartSprite.interactive = true
    restartSprite.cursor = "pointer"
    restartSprite.on("click", () => {
      container.removeChild(gameOverSprite)
      container.removeChild(restartSprite)
      scoreText.text = `得分:${score}`
      playGame()
    })
    container.addChild(restartSprite)
  }
})

// 跳跃
window.addEventListener("keydown", e => {
  if (e.code === "Space") {
    runAnimation.visible = false
    jumpDino.visible = true
  }
})

评论

交流群