hex buffers aren’t really faster than normal arrays, they’re just more efficient in terms of code generation when declaring data in your project.
before i go into ways to improve efficiency of makecode projects, let me first give a warning to anyone who is reading this post in the future: you probably don’t need to follow any of this advice! unless you’re writing something that is extremely performance intensive (like a 3d/voxel engine), over optimizing your project will just leave you with a mess of unreadable code that you don’t enjoy working on. if your game is running slowly, look elsewhere for what might be causing issues before refactoring everything using the advice below!
with that out of the way, here are the big wins for improving performance:
- always use classes instead of object literals, avoid casting to
any, and avoid interfaces. all of these things require expensive string lookups when accessing properties. classes do not, and are much more efficient - always use the built in image functions instead of doing your own thing. if you’re calling
setPixelin a loop somewhere, stop and ask yourself if you should be usingfillRect,fillTriangle, orblitinstead - use integer arithmetic instead of floating point wherever possible. this is an annoying one to deal with, so we have a bunch of helper functions in the
Fxnamespace that you can use to convert floating point numbers to fixed point numbers. if you want to see examples of this, i recommend checking out the physics engine (but be warned, it’s pretty gnarly). i recommend holding off on doing this one until you have things working, it really makes code harder to read and refactor - bitwise arithmetic is your friend. need to cut off the decimal part of a number? use
num | 0instead ofMath.floor. need to divide by a power of 2? use right bitshifting. need to multiply by a power of 2? use left bitshifting. but be warned: any bitwise operation will convert the result into an integer, so dividing/multiplying with bitshifting is only useful when you want the result to be an integer.
now for your other question: if/else is not more efficient than switch or ternary expressions (e.g. expression ? ifTrue : ifFalse), they’re all basically the same. that being said, in general it is always best to avoid using any of these inside of loops!
for example, this code:
function togglePixels(left: number, top: number, width: number, height: number, on: boolean) {
for (let x = 0; x < width; x++)
for (let y = 0; y < height; y++) {
if (on) screen.setPixel(left + x, top + y, 1) // if statement inside loop
else screen.setPixel(left + x, top + y, 0)
}
}
}
is less efficient than this code:
function togglePixels(left: number, top: number, width: number, height: number, on: boolean) {
let color = 0;
if (on) color = 1; // if statement is outside loop
for (let x = 0; x < width; x++)
for (let y = 0; y < height; y++) {
screen.setPixel(left + x, top + y, color)
}
}
}
and of course these are both less efficient than this code, because it uses the builtin image functions:
function togglePixels(left: number, top: number, width: number, height: number, on: boolean) {
screen.fillRect(left, top, width, height, on ? 1 : 0)
}
