PixiJS游戏开发:170行代码实现谷歌小恐龙

介绍

谷歌小恐龙是一款从谷歌浏览器移植而来的小游戏:

游戏介绍:谷歌小恐龙是一款休闲益智类的跑酷游戏,无论是联网还是断网都能玩。在游戏中,玩家需要控制小恐龙跳跃来躲避各种障碍,如仙人掌、小鸟等,同时尽可能获得更高的分数。
游戏特色:
玩法简单易懂,容易上手。
游戏界面设计简约,可以带来轻松的游戏体验。
游戏操作:
在浏览器(如Chrome)中,可以通过输入“chrome://dino”来打开游戏。
点击空格可以使小恐龙跳跃,向下箭头按键可以使小恐龙以蹲姿躲避障碍。

使用技术

Pixi.js是一个强大的2D WebGL渲染引擎,主要用于创建交互式的图形和动画。

  1. 起源与发展

    • Pixi.js由Goodboy Digital开发,并于2013年首次发布。起初,它作为内部工具用于解决市场上复杂且对移动设备性能和资源要求较高的2D渲染引擎的问题。
    • 随着时间的推移,Pixi.js被开源并发布到GitHub上,迅速受到开发者的喜爱,因其出色的性能和易用性。
  2. 技术特点

    • 高性能:Pixi.js通过利用WebGL技术实现硬件加速渲染,可在多种平台上流畅运行。它还使用批处理技术,可以一次性绘制大量精灵,提高了渲染效率。
    • 跨平台:Pixi.js支持多个平台,包括Web、移动和桌面应用程序,以及广泛的浏览器,如Chrome、Firefox、Safari、Edge等。
    • 易于使用:Pixi.js提供简单且直观的API,易于上手和学习。它还提供了一套丰富的功能,如精灵(Sprite)、粒子系统(Particle System)、滤镜(Filter)等。
    • 可扩展性:Pixi.js具有良好的可扩展性,支持插件和自定义扩展。开发者可以根据自己的需求来定制和扩展Pixi.js的功能,并与其他库或框架集成。
    • 跨浏览器兼容性:Pixi.js在多种浏览器中都能良好地运行,提供了一致的API体验。
  3. 应用场景

    • 游戏开发:Pixi.js提供了强大的游戏开发功能,包括精灵动画、物理引擎集成、碰撞检测等,支持各种类型的游戏开发,如休闲游戏、角色扮演游戏等。
    • 数据可视化:Pixi.js可用于创建各种数据可视化图表和图形,将复杂数据以直观的方式展示给用户。
    • 广告创意:Pixi.js的灵活性和高性能使其适合用于创建吸引人的动态广告。
    • UI组件:Pixi.js还可以用于构建高性能的图形界面,如滑块、按钮等。

创建小恐龙

//初始化Pixi容器,设置背景为白色,抗锯齿开启
const app = new PIXI.Application({ width: window.innerWidth, height: window.innerHeight, background: 'white', antialias: true });
//添加到网页中
    document.body.appendChild(app.view)
//创建一个容器,存放游戏内容
    const container = new PIXI.Container()
//添加到舞台
    app.stage.addChild(container);
//加载素材纹理
    const baseTexture = PIXI.BaseTexture.from('./googlepino.png')
//裁剪出小恐龙的纹理
    const pinoTexture = new PIXI.Texture(baseTexture, new PIXI.Rectangle(10, 0, 80, 50))
//创建精灵
    const pino = new PIXI.Sprite(pinoTexture)
//设置位置
    pino.position.set(10, window.innerHeight - 85)
//添加到容器中
    container.addChild(pino)
//设置小恐龙奔跑的纹理数组
    const runTexture = []
//切割出每一帧
    for (let i = 0; i < 2; i++) {
        runTexture.push(
            new PIXI.Texture(baseTexture, new PIXI.Rectangle(935 + (i * 45), 0, 45, 50))
        )
    }
//设置小恐龙蹲下的纹理数组
    const squatTexture = []
//切割出每一帧
    for (let i = 0; i < 2; i++) {
        squatTexture.push(
            new PIXI.Texture(baseTexture, new PIXI.Rectangle(1110 + (i * 60), 20, 60, 30))
        )
    }
//创建动画精灵
    const runAnimation = new PIXI.AnimatedSprite(runTexture)
//设置动画播放速度
    runAnimation.animationSpeed = 0.1
//设置隐藏
    runAnimation.visible = false
//设置位置
    runAnimation.position.set(50, window.innerHeight - 85)
//添加到容器
    container.addChild(runAnimation)

 

该部分我们创建了小恐龙和他的奔跑动作,蹲下的动作

创建仙人掌

//裁剪出仙人掌的纹理
const cactusTexture = new PIXI.Texture(baseTexture, new PIXI.Rectangle(356, 0, 25, 55))
//创建精灵
const cactus = new PIXI.Sprite(cactusTexture)
//设置位置,默认在屏幕中央
cactus.position.set(window.innerWidth / 2, window.innerHeight - 85)
//添加到容器中
container.addChild(cactus)

 

该部分我们创建了一个仙人掌精灵

创建飞鸟

//创建飞鸟的纹理数组
    const birdFlyTexture = []
//裁剪出每一个动作
    for (let i = 0; i < 2; i++) {
        birdFlyTexture.push(
            new PIXI.Texture(baseTexture, new PIXI.Rectangle(135 + (i * 45), 0, 45, 30))
        )
    }
//创建动画精灵
    const flyAnimation = new PIXI.AnimatedSprite(birdFlyTexture)
//设置动画播放速度
    flyAnimation.animationSpeed = 0.1
//默认隐藏
    flyAnimation.visible = false
//设置位置,x坐标为随机
    flyAnimation.position.set(window.innerWidth + Math.floor(Math.random() * (2000 - 1000 + 1)) + 1000, window.innerHeight - 100)
//添加到容器
    container.addChild(flyAnimation)

 

该部分我们创建了一个飞鸟精灵

创建地面

//裁剪出地面的纹理    
    const groundTexture = new PIXI.Texture(baseTexture, new PIXI.Rectangle(10, 50, 1200, 20))
//创建地面精灵
    const ground = new PIXI.TilingSprite(groundTexture)
//设置宽度和高度
    ground.width = window.innerWidth
    ground.height = 20
//设置位置
    ground.position.set(0, window.innerHeight - 50)
//添加到容器中
    container.addChild(ground)

该部分我们创建了一个地面精灵

 添加文字提示

//初始化分数为0
let score = 0
//创建文字,设置字体为30,居中对齐
    const text = new PIXI.Text('开始游戏', {
        fontSize: 30,
        align: 'center'
    })
//设置到屏幕正中央
    text.anchor.set(0.5)
    text.position.set(window.innerWidth / 2, window.innerHeight / 2)
//添加到容器中
    container.addChild(text)
//添加事件,点击的时候开始游戏
    text.interactive = true
    text.on('click', () => {
        playGame()
    })
//创建分数提示文字
    const tip = new PIXI.Text('当前得分为' + score, {
        fontSize: 30,
        align: 'center'
    })
    tip.position.set(window.innerWidth / 2, window.innerHeight / 2)
    tip.anchor.set(0.5)
//默认不显示
    tip.visible = false
//添加到容器中
    container.addChild(tip)

该部分我们创建了游戏的文字提示,当我们点击开始游戏时,游戏开始

    function playGame() {
        text.visible = false
        tip.visible = true
        isPlayGame = true
        pino.visible = false
        runAnimation.visible = true
        runAnimation.play()
    }

    function gameOver() {
        isPlayGame = false
        tip.text = '游戏结束,得分为' + score + ',点击重新开始'

        tip.interactive = true
        tip.on('click', () => {
            location.reload()
        })
    }

游戏开始和游戏结束的代码,当游戏开始时我们隐藏开始游戏文字,显示分数提示文字,隐藏小恐龙精灵,显示奔跑动画精灵

当游戏结束时更改游戏提示信息,然后点击时刷新页面,重新开始游戏

游戏开始

    let isPlayGame = false
    let speed = 10
    let isJump = false
    let up = true

 设置游戏初始值

    app.ticker.add(delta => {
        if (isPlayGame) {
//地面精灵x每次减10,达到地面滚动的效果
            ground.tilePosition.x -= 10
//仙人掌滚动
            cactus.x -= speed
//判断仙人掌是否已超出屏幕左侧,分数加1
            if (cactus.x <= 0) {
//将仙人掌在移动到屏幕右侧
                cactus.x = window.innerWidth
                score += 1
            }
//判断飞鸟是否出现
            if (flyAnimation.visible) {
//移动飞鸟
                flyAnimation.x -= speed
//判断飞鸟是否已超出屏幕左侧,分数加1
                if (flyAnimation.x <= 0) {
//将飞鸟在移动到屏幕右侧
                    flyAnimation.x = window.innerWidth + Math.floor(Math.random() * (2000 - 1000 + 1)) + 1000
                    score += 1
                }
            }
//改变分数信息
            tip.text = '当前得分为' + score
//当分数为5时,显示飞鸟
            if (score == 0) {
                flyAnimation.visible = true
                flyAnimation.play()
            } else if (score == 10) {
//分数为10时,加快速度
                speed = 12
            } else if (score == 20) {
                speed = 15
            }
//判断恐龙是否跳跃
            if (isJump) {
//如果向上的话,y减10,否则就加10
                if (up) {
                    runAnimation.y -= 10
                } else {
                    runAnimation.y += 10
                }
//判断恐龙是否跳到最高处,然后向下
                if (runAnimation.y <= ground.y - 150) {
                    up = false
                }
//判断恐龙是否回到原点,跳跃结束
                if (runAnimation.y > ground.y - 40) {
                    isJump = false
                }
            }
//判断恐龙和仙人掌和飞鸟时候碰撞到一起,游戏结束
            if (b.hit(runAnimation, cactus) || b.hit(runAnimation, flyAnimation)) {
                gameOver()
            }
        }
    })

该部分我们完成了游戏运行,恐龙跳跃,分数判断,如果恐龙与障碍物碰撞到一起了游戏结束,

由于PixiJS没有内置的碰撞检测,所以我们使用第三方库Bump.js来判断碰撞检测

创建Bump对象,将PIXI传入

 let b = new Bump(PIXI)

操作恐龙

//保存恐龙的y坐标初始值    
    let y = runAnimation.y
//添加键盘事件
    window.addEventListener('keydown', e => {
//按下空格时跳跃
        if (e.code == 'Space') {
            e.preventDefault()
            isJump = true
            up = true
        } else if (e.key == 'ArrowDown') {
//按下下箭头时恐龙切换蹲下状态
            e.preventDefault()
            runAnimation.textures = squatTexture
            runAnimation.y = y + 20
            runAnimation.play()
        }
    })
//添加键盘事件,松开下箭头后恐龙切回奔跑状态
    window.addEventListener('keyup', e => {
        if (e.key == 'ArrowDown') {
            e.preventDefault()
            runAnimation.textures = runTexture
            runAnimation.y = y
            runAnimation.play()
        }
    })

 该部分我们完成了恐龙的跳跃和蹲下操作

效果

游戏最终效果如下,喜欢请点个关注,谢谢

 完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://www.kkkk1000.com/js/bump.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/pixi.js@7.2/dist/pixi.min.js"></script>
</head>

<body></body>

<script>
    const app = new PIXI.Application({ width: window.innerWidth, height: window.innerHeight, background: 'white', antialias: true });
    document.body.appendChild(app.view)

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

    const baseTexture = PIXI.BaseTexture.from('./googlepino.png')

    const pinoTexture = new PIXI.Texture(baseTexture, new PIXI.Rectangle(10, 0, 80, 50))
    const pino = new PIXI.Sprite(pinoTexture)
    pino.position.set(10, window.innerHeight - 85)
    container.addChild(pino)

    const runTexture = []
    for (let i = 0; i < 2; i++) {
        runTexture.push(
            new PIXI.Texture(baseTexture, new PIXI.Rectangle(935 + (i * 45), 0, 45, 50))
        )
    }
    const squatTexture = []
    for (let i = 0; i < 2; i++) {
        squatTexture.push(
            new PIXI.Texture(baseTexture, new PIXI.Rectangle(1110 + (i * 60), 20, 60, 30))
        )
    }
    const runAnimation = new PIXI.AnimatedSprite(runTexture)
    runAnimation.animationSpeed = 0.1
    runAnimation.visible = false
    runAnimation.position.set(50, window.innerHeight - 85)
    container.addChild(runAnimation)

    const birdFlyTexture = []
    for (let i = 0; i < 2; i++) {
        birdFlyTexture.push(
            new PIXI.Texture(baseTexture, new PIXI.Rectangle(135 + (i * 45), 0, 45, 30))
        )
    }
    const flyAnimation = new PIXI.AnimatedSprite(birdFlyTexture)
    flyAnimation.animationSpeed = 0.1
    flyAnimation.visible = false
    flyAnimation.position.set(window.innerWidth + Math.floor(Math.random() * (2000 - 1000 + 1)) + 1000, window.innerHeight - 100)
    container.addChild(flyAnimation)

    const groundTexture = new PIXI.Texture(baseTexture, new PIXI.Rectangle(10, 50, 1200, 20))
    const ground = new PIXI.TilingSprite(groundTexture)
    ground.width = window.innerWidth
    ground.height = 20
    ground.position.set(0, window.innerHeight - 50)
    container.addChild(ground)

    const cactusTexture = new PIXI.Texture(baseTexture, new PIXI.Rectangle(356, 0, 25, 55))
    const cactus = new PIXI.Sprite(cactusTexture)
    cactus.position.set(window.innerWidth / 2, window.innerHeight - 85)
    container.addChild(cactus)

    let score = 0

    const text = new PIXI.Text('开始游戏', {
        fontSize: 30,
        align: 'center'
    })
    text.anchor.set(0.5)
    text.position.set(window.innerWidth / 2, window.innerHeight / 2)
    container.addChild(text)

    text.interactive = true
    text.on('click', () => {
        playGame()
    })
    const tip = new PIXI.Text('当前得分为' + score, {
        fontSize: 30,
        align: 'center'
    })
    tip.position.set(window.innerWidth / 2, window.innerHeight / 2)
    tip.anchor.set(0.5)
    tip.visible = false
    container.addChild(tip)

    let isPlayGame = false
    let speed = 10
    let isJump = false
    let up = true

    function playGame() {
        text.visible = false
        tip.visible = true
        isPlayGame = true
        pino.visible = false
        runAnimation.visible = true
        runAnimation.play()
    }

    function gameOver() {
        isPlayGame = false
        tip.text = '游戏结束,得分为' + score + ',点击重新开始'

        tip.interactive = true
        tip.on('click', () => {
            location.reload()
        })
    }

    let b = new Bump(PIXI)

    app.ticker.add(delta => {
        if (isPlayGame) {
            ground.tilePosition.x -= 10
            cactus.x -= speed
            if (cactus.x <= 0) {
                cactus.x = window.innerWidth
                score += 1
            }
            if (flyAnimation.visible) {
                flyAnimation.x -= speed
                if (flyAnimation.x <= 0) {
                    flyAnimation.x = window.innerWidth + Math.floor(Math.random() * (2000 - 1000 + 1)) + 1000
                    score += 1
                }
            }
            tip.text = '当前得分为' + score
            if (score == 5) {
                flyAnimation.visible = true
                flyAnimation.play()
            } else if (score == 10) {
                speed = 12
            } else if (score == 20) {
                speed = 15
            }
            if (isJump) {
                if (up) {
                    runAnimation.y -= 10
                } else {
                    runAnimation.y += 10
                }
                if (runAnimation.y <= ground.y - 150) {
                    up = false
                }
                if (runAnimation.y > ground.y - 40) {
                    isJump = false
                }
            }
            if (b.hit(runAnimation, cactus) || b.hit(runAnimation, flyAnimation)) {
                gameOver()
            }
        }
    })

    let y = runAnimation.y
    window.addEventListener('keydown', e => {
        if (e.code == 'Space') {
            e.preventDefault()
            isJump = true
            up = true
        } else if (e.key == 'ArrowDown') {
            e.preventDefault()
            runAnimation.textures = squatTexture
            runAnimation.y = y + 20
            runAnimation.play()
        }
    })

    window.addEventListener('keyup', e => {
        if (e.key == 'ArrowDown') {
            e.preventDefault()
            runAnimation.textures = runTexture
            runAnimation.y = y
            runAnimation.play()
        }
    })
</script>

</html>

 图片素材:

  • 68
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现一个像谷歌恐龙这样的游戏是一个相当大的项目,需要大量的时间和精力。由于这个问题的复杂性,我将尝试提供一个简单的Java实现框架,以帮助你开始。这个框架将包括一些基本的游戏元素,如游戏循环、用户输入、碰撞检测和移动的物体。 首先,你需要一个Java游戏库,例如LWJGL(Lightweight Java Game Library)或JMonkeyEngine。这些库可以帮助你编写游戏代码,而无需过多关注底层平台的细节。 以下是一个简单的游戏循环框架: ```java public class GameLoop { private static final int FRAMES_PER_SECOND = 60; private static final int GAME_WIDTH = 800; private static final int GAME_HEIGHT = 600; public static void main(String[] args) { // 游戏初始化 Game game = new Game(GAME_WIDTH, GAME_HEIGHT); game.init(); // 游戏循环 while (game.isRunning()) { // 处理用户输入 game.updateInput(); // 更新游戏状态 game.update(); // 绘制游戏画面 game.render(); } } } ``` 在上述代码中,`Game`类代表了一个游戏对象,包含了许多你需要实现游戏逻辑,例如碰撞检测、物体移动等。具体实现需要根据你的游戏设计来进。你可以在这个类中定义各种形状的“小恐龙”,以及其对应的移动为。你需要编写一些代码来检测何时这些“小恐龙”与屏幕边界或其他“小恐龙”发生了碰撞。 此外,你可能还需要处理用户输入,例如键盘或鼠标事件。你可以使用Java的`KeyListener`或`MouseListener`接口来处理这些事件。当用户按下某个键或移动鼠标时,你的游戏代码应该能够检测到这些事件并相应地更新游戏状态。 请注意,这只是一个非常基础的框架,你需要根据你的具体需求进扩展和修改。实现一个完整的谷歌恐龙游戏需要更多的工作,包括创建游戏世界、设计游戏规则、编写动画效果等等。如果你对这个项目感兴趣,我建议你深入学习Java游戏开发的相关知识,并参考一些优秀的游戏开发教程和资源。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值