Vol.11 Dec
2017
Contents: PLAY
New games out this month! with @jerjer GAME JAM 2.0 - Annoucement
LEARN
Steve the Jumping Dinosaur (Part 2) with filmote
Good coding habits (Part 2) with Pharap Pixel Page - Tutorial with @Luxregina
EXPLORE Pixel Page with @Mr_Y
Arduboy on a NES by @uXe Questions with Game Developer @obono Eye is ME by @taniguchi Virus LQP-79 Special Edition by @Keyboard_Camper #arduboy Page 2 of 36
A welcome note: Best wishes and happy holidays from Arduboy Magazine! Hope that everyone is enjoying some time off, spending time with family and friends, and being merry. Perfect time for a Game Jam right? This month Arduboy is hosting the 2nd Game Jam from 5th - 12th Dec. What prizes will the winners get? What theme will the jam be? Read more about it on page 10! The end of the year also welcomes a new wave of Arduboy Magazine contributors.. Thank you @filmote, @Pharap and @Luxregina for educating us with your articles, and @jerjer for lending his voice in reviewing new games! -celinebins
Do you wish to contribute? Have an interesting article you wish to share with the Arduboy community? A cool project you did, your experience on working on it? A funny joke? We want to hear it! Send arduboymag a message through the Arduboy community page or a DM on Twitter! Page 3 of 36
Thank you to this months contributors! @filmote: In between writing articles for this magazine, Simon Simon is currently developing a dungeon crawling game called Dark & Under and hope to release it this December.
@jerjer: Cohost of “Nintendomain Podcast,� aspiring amateur games journalist and recent purchaser of an Arduboy. Jereme enjoys visiting classic gaming conventions and finding new and old portable handheld systems. He lives in Illinois with his 2 cats and a Nintendo Switch. Website: http://www.nintendomainpodcast.com
@Luxregina: Cyril Guichard is an Advertiser turned Indie Game developer turned professor. Visit his site to find out more: http://luxregina.com/portfolio/
@MLXXXp: The biggest contributor to the Arduboy Arduino Libraries also contributes to the magazine with small but useful tips and tricks - look for them with the light bulb icon!
@Pharap: Feel free to ask Pharap for help with things. He believes the three great programming virtues are laziness, impatience and hubris. https://github.com/Pharap
@Your name: This could be you.. Help contribute to the Arduboy Magazine!
Page 4 of 36
Arduboy
Company
news:
What’s happening at headquarters?
@Celinebins
FREE SHIPPING!
We are offering free domestic shipping, and 5 USD off international shipping with the code: SHIPFREE on checkout. Surprise your loved ones on Christmas with an Arduboy! Holiday Shipping Notice: To receive by Dec. 24 order by Dec. 6 for International and Dec. 18 for Domestic (USA).
Where to buy Arduboy? In order to better deliver the Arduboy to you, a distribution model for sales has been currently implemented. You can now purchase the Arduboy from a variety of different retailers from around the world!
New!
New!
Talk to us!
Page 5 of 36
W
ES AM G
by @jerjer So many new games were released this month! If you missed them on the community pages, here they are.
FR ES H
N E
PLAY:
That will get you hooked
Arduball@2BarrelShotgun
Basketball
In the description written by creator @2BarrelShotGun, Arduball is described as “a simple but difficult basketball game.” Upon installing and playing it on my Arduboy I can definitely agree with that description. Arduball, like all other games on this system, has to be boiled down to the most simple and entertaining elements. It’s a one player game, and your opponent is a hard-as-nails AI square. No worries though, because you’re also a square. You run and jump, propelling a ball towards your opponent’s “basket,” represented by a small circle in the upper right hand corner of the screen. The ball bounces all over the place and it can be tough to keep it under control.
game
There’s also a power up move I haven’t completely figured out, but it involves allowing a meter to fill up, much like the “turbo” meter in NBA JAM. Featuring fast-paced gameplay made ever more tense by the timer ticking down, you’ll be hard-pressed to win your first match of this game. Or second. Or 21st. I haven’t beaten it yet. But the gameplay is fun enough that I’ll keep trying. Video Review Link: https://youtu.be/ zTaDMq8HE4A
Especially when the AI square is very aggressively trying to do the same.
Bouncing @jesse
balls
Demo
This is more of a tech demo than a game. User @Jesse has allowed the operator to choose the number of “balls” bouncing around on the screen. Think of the behavior of a dvd screen saver and you’ll understand how the balls move.
I very quickly decided that I needed to max out the number of objects on the screen. The “cpu” meter on the right quickly grew with the increasing number of balls. Then my Arduboy froze. Whoops! But upon rebooting it, I was to be continued next page >> Page 6 of 36
able to get about 40 balls to move around without any slowdown. I’d love to see these physics used for some kind of action-puzzle game; the behavior of the bouncing balls reminded me of the Mushroom Boy minigame in Super Mario RPG on the SNES.
Humanity @giangregorioc
There’s balls bouncing. Now, what are we going to do with them?
Revenge
I’ve had this game for a few weeks and I must say, it is fantastic! It’s easily in my top 5 Arduboy games I’ve played so far, and I’ve played quite a few. User @giangregorioc has managed to cram an arcade-style space shooter onto the itty-bitty Arduboy while retaining fun gameplay and a really, really cool graphic style. This game has a lovely title screen, followed by the chance to choose your character! You have three ships to choose from, each with a power and a speed level between 1-3. The higher the level, the better that particular attribute.
Named after 3 Norse Deities, one character hits hard but moves slow. One character zips all over the place but the enemies become bullet sponges. Then there’s the balanced character with a 2 in both traits. I found myself using the fastest character, Freya, to great effect in spite of her weaker firepower. The ability to move and avoid bullets more efficiently was a winning gameplay choice. I would recommend this game to anyone with an Arduboy, it’s definitely a must-download. If you like any kind of space shooter like R-Type or Defender, you’ll love this game. Give it a try! Video Review Link: https://youtu.be/ Wxxc3PCl8BA
Mine
evolutions
@taniguchi
-
Minesweeper. For many people around the world, that word triggers a lot of memories. Memories of the first time you figured out how to play this stock Windows game. Memories of beating your first giant grid when no one else was around to see. Memories of quickly minimizing the window so your boss doesn’t know you’re goofing off instead of doing your job.
minesweeper User @taniguchi decided it was time for ‘ol Minesweeper to get a facelift. Enter Mine Evolutions, a robust Minesweeper clone with some extra goodies for puzzle game fans. You have the standard options of grid size and difficulty. The game tracks how long it takes for you to win/lose. So far so familiar. But then the Evolutions occur. The developer’s description video is all in Japanese, but from what I’ve gathered the Evolution mode allows to be continued next page >> Page 7 of 36
you to unlock money on the playing field. You then use this money for “Omikuji,” little paper strips with fortunes written on them. You can reveal fortunes ranging anywhere from a “Great Blessing” (dai-kichi, 大吉), to a “Great Curse” (dai-kyō, 大凶). If the developer or someone else ever decide to translate the literal meanings of the Omikuji it could be really fun to unlock all the paper strips through gameplay.
The @jesse
matrix
That text is important for this demo, because that text is this demo. That’s right, user @jesse has put the Matrix into your Arduboy! You can install this demo and those same cryptic, everchanging and glitchy characters will move down your tiny screen. It works exactly as it should.
@Ryan
Player
Personally, I’d love to learn more about the ancient tradition of Omikuji. In the meantime, I’ll just keep placin’ flags and blowin’ up mines. Video Review Link: https://youtu.be/ qlpE59j2OS8
demo
Do you remember the Matrix movie? Keanu Reeves is Neo, trying to save the world from an evil computer that uses people as batteries. At least I think that’s what it was about, I’ve also been told it’s a retelling of Creation Fables. To me, it was always about the leather trenchcoats and slow motion camera rotation. Oh yeah, and the computer monitors with the weird green text sliding down.
Two
This is definitely an evolution, because Minesweeper never allowed you to work towards a goal before by grinding.
tic
tac
If there’s one thing I’ve learned through all my Arduboy adventures, it’s that the little console is a great home for classic games. You’ll see old arcade-style space shooters, top-down adventure games that feel like Gauntlet, sidescrolling platformers that invoke memories of a certain plumber. You’ll see other classics
You can’t alter or control anything, all you can really do is watch the characters move. But maybe that’s good enough. Were you to use your Arduboy as, say, a fashion accessory... I can’t think of any cooler demo to have playing on your screen. Keep the Matrix in your pocket and impress your friends forever! Or wear it as an earring... somehow. The Matrix is your oyster. Video Review Link: https://youtu.be/ o7ePWggt78U
toe too, games that predate computers by centuries. Games like checkers, chess, solitaire, and even... Tic Tac Toe. Also known as Noughts and Crosses, it is arguably one of the oldest games in existence. You can play it with the most to be continued next page >> Page 8 of 36
powerful computer on the market. Or you could scratch it in the dirt with a stick, or on the condensation that builds up on the inside of a car window. Two Player games have never been so easy to learn. I think any 2 people in the world could play a game together without ever having to speak a word. In user @Ryan ‘s first game, Tic Tac Toe has been brought to the Arduboy in a fantastic 2-player adaptation. Settle bets and lose friendships over x’s and o’s. The creator has managed to produce a really clean interface, utilizing the indicator lights to great effect and even including a victory fanfare at the end of each match. @Ryan says his dad, also a member of the community, recently purchased him an Arduboy and he quickly set to work making a game. For now, 2 players are required to get the full enjoyment out of this game.
Ring
Puzzle
@SSNikolaevich
I played it by myself and it only made me sad not to have friends. But @Ryan says the next version will feature a computer AI opponent. Can you lose a virtual friend over tic-tac-toe? I’ll be happy to find out in the future. As for now, I’ll search the countryside looking for someone to play my Arduboy with me. A must-download. Video Review Link: https://youtu.be/1_YHwjfq9_c
Game
In my video review I mention this game was programmed on a plane. I seem to have misread the text, as the creator was saying the game was made while waiting for the Arduboy to travel over the ocean to them. Whoops! Needless to say, this is a full game that was made in Sim-Arduboy software and plays very well. User @SSNikolaevich has put a “T oroidal Topology” style game on the Arduboy that plays like a slide puzzle. Using the directional pad, you slide rows of tiles trying to reassemble them into a depiction of a looping, knotted pattern. At any point you can depress a key to view how the final solution should appear. I found this game to be pretty difficult initially, but could see how the gameplay could become addictive. Although the computer keeps track of the time you’ve spent solving the puzzle, your only real opponent is yourself.
Therefore, the game is only as stressful as you make it to be. I found it quite relaxing once I started taking my time and thinking about my moves in advance a little more. However, I never did successfully finish a puzzle. The interface is very well-polished and the title screen is beautiful. I would recommend this game to anyone who likes slide-puzzles, or just puzzle games in general. It’s free! Download it! Review Link: https:// youtu.be/ Dmtt02HcFbQ
Like game reviews? Be sure to subscribe to NintenDomain Podcast’s Youtube channel and be notified for any new videos!
Page 9 of 36
Make games!
Use fresh code!
Get social!
2n
Ardu Gam ja
5 Dec - 12
A winner will be chosen based on how complete the game is, how fun/unique it is, and how well it fits the theme. The winner will receive Arduboy Swag!
nd
uboy ame am
Win Prizes!
Help the community!
2 Dec 2017
Have fun!
The jam is all about creating something new alongside others and experiencing the creative process together. Join individually or as a team. The official theme of the Game Jam: Holiday! the theme is any holiday that you celebrate nondenominational or otherwise! You could theoretically make a birthday themed game if you want.
#ArduboyJam Page 11 of 36
Level: Beginner LEARN:
Steve the Jumping Dinosaur
- Part 2
by @filmote In part 1 of Steve the Jumping Dinosaur, we start to build a simple game based on the Google browser game that is available if you are offline; Steve the Jumping Dinosaur. These articles assume you have read crait’s series of articles that describe the process of setting up an Arduboy environment, writing
simple applications and culminating in the writing of your first game – the classic Pong! If you haven’t already read crait’s articles, stop reading this and do that first. Likewise, if you have read crait’s tutorials but not part 1of this article, please read that first.
Launching an Obstacle Steve the Dinosaur must avoid four type of obstacles - the single, double and triple cacti and a flying pterodactyl. These various obstacle types are enumerated in an enum called ObstacleType as shown below. The first three elements are self-explanatory - the two pterodactyl elements are used to represent
the animal (I was about to say bird but they were in fact reptiles!) with its wing up and down. Later we will see how we animate the image but for now you can ignore the second element, Pterodactyl2.
enum ObstacleType { SingleCactus, DoubleCactus, TripleCactus, Pterodactyl1, Pterodactyl2, Count_AllObstacles = 4, };
Unless otherwise specified, elements in an enumeration are assigned values starting from zero. In the enumeration above, the SingleCactus element has a value of 0 and the Pterodactly2 element has a value of 4. Although there are five elements, when we randomly launch objects there are only four types to choose from as the Pterodactyl1 and Pterodacytl2 elements describe the same thing. The element Count_AllObstacles is used to define the number of options available. Note that I have explicitly assigned it a value of 4. Enumerations do not have to
have contiguous element values and multiple elements can have the same values. The details of a single obstacle are stored in a structure as defined in the next page. In addition to the obstacle’s position, the structure also contains the object type, an enabled flag and a reference to the image that will be used when rendering it. As mentioned earlier, structures are a great mechanism for capturing related data together.
to be continued next page >> Page 12 of 36
struct Obstacle { int x; int y; ObstacleType type; bool enabled; const byte *image; };
At any time during game play, two or even three obstacles may be visible on the screen.
#define NUMBER_OF_OBSTACLES
To cater for this, I have created an array of obstacles and initialised them with default values. Note that all of the obstacles are disabled by default.
3
Obstacle obstacles[NUMBER_OF_OBSTACLES] = { { 0, 0, ObstacleType::Pterodactyl1, false, pterodactyl_1 }, { 0, 0, ObstacleType::Pterodactyl1, false, pterodactyl_1 }, { 0, 0, ObstacleType::Pterodactyl1, false, pterodactyl_1 }, };
When launching obstacles, we need to make sure that the obstacles are randomly placed but not too close together otherwise Steve may not be able to land between them and jump again. To facilitate this, we generate a random delay and store this into the #define LAUNCH_DELAY_MIN #define LAUNCH_DELAY_MAX
variable obstacleLaunchCountdown which is decremented each pass of the main game loop. When this variable reaches zero, a simple loop passes through the obstacles[] array looking for the first inactive obstacle in the collection.
90 200
--obstacleLaunchCountdown; if (obstacleLaunchCountdown == 0) { for (byte i = 0; i < NUMBER_OF_OBSTACLES; i++) { if (!obstacles[i].enabled) { launchObstacle(i); break; } } obstacleLaunchCountdown = random(LAUNCH_DELAY_MIN, LAUNCH_DELAY_MAX); }
The actual code to launch a new obstacle is shown below. The input parameter, obstacleNumber, defines which of the three obstacles in the array to activate. To help the player get accustomed to the various obstacles, they are introduced slowly as the player’s score increases.
The first section of the routine calculates which of the elements in the ObstacleType enumeration can be chosen based on the player’s score. When the player’s score is less than 100, only the single cacti is valid. When the player’s score is less than 200, the single and double cacti images are valid - likewise a score less than 300 allows all three cacti obstacles to be chosen. to be continued next page >> Page 13 of 36
Once the score exceeds 300 all obstacles including the pterodactyl are valid. If a pterodactyl obstacle is chosen then a flying height is randomly selected between an #define PTERODACTYL_UPPER_LIMIT #define PTERODACTYL_LOWER_LIMIT
upper and lower limit as defined by the two constants PTERODACTYL_UPPER_LIMIT and PTERODACTYL_LOWER_LIMIT. In contrast, cacti are all launched at ground level.
27 48
void launchObstacle(byte obstacleNumber) { // Randomly pick an obstacle .. ObstacleType randomUpper = ObstacleType::SingleCactus; switch (score) { case 0 ... 99: randomUpper = ObstacleType::SingleCactus; break; case 100 ... 199: randomUpper = ObstacleType::DoubleCactus; break; case 200 ... 299: randomUpper = ObstacleType::TripleCactus; break; default: randomUpper = ObstacleType::Count_AllObstacles; break; } ObstacleType type = (ObstacleType)random(ObstacleType::SingleCactus, randomUpper + 1); // Launch the obstacle .. obstacles[obstacleNumber].type = type; obstacles[obstacleNumber].enabled = true; obstacles[obstacleNumber].x = WIDTH - 1; if (type == ObstacleType::Pterodactyl1) { obstacles[obstacleNumber].y = random(PTERODACTYL_UPPER_LIMIT, PTERODACTYL_LOWER_LIMIT); } else { obstacles[obstacleNumber].y = CACTUS_GROUND_LEVEL; } }
Itâ&#x20AC;&#x2122;s worth pointing out the use of ranges in the case statement in the above example. Ranges must be specified in the format shown with three decimal points between them
and the ranges cannot overlap. Although this syntax is valid in the Arduino / Arduboy environment, it is not valid in most C++ implementations.
to be continued next page >> Page 14 of 36
Moving Obstacles The obstacles in our game move from right to left, one pixel per frame. The code below checks to see which of our obstacles are enabled and decrements their x coordinate by one. As the objects move out of view on the left hand side of the screen, they are disabled which allows them to be relaunched in the future.
We apply the same technique used to animate Steveâ&#x20AC;&#x2122;s feet to animate the pterodactylâ&#x20AC;&#x2122;s wings.
void updateObstacles() { for (byte i = 0; i < NUMBER_OF_OBSTACLES; i++) { if (obstacles[i].enabled == true) { switch (obstacles[i].type) { case ObstacleType::Pterodactyl1: case ObstacleType::Pterodactyl2: if (arduboy.everyXFrames(2)) { if (obstacles[i].type == Pterodactyl1) { obstacles[i].type = Pterodactyl2; } else { obstacles[i].type = Pterodactyl1; } } obstacles[i].x--; break; case ObstacleType::SingleCactus: case ObstacleType::DoubleCactus: case ObstacleType::TripleCactus:
}
obstacles[i].x--; break;
// Has the obstacle moved out of view ?
}
}
}
if (obstacles[i].x < -getImageWidth(obstacles[i].image)) { obstacles[i].enabled = false; }
Detecting Crashes The Arduboy library provides a simple function that detects the collision between two rectangles. To detect a collision between Steve and a cactus, the rectangular boundary of the images could be supplied.
The following code loops through the array of obstacles and test for collisions between Steve and enabled or active obstacles. The boundaries of each image are captured into a Rect object - a structure provided by the Arduboy library - and these use as parameters to be continued next page >> Page 15 of 36
in the Arduboy collision() method. If a collision or overlap of the two rectangles is detected, the function returns true. bool collision () { for (byte i = 0; i < NUMBER_OF_OBSTACLES; i++) { if (obstacles[i].enabled == true) { Rect steveRect = Rect{ steve.x, steve.y - getImageHeight(steve.image), getImageWidth(steve.image), getImageHeight(steve.image) }; Rect obsRect = Rect{ obstacles[i].x, obstacles[i].y - getImageHeight(obstacles[i].image), getImageWidth(obstacles[i].image), getImageHeight(obstacles[i].image) }; if (arduboy.collide(steveRect, obsRect)) { return true; } } } return false;
}
Hang on! This code isnâ&#x20AC;&#x2122;t the same as in the sample code. Right .. the reason for this is that the standard collision code works well for detecting head-on collisions between images that fill the majority of the rectangle they are contained within but performs poorly when trying to detect collisions between image corners or images that do not fill the entirety of their containing rectangle.
The code in the sample application uses a modified collision detection function that I have described in detail in the Arduboy Magazine which looks at the pixels of the images themselves rather than the containing rectangle to detect a collision. If you are interested, you can read this advanced article here.
This is shown in the example below. Although the Arduboy collision() function reports a collision, they are clearly not touching.
to be continued next page >> Page 16 of 36
Saving Scores The Arduboy includes a small amount of nonvolatile memory, known as EEPROM, which can store and retain information even when the unit is turned off. EEPROM is ideal for saving user settings, high scores and other information between sessions. EEPROM stands for Electrically Erasable Programmable Read-Only Memory but this is a misnomer as the memory can actually be updated. EEPROMs have a limited life and will eventually fail after they have been erased and rewritten too many times – this number may be in the millions of
operations but a poorly written program that attempts to use it as working memory could easily reach that. The EEPROM class provides three basic functions to read and write a single byte of memory, as shown below. The memory location can be anywhere in the 1Kb and equates to a value between 0 and 1023. The update() function differs from the write() function in that it checks the value to be written against what is already stored in order to minimize the number of updates thus prolonging the life of the EEPROM.
EEPROM.read(memory_location); EEPROM.update(memory_location, value); EEPROM.write(memory_location, value);
The library also offers two other functions that can save and retrieve datatypes other than a byte, such as a float, integer or even a structure. EEPROM.put(memory_location, value); EEPROM.get(memory_location, value);
Using these functions, we can save Steve’s top scores. We can save it anywhere in the 1Kb range however the first 16 bytes are reserved for storing Arduboy system details including the current sound state (on / off), the unit name and other bits and pieces.
The Arduboy library defines a constant, EEPROM_STORAGE_SPACE_START, which indicates the first memory location free for user information. The code below allows us to save and retrieve Steve’s score into the lowest available EEPROM memory location.
EEPROM.get(EEPROM_STORAGE_SPACE_START, highScore); EEPROM.put(EEPROM_STORAGE_SPACE_START, highScore);
Depending on what other games we have been playing previously, these memory locations may contain invalid data that can cause an error or, at worst, report unrealistically high scores. To overcome this, I like to store two fixed characters in front of my application’s data. When the application starts, it checks in the EEPROM memory for the two characters and if it does not find them clears out the memory it plans to use. It then populates the two characters so future checks do not clear the score again. This is achieved using the following code in the next page:
to be continued next page >> Page 17 of 36
#define EEPROM_START_C1 #define EEPROM_START_C2 #define EEPROM_SCORE
EEPROM_STORAGE_SPACE_START EEPROM_START_C1 + 1 EEPROM_START_C1 + 2
void initEEPROM() { unsigned char c1 = EEPROM.read(EEPROM_START_C1); unsigned char c2 = EEPROM.read(EEPROM_START_C2); if (c1 != ‘S’ || c2 != ‘T’) {
}
}
EEPROM.update(EEPROM_START_C1, ‘S’); EEPROM.update(EEPROM_START_C2, ‘T’); EEPROM.put(EEPROM_SCORE, (unsigned int)0);
Putting it all together So far we have delved into the details of creating an endless runner game. We have moving ground, a moving player and random obstacles to avoid. If we do hit an obstacle it can be detected and we can save our best scores into EEPROM for posterity. But how do we put it all together?
In the final part of Crait’s lessons, Make Your Own Arduboy Game: Part 7 - Make Pong From Scratch!, he discusses a ‘state machine’ pattern for controlling the flow of a game between introduction screens, the actual game play and game over screens. Our game uses this exact same concept with a minor change – the gameStatus variable that holds the current state is defined as an enumeration which in turn makes the code more readable.
GameStatus gameStatus = GameStatus::Introduction; void loop() { … switch (gameStatus) { case GameStatus::Introduction: introduction(); break; case GameStatus::PlayGame: playGame(); break;
}
}
case GameStatus::GameOver: gameOver(); break;
The main loop() is intentionally kept clean and all work is done by discrete functions. The introduction() function performs the single task of displaying the introduction screen and waiting for the user to start a game.
Before completing it updates the gameStatus variable with the next state – in this case GameStatus::PlayGame. On the next pass through the main loop(), control will pass to the playGame() function. to be continued next page >> Page 18 of 36
void introduction() { EEPROM.get(EEPROM_SCORE, highScore); arduboy.clear(); initialiseGame(); arduboy.setCursor(17, 12); arduboy.print(F(“Press A to begin”)); drawGround(false); drawSteve(); drawScoreboard(false); arduboy.display(); if (arduboy.pressed(A_BUTTON)) {
}
}
gameStatus = GameStatus::PlayGame; steve.stance = Stance::Running1;
I encourage you to review the structure of the code taking note how control is passed between the functions using the gameStatus variable. Digging into these functions will reveal the snippets of code we have discussed above and they should be quite recognisable.
Maybe some different obstacles – you could simply replace the images or you could add new obstacles by creating images, adding the new types into the ObstacleType enumeration and changing the launchObstacle() function. Why not add a caveman with a big club?
Finally, what could you change to make this version of the game your own?
You can download the finished game here. Have fun and watch those pterodactyls!
to be continued next page >> Page 19 of 36
Level: Beginner
Good Coding Habits
Part 2 - Good Formatting by @Pharap Foreword:
Introduction:
Hello readers.
This second part is about using good formatting. Once again this is something beginners sometimes struggle with, and equally something experienced programmers let slip due to laziness or time constraints.
As before, this article is mainly aimed at beginners, but I’d recommend reading it even if you aren’t a beginner because frankly everyone is capable of writing messy code and it’s good to be reminded of that from time to time. This time the article is going to be focusing more on form than contents. Having meaningful names is all well and good, but even the best variable names in the world would be useless if they are strewn across the page like a Jackson Pollock painting. (Spoiler: I’m not a fan of Jackson Pollock paintings.) And so begins part two...
Visual structure is important in all languages, not just programming languages. Without spaces, paragraphs and punctuation we would all be struggling to discern great walls of text (which admittedly Japan seems to manage by some miracle). Programming languages don’t just have symbols and braces for the sake of the language, they’re also there as a tool for the programmer to keep the code nicely formatted and by extension keep the code readable. So in this article I’m going to be discussing formatting in an attempt to save the world from messy code.
Tip 1: Format your code wisely Even with short functions it’s possible to end up with code that looks cluttered. Sometimes people write code that ends up being quite squashed up and hard to read because they don’t use blank lines, spaces or brackets to keep their code neat. This tip comes with a few little ‘rules of thumb’ to help you do this:
• Make sure operators have spaces around them. • Break a line up into smaller logical chunks if it’s too long. • Use brackets to separate expressions when appropriate. • Use well named variables to store intermediate results. I think this tip and its rules are best expressed by example, so here’s some code:
bool intersects(Point point, Rectangle rectangle) { return point.x>=rectangle.x&&point.x<rectangle.x+rectangle.width&&point. y>=rectangle.y&&point.y<rectangle.y+rectangle.height; } It works perfectly and everything is reasonably well named, but it’s still hard to read because it’s being let down by the way it’s formatted.
So to make it better, I’ll apply the rule “Make sure operators have spaces around them”, which results in this:
to be continued next page >> Page 20 of 36
bool intersects(Point point, Rectangle rectangle) { return point.x >= rectangle.x && point.x < rectangle.x + rectangle.width && point.y >= rectangle.y && point.y < rectangle.y + rectangle.height; } It’s not brilliant, but it’s a start – at least now it’s clearer what operators are being used. If you squint you can probably make out a couple of comparison operators, some and-operators and some addition operators.
Next I’ll apply the rule “Break a line up into smaller logical chunks if it’s too long”, which results in this:
bool intersects(Point point, Rectangle rectangle) { return point.x >= rectangle.x && point.x < rectangle.x + rectangle.width && point.y >= rectangle.y && point.y < rectangle.y + rectangle.height; } Now it’s getting somewhere. From this it’s now clear that the function is returning the result of a long conditional expression made up of four smaller conditions.
But it could still be better, so next I’ll apply the rule “Use brackets to separate expressions when appropriate.”. Of course ‘when appropriate’ is open to interpretation and different people will have different opinions of when that is, but usually you’ll be able to tell what you think looks better. In my case, I think I like the look of this arrangement best:
bool intersects(Point point, Rectangle rectangle) { return (point.x >= rectangle.x) && (point.x < (rectangle.x + rectangle.width)) && (point.y >= rectangle.y) && (point.y < (rectangle.y + rectangle.height)); } I could have decided I only wanted to put brackets around the addition parts, or I could have gone further and put in more brackets, but I think this is a suitable balance. Here there is no ambiguity as to what the order of the operators are and there aren’t so many brackets that the code is overloaded with them. Normally I would be perfectly happy with this arrangement, since I think it looks clear and easy to maintain.
However more experienced programmers (like me) sometimes take for granted that code like this isn’t as clear to beginners as it is to us, so we tend to settle for something halfway between minimalism and verbosity. Truly, most experienced programmers would be able to understand this However, there is more that could be done to make this code more understandable, and I want to take it a few steps further so I’m going to apply another rule, “Use well named variables to store intermediate results.”
to be continued next page >> Page 21 of 36
bool intersects(Point point, Rectangle rectangle) { const int rectangleLeft = rectangle.x; const int rectangleRight = rectangle.x + rectangle.width; const int rectangleTop = rectangle.y; const int rectangleBottom = rectangle.y + rectangle.height;
}
return (point.x (point.x (point.y (point.y
>= rectangleLeft) && < rectangleRight) && >= rectangleTop) && < rectangleBottom);
Adding meaningful variables can make code a lot easier to understand in some cases. In this case, the variables now make the code’s functionality a lot clearer. Before the change it might not have been as obvious, but now it’s clear that rectangle.x was actually the left side of the rectangle and rectangle.x + rectangle.width was actually the right side of the rectangle.
So, I’ve applied all the rules, but actually, I think there’s one more thing I’d like to change before I’m happy with this.
bool intersects(Point point, Rectangle rectangle) { const int rectangleLeft = rectangle.x; const int rectangleRight = rectangle.x + rectangle.width; const int rectangleTop = rectangle.y; const int rectangleBottom = rectangle.y + rectangle.height;
}
return ((point.x >= rectangleLeft) && (point.x < rectangleRight)) && ((point.y >= rectangleTop) && (point.y < rectangleBottom));
One of the rules is “Group code logically.”, and in this case I think using less lines and extra brackets actually makes the code more understandable. Here not only can you see what the comparisons are, but it makes the bigger picture clearer. The first part of the return statement is checking whether point.x is between the left and right sides of the rectangle, and the second part is checking whether point.y is between the top and bottom sides of the rectangle. In fact, I think that’s actually quite a good definition for what it means for a point to be intersecting a rectangle. When you write it clearly enough, code can actually be pretty similar to a description of what it does.
As I said before though, this is probably more descriptive than what you might find in production code (even very high quality production code). This is the other end of the scale, where great effort has been put into making the code extra readable. More advanced programmers probably won’t write like this unless they’re specifically writing code for educational purposes or want their code to be especially clear. Good use of space can make the difference between code that’s easy to read and code that’s too messy to make sense of. Sometimes it’s alright to break these rules, especially if there’s a measurable difference in code size or speed, but if you do, please comment your code to explain what it does.
to be continued next page >> Page 22 of 36
Tip 2: Keep formatting consistent A lot of different people write their code with different formatting styles. This is a fact of programming and it won’t be changing any time soon. In fact it’s so notable that there’s an entire Wikipedia article about different ways of placing braces and indents in code (according to which my preferred programming style is called ‘Allman style’ after Eric Allman).
I won’t sit here and discuss the different brace styles since there are a lot of arguments for and against each of them, and frankly I’m biased anyway. I will however give you a sample of four of the more popular brace styles:
// K & R style // named after Brian Kernighan and Dennis Ritchie // the authors of “The C Programming Language” // Dennis Ritchie created C int main(int argc, char *argv[]) { while (x == y) { something(); somethingelse();
// “One true brace style” (origin unknown) int main(int argc, char *argv[]) { while (x == y) { something(); somethingelse();
} }
if (some_error) do_correct(); else continue_as_usual();
}
finalthing();
finalthing();
// Stroustrup // named after Bjarne Stroustrup // the author of “The C++ Programming Language” // and the creator of C++ int main(int argc, char *argv[]) { while (x == y) { something(); somethingelse(); if (some_error) { do_correct(); } else { continue_as_usual(); } } }
}
if (some_error) { do_correct(); } else { continue_as_usual(); }
// Allman style // named after Eric Allman // the creator of sendmail and syslog int main(int argc, char *argv[]) { while (x == y) { something(); somethingelse();
} }
if (some_error) do_correct(); else continue_as_usual();
finalthing();
finalthing();
to be continued next page >> Page 23 of 36
There’s nothing wrong with preferring a certain style, but it’s important to be consistent when writing code – which means picking a style and sticking to it. You don’t have to use the same style all the time; in fact, being able to switch between styles is a good skill to have (one I admit I struggle with).
However it’s important to keep individual projects in the same style.
Summary Formatting isn’t just aesthetic, it serves an important purpose. Good formatting can be the difference between readable code that is easy to maintain and code that is difficult to read and thus hard to make sense of. Some of you are probably thinking “but nobody else reads my code”. That doesn’t matter though, because even if it’s only you reading your code it can still cause issues. If you stop working on a project for a while and then come back later only to find that you can’t read or understand your code then you’ll only have yourself to blame (and that’s never a fun experience).
Worse yet, if your code isn’t well formatted then you’re not only making it hard to read, you’re also making it hard to spot bugs. If you’ve got a stray increment floating around the page it could be the difference between spotting a bug immediately or sitting there scratching your head for three hours. I liked having a quote to end on last time, so I went out and found another one (albeit a less famous one): “A developer who doesn’t car about style is like an artist who doesn’t care about colour.” Brian Ensink, Stack Overflow.
Did this article help you as a beginner, or reminded you of good coding practices? Start a discussion in our community!
What will be exact size of a full-screen pic in the Arduboy’s native format? The Arduboy screen resolution is 128x64. Graphics are 1-bit bitmaps, and there are 8 bits in an Arduboy byte so that’s (128 * 64) / 8 bytes, which is 1024 bytes (1 KB). The Arduboy has 32KB of progmem, 4KB of which is taken up by the bootloader, leaving 28KB, so a full screen image is 1/28th of the memory available for code and read-only data. However, a screen image can be compressed when stored in program memory. If you decide to use compressed images, the number you can store will depend on the resulting compression ratio. The compression ratio of each image will depend on the compression technique used and the contents of the image. (And remember that 28KB has to contain code as well, so it’s less than 28 full screen images. The more code and other data there is, the less images there will be room for.)
Page 24 of 36
In this segment of the magazine we feature work from pixel artists. Do contact them if you would like to work with them or use their work. Their contact information is listed below.
Chiptune musican @Mr_Y started making pixel art on the ZX Spectrum computer. He recently took up the challenge to make some art with Arduboy’s limitations. Even though he calls his style “trashy” or “glitchy”, it won praise from some members in the community who likened it to Reg Mombassa’s work (shown on right). His secret? Sketching it on paper beforehand.
Artisit: @Mr_Y Chiptune / micromusic / 8bit music / lo-fi. Website: yerzmyey.i-demo.pl/ Are you a pixel artist? Done some Arduboy Fan art? Wish to have your work shared with the Arduboy community? Send arduboymag a message through the Arduboy community page or a DM on Twitter!
Level: Beginner
Tutorial series
Hello, I’m Cyril Guichard, also known online as @Luxregina. I’ve been doing art for video games since 1999. My first game then was strangely like the one I’m currently developing for Arduboy. It was called “the adventures of a footman in Azeroth” and was very heavily inspired by the graphics and lore from Warcraft 2. The player was controlling a human soldier through a maze, trying to find the exit while fighting Orc soldiers. It wasn’t a very complicated game, but it was my first one and I did both the art and the programming, using Flash and Actionscript 1.
To understand how the assets were made, I looked at the Warcraft spritesheets and tried to replicate them with my own graphics. The game still looked a lot (way too much, actually) like Blizzard’s blockbuster, but with this approach, I learned how to prep my assets so that they would be game ready. And that would be my first advice to any aspiring pixel artist: don’t think you can just make art – you must understand how your assets are going to be used in game, what are the limits of the game engine you are designing for, etc.
Base rules: Avoid jaggedness The first thing to understand about Pixel Art is that it is about controlling what pixels are used and where. That means that Pixel Art isn’t very friendly to freehand drawing. That doesn’t mean that you absolutely cannot freehand, but you will most likely have to edit that drawing to remove unnecessary pixels. There are tools, like Piskel, that provide you a better pipeline and tools to create Pixel Art, but I seldom use them: I’ve been using Photoshop professionally all my life, and it’s still my tool of choice for Pixel Art.
Left is a curve drawn freehand. You can see that some pixels are “doubled” (marked in red in the middle figure). Drawing correct pixel art is about removing those unnecessary pixels, as shown on the figure on the right, to remove the “jaggedness” of the left curve. to be continued next page >> Page 26 of 36
Likewise, drawing lines in pixel art is less straight-forward than it seems:
Just like for the curves, when drawing a line in pixel art, one must pay attention to where the pixels fall, or the line will most likely look jagged. As a rule of thumb, you want to pixel progression of your lines to be consistent: on right of the figure on the left column, you can see various lines with steady pixel progression: 2pixels up+1 right, 1 pixel up+1 right for a diagonal, etc.
Left is a line drawn with little consideration to the pixels. On the right, various lines drawn while paying attention to the pixels repartition.
When I work on a new pixel piece, I usually start with a template that I made that includes a collection of pixel-correct curves and lines, so that I don’t need to reinvent the wheel every time.
Base rules: Understanding dithering With Arduboy, you get black and you get white, and nothing else! That means that if you want some form of grey, you will have to use what’s called dithering. Dithering is about creating shading by interlacing different patterns.
By cleverly manipulating the pixel density in each pattern, you can achieve various levels of grey scales. Keep in mind that dithering adds significant visual complexity and clutter on a screen as small as Arduboy’s, so use it wisely.
The usage of patterns with various pixel density will give you better, fuller greys than the random noise method. to be continued next page >> Page 27 of 36
Base rules: Learn how to pack a sprite sheet The secret of making good sprite sheets is to understand how they are used. Note: This section is not specific to Arduboy: the necessity of sprite sheets become less relevant when the graphics need to be converted for usage.
For that reason, positioning and spacing are extremely important: if you are going to extract the different elements of a sprite sheet with code, you will want to make sure that all images are spaced evenly in your sprite sheet.
Usually a sprite sheet is a collection of images that will be used in game. They are often cut directly though code, or displayed through a mask to only show the image that needs to be displayed.
An example of the sprite sheet for a nonArduboy game. Each sprite is arranged on a grid which units are 8x8. This make it easy to grab the images through code: I know that the first image coordinate in 0,0, the second is 8,0, the third is 16,0 etc.
Base rules: Favor visual clarity This last basic rule may be one of the toughest to apply on Arduboy. Pixel art is about showing complex shapes at a tiny size. Because there is just black and white, when designing for Arduboy, one cannot rely on color to convey and organize visual information.
When designing your game, temptation to have intricate details will be great! But ultimately, always think on how you can simplify the visual information: with no color, intricacy will invariably become visual clutter. And on a tiny screen, clutter doesnâ&#x20AC;&#x2122;t look too nice.
In our upcoming game, Dark&Under we abandoned a visually intricate wall set because it ended being difficult to read on the Arduboy screen.
to be continued next page >> Page 28 of 36
Project Post Mortem: Dark & Under Being the happy owner of a Arduboy, I really wanted to make a game for the device. I looked at simple, old-school games that could be executed within the constraints of the device. I remembered playing Wizardry 1 or Eye of the Beholder back in the day and thought “This could be a fun Arduboy game!” There were two main challenges on porting this type of game on Arduboy: the limited controls and the very tiny screen with a low resolution. This meant that I would need to really boil down the gameplay to its fundamentals. I started by designing the main interface, and all information that would need to be included. I decided to sacrifice some screen real estate for a permanent minimap to make the maze navigation easier. The interface established, it gave me a clear indication on how much room I had left for my graphics. I researched how I would lay-out the walls, and even coded a small prototype in JAVA to make sure the way I was approaching the art would work. A lot of attention went into designing the enemies: particularly since we didn’t have enough room to store multiple wall sets, we would need to rely on enemies’ variety and the fight system to give players a sense of progression. Hopefully, Arduboy users will enjoy their experience with Dark & Under when it comes out later this month.
Did this help you with planning for your next game? If you’d like to see more of this, drop us a message on Twitter! Page 29 of 36
Community:
Arduboy-on-a-NES-cartridge by @uXe Community member, @uXe created an Arduboy-on-a-NES cartridge. It even got picked up by Hackaday! Read the article here.
Arduboy’s screen buffer and translating it into tiles to be displayed on the NES is just a matter of shifting data around in RAM from the 2560’s perspective.
On the NES side, some code was written that simply displays these tiles on screen, and also reads input from the NES joypad and stores the button states into an unused byte of CHR-RAM for the 2560 to access.
How was it done? A basic NES cartridge just has two ROM chips - one for the program (PRG), and one for the character / tile data (CHR). A shield for the Arduino Mega 2560 that substitutes two dualport RAM chips in place of these ROM chips was designed, and a breakout board to connect the necessary signals to the NES cartridge port. The 2560 accesses the CHR-RAM chip via its built-in XMEM (eXternal MEMory) interface, which means that taking the
The tiles are being continually updated by the 2560 from the Arduboy screen buffer, all the NES has to do is display them. The NES program code is stored in PROGMEM and uploaded to the PRG-RAM chip on start-up. PRG doesn’t have to be dual-port RAM though, it could just be an EEPROM, but it made testing easier. Sound is just a single Arduino pin going through a resistor into a pin on the NES cartridge port that is commonly used for feeding in external audio (EXP6). Of course you could also forget the Arduboy screen buffer entirely and write new Arduino libraries to use the ‘traditional’ tile system of the NES. If you’d like to find out more, or have questions, reach out to uXe in the community thread here. What’s next? To play Arduventure on it!
Page 31 of 36
EXPLORE:
In this section we’ll ask the same questions to a different developer in every new issue.
Questions with game developers by @Widehaslet
This issue we interview @obono! Developer of addictive side scrolling game - Hollow Seeker; voted one of the Top 5 games by the Arduboy community! Recently launch a new game, Hopper, we sit down with Obono to find out more..
1. Where did you find out about Arduboy the first time?
4. What do you read to learn how to code for Arduboy?
By this article: http://nlab.itmedia.co.jp/nl/ articles/1403/04/news131.html
t-miyajima blog: review of Arduboy, how to install, etc. http://dvorak55.hatenadiary.jp/ entry/2016/05/15/002427
2. What is the first program/game you created for Arduboy? Displaying characters of Smile BASIC.
Qiita: Use Visual Studio for Arduboy development https://qiita.com/hisadg/items/ b20a263f56f351b96a14 Qiita: About ArduboyPlayTune https://qiita.com/bkzen/items/ bb8e78008b892d790380
5. What app/game do you currently have on your Arduboy.
3. Did you have app / game development experience before Arduboy? Yes. Languages: BASIC, C, C++, Java, and so on. Platforms: Windows, DoJa (Java profile for Japanese cell-phone), Android, Smile BASIC (Nintendo DS & 3DS), PICO-8
I have 2 Arduboys. “Hopper” is on the yellow one, and a WIP game on the green one.
6. What app/program is your favorite? Tiny 2048 by @akkera. http://akkera102.hatenablog.com/ entry/2016/02/20/224847
to be continued next page >> Page 32 of 36
7. What is the next app/program for Arduboy we can expect? I’d like to develop a puzzle game…
8. What app/game would you love to see on the Arduboy?
10. What is your best tip for other people who want to start creating apps/games for Arduboy? Since it is cheap resolution and less memory size, your unique idea will be very important and deserve to be realized. Want to find out more on @obono’s work? Visit his website here
Something like “Devil Dice” of PSX.
Are you a developer and want to be featured here? Reach out to the Magazine through Twitter DM @arduboymag
Community:
ME is eye (Playful game) by @taniguchi
Having trouble expressing yourself? Community member @taniguchi has come to your rescue with his playful “Me is eye” sketch. The instructions are pretty simple: Please play with your face.
Your Arduboy will display an eye, and use the 6 buttons to express your feelings Heart, Sparkle, Roll Eye, etc. Help emote yourself here!
Kevin jokes that it is an improvement of his paper prototype that helps you get some Zzzs at work. Page 33 of 36
Community:
Deluxe Edition Virus LQP-79 Arduboy by @Keyboard_Camper How was it done? Community member @Keyboard_Camper made his own limited edition Arduboy packaging for TEAM a.r.g.’s popular Virus LQP-79 zombie shooting neighbor saving game.
What’s next? The next time the Arduboy team does a limited edition run, it seems like they should approach Keyboard_Camper for some advice!
The packaging was a cool metal casing and contained printed instructions and story line in Arduboy sazed cards. If you’d like to print your own Deluxe Edition, you can download the PDF here.
Would you make your own limited edition Arduboy for your favorite game?
Page 34 of 36
#arduboy: Arduboy
is
Monochrome!
Some argue that Arduboy’s charm is it’s monochrome screen. Others say it makes for simipler programing. This month we celebrate it’s monochrome screen with some b/w photography!
@mintymintendo
@brzezinskitv
@ oritakemura
@samstpg
@ jnzer0p
@ raptordevitesse
@ raptordevitesse
@brzezinskitv
@gatkinphoto
Post your photos with Arduboy on Instagram and Twitter with #arduboy. We want to feature them in this segment! Page 35 of 36
Thank
you!
Thank you for reading the Magazine! Hope you enjoyed it as much as we did putting it together. We want to know how to make Volume 12 better than the last, so write in to us to tell us what you think!
https://twitter.com/arduboymag