您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么利用pixi.js制作簡單的跑酷小游戲”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么利用pixi.js制作簡單的跑酷小游戲”吧!
使用vite初始化項目
pnpm create vite my-vue-app
安裝pixi.js和pixi-tweener
pixi-tweener一個做過度動畫的開源庫
pnpm i pixi.js pixi-tweener
此函數(shù)用于創(chuàng)建pixi app,將場景,障礙物,人物添加到app中
containerRef canvas的容器
gameStart 開始游戲
start 開始狀態(tài)
score 分數(shù)
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 }; }
此函數(shù)用于創(chuàng)建天空、地面場景
加載天空、地面紋理,創(chuàng)建平鋪精靈(TilingSprite),這個TilingSprite類比較方便做場景的移動
創(chuàng)建ticker遞減精靈的x坐標實現(xiàn)場景移動
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 }; }
此函數(shù)用于創(chuàng)建障礙物
和創(chuàng)建場景其實差不多,只是障礙物是普通的精靈類(Sprite),創(chuàng)建ticker移動其x
在移動時做和人物的碰撞檢測,如果碰撞則減少生命值,如果沒有則增加分數(shù)
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 }; }
玩家類:實現(xiàn)跑動、上跳、滑鏟、入場的效果
通過變換Sprite的texture實現(xiàn)跑動效果,監(jiān)聽鍵盤事件,上鍵時減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制作簡單的跑酷小游戲”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對怎么利用pixi.js制作簡單的跑酷小游戲這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。