TINS Logo

Welcome, new user. Please log in or register.

Eric Thu 31 Dec 20, 04:22
(This post is marked spoiler. It will be hidden for some viewers)

I spent a short time today doing some last-minute experimentation. I mainly toyed with reducing brightness of certain elements in-shader to enhance the lighting effect. It worked quite well, but broke some color tinting. I also wanted to further reduce color banding by producing the lights' gradient in a shader, as well as possibly experimenting with dithering, but I simply lack the time. So the version of the game as already submitted will have to suffice.

Here are some things I wish I had done:
- Drew yellow elephants.
- Fixed that lingering collision bug.
- Refactored the global file some more.
- Added a main menu screen, complete with credits.
- Prevented the player from occasionally cheesing their way to victory.
- Added power-ups (like an extra hit or a more powerful snowball that shoots through multiple targets).

Here are some things I am proud of:
- Poor man's bitmap font.
- The general art style and "wiggling".
- Hue-rotation after hitting a special heart.
- All the little procedural animations (bouncing, shrinking, and bobbing).

The original deadline was Thursday at midnight, but seems to have been changed to Friday instead. I don't know why it's been changed, but I'm sticking with the original date. The data and source, along with any and all future commits, can be found on GitHub: https://github.com/ecj2/yukidaruma. Additionally, the game can be played in your Web browser on my site: https://thardus.xyz/yukidaruma.

Eric Sat 26 Dec 20, 04:29
(This post is marked spoiler. It will be hidden for some viewers)

That's a wrap! I did another round of refactoring, and now my game is (seemingly) complete! It fulfills the recipient's wishes (at least by my loose interpretation), and accomplishes most of what I set-out to do. I may tweak it further, or I may not. I'll submit it soon.

Now for something a little silly. In Poyo, my game-making library, when you render bitmaps in a batch, the last texture sent to the batch is used for all instances of said batch. While doing some refactoring, I removed the method call for ending the batch, and so some future draw calls were sent by accident. This resulted in my lights using the wrong texture (see screenshot). :P

Best of luck to the rest of us! Here's to finishing our games before the deadline! :)

Eric Fri 25 Dec 20, 23:38
(This post is marked spoiler. It will be hidden for some viewers)

I added a favorite icon, changed yellow/gold hearts to green, changed the intro transition to be snappier, and added a hue-shifting filter that rotates 45 degrees each time a special heart is struck.

I also tried to fix the collision bug. It occurs whenever a heart collides with the platform on which the player rests. Because of the way the collision works (in that it's supposed to prevent the player from walking onto a broken platform), when the platform beneath the player is destroyed, the player is teleported to the nearest platform opposite of its facing direction. So if it's facing left, it'll be moved right, and vice-versa. But the heart-to-player collision is just narrow enough to sometimes miss the player and collide with the platform instead, which, when the player is stuck on a single platform, pushes the player to the next one. If all platforms in the direction opposite of its facing is destroyed, the player is pushed out of view. My temporary (and perhaps permanent) solution to this was to simply defeat the player when it falls out of view. However, I experimented with treating this rare occurrence like a good thing, and repair all platforms when the player falls out of view. The platform-repairing process takes some time due to its animation, and so the player ends up stuck in limbo until the nearest platform lands and finishes its fall. I don't like this, so for now I've reverted to defeating the player again. This only happens every now and again, but it feels cheap and annoying, so I may give it another go.

Eric Fri 25 Dec 20, 16:56
(This post is marked spoiler. It will be hidden for some viewers)

Merry Christmas, everyone! :)

I haven't had time to work on the game the past few days due to being busy with work, but I'm off today and have made a few adjustments:

- Tweaked lights' tints.
- Changed intro text color.
- Added README and LICENSE files.
- Touched-up the birds' graphics.
- Added transition for "try again" text.

I'd like to add some "speed up!" text when the game speeds-up, and maybe tweak the intro some more.

Here's a quick play-through video: https://youtu.be/ar74kfQ8n-0

Eric Tue 22 Dec 20, 19:13
(This post is marked spoiler. It will be hidden for some viewers)

I settled on a name for my game, but I'll keep it a secret for now. ;) I also spruced-up the click-to-start feature (which is necessary only because Web browsers may refuse to play sounds unless the sound was initiated by a user event, like a click). I also compressed the game's PNGs (compresspng.com), majorly tweaked difficulty, removed linear filtering from fullscreen mode, and added the intro back with improved visuals and transitions.

I also added the ability to clear your best score (hold D + 0). I encountered a bug where the player is occasionally teleported out of view, due to some buggy collision detection. I don't know if I'll have time to fix it, but for now my "fix" is simply defeating the player when he falls out of view. :P Oh, and I experimented with adding lights to the trees in the background, but I scrapped it because they looked bad at such a low resolution.

Lastly, there was a bug where the little birds in the background would abruptly "pop" into view, and I couldn't figure it out! There were no issues with its updating nor rendering, so I was pulling my hair out trying to find the problem. In the end, the problem was that the sliding intro text's background was the same color as the sky and was obscuring the birds during the transition! That's what I get for hacking together transition slides rather than using transforms...

Eric Mon 21 Dec 20, 17:36
(This post is marked spoiler. It will be hidden for some viewers)

The score and best score systems are complete! When a heart is destroyed, the score increase appears in the air for a split second, then its value is added to the running total. The best score is updated when the running total surpasses the previous best score, and is then saved to local storage. The best score is set to 5,000, but my personal best so far is 11,030. :)

Poyo lacks the ability to render text from a bitmap font, but I implemented a poor man's version for drawing the scores. I have an atlas containing imagery for numbers 0 through 9, each cell being a fixed size. I then convert the score to a string, count its length, run a for-loop, then use the index as an offset to select the appropriate tile from the atlas for drawing. Here's what that looks like:

function renderScore() {

. // Enables instance rendering for the next texture.
. Poyo.batchDrawing(true);

. let score_string = score.toString();

. let i = 0;
. let length = score_string.length;

. for (i; i < length; ++i) {

. . // Draw score.
. . Poyo.drawClippedBitmap(bitmap_score, parseInt(score_string[i]) * TILE_SIZE, animation_frame * TILE_SIZE, TILE_SIZE, TILE_SIZE, i * TILE_SIZE / 2, 0);
. }

. let best_string = highscore.toString();

. i = 0;
. length = best_string.length;

. let distance_from_right = TILE_SIZE / 2 * length + TILE_SIZE / 2;

. for (i; i < length; ++i) {

. . // Draw best / highest score right-aligned at the top-right of the screen.
. . Poyo.drawClippedBitmap(bitmap_score, parseInt(best_string[i]) * TILE_SIZE, animation_frame * TILE_SIZE, TILE_SIZE, TILE_SIZE, CANVAS_W + i * TILE_SIZE / 2 - distance_from_right, 0);
. }

. if (Player.isDefeated()) {

. . let bitmap_width = Poyo.getBitmapWidth(bitmap_score);

. . let x = CANVAS_W / 2 - bitmap_width / 2;
. . let y = CANVAS_H / 2 - TILE_SIZE / 2;

. . Poyo.drawClippedBitmap(bitmap_score, 0, TILE_SIZE * 2 + animation_frame * TILE_SIZE, bitmap_width, TILE_SIZE, x, y);
. }

. Poyo.batchDrawing(false);
}

Like with all of the other graphics, the text "wobbles" as it alternates between frames. Here's the code responsible for that:

function updateAnimationFrames() {

. ++animation_ticks;

. if (animation_ticks > 60 / 4) {

. . animation_ticks = 0;

. . ++animation_frame;

. . if (animation_frame > 1) {

. . . animation_frame = 0;
. . }
. }
}

Also, I completely revamped the heart spawning system! It works well now, and is a lot of fun to play! I also added the ability to play again after being defeated, complete with some new visuals. Further, I removed the intro text temporarily. Oh, and I played with headphones, and the audio is abysmal! :( You can hear the crackling of my cheap microphone. It sounds acceptable on regular speakers though.

The game is pretty much feature-complete at this point. There's still some tweaking and refactoring to be done, but everything from here on out will be extras and polish. :)

To do:
- Redesign intro.
- Redesign click-to-start.
- Add some visual flair to scores and text.
- Add a shader effect or two (if I have time).

Eric Sun 20 Dec 20, 18:30
(This post is marked spoiler. It will be hidden for some viewers)

I'm nearly at the finish line. Just a little more to go...

In regards to graphics, I designed a loading poster but later scrapped it because I wasn't happy with it; I re-arranged some elements of my main atlas; I improved the intro text, but am still not satisfied with it, and I may remove it altogether; I added tints to broken hearts; I reduced color banding on lights by leveraging linear texture filtering; I tweaked the intro slide; and I re-designed the score-drawing routines to sport new visuals with some slick fades, which I'm very happy with.

On the technical side of things, I changed the player's starting spawn; I tweaked the spawn condition for special hearts; I stopped awarding points for damaging a platform; I fixed a Firefox-specific audio loading bug; I added a click-to-start feature but then scrapped it; I added a full-screen mode (looks great); changed the score calculation for special hearts; and did a lot of refactoring.

Continuing with the technical, points are awarded in increments of 10, 50, 100, and 300, depending on how high-up the heart is when struck. Higher, trickier shots award the most points, and cheap ones award the fewest. There's ample room for cheesing the hearts, which I'm not happy about. I experimented with changing the throwing angle from 45 degrees to 35, forcing the player to move around more often, but it wasn't sufficient to fix the problem. I also tweaked the collision detection, but sometimes it threw false positives. This will need more work.

I'm working on an aging TV, and it's displaying artifacts. So I whipped-out my monitor for testing, and my goodness, I forgot how nice it was to use a monitor! So crisp, so responsive! I only wish my monitor were larger. No artifacts on the monitor. So now I'm rocking a dual display set-up, with code on my TV and the game my monitor.

What's left:
- Finalize intro.
- Display total score.
- Implement high-score feature.
- Be able to play again after defeat.
- Totally over-haul the heart-spawning system.

Eric Sun 20 Dec 20, 05:57
(This post is marked spoiler. It will be hidden for some viewers)

I'd like to briefly discuss the art style of my yet-to-be-titled game. The wiggling line art of "Ed, Edd n Eddy" was an inspiration for the "wiggle" art featured in my EasterHack 2017 game, Keebo's Quest (https://thardus.xyz/keebos-quest). Much like in that game, I begin by drawing a crude frame in a 64x64 area, then I draw it again in the 64x64 space directly below it. Depending on my needs, I'll either trace over the first frame or continue free-hand (the latter produces an even cruder copy, which is occasionally advantageous). Then in software, I alternate between the two frames, displaying each for a quarter of a second. This produces a crude, yet perhaps child-like style (see the attached GIF).

I'm using GIMP to produce the images, even the in-game text (also traced). I'm using a crayon brush set created by "wflu" (deviantart.com/wflu/art/GIMP-animated-crayon-31853987) with the pencil tool. Here are my settings:

Size: 10.00
Aspect Ratio: 0.00
Angle: 0.00
Spacing: 20.0
Hardness: 100.0
Force: 100.0
Dynamics: Off
Apply Jitter: False
Smooth stroke: False
Lock brush to view: False
Incremental: False

This game is more crayon-like than Keebo's Quest. Perhaps someday I'll make a game with real crayon art, like scanned from a piece of paper. I think that'd be pretty cool. :)

Eric Sat 19 Dec 20, 20:49
(This post is marked spoiler. It will be hidden for some viewers)

Audio:
- Stopped music upon player's defeat.
- Added a sound effect which plays upon the player's defeat.
- Added a sound effect which plays when a special heart is destroyed.
- Added a "whoosh" sound effect which plays when a snowball is thrown.

Technical:
- Fixed previously mentioned bug (I think).
- Made player jump upon being defeated.
- Increased time until next platform repair.
- Tweaked collision between snowball and hearts slightly.
- Don't allow the player to throw snowballs if they're defeated.
- Prevented snowballs from colliding with hearts that are out of view.

Graphics:
- Draw player above hearts.
- Added place-holder intro text.
- Added player defeated graphics.
- Draw lights above all hearts, not just specials.
- Added slide-down transition from text to background.
- Made falling platforms and player bounce a bit upon spawning.

I experimented with changing the hearts to candy canes, but didn't like the way they looked. Also, I'm using Bxfr (bfxr.net) to produce some sound effects, which I'm then mixing with my own mouth-made sounds in Audacity. I've slept poorly the past few nights due to working so late, so I'm dragging today.

Eric Fri 18 Dec 20, 16:48
(This post is marked spoiler. It will be hidden for some viewers)

Audio:
- Added "pop" sound effect that plays when a heart is destroyed.
- Added a slide whistle sound effect that plays when a platform falls.
- Added background music that ramps-up in speed as the chaos increases.

Graphics:
- Looped birds' animation as it leaves the view.
- Synchronized hearts' pulse interval (previously random).
- Animated the player and platform spawning into the scene.
- Used additive blending on special hearts to produce pretty lights (wish: granted).
- Changed the special heart's tint to a series of pre-defined colors (previously random).

Technical:
- Reduced frequency of spawning non-red hearts.
- Destroyed snowballs sooner as they leave the view.
- Prevented falling platforms from activating special hearts' ability.

I'm producing the sound effects myself with my cheap microphone. Using Audacity, the pop and whistle sounds were easy to clean-up. There are still a few more sounds to create (platform destruction, player defeat, and special ability). As for the background music, I'm using a piece by Kevin MacLeod (incompetech.filmmusic.io). Sounds and music certainly breath lots of life into the game!

I experimented with the snowball's throwing arc that incorporated velocity, and allowed it to hit multiple hearts at once. It looked and felt cool, but aiming and the cool-down weren't fun.

I have another full day at work, so I likely won't accomplish much else today. The next big thing to complete will be tweaking the spawn rates and rules for the hearts, as it's pure chaos right now.

Eric Fri 18 Dec 20, 07:03

It's a little past 1 AM in my time-zone and I just returned home from work about an hour ago. I researched various pseudo-random number generation algorithms, and decided to use the so-called "xorshift" algorithm. Here's my implementation in JavaScript, which I'm using to mimic the functionality of Math.random() but with a consistent seed:

let seed = 1;

function getRandomNumber() {

seed ^= seed << 13;
seed ^= seed >> 17;
seed ^= seed << 5;

let number = seed;

if (seed < 0) {

number = ~seed + 1;
}

let number_of_digits = number.toString().length;

let divisor = "1";

let i = 0;

for (i; i < number_of_digits; ++i) {

divisor += "0";
}

// Return a pseudo-random number between 0.0 and 1.0.
return number / parseInt(divisor);
}

This should be a tremendous help with testing. You can learn more about the algorithm on Wikipedia: https://en.wikipedia.org/wiki/Xorshift

Eric Thu 17 Dec 20, 16:42
(This post is marked spoiler. It will be hidden for some viewers)

I scrapped the previously described hook mechanic for a simple projectile system. I think it's a comfortable compromise between the hook/reel and the infinite pea-shooter systems I toyed with before. The player can freely move while using the projectile (a snowball), but the catch is that he can't toss another one until the first one either hits an obstacle or flies out of view. So there's a degree of strategy in picking targets while also avoiding them.

I also debated whether or not to rotate snowballs when thrown. I feel as though they should rotate, since that's only natural (not that I ought to be striving for realism, given the player is a bouncing snowman's head and all), but it *feels* better when they don't rotate. For now I'll leave it be.

On the technical front, I flipped snowballs horizontally to match the player's facing direction at the time of being thrown; I refactored all of the code again; I renamed the obstacles to hearts and the hook to a snowball; and I added a basic state machine (intro and game, but nothing done for the intro yet).

On the graphical front, sometimes yellow/gold-colored hearts spawn instead of red ones (no mechanical difference between the two); I gave special hearts a flashing tint (they're grayscale, so I can programmatically tint them whatever color I please); I made the canvas bigger; I changed the platforms to be an icy blue color; and I added little birds that fly in the background.

I leave for work in a couple of hours and won't return until sometime after midnight local time, so I likely won't make much more progress today.