Jump to content

Leaderboard


Popular Content

Showing most liked content on 09/15/2020 in all areas

  1. 2 likes
    So, last Monday I started a little game project as an excuse to experiment with my ConsolePaint library for .Net, but also as an exercise for a much more ambitious project later (which will be fully retro). For this occasion, I thought I'd replicate one of my favourite games of the NES; Tetris, but with a twist; the user should be able to create his own difficulty by directly modifying drop delays, game execution speed and the rate at which the game becomes faster (and thus, more challenging). There are a couple of challenges in doing a game in the console terminal: Printing characters to the console window is slow. Refreshing the screen is even slower and just printing the characters on new lines wouldn't entirely sell the illusion of a piece moving. You can only use characters when using the terminal, so no graphics (duh!) In this case, the "user interface" needs to be user friendly enough so that anyone can play and alter the game variables without having to remember the command names. There needs to be some kind of sound for tetrises and background music. I couldn't really solve the first problem since .Net doesn't have any way to hijack the console screen buffer like in C++ with windows.h, so I ended up trying to minimize as much as possible calls to Write and WriteLine by only writing and rewriting in precise areas of the screen by repositioning the cursor. Because some areas of the screen are only drawn once or occasionally, it saved some execution time. This did more to solve the second problem than the first one actually, since it entirely got rid of the slow refresh problem you'd get with the Clear method. First shot shows the areas where the characters are only printed once on the screen. Second shot shows areas which are only reprinted when the information needs to be updated. So the thing with Tetris is that the game is basically just squares on a screen. You don't need to be particularly fancy with the graphic design and people know this (except maybe the folks who made Tetris Effect haha). However, I still wanted to use the most out of the character set to make it as pleasant to the eye as possible. This is where the lack of graphics really hurts because the .Net console only supports 16 colours and a limited set of characters. I did notice also that the pieces in classic nes Tetris actually don't always use the same palette and appearance, so I at least wanted to include alternating colours and use fun characters as alternative tetromino blocks. However, after I started showing pictures on a few discord groups and to friends, all were unanimous that the special characters HAD to go and at least half of them found the colours jarring and too much to process. That made me sad because I really liked the fun character set and I sincerely thought the colours made the experience better. But I aim to please everyone, including I. So what I ended up doing is making those things optional; they can be turned on and off in the game settings. The above screenshot shows a game where the special characters are disabled with colour enabled, this one below is the reverse. These options are not mutually exclusive by the way; you can have grey bland tetrominos or colourful tetrominos using the fun characters. "The fool did not see that he was not Tetris ready. He was severely disappointed!" Now, there remains the case of the GUI. If I was going to write code for something which wouldn't make people flee, it would take a while. Remember earlier when I wrote that I was looking for an excuse to use my ConsolePaint library? Well, I put it to good use. All these rectangles on the screen were "drawn" by it, I just called the right methods and it wasn't even something I had to worry about. The library can draw all sorts of different borders too and initially I tried a more varied design until I ended up with what we have now. I also used that library to draw a picture on the screen so that the main menu didn't look too empty. What I did first was to draw some quick pixel "art". The colours of the image were converted to the 16 colour palette of the .Net console and then the pixels were converted to characters. Although in this case, the conversion was probably not needed. The image I drew: The result: You may be surprised to see that I named my Tetris clone "Retro Tetro Pro". That's actually because the name Tetris is trademarked. Maybe I'm being overly cautious, but I want no trouble for a game which only a few number of people are going to play. I'm not going to talk to much about the user friendliness of the GUI, I think navigating the menus with the arrow keys and pressing enter is a pretty obvious design choice. However it may or may not surprise you to learn that I didn't use a switch statement or if statement for handling user choices in the menu. That would have been too long and tedious! Instead I chose to put some actions in an array and the arrow keys actually increase or decrease an index which is used to call those actions. I wish I had thought of that before. Strictly speaking of design though, the only thing I consciously thought about for more than one second is how to give an obvious visual cue that a value is being increased or decreased. I chose to print a green upward triangle when the user is increasing a value and red downward triangle when the user is decreasing the value. You can see more of the GUI and the effects the options have on the game in this little demonstration video: https://www.youtube.com/watch?v=MuE_L0-kAlI Those who went ahead and watched the video will notice that the game only plays a sound when its in the menu... That's actually a reflection of the how bad it is to use sounds in .Net. There was nothing I could do to really play music or fun sounds without it being a huge pain in the neck. I tried several solutions and ways to circumvent the problem, but the tools .Net comes with are insufficient for a pleasant experience. I figure if I have enough time and motivation in the future that I'll have to use a custom sound library with .Net bindings; Beeps are too annoying and trial-and-error based to be practical and the SoundPlayer is incredibly frustrating; it has its own little thread and it does its own little thing, so no way to directly interact with it or do "complex" algorithms like having a playlist of music or playing consecutive sounds. It plays the tune until its over or until the process is dead and sometimes its stop method inexplicably doesn't work. Also there's no way to tell when the SoundPlayer is done... not mentioning several limitations like being limited to playing wav files out of anything. At this point, I was a bit tired of working on this project and anyways, to me, one of the rare people on earth who does not enjoy music due to a medical condition, it was the least of my priorities. Thus, I felt it was a job well done and decided to release the game to a slightly wider audience with the bugged music player (I ended up removing the music altogether in the new version because the obsolete wav files made the download too large). I haven't gotten a lot of feedback yet because well... it's a Tetris clone. Everyone and their grandmother has both played and made it before. So I can't tell you if it was a success from the point of view of others. But I can tell you I'm satisfied with what I came up with despite the fact that I wasn't able to solve every issue I had. I learned a lot of things by putting myself to the challenge of making it work in the terminal window and it was a pretty interesting experience which I don't regret. Thank you for reading this post. And if you try Tetro Retro Pro, thank you once more, it makes me incredibly happy that it will not all be merely for showing off and experimenting. You can download the game here. Arrow keys to move and z to rotate.
  2. 1 like
    Ren leaned on his broom as he wiped the sweat from his brow, starting to breath a little heavier from behind his mask. He had greatly underestimated how much garbage his little maneuver would unearth, revealing several months worth of trash buried under layers of sand and algae. Nature had done her best to reclaim the filth, causing the heap to stink like an open grave. He had already filled most of his garbage bags, but the mountain still towered as high as it did when it was created. “Damn, having a Quirk powered by breath does not suit picking up garbage at all,” Ren thought as he tried not to gag as the smell crept through his mask. Mouldering soda dregs and leftover sandwiches had mingled with the tainted sea foam, creating a miasma that he swore he could see rise from the ground like spirits of the underworld. As he leaned on his broom as he regained his composure, he heard the voice of a fellow classmate from behind him. "Hey! Figured you could use a bit of help here with Mt. Garbage." Ren turned to see that Benjamin had already begun filling a garbage bag, with his writhing army of spiders carrying away spent batteries and empty lighters into another spider silk basket. “O’Hara-san, thanks for the help!” Ren replied with a sheepish smile from behind his mask, “I may have taken more than I can handle. I wasn’t expecting the stench to be so bad.” At first, Benjamin did not notice the smell of the dreg heap, but the moment a sudden shift of the wind delivered the scent to him, he immediately started coughing. “J-Jeez...okay...the saying is one man’s trash is another man’s treasure...but I don’t think any treasure can be found with that scent...ugh…” Ren made his way to Ben, tiptoeing around old food wrappers, handing him his extra mask. “Here, it helps with the smell a bit. Hopefully your spiders don’t mind the smell.”
  3. 1 like
    I've heard this a few times and it never registered it was a meme until now, 7.5/10 so is this Ocean Man's unevolved form? 5/10
  4. 1 like
    "Heeey, Omurice!" Me? Yumi glanced around. Nobody else particularly close by. Must have been her, then, but why omurice? "You look bored, so, how about..." Yumi watched as Tsubasa kicked a can through the air, landing it cleanly into a bin over in that direction. "So, come on. Want to try it out? You got long legs so I'm sure you can get some good kicking distance with them." Well, it wasn't like having a bit of fun would slow her down, right? "Sure. We'll see who can get the most cans in." Competition also never hurt. Yumi looked at the trash around her, stabbing her picker through the first can she found, and sliding it off to rest on her shoe, before swinging her leg forward, sending the can careening through the air. It landed on the rim of the trash can, wobbling in the balance for a moment. The keen observer would see a very small flash of electricity in the air between Yumi and the can, giving the can the final little push it needed to fall into the trash can. "That's one," Yumi smiled, picking up other nearby trash and putting it into the bag she'd been dragging around as she kept her eyes open for more cans to kick away. "Using my Quirk's all about accuracy, so don't expect easy pickings off me."
  5. 1 like
    Yoooo welcome welcome @ass looks like you're gonna be stuck with this name bro
×
×
  • Create New...