The Mezunian

Die Positivität ist das Opium des Volkes, aber der Spott ist das Opium der Verrückten

Let’s Code a Crappy 2D Platformer Like Millions o’ Other People on the Internet & Lose Interest & Give Up Only a Few Months In, Part III

¡So much done!

Title Screen & Messages

As shown ’bove, a title screen, as well as a message screen that pops on ’pon starting the game, to say what you should do to beat the level, & 1 that appears ’pon beating the level.

Game States

In relation to this, a game state system, which can not only change states, but also “pop” & “push” states as a way to interrupt states & still be able to go back to them.

Since I’m terrible @ ’splaining what I’m doing—it’s mostly just me breathlessly talking ’bout something I did, as if by magic—here’s a much better explanation. In fact, I recommend reading most o’ those articles; they were an immense influence o’er the past year or so.

Pause Menu

Speaking o’ which, the latter is used in the pause screen I made, as well as the level-beginning aforementioned message. (Unlike the victory message, this message must pop up after the LevelState has already started so it can get info from its Goal—mo’ on that later).

Levels with Multiple Maps

The level class with submaps held by it, as well as fully-working warps that allow the player to move throughout the entire level.

Level Goals

Within the level class is also a goal class that determines how to beat the level (in addition to touching the goal block, which always completes the level). For this level, the goal is to collect 75 gems.

Palettes

A palette system. With so many things turning out easier than expected, this surprised me by how long it took to get right, simply due to my inability to decide how to organize the code. I finally elected to keep the actual palette file in the Graphics class, since it works directly with it. I then added a PaletteSet, which is just the name o’ the hue & the background # that can be used to create a palette, to GameState & Map. A GameState automatically creates a PaletteSet when created, & the Game engine automatically changes Graphics’s palette ’pon changing states & the Graphics automatically reloads graphics to apply the palette. This keeps the palette that’s applied in LevelState from continuing to any other states, other than the pause menu, which has its palette pushed to it in its constructor from the level state. Meanwhile, GameState also has a method that allows for changing its palette manually, which filters through to graphics with the same automation, which is used for map-switching (since that doesn’t actually change the game state).

It should be obvious that the palette system wasn’t created out o’ necessity or practicality, since SDL can easily load images with a full range o’ colors; I simply chose it for stylistic purposes. I don’t know: sometimes monochrome looks nice, specially when contrasted with other monochrome hues. Plus, Super-Game-Boy-like monochrome graphics is a form o’ retro callback that doesn’t seem to be o’erused yet, like most.

Text

A text system, which includes some frills, such as auto-aligning text lines & blinking text. This is not done by loading a font, since I actually find that that would add a bunch o’ complications that I don’t want to deal with, but just by using a graphic file & making a simple conversion map that outputs a frame # for a given character & functions for getting the x & y coordinates from that frame, which corresponds to the position o’ that character in the graphic file.

This reminds me that I didn’t go into much detail ’bout some o’ the things I’ve already done, ’specially the level construction, which is 1 o’ the most complex aspects.

1 programming pattern I’ve noticed a lot is breaking 2d grids into a single line o’ #s—what I usually call “frames.” For example, the text system I mentioned earlier did that, as well as the tilemaps for level maps (Tiled outputs 1d arrays). The best way to deal with that is with these 2 formulae that I’ve used countless times in programming:

1: x = n % width

2: y = floor( n / width )

“x” & “y” refer to their respective cardinal positions. For example, if one wants to find out where to place a block from the 28th ([27]) element in a 1d array for a 128-block-wide map, simply look for 27 % 128, while its vertical position is floor( 27 / 128 ). (Note: if this position is in pixels & not blocks, you’ll need to multiply the answer by the width & height respectively in pixels o’ blocks.

The 1st formula uses remainders, which, going up in #s, counts up the #s up to the 2nd # (the width, which is, logically, the maximum x position), & then back to 0 (the minimum x position), counting up ’gain & ’gain till the last block:

012345678
012345678
012345678
012345678

The y formula, meanwhile, stays @ the same # for every width # o’ blocks, & then rises 1 for ’nother width # blocks, & so on:

00000000
11111111
22222222
33333333

Looking @ these graphs, one can hopefully see how these formulae make sense, since I certainly can’t ’splain it logically.

I don’t know what I’ll do next. Maybe sleep.

Download the source code to this e’en less sloppy program.

Posted in Boskeopolis Land, Programming

Let’s Code a Crappy 2D Platformer Like Millions o’ Other People on the Internet & Lose Interest & Give Up Only a Few Months In, Part II

Accomplished so much in the last few days:

  • Fully-working camera that automatically adjusts to player position (if she goes past its inner boundaries) & map boundaries & can be moved independently with certain buttons.

  • Block & Map system with tileset. After the slight tedium o’ creating the tileset, the need to create a hundred sprites was replaced by the simple need to paste in an array o’ numbers spewed out by a map made in Tiled. The player’s collision code was changed to respond to the blocks’ types ’stead o’ sprite types. New block types include gems that disappear ’pon being collected & add to a funds # (see next point), a hurt block that causes you to lose health & warps you to the start o’ the room if you lose all health, & a goal block, which now justs closes the program with a printed message in the console that says “YOU WON”—an amazingly worse victory reward what you got from beating Ghosts ’n Goblins for the NES.

  • Inventory system with simple text printing system, used to print the # o’ gems the player collects.

  • A few mo’ animations, including blinking for Autumn when she’s standing or crouching round & an animation from holding up. O yeah, & I finally added the climbing animation; I thankfully already had a climbing graphic for Autumn from some sprite comic I made for later.

’Cause I was so tired & yet also so buzzed on coffee in the last article, for some reason though I mentioned using C++ to make this game, I forgot to mention using SDL2, which makes it look like I did everything from scratch, which would be ridiculous. O well: if anyone cared, they could’ve looked @ the code themselves.

I should also point out that I’m tired & buzzed on coffee today, too, so this article’ll probably be just as incoherent—’specially as I’m publishing it right after writing it, rather than waiting half a year, as is my wont.

I think I’ll next work on developing the Map class into a Level class with multiple maps & ways to warp round these levels. That’s what the open manhole @ the end’s s’posed to be used for.

& where there’s an unsightly hole under it—that’s s’posed to be a warp block with the same graphics as the rest o’ the lower dirt, which I simply neglected to add to the tileset. I should also add that the open manhole’s technically s’posed to be nonsolid—’nother slight o’ersight.

As these screenshots also show, I also changed the resolution o’ the game a bit to fit the wider screens o’ modern computers—from 256 x 192 to 320 x 176, which is the closest approximation to 16:9 that fit within multiples o’ 16 & didn’t make the game space too big or small. Thankfully, I was halfway decent with programming, so changing this resolution only required me to change 2 variables. Changing the camera to fit in the inventory bar only required me to decrease the camera’s height by 2 bars.

After doing the level & map stuff, I’ll probably move on to doing game states & a level state & crapping together some halfway decent victory screen, as well as a less jarring death animation & maybe an intro screen. @ that point I’ll technically have a complete game; it’ll be a lame, immensely short game, but it’ll technically be a fully-working game, & that’s better to finish ’fore finishing the palette system, which is inessential (& the plan to make this, by the way, should ’splain why all these graphics are grayscale).

Download latest source code & see it in its slightly less-sloppy glory.

Posted in Boskeopolis Land, Programming

Let’s Code a Crappy 2D Platformer Like Millions o’ Other People on the Internet & Lose Interest & Give Up Only a Few Months In, Part I

After days o’ not being able to do anything useful, I had a certain programming binge the past day or 2, which involved restarting a 2D platformer game I’d been starting o’er & o’er ’gain since 2014, since I’m anal-retentive. I’d always tell myself I should blog ’bout it, since it’s obvious that this fiddling isn’t going to be useful in any other way, & this is the best opportunity.

This time, rather than my usual anal-retentive strategy o’ carefully crafting complex class & component systems that were elegant, but empty o’ content, I started simple, focusing primarily on getting the player’s physics right, with the only extra tinkering being visuals, since they’re important for seeing reactions to physics (the screen-magnification system, so I don’t have to squint to see everything, & movement animation, so I can better gauge the player’s movements—I don’t know). This is based on a principle I read ’bout called “YAGNI”: “You Ain’t Gonna Need It,” which I read ’bout from some great website full o’ nifty programming tips whose URL I sadly can’t remember anymo’. That’s the perfect time to show off my code so everyone can see what a sloppy mess it is.

This project’s done in C++, the sloppiest o’ programming languages, but 1 I’m strangely better @ understanding than s’posedly “easier” languages, like JavaScript.

The problem is, e’en in only a day, I’ve done so much—& by “done so much,” I mean copied & pasted a lot o’ code I already did from my earlier projects (this experience o’ copying & pasting the good parts from older projects is what taught me that refactoring isn’t nearly as hard as I 1st imagined, which makes YAGNI easier to apply).

  • Master graphics object that holds basic SDL graphical junk, as well as simple spritesheet system for loading graphical files, which can easily be referenced by sprites through simple enums (androgyn, do I love enums).

  • Includes simple magnification system I’ve been copying & pasting since 2014 that simply reads the computer’s resolution & uses that to automatically magnify the 256 x 192 pixel screen to as big as will fit evenly in the monitor, as well as automatically centering it.

  • Simple graphics & movement components for sprites, which are only used by the player. To make things ’specially wasteful & redundant, sprites have a built in simple rendering function & variables that are used if said sprite doesn’t have a graphical component, for blocks, since I didn’t feel like making a graphical component for them, when they probably won’t be sprites later in development, anyway. It’ll take a minute or so to delete the redundant function & variables.

  • Input system that abstracts button presses from actions.

Most o’ the code is crammed into the sprite class, & almost all o’ it is the physics o’ the player & collision with sprites o’ other types. So far, the player can run, jump, & duck as well as I can imagine, & has working collision for solid blocks, those strange blocks that are only solid on top (those cloud platforms from Super Mario World), & ladders (ladders are still somewhat wonky in that the player falls off if she climbs ’bove the ladder & has no climbing graphics).

I have mixed feelings ’bout the collision code. I used to use this simple formula I got from some book years ago, but I found that finicky, so I replaced it with a mo’ complex collision system I borrowed from Sonic games. In this case, the sprite has collision dots for each side & tests whether those dots are within a certain boundary box within the other sprite. The way this is actually done is immensely messy, with many probably-redundant integers; but I’ll worry ’bout cleaning that up later. It does seem to work well: so far I’ve yet to see clipping while walking o’er flat land (bumping into the sides o’ the corners o’ the blocks) or being able to land on the corner o’ a block in a vertical wall, which took far longer than one might expect to fix.

Also, since I kept changing the collision system, the collision class is full o’ redundant variables that’ll need to be cut out later, when I decide which collision method to stick with.

1 problem while trying to research solutions is that I can only find the most basic tutorials on the internet, not any advanced problems, such as handling trying to stand up from a crouch while in a small vertical space, which took almost the whole day fixing, or the best way to handle climbable blocks.

Also, much o’ the advice given is terrible or inaccurate. Don’t get me started on the tutorials I’ve seen that advise creating enemies like Red Koopas by putting invisible blocks solid only to enemies on the edges o’ every platform to keep them from falling off, rather than actually programming the enemies to detect edges. That’s god awful, & one can be assured that no Mario game e’er did something so dreadful.

Other than fixing the ladder quirks & cleaning up my code a bit, I’m not sure what to move onto next. Most likely creating a block system, which’ll ’ventually be a pain in the ass, since it’ll probably require creating tilesets o’ block types, as well as graphical & collision components. ’Gain, I want to keep myself from building too much architecture @ once, so I’ll probably just start with a simple block system.

& after all that, we have a map system, a camera system, & the fun that is a system that reads an array o’ #s & creates blocks in the right places.

I had the idea o’ putting this up on Github, only to realize that that’s based on, duh, Git, & I don’t actually know how to use Git, despite how useful it apparently is. Perhaps I should learn how to do that later. For now, I have just a dumb archive file with all the code. I would’ve also attached a video ‘stead o’ a lame screenshot, but I can’t get my capture software to make videos that don’t look like slideshows.

Download code & see it in all its sloppy glory.

Posted in Boskeopolis Land, Programming

Pro Theme Design!

So, I was searching for a WordPress-widget-making tutorial that wasn’t just the author throwing code in your face & telling you to paste it without saying what any o’ it does when I saw this splendid page @ “Pro Theme Design”:

Now, you’re probably thinking, “Wow, this code’s garbage; it cuts off in the middle o’ functions just like that. That’ll almost certainly cause errors.

But that’s not where the stupidity arrives. Here is:

There’s no design mo’ professional than making it impossible to tell 1 element from ’nother. Note that the textbox is so tall, you have to scroll far down to see that & know that a textbox exists @ all.

By the way, you could probably ascertain by these screen shots that this tutorial, too, simply throws code @ you without explaining what it does.

Posted in Programming, Web Design