<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="
default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:;
media-src * blob: 'self' http: * 'unsafe-inline' 'unsafe-eval';
style-src * 'self' 'unsafe-inline';
img-src * 'self' data: content:;
connect-src * blob:;">
<link rel="stylesheet" type="text/css" href="/content/d85ad6e7b0b9246b3150b85eb0b7a5a1e6363a532d7c5c39cca772dfaf248901i0" />
<script src="/content/6197dd405f22c32e9d1deec63b497d20a037a4056caf2b795f773a7dccd2b8b2i0"></script>
<script src="/content/39ab73eb5d1a7c0f9778d15cb254f90b077036c5828538eb5409575ac08173cci0"></script>
<script src="/content/9a0ba44f13aa5e9231fad706fdb82640227ec3e6c8b0a70f96f793c69d28299ai0"></script>
<style>
@font-face {
font-family: Silkscreen;
font-style: normal;
font-weight: 400;
src: url("/content/333fbf364cebb295eec139c03b9e0facf13b5dbcc9834b5a5a254ce8d7024673i0")format("woff2");
unicode-range: u+00??, u+0131, u+0152-0153, u+02bb-02bc, u+02c6, u+02da, u+02dc, u+2000-206f, u+2074, u+20ac, u+2122, u+2191, u+2193, u+2212, u+2215, u+feff, u+fffd
}
</style>
</head>
<body>
<div class="snake-content">
<div class="actual-region">
<div class="header">
<div class="header-item" style="text-align: left">
<div>SATS</div><span id="fee">000000</span>
<div class="fee-add-count"></div>
</div>
<div class="header-item">
<div class="block-number"></div>
<div class="food"><span class="food-icon" style="background: transparent"><img style="width: 100%; height: 100%; vertical-align: top" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAKJJREFUaEPtmUEOwCAIBOGtfVffqmdtUkPWSrTjHRF2XI16uazYxsMpIFm98xTw2zy5qa/pe+QfClDAx/L9T4Fsm+2RDitAAeKeQAEQAqH2ZoALiUSEw3EhXCgMTRsAQiAEQhxkuQ9fuBAuhAvhQriQtAuwUWxUAsgMhEAIhMSTWGzg9PDwy9z0FYgTUoDYQDl8qICcYfEE5/3UL26gnG57BSrRZUpw9rioigAAAABJRU5ErkJggg==" alt="" /></span><span style="margin-left: 5px" id="food">0</span><span>/</span><span id="remaining-food">689</span></div>
</div>
<div class="header-item" style="text-align: right">
<div>TIME</div><span id="time">00:00</span>
</div>
<div class="food-hash">
<div class="value"></div>
</div>
</div>
<div class="start-interface first-show">
<div class="game-title">RUNES SNAKE</div>
<div class="email-input pixel-box">
<div class="pixel-box-child">
<div class="email-icon"></div><input type="text" value="840000" id="ipt" placeholder="Enter a BTC block to Claim" style="display: none" />
<div class="select-box">
<div class="select-value" onclick="toggleSelectVisibility(!selectVisibility)">
<div class="select-item-info"><span>840000(BTC HALVING)</span><span></span></div>
<div class="icon">></div>
</div>
<div class="select-list">
<div class="select-item" onclick="toggleSelectVisibility(false)"><span>840000(BTC HALVING)</span><span style="opacity: 0"></span></div>
</div>
</div>
</div>
</div>
<div class="copy-list">
<div class="info-item"><span class="label">PICK A BLOCK&COLLECT ALL TXS TO WIN</span></div>
<div class="info-item"><span class="label">CHECK LEADERBOARD AT</span><span onclick="_gameInstance.copyValue('website')">ORDZ.GAMES/ORDZ-SNAKE</span></div>
</div>
<div class="start-button pixel-box" onclick="_gameInstance.startFn()">
<div class="pixel-box-child">
<div class="lds-ring">
<div></div>
</div>START
</div>
</div>
</div>
<div class="replay-content game-over">
<div class="game-title">GAME OVER</div>
<div class="start-button pixel-box" onclick="_gameInstance.replayFn()">
<div class="pixel-box-child">TRY AGAIN</div>
</div>
<div class="claim-tips" style="opacity: 0">OR<br />REFRESH PAGE TO CLAIM<br />A DIFFERENT BLOCK</div>
</div>
<div class="start-interface address-interface">
<div class="game-title">YOU WIN!</div>
<div class="block-number">You Can Claim Block:<span></span></div>
<div class="email-input pixel-box">
<div class="pixel-box-child">
<div class="email-icon"></div><input type="text" value="" id="claimAddress" placeholder="'BC1..' TAPROOT ADDRESS" />
</div>
</div>
<div class="start-button pixel-box" onclick="_gameInstance.submitAddress()">
<div class="pixel-box-child">SUBMIT</div>
</div>
</div>
<div class="replay-content game-win">
<div class="game-title">Block<span></span></div>
<div class="copy-list">
<div class="info-item"><span class="label">CLAIM AT</span><span onclick="_gameInstance.copyValue('website')">ORDZ.GAMES/ORDZ-SNAKE</span></div>
<div class="info-item"><span class="label">PASTE TOKEN:</span><span id="token-input" onclick="_gameInstance.copyValue('token')"></span></div>
</div>
</div>
<div class="game-content" id="container"></div>
</div><input id="copyI" />
<div class="message-tips">copied!</div>
<div class="canvas-content"><canvas id="webgl-canvas"></canvas></div>
</div>
<style>
.food {
display: flex;
align-items: center;
justify-content: center;
}
.game-title {
color: #ff6300;
}
.start-button {
color: #ff6300;
background: #ff6300;
}
.start-interface .email-input .email-icon {
background: #ff6300;
}
.food-symbol {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
left: 0;
top: 0;
overflow: hidden;
}
.food-sats-position {
position: absolute;
height: 100%;
display: flex;
align-items: center;
}
.select-box {
flex: 1;
height: 40px;
position: relative;
cursor: pointer;
}
.select-box .select-value {
line-height: 40px;
padding-left: 10px;
}
.select-box .select-value .icon {
position: absolute;
right: 0;
top: 2px;
transform: rotate(90deg);
}
.select-box.show .select-list {
display: flex;
justify-content: space-between;
}
.select-box .select-list {
position: absolute;
width: calc(100% + 48px);
top: 40px;
left: -30px;
background: #2e2c2c;
padding: 0.5em 0 0.5em 0px;
z-index: 99;
line-height: 1.8em;
max-height: 200px;
overflow-y: auto;
display: none;
}
.select-box .select-list .select-item {
padding-left: 40px !important;
width: 100%;
}
.select-box .select-list .select-item:hover {
background: #000;
}
.select-box .select-list::-webkit-scrollbar {
width: 8px;
height: 6px;
}
.select-box .select-list::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #808080;
}
.select-box .select-list::-webkit-scrollbar-track {
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #404040;
border-radius: 10px;
}
.select-box .select-list::-webkit-scrollbar-corner {
opacity: 0;
}
.select-box .select-list .select-item {
display: flex;
justify-content: space-between;
padding-right: 10px;
}
.select-item-info {
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 25px;
}
</style>
<script>
function formatParams(data) {
let arr = [];
for (let name in data) {
arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]))
}
arr.push(("v=" + Math.random()).replace(".", ""));
return arr.join("&")
}
function ajax(options) {
options = options || {};
options.method = (options.method || "GET").toUpperCase();
options.dataType = options.dataType || "json";
let params = options.method == "GET" ? formatParams(options.data) : options.data;
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest()
} else if (window.ActiveObject) {
xhr = new ActiveXobject("Microsoft.XMLHTTP")
}
if (options.method == "GET") {
xhr.open("GET", options.url + "?" + params, true)
} else if (options.method == "POST") {
xhr.open("POST", options.url, true);
if (!options.customHeaders || !options.customHeaders["Content-Type"]) {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}
} else if (options.method == "PUT") {
xhr.open("PUT", options.url, true)
}
if (options.customHeaders) {
Object.keys(options.customHeaders).forEach((key) => {
xhr.setRequestHeader(key, options.customHeaders[key])
})
}
xhr.send(options.method == "GET" ? null : params);
setTimeout(function() {
if (xhr.readySate != 4) {
xhr.abort()
}
}, options.timeout);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var status = xhr.status;
if ((status >= 200 && status < 300) || status == 304) {
options.success && options.success(xhr.responseText, xhr.responseXML)
} else {
options.error && options.error(status)
}
}
}
}
function request(options) {
return new Promise((resolve, reject) => {
ajax({
method: options.method || "GET",
url: options.url,
dataType: "json",
data: options.data || {},
timeout: 25 * 1000,
contentType: "application/json",
...options,
success: (data) => resolve(data),
error: (error) => resolve({
code: -1
}),
})
})
}
function $(s) {
return document.querySelector(s)
}
function checkMobile() {
return new Promise((resolve) => {
const ua = navigator.userAgent || navigator.vendor || window.opera;
window.isMobile = /android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos/i.test(ua);
resolve(window.isMobile)
})
}
function showMessage(message) {
const dom = $(".message-tips");
dom.innerHTML = message;
dom.classList.add("show");
setTimeout(() => dom.classList.remove("show"), 2 * 1000)
}
function formatTime(timestamp) {
const timeDom = $(".header #time");
const minute = Math.floor(timestamp / 60);
const second = timestamp % 60;
timeDom.innerHTML = `${minute>=10?minute:"0"+minute}:${second>=10?second:"0"+second}`
}
function createScreenshot(node) {
return new Promise((resolve, reject) => {
domtoimage.toPng(node, {
quality: 1.0,
magnification: 0.5,
bgcolor: "#000",
}).then((dataUrl) => {
if (dataUrl.indexOf("base64,")) {
dataUrl = dataUrl.split("base64,")[1]
}
resolve(dataUrl)
}).catch(reject)
})
}
function getUtcTime(len, i) {
const date = len ? new Date(len) : new Date();
len = date.getTime();
const offset = date.getTimezoneOffset() * 60000;
const utcTime = len + offset;
return new Date(utcTime + 3600000 * i)
}
function getLocalTime(i) {
const time = getUtcTime("", i);
const m = time.getMonth() + 1;
const d = time.getDate();
return `${time.getFullYear()}-${m>10?m:"0"+m}-${d+1>10?d:"0"+d}`
}
function onCopy(value) {
const copyInput = $("#copyI");
copyInput.value = value;
copyInput.select();
try {
document.execCommand("copy", true);
const dom = $(".message-tips");
dom.innerHTML = "copied!";
dom.classList.add("show");
setTimeout(() => {
dom.classList.remove("show")
}, 2 * 1000)
} catch (error) {}
}
function createUuid() {
let uid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
let r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16)
});
try {
uid = uid.split("-").join("")
} catch (error) {
console.error("error=>", error)
}
return uid
}
function getSymbol() {
const index = Math.floor(Math.random() * window.symbolList.length);
const s = window.symbolList[index];
const [name, icon] = s.split("|");
return {
name: `#${index+1} ${name}`,
icon,
}
}
let audio = null;
let loading = false;
function updateLoading(v) {
loading = v;
$(".start-interface .start-button").classList[v ? "add" : "remove"]("loading")
}
const handleSnakeWindow = () => {
const bodyw = window.innerWidth;
const gameContent = $(".snake-content");
const gcw = gameContent.clientWidth;
if (bodyw / gcw > 1) return;
gameContent.style.transform = `scale(${bodyw/gcw})`
};
handleSnakeWindow();
window.addEventListener("resize", () => handleSnakeWindow(), false);
function Map(options = {}) {
this.width = options.width;
this.height = options.height;
this.id = options.id || "map"
}
Map.prototype.show = function() {
const el = document.createElement("div");
el.style.width = this.width + "px";
el.style.height = this.height + "px";
el.className = this.id;
el.id = this.id;
$("#container").appendChild(el)
};
const _gameInstance = (function() {
const defaultSnakeMoveSpeed = 80;
let gameInstance = null;
let transactions = [];
let gameMap = null;
const gameData = {
score: 0,
foodCount: 0,
remainingFood: 0,
playTime: 0,
operateCount: 0,
feeCount: 0,
snakeMoveSpeed: defaultSnakeMoveSpeed,
snakeMoveSpeedTimer: null,
addressValue: "",
ac: "",
uid: "",
_p: "",
};
const gameUtils = {
playTimeTimer: null,
updateScore() {},
startUpdateState() {},
renderBorder() {
const gameContent = $(".game-content");
const boxSize = 3;
const size = 450 / 3 / boxSize;
for (let i = 1; i < size; i++) {
const renderHorizontalBox = document.createElement("div");
renderHorizontalBox.style.top = `${i*boxSize*3}px`;
renderHorizontalBox.classList.add("horizontal");
const renderVerticalBox = document.createElement("div");
renderVerticalBox.style.left = `${i*boxSize*3}px`;
renderVerticalBox.classList.add("vertical");
gameContent.appendChild(renderHorizontalBox);
gameContent.appendChild(renderVerticalBox)
}
},
checkSnakeMoveSpeed(callback) {
if (gameData.foodCount == 5) {
gameData.snakeMoveSpeed = 50;
clearInterval(gameData.snakeMoveSpeedTimer);
gameData.snakeMoveSpeedTimer = setInterval(() => callback && callback(), gameData.snakeMoveSpeed)
}
},
updateFee() {
const fee = $(".header #fee");
const stringFee = String(gameData.feeCount);
let feeValue = "";
for (let i = 0; i < 6 - stringFee.length; i++) {
feeValue += "0"
}
fee.innerHTML = `${feeValue}${gameData.feeCount}`
},
updateFeeAddCount(v) {
const count = $(".header .fee-add-count");
count.innerHTML = `+${v}`;
count.classList.add("show");
setTimeout(() => {
count.classList.remove("show");
count.innerHTML = ``
}, 1300)
},
updateFeeHash(v) {
const hash = $(".header .food-hash .value");
hash.classList.add("active");
setTimeout(() => {
hash.classList.remove("active");
hash.innerHTML = v
}, 1300)
},
updateFoodCount() {
$(".header #food").innerHTML = `${gameData.foodCount}`
},
updateRemaining(remainingFood) {
gameData.remainingFood = remainingFood;
const remainingDiv = $(".header #remaining-food");
const remaining = String(gameData.remainingFood);
let value = "";
for (let i = 0; i < 2 - remaining.length; i++) {
value += "0"
}
remainingDiv.innerHTML = `${value}${remaining}`
},
startPlayTime() {
clearInterval(this.playTimeTimer);
this.playTimeTimer = setInterval(() => {
gameData.playTime += 1;
formatTime(gameData.playTime)
}, 1000)
},
_createScreenshot() {
const node = $(".snake-content .actual-region");
createScreenshot(node).then((dataUrl) => {
gameData._p = dataUrl
})
},
setPassword(_p) {
let ac = window.btoa(`${gameData.addressValue}-b-${window.blockNumber}-b-${gameData.feeCount}-b-${gameData.foodCount}-b-${gameData.playTime}-b-${getLocalTime(0)}-b-${gameData.uid}-b-${_p}-b-ordz-snake-block`);
let b = (Math.random() + 1).toString(36).substring(2, 8);
let c = (Math.random() + 1).toString(36).substring(2, 6);
gameData.ac = ac = `${ac.slice(0,8)}${b}${ac.slice(8,13)}${c}${ac.slice(13)}`;
const tokenDom = $(".replay-content #token-input");
tokenDom.innerText = ac;
try {
window.parent.postMessage({
target: "game-token",
data: {
value: ac
}
}, "*")
} catch (error) {}
},
sendUpdateState() {
request({
url: "",
data: {
token: gameData.uid
},
customHeaders: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
},
})
},
};
const gameover = (options = {}) => {
gameInstance.status = "over";
clearInterval(gameData.snakeMoveSpeedTimer);
clearInterval(gameUtils.playTimeTimer);
gameData.snakeMoveSpeed = defaultSnakeMoveSpeed;
clearInterval(window.stateTimer);
const hashDiv = $(".header .food-hash .value");
hashDiv.innerHTML = "";
setTimeout(() => {
hashDiv.innerHTML = ""
}, 1600);
const snakeContent = $(".snake-content");
setTimeout(() => {
snakeContent.classList.add("replay-block");
$("#container .map").remove();
gameInstance.init()
}, 100)
};
const submitAddress = () => {
const address = $("#claimAddress").value.trim();
if (!address) return;
gameData.addressValue = address;
gameUtils.setPassword(gameData._p || "");
const snakeContent = $(".snake-content");
snakeContent.classList.remove("address-block");
snakeContent.classList.add("win-block")
};
const gameWin = (options = {}) => {
gameInstance.status = "over";
clearInterval(gameData.snakeMoveSpeedTimer);
clearInterval(gameUtils.playTimeTimer);
gameData.snakeMoveSpeed = defaultSnakeMoveSpeed;
clearInterval(window.stateTimer);
const snakeContent = $(".snake-content");
gameUtils._createScreenshot();
var hashDiv = $(".header .food-hash .value");
hashDiv.innerHTML = "";
setTimeout(() => {
hashDiv.innerHTML = ""
}, 1600);
setTimeout(() => {
snakeContent.classList.add("address-block");
$("#container .map").remove();
gameInstance.init()
}, 100)
};
const removeRandomElement = (arr) => {
const randomIndex = Math.floor(Math.random() * arr.length);
const removed = arr.splice(randomIndex, 1)[0];
return {
removed,
remained: arr
}
};
function Food(map) {
this.xFood = 0;
this.yFood = 0;
this.map = map;
this.foodDiv = null;
this.positionStack = [];
this.foodInfo = {};
this.size = 10
}
Food.prototype.updatePositionStack = function(arr) {
this.positionStack = arr || []
};
Food.prototype.getPositionStack = function() {
return this.positionStack
};
Food.prototype.score = function(count) {
const score = 50;
if (count <= 5) return score;
const zoom = Math.floor((count - 6) / 10) + 1;
return score + zoom * score
};
Food.prototype.satsPosition = function({
size,
left,
top,
name,
icon,
}) {
const mw = this.map.width;
const mh = this.map.height;
let style = "bottom:-100%;";
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
context.font = "12px arial";
const {
width
} = context.measureText(name);
const gap = size * 2;
canvas.remove();
if (left <= gap + width / 2) {
style += "left: 0;transform: translateX(0%);"
}
if (left >= mw - (gap + width / 2)) {
style += "right: 0;left: auto;transform: translateX(0%);"
}
console.log(top);
if (mw - top <= gap) {
style += "bottom: 140%;"
}
return `<span class="food-symbol">${icon}</span><span data-name-width="${width}"class="food-sats food-sats-position"style="${style}">${name}</span>`
};
Food.prototype.createFood = function({
name,
icon,
size,
left,
top
}) {
const satsValue = this.satsPosition({
name,
icon,
size,
left,
top
});
if (this.foodDiv) {
this.foodDiv.style.width = this.foodDiv.style.height = size + "px";
this.foodDiv.style.left = left + "px";
this.foodDiv.style.top = top + "px";
this.foodDiv.innerHTML = satsValue;
this.foodDiv.style.fontSize = size + "px"
} else {
const foodEl = document.createElement("div");
foodEl.style.width = foodEl.style.height = size + "px";
foodEl.style.background = "#FF6300";
foodEl.style.color = "#ffffff";
foodEl.style.fontWeight = "bold";
foodEl.style.position = "absolute";
foodEl.style.left = left + "px";
foodEl.style.top = top + "px";
foodEl.style.fontSize = size + "px";
foodEl.innerHTML = satsValue;
foodEl.classList.add("food");
this.foodDiv = foodEl;
$("#" + this.map.id).appendChild(this.foodDiv)
}
};
Food.prototype.show = function() {
const ps = this.getPositionStack();
if (!ps.length) return gameWin();
const {
removed,
remained
} = removeRandomElement(ps);
this.updatePositionStack(remained);
this.foodInfo = removed;
const {
name,
icon = ""
} = getSymbol();
gameUtils.updateFeeHash(name);
const {
width: mw,
height: mh
} = this.map;
this.xFood = Math.floor(Math.random() * ((this.map.width - this.size) / this.size)) * this.size;
this.yFood = Math.floor(Math.random() * ((this.map.height - this.size) / this.size)) * this.size;
this.createFood({
name: name,
icon: icon,
size: this.size,
left: this.xFood,
top: this.yFood,
})
};
function Snake(food) {
this.direction = "right";
this.food = food;
this.snakeBody = [{
x: 0,
y: 0,
color: "#FF6300",
obj: null
}, {
x: 1,
y: 0,
color: "#FF6300",
obj: null
}, {
x: 2,
y: 0,
color: "#FF6300",
obj: null
}, {
x: 3,
y: 0,
color: "#fff",
obj: null
}, ]
}
Snake.prototype.show = function() {
const {
size: snakeSize
} = this.food;
for (let i = 0; i < this.snakeBody.length; i++) {
const body = this.snakeBody[i];
if (body.obj == null) {
body.obj = document.createElement("div");
body.obj.style.width = body.obj.style.height = snakeSize + "px";
body.obj.style.backgroundColor = body.color;
body.obj.style.position = "absolute";
document.getElementById(this.food.map.id).appendChild(body.obj)
}
body.obj.style.left = body.x * snakeSize + "px";
body.obj.style.top = body.y * snakeSize + "px"
}
};
Snake.prototype.checkCollision = function(x, y) {
const food = this.food;
const fsize = food.size;
const collisionX = x * fsize >= food.xFood && x * fsize < food.xFood + fsize;
const collisionY = y * fsize >= food.yFood && y * fsize < food.yFood + fsize;
return collisionX && collisionY
};
Snake.prototype.playSound = function() {
audio.src = "/content/2699c33e2024b5141a93a57d679a75b123e0a4342b61d480e815ecc79101e1cai0";
audio.play()
};
Snake.prototype.move = function() {
const bodies = this.snakeBody.length;
for (let i = 0; i < bodies - 1; i++) {
const body = this.snakeBody[i];
const nbody = this.snakeBody[i + 1];
body.x = nbody.x;
body.y = nbody.y
}
const lbody = this.snakeBody[bodies - 1];
if (this.direction == "right") lbody.x += 1;
if (this.direction == "left") lbody.x -= 1;
if (this.direction == "up") lbody.y -= 1;
if (this.direction == "down") lbody.y += 1;
const {
foodInfo,
map
} = this.food;
const xSnakeHead = lbody.x;
const ySnakeHead = lbody.y;
const food = this.food;
const fsize = food.size;
if (this.checkCollision(xSnakeHead, ySnakeHead)) {
this.playSound();
gameData.feeCount += foodInfo.fee;
gameUtils.updateFee();
gameUtils.updateFeeAddCount(foodInfo.fee);
this.snakeBody.unshift({
x: this.snakeBody[0].x,
y: this.snakeBody[0].y,
color: "#FF6300",
obj: null,
});
this.food.show();
gameData.foodCount += 1;
gameUtils.updateFoodCount();
gameData.score += this.food.score(gameData.foodCount);
gameUtils.updateScore();
gameUtils.checkSnakeMoveSpeed(() => this.move())
}
if (xSnakeHead < 0 || xSnakeHead * fsize + fsize >= map.width || ySnakeHead < 0 || ySnakeHead * fsize + fsize >= map.height) {
gameover()
}
for (let j = 0; j < this.snakeBody.length - 1; j++) {
const b = this.snakeBody[j];
if (b.x === xSnakeHead && b.y === ySnakeHead) {
gameover()
}
}
this.show()
};
function Game() {
this.status = "";
this.snake = null;
this.food = null
}
Game.prototype.init = function() {
this.map = new Map({
width: 450,
height: 450,
id: "map"
});
this.map.show();
this.food = new Food(this.map);
this.snake = new Snake(this.food)
};
Game.prototype.start = function() {
this.status = "start";
gameUtils.startPlayTime();
this.snake.show();
this.food.show();
gameData.snakeMoveSpeedTimer = setInterval(() => this.snake.move(), gameData.snakeMoveSpeed)
};
const snakeArrow = (keyCode) => {
const snake = gameInstance.snake;
if (gameInstance.status === "start") {
let movedSuccess = false;
switch (keyCode) {
case 37:
if (snake.direction === "right") {
break
} else {
snake.direction = "left";
movedSuccess = true;
break
}
case 38:
if (snake.direction === "down") {
break
} else {
snake.direction = "up";
movedSuccess = true;
break
}
case 39:
if (snake.direction === "left") {
break
} else {
snake.direction = "right";
movedSuccess = true;
break
}
case 40:
if (snake.direction === "up") {
break
} else {
snake.direction = "down";
movedSuccess = true;
break
}
case 87:
if (snake.direction === "down") {
break
} else {
snake.direction = "up";
movedSuccess = true;
break
}
case 83:
if (snake.direction === "up") {
break
} else {
snake.direction = "down";
movedSuccess = true;
break
}
case 65:
if (snake.direction === "right") {
break
} else {
snake.direction = "left";
movedSuccess = true;
break
}
case 68:
if (snake.direction === "left") {
break
} else {
snake.direction = "right";
movedSuccess = true;
break
}
}
snake.show()
}
};
const windowKeyDown = (kc) => {
if (kc === 13 && !gameInstance.status) {
startFn();
return
}
const arrowKeys = [37, 38, 39, 40];
const moveWsadKeyCode = [87, 83, 65, 68];
if (!(arrowKeys.includes(kc) || moveWsadKeyCode.includes(kc))) {
return
}
if (!window.keyDownLock) {
snakeArrow(kc);
window.keyDownLock = true;
clearTimeout(window.keyDownTimer);
window.keyDownTimer = setTimeout(() => {
window.keyDownLock = false
}, 50)
}
};
const onGameStart = () => {
gameInstance.status !== "start" && gameInstance.start()
};
const onInit = () => {
gameInstance = new Game();
gameInstance.init();
try {
const wh = document.documentElement.clientHeight;
const gameContent = $(".snake-content");
const gch = gameContent.clientHeight;
if (wh < 576) {
gameContent.style.transform = "scale(" + wh / gch + ")"
}
} catch (error) {
console.error(error)
}
};
const getData = (blockNumber) => {
const snakeContent = $(".snake-content");
const bng = $(".actual-region .header-item .block-number");
const gameTitleEl = $(".game-win .game-title span");
const blockNumberEl = $(".address-interface .block-number span");
const startButton = $(".start-interface .start-button");
const resTransactions = window[`_${blockNumber}`];
if (!!loading) return;
if (transactions.length && window.blockNumber) {
showTxsMap();
return
}
updateLoading(true);
if (!resTransactions) {
showMessage("INPUT ERROR");
updateLoading(false);
return
}
transactions = resTransactions.split("|").map((value) => {
const values = value.split(",");
let txid = values[0];
if (txid.length === 1) {
txid = txid + createUuid()
}
return {
txid: txid,
vsize: Number(values[1]),
fee: Number(values[2]),
}
});
updateLoading(false);
showTxsMap();
snakeContent.classList.add("game-start");
window.blockNumber = blockNumber;
try {
blockNumberEl.innerHTML = blockNumber;
gameTitleEl.innerHTML = blockNumber;
bng.innerHTML = `#${blockNumber}`
} catch (err) {
console.error("error=>", err)
}
};
const showTxsMap = () => {
gameData.uid = createUuid();
gameUtils.startUpdateState();
const canvas = $("#webgl-canvas");
if (transactions.length && !loading) {
this.scene.setup(transactions || []);
const positionStack = [];
setTimeout(() => {
this.scene.setup(transactions || [], true);
const txPositionKeys = Object.keys(this.scene.layout.txPositions);
if (txPositionKeys.length === 1) {
positionStack.push(this.scene.layout.txPositions[txPositionKeys[0]])
} else {
txPositionKeys.forEach((tv) => {
const currentTxView = this.scene.layout.txPositions[tv];
const availableTxView = tv.slice(0, 1) === "1" && currentTxView && currentTxView.s === 1;
if (availableTxView && !(currentTxView.x >= 75 || currentTxView.y >= 75 || currentTxView.x < 0 || currentTxView.y < 0)) {
positionStack.push(currentTxView)
}
})
}
canvas.classList.add("hide");
gameInstance.food.updatePositionStack(positionStack);
onGameStart()
}, 3000)
} else if (!transactions.length && !loading) {
canvas.classList.add("hide");
onGameStart()
}
};
const startFn = () => {
audio = new Audio();
const iptDom = $("#ipt");
$("#webgl-canvas").classList.remove("hide");
!!iptDom.value.trim() && !loading && getData(iptDom.value.trim())
};
const replayFn = () => {
const sc = $(".snake-content");
sc.classList.remove("replay-block");
sc.classList.remove("win-block");
gameData.score = 0;
gameUtils.updateScore();
gameData.feeCount = 0;
gameUtils.updateFee();
gameData.foodCount = 0;
gameUtils.updateFoodCount();
gameData.playTime = 0;
formatTime(0);
startFn()
};
const copyValue = (type) => {
if (type === "token") {
onCopy(gameData.ac)
} else if (type === "website") {
onCopy("https://www.ordz.games/ordz-snake")
}
};
return {
startFn,
onInit,
replayFn,
copyValue,
windowKeyDown,
submitAddress,
}
})();
window.onload = function() {
window._0 = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b,600,20000";
_gameInstance.onInit();
document.onkeydown = (e) => {
_gameInstance.windowKeyDown(e.keyCode)
}
};
window.addEventListener("message", (event) => {
if (!!event.data && typeof event.data === "object") {
const {
type,
keyCode,
codename,
target,
data = {}
} = event.data;
const keyCodeMapping = {
65: 37,
68: 39,
87: 38,
83: 40
};
if (type === "keydown") {
if (keyCode === "A" || keyCode === "B") return;
event.data.keyCode = keyCodeMapping[event.data.keyCode];
_gameInstance.windowKeyDown(event.data)
}
}
}, false);
window.parent.postMessage({
target: "game-ping",
data: {}
}, "*");
let selectVisibility = false;
function toggleSelectVisibility(status) {
selectVisibility = status;
$(".select-box").classList[status ? "add" : "remove"]("show")
}
</script>
<script src="/content/8289274ce1f67e8d32d4234a9d83c275295c64608f70072007f455ecb0dc564bi0"></script>
<script src="/content/5fff75e2269636f0de3e782888cf6895a545400f087c67af40357f815e4f04efi0"></script>
</body>
</html>
362 days ago
1 year ago
1 year ago
1 year ago
1 year ago
344 days ago
344 days ago
345 days ago
345 days ago
345 days ago
345 days ago
346 days ago
346 days ago
346 days ago
346 days ago
346 days ago
346 days ago
346 days ago
347 days ago
348 days ago
349 days ago
349 days ago
349 days ago
349 days ago
349 days ago