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
}
})