1import Fly from "../npc/fly.js"; 2import { ParallaxText } from "../text/parallax-text.js"; 3var gameInstance = null; 4export default class Game { 5 6 constructor(canvasId) { 7 if (gameInstance) return gameInstance; 8 gameInstance = this; 9 const canvas = document.getElementById(canvasId); 10 11 this.context = canvas.getContext('2d'); 12 this.context.canvas.width = window.innerWidth; 13 this.context.canvas.height = window.innerHeight; 14 this.canvas = canvas; 15 this.hodlers = [] 16 const textCanvas = document.getElementById('textCanvas'); 17 this.textRenderer = textCanvas.getContext('2d'); 18 this.textCanvas = textCanvas; 19 this.resources = []; 20 this.character = null; 21 this.allResourcesLoaded = false; 22 this.playTime = 0; 23 this.context.imageSmoothingEnabled = false; 24 this.started = false; 25 this.text = new ParallaxText('', Math.round(255 * 3 / 2), 50, -0.5); 26 27 this.resources.push(this.text); 28 canvas.addEventListener('click', (e) => { 29 const x = e.clientX; 30 const y = e.clientY; 31 this.handleClick(x, y); 32 }); 33 34 this.mousePos = { x: 130, y: 0 }; 35 canvas.addEventListener('mousemove', (e) => { 36 const { mouseX, mouseY } = this.normalizeMousePos(e.clientX, e.clientY) 37 this.mousePos.x = mouseX; 38 this.mousePos.y = mouseY; 39 }); 40 41 42 const scale = window.innerHeight / canvas.height;; 43 this.camera = { 44 x: 0, 45 y: 0, 46 targetX: 0, 47 targetY: 0, 48 width: canvas.width, 49 height: canvas.height, 50 viewportWidth: window.innerWidth / scale 51 }; 52 } 53 54 async loadAssets() { 55 // Assuming each asset has a `loaded` promise that resolves when the asset is loaded 56 await Promise.all(this.resources.map(r => r.loaded)); 57 } 58 59 moveCamera(targetX, targetY) { 60 this.camera.targetX = targetX; 61 this.camera.targetY = targetY; 62 } 63 64 updateResources() { 65 this.camera.viewportWidth = window.innerWidth / (window.innerHeight / this.canvas.height); 66 this.playTime++; 67 this.resources.forEach(r => r.update && r.update(this.mousePos, this.camera)) 68 this.resources.sort((a, b) => a.zIndex - b.zIndex); 69 70 71 72 } 73 updateCamera() { 74 /*let smoothing = 0.05; // This value can be adjusted 75 76 // Define the "dead zone" in the center of the canvas where the camera won't move 77 const deadZoneWidth = this.canvas.width * 0.20; // 20% of the canvas width 78 const deadZoneHeight = this.canvas.height * 0.20; // 20% of the canvas height 79 80 // Calculate the center of the dead zone 81 const deadZoneCenterX = this.canvas.width / 2; 82 const deadZoneCenterY = this.canvas.height / 2; 83 84 // Calculate the distance of the mouse from the center of the dead zone 85 let dx = this.mousePos.x - deadZoneCenterX; 86 let dy = this.mousePos.y - deadZoneCenterY; 87 88 // Normalize the distance based on the dead zone size 89 dx = Math.abs(dx) > deadZoneWidth / 2 ? dx - Math.sign(dx) * deadZoneWidth / 2 : 0; 90 dy = Math.abs(dy) > deadZoneHeight / 2 ? dy - Math.sign(dy) * deadZoneHeight / 2 : 0; 91 92 // Calculate the proportion of the distance to the total possible distance 93 const proportionX = dx / (this.canvas.width / 2 - deadZoneWidth / 2); 94 const proportionY = dy / (this.canvas.height / 2 - deadZoneHeight / 2); 95 96 // Calculate the target camera position based on the proportion 97 const targetX = proportionX * 126; // Assuming 126 is the maximum X value for the camera 98 const targetY = proportionY * 0; // Assuming vertical movement is not desired 99 100 // Apply smoothing to the camera movement 101 let cameraDx = (targetX - this.camera.x) * smoothing; 102 let cameraDy = (targetY - this.camera.y) * smoothing; 103 104 this.camera.x += cameraDx; 105 this.camera.y += cameraDy;*/ 106 } 107 108 addResource(resource) { 109 this.resources.push(resource); 110 111 } 112 113 normalizeMousePos(x, y) { 114 const rect = this.canvas.getBoundingClientRect(); 115 116 const XOffset = rect.x; 117 const YOffset = rect.y; 118 119 const ratio = window.innerHeight / this.canvas.height; 120 121 const mouseX = (x - XOffset) / ratio 122 const mouseY = (y - YOffset) / ratio 123 return { mouseX, mouseY }; 124 } 125 126 handleClick(x, y) { 127 const { mouseX, mouseY } = this.normalizeMousePos(x, y); 128 129 for (const resource of [...this.resources]) { 130 if (resource.containsPoint && resource.containsPoint(this.camera.x + mouseX, this.camera.y + mouseY)) { 131 if (resource.clickAction) { 132 if (resource.onClick()) 133 break; 134 } 135 136 } 137 } 138 } 139 140 141 draw() { 142 this.context.canvas.width = window.innerWidth; 143 this.context.canvas.height = window.innerHeight; 144 this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); 145 this.textRenderer.clearRect(0, 0, this.textCanvas.width, this.textCanvas.height); 146 147 if (!this.allResourcesLoaded) { 148 // Draw loading screen 149 this.context.fillStyle = 'black'; 150 this.context.fillRect(0, 0, this.canvas.width, this.canvas.height); 151 return; 152 } 153 154 // Sort resources by zIndex, maintaining the order for those with the same zIndex 155 // Assuming each resource has a `zIndex` property; if not, you might need to add it 156 157 for (const resource of this.resources) { 158 // Only draw the resource if its image is loaded 159 resource.draw(this.context, this.camera); 160 } 161 162 if (this.cursor) { 163 this.cursor.draw(this.context, this.camera); 164 } 165 } 166 167 168 addFly(fly) { 169 setTimeout(() => this.resources.push(fly), Math.floor(Math.random() * 1000)) 170 // Adds the new fly instance to the flies array 171 } 172 173 removeFly(flyToRemove) { 174 // Assuming each fly has a unique 'address' property 175 flyToRemove.destroy(); 176 // This will remove the fly with the matching address from the flies array 177 } 178 findFly(account) { 179 // Finds and returns the fly instance with the given address 180 return this.resources.find(fly => fly.isFly && fly.account === account); 181 } 182 183 updateHodlers(data, delayed) { 184 // Step 1: Update existing hodlers or add new ones 185 const updatedAddresses = new Set(); 186 187 const removeMissing = () => { 188 // Step 2: Check for and remove missing addresses
189 this.hodlers.forEach(({ account }) => { 190 if (!updatedAddresses.has(account)) { 191 // If the address from current hodlers is not in the updated data, remove the corresponding fly 192 const flyToRemove = this.findFly(account); 193 if (flyToRemove) 194 this.removeFly(flyToRemove); // Assuming this method removes the fly from the game 195 } 196 }); 197 198 // Update the current hodlers list to the new data 199 this.hodlers = data.slice(); // Make a shallow copy of the data array 200 } 201 202 data.forEach(({ account, value: v }, i) => { 203 setTimeout(() => { 204 const value = BigInt(v) / BigInt(1000000000); 205 if (value > 0) { 206 207 208 const fly = this.findFly(account); 209 if (fly) { 210 211 // Update existing fly if the value is higher 212 if (value >= fly.tokens) { 213 fly.changeState("green"); // Set state to green 214 } else fly.changeState("red"); // Set state to green 215 fly.updateTokens(value); 216 } else { 217 // Create a new Fly instance if the address is not found 218 const newFly = new Fly(account, value); 219 220 // Assuming there's a method to add the new fly to the game 221 this.addFly(newFly); 222 } 223 updatedAddresses.add(account); 224 } 225 if (i === (data.length - 1)) removeMissing(); 226 }, delayed ? i * 40 : 0) 227 228 }); 229 230 231 } 232 233 234 235} 236 237 238export function game() { 239 return gameInstance ? gameInstance : new Game("gameCanvas"); 240}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.