Microsoft MakeCode

Noob questions

Hi all,

I’m a long-standing developer.
I have a number of random questions, if anyone can answer them, it would be super-helpful to my coding!

  1. How does the sprite collision detection operate? Is it distance from centre point, or bounding box, or non-transparent pixel overlap, or something else? Essentially, I’m trying to figure out how to design levels for a platformer and get the jump distances just right, and I need to know if just one pixel overlapping would be enough to trigger an overlap, or what criteria are being used.

  2. If a tile map contains a landscape, (say, gentle rolling hills), how should player movement be handled - i.e. if I want a player sprite of a car to move forward and be able to traverse the landscape, how would I do that in a tile map?

  3. What is the maximum size of a tile map?

  4. Can you have multiple tile maps representing different parts of a level?

  5. Why don’t Sprite flags, and kinds show up in the debugger?

Thanks for any insights!

1 Like

Answers, in order:

  1. For sprite-sprite collisions, it’s based on non transparent pixels. For sprite-tile collisions, it’s based on bounding boxes. All tiles have the same bounding box, regardless of image contents (it’s set by the tilesize) but sprites use a box that bounds the non-transparent pixels. This is mostly done to make the physics engine run faster with large tilemaps.
  2. Are you asking about how to snap the movement to the tile grid? If so, this is something we’re looking to improve. If you have any suggestions we’d love to hear them!
  3. The max size is 2000x2000 tiles on beta beta (arcade.makecode.com/beta)
  4. You can load/unload tilemaps by calling the setTileMap function, but you can only have one tilemap loaded at a time. They cannot be layered (but maybe will be down the road)
  5. We limit the fields that show up in the debugger. Internally, the kind is stored as a number (not the name given by the user) and flags are stored as a bitmask (which usually looks like a giant number). Flags are actually visible, but the kind was intentionally hidden to prevent confusion
1 Like

For the record, I’m not sure if a 2000x2000 tilemap would work in practice. Tilemaps are represented internally as images and that would be much more memory than most of our targeted hardware could handle. You might be able to get away with it if you declared it as an image literal. @mmoskal correct me if I’m wrong.

Definitely not a scenario that we’ve tested :slight_smile:

On hardware you have maybe 100-300k for static assets. Let’s say it’s 200k - this is 400k pixels, since each pixels takes half byte (16 colors), which works out to be a bit more than 600x600px, but honestly I wouldn’t go more than 200x200px… or so.

2 Likes

Thank you all so much for your replies; I was concerned at posting so many questions as my first post, and your answers have been exactly what I was looking for.

I am currently making a ‘runner’ type game, just to learn the platform, and I’ve made a manually-scrolling landscape generator that has hills and valleys and blank spots to represent holes to fall into. The decision to go manual - and even to forgo the physics/velocity systems - was based around the small size of the tile maps I could generate, and that when I tried to set vx on the landscape sprite columns the physics time calculations/on game update calls are obviously not sync’ed so I got single-pixel gaps in between the landscape as it moved.

I did see that I could make a tile map manually by using the image template in ‘JavaScript’ (I don’t know why it’s called that, when it’s clearly not actual JavaScript :-p), but I didn’t know if I could make a 100x8px map just to hold the landscape, hence these questions. I assume you don’t offer the ability to enter the tile map dimensions to the coder in order to keep it simple and explain the concept of a tile map easier, but I do wish the JavaScript->Block decompiler would be able to recognise these custom sizes.

The sprite collisions seem like the best of both worlds, I’m very impressed. (I’m impressed with the general quality of this whole system, in fact. I’ve had a long career as a programmer, [I was on the team that wrote Microsoft Windows, for example], and it’s great to see that you guys didn’t just take the easy way out and use pythagoras for collision detection).

I was asking about multiple tile maps partly for RAM usage (I would love to get file IO as an extension) and partly as a workaround for pseudo-infinite runner games with large tile maps (which is now resolved anyway), and partly as a way of having a switch between ‘room maps’ as a section of a level map. So, for example, imagine a rogue-like game where you open a door, and the room content beyond would be in a second tile map. But only one tile map at a time limits that kind of behaviour. No big deal, plenty of ways around that.

I guessed the sprite kind would be an enum or equivalent, and the flags obviously a bitmask, it’s just that those are the only two identifying attributes of a given instance of sprite - you aren’t told what the ID is, so you can’t match up the sprite description with any given instance, and if you can’t tell what kind it is, and can’t interpret the flags, you just can’t debug any issues involving sprites. It would be pretty trivial to display the flags as either hex or binary, I think, but I don’t know how you could show a reference for which bits are which, and the same problem with the Kind.

Finally (sorry for the long post again!), my second question was for my runner game again. If I have a landscape like this:

That is being moved one pixel per game update to the left of the screen, without the user controlling the player sprite, I want it to ‘run’ up the hill and back down again. The animation is no problem, rather it’s the detection of an uphill area in fron of the sprite, and the upward movement. Currently, as I’m doing all this manually, I was getting ready to examine a collision with the player sprite and a tile of Kind Uphill, and start moving the player upwards. But the collision detection is different if I’m not using a tile map, so I’m not clear on how handle that case - and going downhill is worse because of the bounding box on the Downhill tile. I was thinking maybe I have to draw the up and down tiles the same as the flat ones, and just teleport the player sprite up a level, or use gravity (-vy) to drop down; but I also don’t know how to auto-move the whole tile map towards the left, so I haven’t yet been able to experiment with this.

As for suggestions for snapping movement to the tile grid, I think it’s a case of treating the map as being flat or upright; if it’s upright, then the look-ahead collision for climbing up and gravity for dropping down could be implemented either built-in or more likely as a callback of some kind. It’s all I’ve got so far, anyway :-p

Thank you for your kind words!

I think it makes more sense to generate the landscape on the fly. We have Image.scroll(dx,dy) method that you can use to move the pixels and the only draw the new row (the scroll has currently only dx implemented, but this is fine for your game). You can use pixel testing on your generated image to see where the player sprite should be (I would start with previous vertical player position and probe the background with getPixel(), then move up or down depending whether the pixel is transparent).

I would suggest not scrolling by one pixel each frame, since this will vary between devices with different frame rates. It’s better to use game.eventContext().deltaTime and multiply that by speed (which will also let you increase the speed as you go). Keep position as a double, and only scroll by the integer part.

The language is actually Static TypeScript, see paper or more approachable blog post. Most programmers using the text editor are writing very simple programs that, because of type inference, look exactly the same in TypeScript and JavaScript, so for name recognition reasons, the text editor is labeled JavaScript. I was personally always against that though.

To get non-standard image sizes you can just edit the text of the image and the image editor will adapt.

Generating the landscape on the fly has the advantage of lower memory pressure (as I don’t have to hold a tile map image in RAM as well), and my current implementation (as shown) generates on 16-pixel wide column of landscape at a time; just enough to keep the screen full even after a 1-pixel scroll. Removing the sprite columns from the array when they go off screen to the left means I can also mark them for auto destruction, but I have to wait for one game update before I can mark it as it won’t be on screen until then, and so wouldn’t appear at all.

That’s the lowest memory cost implementation I can think of, and although I now know that I can generate a tile map of appropriate size, it works well and is small enough to keep going. The real choice of sprite vs tile map comes down to the collisions and subsequent behaviour.

I’m not clear whether you mean to keep a single, screen size Image that holds the landscape graphics, or if you’re referring to the tile map Image representation, when you mention Image.scroll…?

Scrolling a large image sounds like a heavy operation to me, so I’m not certain how that would perform? Plus, working on a column of pixels at a time is more complex than a sprite column. The downside is that I don’t know how to test my setup for individual pixels or sprites, although if I were to pixel test, I’d need to implement animation first so I could map the position of the player’s feet in order to know which pixels to check. And then I’m not sure what to check in terms of the uphill version as the first time you’d see a change, the player would be ‘in’ the uphill sprite.

I’m familiar with the delta time approach, but the periodic garbage collections put a real dent in performance when they run, sometimes stopping the game for a couple of seconds, and that always breaks the delta approach. Until I can get the garbage collection down to a negligible amount, the one pixel per ‘on game’ call is at least smooth and completely consistent even if it pauses from time to time.

I’m generally opposed to deliberately obfuscating the name of the language just for publicity/marketing, especially since the lack of obvious documentation makes it really hard to see which bits of real JavaScript you can’t use, and it’s not like Static TypeScript is unheard of amongst people who need to write code. But it’s not the worst thing in the world.

I was thinking something like this: https://makecode.com/_LtgPpUK9dDpe

Oh wow, that is absolutely perfect - I love the more ragged landscape than my simple effort, and I especially love the tiny code!

Lots of functions I didn’t know existed in there too, thank you - I’m going to study this closely.

I always loved working with other programmers and seeing what they come up with, it’s a real learning experience. I’m deeply grateful to you, @mmoskal, and to the community here for being so gracious to a noob to the platform. Thank you!