Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411485 Posts in 69371 Topics- by 58427 Members - Latest Member: shelton786

April 24, 2024, 07:14:21 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsPlumber's Smile - C64 game about pipes made in Turbo Rascal
Pages: 1 [2]
Print
Author Topic: Plumber's Smile - C64 game about pipes made in Turbo Rascal  (Read 9313 times)
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #20 on: March 18, 2020, 11:43:59 AM »

Another WIP gif of wrench throwing - now some real usage Smiley


Logged

JobLeonard
Level 10
*****



View Profile
« Reply #21 on: March 18, 2020, 11:46:42 AM »

Nice!
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #22 on: March 21, 2020, 10:00:11 AM »


Some people asked me why the main character carries a wrench but he just kicks the pipes to fix them - well I had different plans for it. Lately, I've been working on wrench and wrench throwing mechanics.

First I had to design and animate the wrench and as previously I used GIMP. I started with 24x21 resolution as it's the max of C64 sprite remembering that whole thing would have to be stretched to 12x21 for multicolor. I wanted to make spinning animation of the wrench and as I designed it to be symmetrical I needed to animate 180 degrees of rotation with only 4 frames for a quite smooth animation:


After that I did the rescaling for C64 multicolor sprite constraints, some fixing and added the first coat of shading:


I wanted to add some more shiny shading to the object and this resulted with few versions and I just couldn't decide which one to use:


So I've uploaded the above gif to Twitter and other places just to ask people about their opinion. Most of them voted I should use just the simple shading so, for now, I decided I will go that way and I can always change it if I don't feel it's ok.

I've imported 4 frames of animation to TRSE sprite editor and jumped into the implementation part. Before that I also painted two frames of plumber throwing animation:


As you could already see in sneak peek gifs above this post I wanted the plumber to throw the wrench on the parabolic path so once again I referred to the good old sine table. And after some tweaks I can show you one the capabilities of our character's trusty multitool:



Now for the hard part - I need to implement sprite order sorting based on Y position because currently, sprites draw in the order based on their index. If I finish that it will also result in the ability to use more than 8 sprites with no effort and barely an inconvenience Smiley
« Last Edit: March 21, 2020, 01:10:42 PM by nosferathoo » Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #23 on: March 21, 2020, 10:29:57 AM »

Nice!
thanks!
Logged

JobLeonard
Level 10
*****



View Profile
« Reply #24 on: March 21, 2020, 12:45:31 PM »

I guess you have a few puzzles planned where you need to combine kicking with wrench throwing to finish the level?

Also, what's your twitter handle?
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #25 on: March 21, 2020, 01:03:22 PM »

I guess you have a few puzzles planned where you need to combine kicking with wrench throwing to finish the level?

Also, what's your twitter handle?

Yes, the kicks are faster but have a limited range. The wrench has better range, can go over obstacles due to parabolic movement but it is also slower and it requires targeting/timing.

My twitter handle is @nosferathoo Smiley
Logged

nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #26 on: April 01, 2020, 10:49:37 AM »



Recently I've changed my boing boing routine so I could have multiple of them on screen for harder levels and during this, I've stumbled on a rather obvious issue:


The conclusion was also very obvious - I needed to implement sorting by Y position as C64 have predefined sprites priority - sprites with lower index always display on the front of others. So what I needed to do is get around of C64 sprite handling by using my own structure to hold sprite information (position, frame, color, etc.), sort this structure and after that put the info in hardware sprites in the right order.
This also opens the possibility to render more than 8 sprites by using the technique used by many old C64 games - f.e. Green Beret. In C64 you can use interrupts and synchronize with VIC raster lines right when it starts or ends drawing them. When you wait for one sprite to end drawing you can change its position to the lower area. There were two techniques used for this - Zone Split and the one that suited me best - sorting.

The whole process looks like this:


It's all looking quite smart and simple but there is one catch - TIMING. You need to do all operations in sync with VIC and be aware that there are "only" 63 cycles of CPU for each raster line that you can spend on sorting and repositioning of the sprites and setting up proper graphics, color and stretching (sprites can be individually stretched in X and/or Y).

Here's example of first failed attempt that I will try to describe:


The border color shows when separate functions start and end in sync with VIC while it draws the screen and sprites:
- RED means the "main" procedure with one loop that updates sprites positions in my structure - it starts at raster line number 250 (lower border) just after the previous frame was drawn - as you can see it takes some time even bleeding into the next frame (top of the screen)
- WHITE means sorting - simple bubble sort and not even properly working Smiley
- GREEN - setting up sprites, waiting for them to finish drawing, etc. - as you can see it doesn't even start on the top border so top sprites simply don't have time to be properly set up on the screen

After that, I've changed my sorting technique to not try the entire sorting at once but simply do one step per frame. There are 50 frames on PAL machines so I can do plenty of comparisons even in simple bubble sort, traverse entire structure a few times per second and, hopefully, the player won't even notice short situations when sprite that is higher is drawn on top of the one that is lower.


As you can see the sorting routine (white) doesn't take much time now (the green/blue blinking means swapping was needed due to the comparison). Also, you can notice nice sorting as the sprites that are on the top are shown below those in the bottom.

One more time without the blinking and 4 extra sprites:


All that is left now to do is implement this technique into the game and try to optimize it further as currently 16 sprites limit is my max but I read about 30 sprites in some games :O. There are some things that I could write in a different manner but for now, I am quite happy with the result as I don't even write it using assembler but trusty Turbo Rascal Smiley.

« Last Edit: April 01, 2020, 11:15:22 AM by nosferathoo » Logged

JobLeonard
Level 10
*****



View Profile
« Reply #27 on: April 01, 2020, 11:10:04 AM »

Aww yeah, detailed write-ups of implementation processes are my jam

The results look pretty sweet too!
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #28 on: April 01, 2020, 11:16:26 AM »

Aww yeah, detailed write-ups of implementation processes are my jam

The results look pretty sweet too!

Thanks - glad you like it!
Logged

JobLeonard
Level 10
*****



View Profile
« Reply #29 on: April 02, 2020, 12:12:24 AM »

What kind of sorting algo do you use? For very small arrays (and 16 or 30 sprites counts) insertion sort is generally considered the fastest.
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #30 on: April 02, 2020, 03:48:54 AM »

What kind of sorting algo do you use? For very small arrays (and 16 or 30 sprites counts) insertion sort is generally considered the fastest.
I use really simple bubble-sort-like. I try do describe it in pseudocode:
Code:
var
p:pointer;
orderlist:array[] of byte; // array of sprite indexes that should be sorted by their ypos
ypos:array[] of byte; // array of ypos
i,j:byte;
...
procedure Init()
begin
p:=orderlist;
end;

interrupt MyInterrupt()
begin
...
i:=p[0];
j:=p[1];
if ypos[i]>ypos[j] then
begin
swap(p[0],p[1]);
end;
p:=p+1;
if p>orderlist+sprite_count then p:=orderlist;
...
end;

Thanks for the suggestions - might try to optimize this more.
Logged

JobLeonard
Level 10
*****



View Profile
« Reply #31 on: April 02, 2020, 04:16:24 AM »

One little thing about insertion sort that may or may not help* is that you can avoid swapping: instead assign the value to a temporary and shift all the values below it up by one until you reach the point where it should be inserted

* Always the difficult thing with sorting, right? It's so contextual based on what data you are sorting, on which architecture, in which state (random or nearly-sorted).

I'm not sure how well insertion sort works with partial sorting - bubble sort is very nice for that (since it's embarrassingly parallel)
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #32 on: April 11, 2020, 09:05:14 AM »

I've finally got some time to implement my sprite sorting into Plumber's Smile


Logged

JobLeonard
Level 10
*****



View Profile
« Reply #33 on: April 11, 2020, 11:16:31 AM »

 Coffee

My only complaint is that you turn the sprite so fast that we don't get to see the stereotypical butt-crack properly
Logged
nosferathoo
Level 1
*


indiedev from Poland


View Profile
« Reply #34 on: April 18, 2020, 09:10:02 AM »


Boing boings are wreaking havoc


Logged

JobLeonard
Level 10
*****



View Profile
« Reply #35 on: April 18, 2020, 02:05:59 PM »

Oooh, nice

But isn't the second on - the one that bounces from the right to the left - affecting the wrong tile? It seems like it should affect the middle pipe, not the bottom one
Logged
Pages: 1 [2]
Print
Jump to:  

Theme orange-lt created by panic