覽器和 JavaScript 的功能逐年不斷的變強(qiáng)變大。曾幾何時,任何類型的游戲都需要Flash。但隨著 HTML5 發(fā)展,HTML5 + WebGL 游戲式就慢慢占領(lǐng)著這個舞臺。以下是30款流行的游戲,它們可以在所有現(xiàn)代瀏覽器中運行,并且只使用web技術(shù)構(gòu)建。
地址:http://hexgl.bkcore.com/
類型:街機(jī),賽車
HexGL 是一款基于HTML5,JavaScript和WebGL的快節(jié)奏的賽車游戲。玩家可以使用鍵盤,觸摸屏設(shè)備或leap motion(體感控制器)來控制太空飛船。
地址:http://www.cross-code.com/en/home
類型:動作,角色扮演
一個復(fù)古靈感的2D游戲設(shè)定在遙遠(yuǎn)的未來。這是一個充滿偉大的游戲機(jī)制,如組合,拼圖,技能樹,任務(wù),物品等等。
地址:https://sketch-out.appspot.com/
類型:街機(jī)
Sketchout的任務(wù)保護(hù)你的行星,并通過改變流星的方向來消滅對手,通過使流星偏轉(zhuǎn)來保護(hù)您的星球并消滅對方,這款游戲有很棒的視覺效果和音樂特效。
地址:http://www.treasurearena.com/類型:多人,角色扮演,動作
Treasure Arena 是一款動態(tài)的競技場戰(zhàn)斗游戲,最多可容納4名玩家。它具有不同的游戲模式,出色的幀率和配樂,是一個非常有趣的游戲。
地址:http://bejeweled.popcap.com/html5/
類型:街機(jī),解謎,娛樂
HTML5格式的經(jīng)典“寶石迷陣”游戲。這是一個官方克隆,因此可以正常運行且外觀完美。
地址:http://missile-game.bwhmather.com/類型:街機(jī)
這是一款非常具有挑戰(zhàn)性的游戲,游戲中我們扮演的是一枚被發(fā)射進(jìn)隧道的導(dǎo)彈。游戲有很酷的黑白圖像,玩的時候會有很強(qiáng)的場景效果。
地址:http://www.deconstructeam.com/games/gods-will-be-watching/類型:拼圖
在這個令人毛骨悚然(但又很棒)的游戲中,我和自己團(tuán)隊必須獨自生存40天。團(tuán)隊有六名成員,其中包括一只狗,一名精神病醫(yī)生和一個機(jī)器人,您必須與他們互動,以使其保持溫暖,溫飽和理智的狀態(tài)。
地址:http://www.sinuousgame.com/類型:街機(jī)
一個簡單的游戲,極簡的圖形和流暢的幀率。拾取電源時避免與紅點碰撞。此外,如果你想要那些額外的積分,就需要不停向前移動
地址:http://swooop.playcanvas.com/類型:街機(jī)
在一個美麗多彩的3D世界里,到處飛翔,收集寶石和星星。
地址:http://www.freeriderhd.com/
Free Rider HD 是一款令人上癮的游戲,你可以在其他玩家繪制的賽道上騎自行車。可以在成千上萬的播放器曲目中選擇一個播放,也可以創(chuàng)建自己的曲目并分享。
地址:http://entanglement.gopherwoodstudios.com/zh-CN-index.html類型:拼圖,娛樂
這個游戲的目的是通過在網(wǎng)格上放置線段來創(chuàng)建一條盡可能長的路徑。你可以單獨玩,也可以和朋友一起玩。
地址:https://www.modern.ie/en-us/ie6countdown#escape-from-xp
類型:動作,街機(jī)
用“Escape from XP”來慶祝 Windows XP 的終結(jié)。你的任務(wù)是拯救最后一個陷入Clippy暴政的開發(fā)人員。
地址:http://polycraftgame.com/類型:角色扮演,塔防,動作
在這個很棒的3D游戲中,你到處收集資源,建造東西,完成任務(wù)。關(guān)于它的所有東西都經(jīng)過拋光,并且運行也非常順暢。
地址:https://gabrielecirulli.github.io/2048/類型:拼圖
一個非常上癮的游戲,你可能已經(jīng)玩過了。在 2048 ,你移動編號的圖塊并合并它們。當(dāng)界面中最大數(shù)字是`2048 時,游戲勝利。
地址:http://arcade.lostdecadegames.com/onslaught_arena/
類型:動作
一種快節(jié)奏的復(fù)古生存游戲,您可以使用不同的武器與成群的敵人作戰(zhàn)。
地址:http://chrome.angrybirds.com/類型:游戲
《憤怒的小鳥》游戲,這就不用介紹了。
地址:https://www.cubeslam.com/mcycrs
類型:街機(jī),多人
具有豐富的色彩和炫酷的3D圖形乒乓球游戲。我們可以通過向朋友發(fā)送一個URL來挑戰(zhàn)他們,還可以通過網(wǎng)絡(luò)攝像頭看到對方。
地址:http://hypnoticowl.com/games/the-wizard/類型:動作,角色扮演,策略
Wizard 是基于回合的地牢爬行者,在里面會遇到神話般的怪物并找到奇妙的咒語。該游戲具有酷炫的戰(zhàn)斗機(jī)制,有時可能會帶來很大挑戰(zhàn)。
地址:http://phoboslab.org/xtype/類型:動作,街機(jī)
在這款酷炫的太空射擊游戲中,你目的就是要起戰(zhàn)勝 Boss。
地址:http://orteil.dashnet.org/cookieclicker/類型:休閑,搞笑
Cookie clicker 是一款可能為了開玩笑而創(chuàng)建的游戲,但仍然提供了大量的樂趣。你可以從0個cookie開始,然后單擊一些有效率的cookie,最后你可能會發(fā)現(xiàn)自己擁有數(shù)十億個cookie。
地址:http://play.elevatorsaga.com/類型:拼圖,編碼
這類屬于程序員類型游戲 。在電梯中的任務(wù)是通過對電梯的運動進(jìn)行編程,以最有效的方式運送人員,這些都是用 JavaScript 來完成的。
地址:http://gameofbombs.com/landing類型:動作,角色扮演,多人
Game of Bombs是一個轟炸機(jī)類型的游戲,在廣闊地圖上,都有著敵方玩家。收集力量,皮膚和成就,以成為最佳轟炸機(jī)玩家的方式。
地址:http://or.paleozoic.com/類型:平臺游戲,動作
Olympia Rising具有漂亮復(fù)古外觀圖形的游戲。它坐落在古希臘,在那里我們扮演的女人被賦予了重新的機(jī)會,所以我們的任務(wù)就是逃離死者的世界。
地址: https://ned.im/pixel-race-game/類型:街機(jī),賽車
Pixel Race是一款簡單概念概念,你可以在收集硬幣的同時控制汽車以避開障礙物。如果有足夠的耐心和空閑時間,那么你可能會打破記錄(記錄為36309個硬幣)。
地址:https://littlealchemy.com/類型:拼圖
從這四個基本元素開始,將它們組合起來,創(chuàng)建510種可能的組合。
地址:http://www.kevs3d.co.uk/dev/arena5/類型:街機(jī)
在數(shù)字領(lǐng)域中飛行并射擊幾何敵人以獲得高分。
地址:https://vector-runner-remix.tresensa.com/
類型:街機(jī)
在這個充滿色彩和幾何形狀的平臺游戲中,盡你所能奔跑吧。
地址:http://playbiolab.com/類型:動作
一款出色的像素藝術(shù)平臺游戲,你必須在這里逃脫充滿突變生物和其他不良生物的實驗室。
地址:http://worldsbiggestpacman.com/#類型:街機(jī)
地址:http://games.jessefreeman.com/new-super-resident-raver/
從即將到來的僵尸入侵中拯救驚慌失措的人們。收集錢,升級你的武器和戰(zhàn)斗僵尸。
作者:Danny Markov 來源:tutorialzin 譯者:前端小智
原文:https://tutorialzine.com/2015/02/30-amazing-games-made-only-with-html5
發(fā)語言:js
實例大小:5.05M
實例類別:網(wǎng)頁游戲
【核心代碼】Html JavaScript游戲源碼
Runner.loadImage = function()
{
var img = new Image();
img.onload = Runner.imgLoadHandler;
img.src = imageURLs.shift();
ImageManager.push(img);
document.getElementById(“status”).innerHTML = “Loading(” loaded “/6)” ": " img.src;
}
gif 圖較大,耐心等待,源碼見文末
為了上班摸魚合理的玩游戲,我寫了一個3d塔防游戲,其中功能包含動畫、敵人運動、放置武器、升級武器、銷毀武器、動態(tài)檢測等功能。請動動小手,點贊收藏,這就發(fā)車~
具體功能和思路如下
有了這個思維導(dǎo)圖,就可以按部就班,一步一步的實現(xiàn)游戲功能
由于項目體系較大,內(nèi)容覆蓋較廣,下面挑幾個關(guān)鍵內(nèi)容介紹一下
首先要加載一個地圖,地圖功能包含可放置模塊,不可放置模塊(敵人路線,裝飾元素),大概思路就是根據(jù)floorSize生成一個長和寬相等的地圖,每個地圖都是一個plane。
const createPlane = (texture: THREE.Texture): THREE.Mesh => {
const geometry = new THREE.PlaneGeometry(1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide });
let plane = new THREE.Mesh(geometry, material);
plane.rotation.x = Math.PI * 0.5;
plane.material.map = texture;
plane.material.needsUpdate = true;
castShadow(plane)
return plane
}
第一步用for循環(huán),生成一個二維數(shù)組存放在mapUseV2中,設(shè)定一個起點const startPoint = new THREE.Vector2(0, 0)和終點const endPoint = new THREE.Vector2(floorSize - 1, floorSize - 1),用于生成敵人運動軌跡。
生成軌跡的代碼
const maps = new (window as any).Graph(mapUseV2);
// 夸過阻礙的隨機(jī)點位,生成怪物的路線圖
var starPosition = maps.grid[startPoint.x][startPoint.y];
var endPosition = maps.grid[endPoint.x][endPoint.y];
// 計算路線圖
let trailPoints = (window as any).astar.search(maps, starPosition, endPosition, {
closest: false
});
尋路生成后的數(shù)據(jù)結(jié)構(gòu)如下
這些14個點位都是敵人的路線,所以不可以放置武器,所以要在mapUseV2中將數(shù)據(jù)置為0
mapUseV2[trailPoints[i].x][trailPoints[i].y] = 0;
這樣我們就得到了一個包含敵人行動路線、裝飾、可放置區(qū)域的地圖。
前面定義的startPoint作為敵人的出生點。生成敵人的方法為EnemyCrouched類,初始化敵人的血條,移動速度,攻擊力,和等級。
繼承基類Enemy_Level,Enemy_Level定義了添加方法、運動、和動畫的更新。如果要多加一種敵人類型,再繼承Enemy_Level即可,(項目目前只有一種敵人類型),而Enemy_Level也繼承了公共類ModelCheck,這個公共類主要功能是修改位置、旋轉(zhuǎn)角度、獲取包圍盒等功能。武器、子彈、敵人、水晶塔都繼承了這個公共類。
創(chuàng)建敵人的時候遇到一個問題,本來想著節(jié)約渲染成本,只加載一次敵人模型,再使用clone()方法,復(fù)制出多個敵人,但是敵人模型包含了骨骼模型,在克隆模型的時候,骨骼動畫和敵人模型復(fù)制了,但是兩者的綁定關(guān)系沒有復(fù)制成功,導(dǎo)致骨骼動畫和模型不匹配,導(dǎo)致動畫不生效,所以每次生成敵人的時候都重新加載了一下模型。
export class EnemyCrouched extends Enemy_Level {
coefficient: number = crouched_coefficient
constructor(level: number) {
super(ENEMY_CROUCHED_NAME)
this.speed = this.coefficient * 60
this.price = this.coefficient
this.HP = this.coefficient * level
this.level = level
// 骨骼在執(zhí)行clone()時候,骨骼之間的位置和動畫發(fā)生錯位,所以每次重新拉一次模型,很不可取。
// 但是可以重新克隆一個骨骼動畫,并重新綁定骨骼動畫和新的模型之間的關(guān)系
loadGltf(import.meta.env.VITE_ASSETS_URL + '/assets/models/snowgolem/scene.gltf').then((gltf: any) => {
this.model = gltf.scene
this.bindAnimite(gltf.animations)
this.addModel()
this.group.example = this
this.handleModel(this.group)
this.run()
this.runStart()
});
}
}
通過bindAnimite綁定動畫可以將模型中提供的骨骼動畫綁定到模型上并播放動畫。
bindAnimite(animations: GltfModel['animations']) {
if (this.model) {
this.modelAnimation = new Animation(this.model, animations);
this.modelAnimation.once(['death'])
this.modelAnimation.play('walking');
}
}
這里說一下Animation類,提供播放動畫play、切換動畫fadeToAction、顯示骨骼createSkeleton,過濾一次性動畫once比如跳躍,死亡,敬禮這種非循環(huán)播放的動畫。 更新動畫upDate,這個方法接受一個鏡頭參數(shù),如果將鏡頭參數(shù)傳進(jìn)來,可以實現(xiàn)鏡頭跟蹤功能。
生成武器通過點擊操作欄對應(yīng)的按鈕進(jìn)行。
在點擊十字弓按鈕后,將觸發(fā)鼠標(biāo)的射線檢測,并將檢測目標(biāo)設(shè)置為地板,當(dāng)鼠標(biāo)移動至可放置模型的位置時,顯示藍(lán)色的框,如果檢測到鼠標(biāo)位置不可放置模型,則輔助色塊變?yōu)榧t色,點擊無效,需重新選擇位置。
Crossbow_level初始化十字弓,Rifle_level初始化火炮。這兩個類是區(qū)分不同的武器,并在初始化的時候加載武器模型并提供武器的upDate方法,這兩個類都繼承他們的基類Weapon。Weapon提供目標(biāo)檢測、射擊等功能。Weapon又繼承公共類ModelCheck為武器提供包圍盒,尺寸和模型矯正的功能。初始化武器時有幾個屬性比較重要:武器系數(shù)coefficient、等級level這兩個數(shù)值影響武器的子彈發(fā)射間隔,威力,和單價(包括升級的價格)。
這里介紹一下IntervalTime
.setAnimationLoop ( callback : Function ) : undefined
callback — 每個可用幀都會調(diào)用的函數(shù)。 如果傳入‘null’,所有正在進(jìn)行的動畫都會停止。 可用來代替requestAnimationFrame的內(nèi)置函數(shù). 對于WebXR項目,必須使用此函數(shù)。
requestAnimationFrame方法熟悉threejs的都了解,基于屏幕刷新率調(diào)用的,一般60次/秒,實現(xiàn)定時的原理很簡單,調(diào)用一次的時候獲取一次當(dāng)前時間,用當(dāng)前調(diào)用時的時間now減去上次存的時間lastTime,如果超過規(guī)定的循環(huán)間隔時間time調(diào)用一次回調(diào),這時會將lastTime置為time,并進(jìn)行新一輪的計時。項目中炮彈發(fā)射間隔就是這么做的。當(dāng)然,你也可以在threejs以外的項目使用。
export class IntervalTime {
lastTime = 0
constructor() {
}
interval(time: number, callback: () => void) {
let now = performance.now(); // 使用 performance.now() 獲取高精度時間
let deltaTime = now - this.lastTime;
if (deltaTime > time) {
// 執(zhí)行一秒內(nèi)需要做的事情
callback()
// 重置時間
this.lastTime = now;
}
}
}
武器在生成后會發(fā)射子彈,調(diào)用TransmitDiscards類。根據(jù)不同的武器生成不同的子彈,并在render中調(diào)用子彈類的upDate方法。子彈會跟蹤檢測敵人的位置,并找到最近的敵人進(jìn)行攻擊,得到最近敵人的位置和子彈發(fā)射位置,生成一條拋物線,開口向下,并讓子彈沿著拋物線進(jìn)行運動,直到子彈運動到終點,并利用敵人的包圍盒檢測子彈的位置,判斷子彈是否進(jìn)入敵人包圍盒的范圍。如果在范圍內(nèi),敵人HP掉對應(yīng)的血量,并銷毀子彈。
upDate() {
// 子彈檢測敵人
EnemyGroup.traverse((enemy) => {
if (enemy.example) {
if (this.model) {
this.getBox()
const worldPos = new THREE.Vector3()
this.model.getWorldPosition(worldPos)
this.position = worldPos.clone();
enemy.example.getBox();
const contains = enemy.example.box3.containsPoint(this.position)
// 子彈撞擊敵人
if (contains) {
console.log('擊中敵人');
let hp = enemy.example.HP - this.power
enemy.example.HP = hp
enemy.example.hpDom.element.innerHTML = `HP:${Math.max(0, hp)}`
this.dispose()
}
}
}
})
}
當(dāng)敵人的hp歸零時,則銷毀敵人并增加對應(yīng)數(shù)量的金幣
敵人的update方法
upDate() {
this.getBox()
if (this.modelAnimation) {
this.modelAnimation.upDate()
}
if (this.HP <= 0) {
this.dispose();
wallet.add(this.price);
}
}
操作欄的功能區(qū),提供了幾個屬性,區(qū)分放置、升級、銷毀等功能
// 存放全局變量的
export const buttonState = {
DOWN_HERO: false, // 是否可以放置模型
CHECK_HERO: true, // 是否可以選中模型
HREO_TYPE: 'crossbow' as "crossbow" | "rifle",
UPGRADE_HERO: false, // 是否升級英雄
DISPOSE_HERO: false, // 是否銷毀英雄
SHOW_BOX3_HELPER: true, // 是否顯示輔助線
GAME_STOP: false // 暫停游戲
}
前面提過,放置武器的時候,射線檢測的對象為floor組,而升級則會將射線檢測的組改為武器組,通過檢測到的模型去升級對應(yīng)的二級和三級,當(dāng)武器達(dá)到三級的時候則不可再升級,升級武器時將原有武器銷毀,添加一個新的模型,目前對于武器升級只是將系數(shù)調(diào)高,如感興趣可根據(jù)武器等級,生成多個子彈,從單一攻擊改為群攻。
相對于水晶塔,則復(fù)用子彈的邏輯即可,將敵人視作子彈,水晶塔視作敵人,在水晶塔的upDate方法,檢測敵人的位置,如果敵人的包圍盒與水晶塔的包圍盒相交,則水晶塔減去對應(yīng)的hp,如果水晶塔的hp歸零,則視為游戲失敗
金幣方法相對簡單一些,咱們這里沒vip充值,所以不必考慮一個648換算幾個鉆石,1個鉆石換算幾個金幣,游戲的金幣系統(tǒng),只有一個加一個減,創(chuàng)建和升級武器減去相對應(yīng)的金幣,消滅敵人增加對應(yīng)的金幣
import { Money } from "./variable";
// 錢包實例
class Wallet {
money: number = Money;
moneyDom: HTMLDivElement | undefined
constructor() {
const dom = document.querySelector('.money') as HTMLDivElement | undefined
if (dom) {
this.moneyDom = dom;
this.changeText()
}
}
add(money: number) {
this.money += money;
this.changeText()
}
sub(money: number) {
if (this.money < money) {
return false
} else {
this.money -= money;
this.changeText()
}
return true
}
changeText() {
if (this.moneyDom) {
this.moneyDom.innerText = this.money + '金幣'
}
}
}
export const wallet = new Wallet()
金手指支持初始化金幣數(shù)量、武器系數(shù)、地圖尺寸。通過路徑參數(shù)提供
const searchParams = getParams()
const getValue = (field: string, def: number): number => {
console.log('searchParams',searchParams);
const f = searchParams[field]
let fz = f ? Number(f) : def;
return fz
}
export const floorSize = getValue('floorSize', 8) // 必須雙數(shù),不然后面的計算有問題
// 系數(shù)
// 十字弩系數(shù)
export const crossbow_coefficient = getValue('crossbow_coefficient', 10)
// 火炮系數(shù)
export const rifle_coefficient = getValue('rifle_coefficient', 10) * 2
// 初始化金幣
export const Money: number = getValue('money', 100);
如果將路徑地址后面拼上這段參數(shù)
?crossbow_coefficient=100&rifle_coefficient=100&floorSize=16&money=500,
那么你將擁有500個金幣,攻擊力100打底的武器,并且地圖尺寸變大,敵人行動軌跡變長
這會影響游戲的平衡性,當(dāng)然,我們的游戲也沒做公平性和平衡性的考慮。
鏈接:https://juejin.cn/post/7355745761370505231
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。