Jump to content
IGNORED

[Tuto - step by step] Prototyping a JagStudio game in a few hours - flappyChicken


Fadest

Recommended Posts

Yesterday, I made a little experience (again) with JagStudio.

My goal was to rework with the tool after last year experiments, and get back a bit to Jag programming.

 

The best way to do so is to work on a tiny prototype, with clear objectives.

First, let me explain the differences I make between a game and a game prototype.

 

A game prototype has to be : (barely) playable, its goal is to demonstrate/validate a gameplay idea, a graphical asset, or whatever you want to check if it can work or not, and don't want to spend weeks on it to know. It will of course not be as good as a full game, the code can be crappy, there is no optimisation in assets or code (will come back to this point later)

 

So once this point is cleared (do no expect a full game in this first iteration), let's start the journey.

 

It all started with a mail received from itch.io on tuesday, that I have read only yesterday morning :

image.thumb.png.9a41398daccb8a943a1e6a44e81d5f1b.png

 

Ansimuz is a great artist, providing free and paid assets for developpers on itch.io. And sometimes, he creates simple games to showcase his assets. It was the case in this release which includes 'nearly) all needed stuff :

- background

- sprites

- sound effects (in WAV)

- background music (in ogg or WAV)

- Godot source code 

 

The game is fun, reminds a bit Joust, Flappy bird & co

 

I played a bit the game, thought it would be nice to use assets for a Jag prototype, noted some ideas, and downloaded the asset archive.

 

So let's start the hard fun work :D

 

Preliminary point: I work in C, but most of the tutorial is suitable to Basic & ASM. Only the gameplay code will have to be adapted to your selected language.

 

Of course, every assets and declarations/source file is included in the archive. Just unzip it inside your JagStudio/projects/c folder

For obvious reasons, I do not distribute ansimuz original archive, you can find it at his itch.io page.

 

 

1st step: creating the project

You obviously need Jagstudio to be installed on your computer, if you have not do it already, go and get it on JagStudio (reboot-games.com) .

I won't comment this point as this is quite straightforward, and there are already lot of topics covering this.

Open a script command tool (DOS/Powershell/...) and navigate inside the JagStudio folder

To create a new project called "flappyChicken" in C, you need to type :

build.bat flappyChicken newc 

 

Then, when you will want to test your game, your will just have to type one of this command, depending on your setup (Virtual Jaguar, Jag GD or Skunkboard)

build.bat flappyChicken to launch game with Virtual Jaguar

build.bat flappyChicken jaggd to launch game on a connected Jag GD

build.bat flappyChicken skunk to launch game on a connected Skunkboard

 

If everything is correct, the project is compiled, and the game starts automatically on selected device.

 

2nd step: working on graphical assets

Ansimuz provides his assets in png format, with alpha layer for transparency, and use different spritesheets for each elements.

Here are the main assets files provided :

image.png.025fb189aa45a6c675d29899735d5ad3.png

Each file is color indexed.

To be honest, I don't know if Jagstudio can handle them directly, I prefer to work with my own habitudes, so it means BMP format, and for sprites, transparent color is color 0 in the palet.

So this means a bit of rework.

It also has the advantage of letting me know how much colors each asset use.

 

On color number, ansimuz usually do a great optimisation job, let's check the main title screen :

image.thumb.png.8673ca6f2422aa39669c5c16c2a22ef4.png

 

During the conversion process, I also reput spritesheet in vertical format. Don't know if this is really mandatory for JagStudio but I think it is (looking at how we describe assets later), and I find it more convenient.

So here is typical before/after asset spritesheet file :

image.thumb.png.05c9c0904c6e2a1897b2a204a70e420d.png  image.thumb.png.5ad1ba5ed03159e067515c00c59d9ff0.png

Pink is for transparency. Note the crappy work in palette (after all, this is just a prototype)

 

Once every assets have been converted (side note, there were no spritesheets for eggs, so I created one based on individuals sprites ansimuz is also providing), I put them in my <project folder>/assets/gfx folder :

image.thumb.png.410fdcd9c77f9d303a042b2959c6ceb0.png

I also created a dead_chicken.bmp file which is barely the first chicken sprite with a vertical mirror (when player dies) that was not included (Godot probably has a vertical mirror option)

 

3nd step: working on SFX & musical assets

Nothing special here, I just took the .wav sound effects from ansimuz "Godot Project/Audio" folder and putted them in my assets/sfx folder

For music, I downloaded a mod file and putted it inside assets/music folder.

I chosed a very old MOD from dms-sc : Rainbows Factory

[dma-sc music factory] works (atari.org)

 

dma-sc was kind enough to let me include this mod inside this tutorial

 

4th step: setting up project

Now, the real work inside Jagstudio is about to start.

All we need is a text editor (I am using Visual Studio Code, but there are many other great tools, just chose the one you are more efficient with)

There are 6 files that we will have to edit in order to make our prototype :

image.png.e15d7b478e60796c92d8cf902e483d76.png

First thing, we need to decide if we go with Zerosquare player or U235 player for music/SFX pay routines, but also jagpad routines (as this is done by DSP, this part in included inside the player)

There is no good or bad choice, I guess it is up to everyone to test and choose.

I personnally use U235 for this project, so I had to edit rapapp.s to declare U235 player (on line 10) :

image.thumb.png.3d3e82b0d3b9e330935735e28e29af8f.png

DO NOT TOUCH SOMETHING ELSE IN THIS FILE, AND SAVE IT

 

5th step: declaring assets files used by the projet

So, in steps 2 & 3, we prepared our graphical, SFX and musical assets.

Now it is time to tell Jagstudio where to find them, and also give some informations about them.

Open assets.txt in your text editor :

image.thumb.png.e172c8fb3603822f60c95f6a46d3cff2.png

As you can see, there is 1 line per asset, and depending on type of asset, the declaration will differ.

The assets file by default is self-explanatory, but remember this for graphical assets :

If you use color indexed files, you must use gfx_clut, otherwise, you use gfx_noclut

 

Save the file

 

6th step: SFX assets - declaring objects

As I use U235, I have to declare every SFX asset inside the rapu235.s file

image.thumb.png.2e9d5657cfa017ad9dd5f3cbc62568a7.png

this is the bank of samples.

For each sample, I need to create a bloc, with the sample tag (I just numeroted them from sample0 to sample5 as I have 6 samples) and a tag for volume (can be usefull if we want to change it during the game). Once again, I used s0_vol to s5_vol

In code, I just have to call the routine :

   u235PlaySampleFreq(4,1,8000)

to play on voice 4 the sample n°1 (death.wav) with a replay routine of 8000hz

 

7th step: graphical assets - declaring music

Nothing special to do, the MOD replay routine will be called in code by:

    u235PlayModule((int)STRPTR(MOD_ROCK),MOD_STEREO);
    u235ModuleVol(32);

 

8th step: graphical assets - declaring objects list

Here is starting the real conception work.

And here is where prototyping a game is different from thinking of a real game.

 

My goal is to get quickly a satisfying visual aspect. I don't really care about memory consumption or optimisation (I mean I do not really care but I want the prototype to remains playable...)

 

The objects list is declared inside rapinit.s which is the main file of JagStudio. The difference between a well thought and defined rapinit.s and a badly done can be very important on the fianl game result.

So you need to think about it very carefully.

 

But first, I think I should barely explain what is the list and object list.

When you want to display something on screen, you send the Jaguar video processor a list of objects, and this list is processed in order.

So first object is displayed, then 2nd one and so on.

So you can see it as a stack. The last object is displayed on top of the other ones and can of course hide them.

 

An object is a sprite. It can be of whatever size you want, it also has some attributes, like position on screen, visible/not visible, mirrored or not, zoom, and so on.

JagStudio also add other properties like automated movements, automated animations, collisions, life point management, ...

 

Once again, as we are working on a tiny prototype, let's keep the object list simple.

We need to display a background (obviously) and sprites. Also maybe some informations like number of life or score.

image.png.e202518163361736549ef6e8aa9deb7f.png

 

First gameplay decisions:

  • All ennemies (chicks, bomb) will move only on 6 possible lines
  • If we collide with a bomb, it explodes and we lose a life
  • If we collide with a chick from top (jump on head, like in joust), it collapses and an egg is created
  • If we collide with a chick from bottom, we close a life
  • If we catch an egg, we get some rewards

 

 

So for sprites, we have on screen:

  • our chicken
  • chicks: I decided to put them on 6 lines, and 3 chicks per lines max (so 18 sprites)
  • bombs: 1 per line (so 6 bombs)
  • eggs: 1 egg can be created per chick, so 18 eggs on screen max
  • eventually, dead chicken falling while we are playing next life
  • eventually bombs explosions

 

Eggs management is a choice to make. It could be probably better to just change the chick sprite by an egg one, and change setup of movement. Would also require to keep trace of kind of sprite displayed (egg or chick) when collision occur as management is different. So a bit more complexity in code.

So, as this is a prototype, I choosed the most convenient solution: I consider they are different objects (so 18 chicks + 18 eggs).

Can't tell which solution is the best (or if there is a better solution), just choosed the easier for me in a limited time.

 

Same for bombs vs bombs explosion. As we can collide with bombs but not with explosion, it is better to manage them in different objects.

 

So he is what my object list looks like:

  • 2 x background (as bg.bmp does not cover the whole screen, I need to display it twice)
  • 18 x eggs
  • 18 x chicks
  • 6 x bombs
  • 1 x title screen (we obviously need a title screen - as it is putted here in the list, it will hide all previous sprites at no cost)
  • 1 x chicken (also used as selector on main title)
  • 1 x dead chicken (this is not optimised to put it here, as when you lose a game, it still fall on title screeen, after all, this is nice unwanted effect - easy to correct)
  • 6 x bombs explosion (idem)
  • Text/particle layer (stand from JagStudio, allow to display information on screen - once again, maybe better to put it before title screen ,as it remains displayed after death)

 

This has to be configured inside rapini.s

You will notice rapini.s has a lot a comments

Each type of object in my object list has to be defined in 1 bloc in rapini.s (thankfully, the 18 chicks objects do not need 18 declaration but only 1 :D )

 

Here is the background bloc as example:

image.thumb.png.ca708eccba9ff0aeabaea604decfce00.png

As you can see, there is a lot of informations.

Also, on the right of each data, there is the Raptor (the libray under JagStudio) name, this will be very usefull when we will start to code)

between value and description, there are also the possible values, also very useful in code.

 

I suggest you to read the documentation, but here is a little overwiew

Now, let start to describe a bit this definition list.

  • First we define the number of objects with the same description to create
  • The object can be active (visible) or inactive (not visible)
  • Then we define the position x,y (also with subpixel if needed), and automatic offsets to move in x & y
  • We give Jagstudio the size of 1 sprite (not the spritesheet if it has many sprite, but a single sprite)
  • Then display mode : normal or horizontal flip
  • Collision informations will be describe later
  • the adress of the graphical assets (remember, it is the name we used in assets.txt)
  • display mode : we have 16 colors files, so 4bits, in RGB
  • Opaque for background, and transparent for sprite (index 0 of the palette in transparent for color indexed sprites - the pink in our assets)
  • Then we have some byte size deplarations and calculations. It is to help Raptor display sprites and manage animations. This is quite straightforward. I usually keep my sprite size and divide by the correct number depending on bits of the filte type, rather than making calculations by hand. Here, we have a 192pixels x 240pixels sprites in 4bits (so divided by 2)
  • Animations informations, tells how many frame to wait between 2 aprites, how many additional sprites to use in asset file, and what Raptor must do with the object once animation is ended (loop or once).
  • Tells Raptor what to do with objects when they go out of the screen (wrap to the opposite side or kill). Beware, killing means the object status will be incative automatically, and so will no more be displayed. Also possible to define a more complex movement via a tracking table
  • Zoom informations
  • The R_sprite_was_hit will be very important in code when using automatic collision, wil come back to it later
  • clut is the palet description to use for color indexed objects. As every asset can have a different palet (limited by number of available palet), we have to tell each object which clut to use (will see more about it later in the code section)
  • Once again, some collision informations, and how the object must react after collision (raptor can manage automatically life points, and kill object when they have 0 point)
  • Lest information is probably when you manage your spritesheet horizontally

 

 

So we just saw that JagStudio can manage collisions.

Do we need them in our prototype : YES

 

The player can collide with : chicks / bombs / eggs

So for each of those object, we must setup the collision data 

 

First, we need to define the collision box. By default, it use center point of sprite as base, then definf a rectangle shape. I used 10x10 pixel here.

image.thumb.png.2d6464c6947ae9e6f59a7e7f851c398d.png

Of course, we must define object as can_hit. I don't want JagStudio to remove automatically object or manage life points in this prototype (but it works very well - just easier to do by hand when debugging)

image.thumb.png.59881677ec64d7e8cbf3bd0ec3b7ba4c.png

 

Here we are with the rapini.s file.

As said before, this is probably the main point to apprehend when learning Jagstudio. But it is also a real time-saver when you manage to use it efficiently.

 

9th step - the code

Have you noticed ?

We have write no line of code yet, but if you run your project, you should have the title screen displayed...

 

Jagstudio create a template for code that displays object list (so title screen + chicken in front of play if you look carefully rapini.s and also a bit of text)

 

But now, it is time to code our prototype.

As I said before, this is in C, but a really basic C, so probably easy to convert in Basic (and I think ASM coders do not need me to do this kind of job)

 

First thing to do, and to ease life is to declare the object list inside the code.

I usually put them in common.h

image.thumb.png.78f824b31cf757f74f5f611621d8b7fd.png

So now, if I want to adress the chicken object, i can use CHICKEN instead of 45

And if I change my object list, I just need to change this 45 value by the correct one instead of going though the whole code to do so

 

I won't comment all the code.

Just note it is ugly, and not something to base your future work on (please make a real conception before starting to code) unless you want to make a quick & dirty prototype of course.

I tried to include lots of comments (for me) inside the code

 

I will just comment here some important points related to JagStudio

 

First of all, there is this inside the basicmain() procedure (main C routine)

image.thumb.png.0709e592588f44b8d37ce9e242cfba24.png

It initialise the differents clut with the objects palets Jagstudio retrieved from the graphical assets files.

These values (from 0 to 5) have to be associated in rapini.s to the corresponding objects in order to display them with the correct palet.

Note that ansimuz only use 4-6 colors per spritesheet, so it could be easy to associate different spritesheets with the same palet (just combine them) in order to limit number of palet. There is no need here as we only need 6 clut over a limit of 16 IIRC

 

Also initialise the 2 backgrounds (remember, bg.bmp is smaller than a screen, wo we need to display it twice) one for all.

You see we can adress the rapini.s structure element with the sprite[] array

Remember the Raptor names inside rapini.s tagged as R_sprite_<property> ?

We can adress them with sprite[<number>].property

 

Also, we can use the Raptor predefined value (is_flipped, is_normal, ...) just by adding R_ in front of them, for example, how to set a sprite as active and flipped:

     sprite[CHICKEN+1].active = R_is_active;         // active dead chicken object
     sprite[CHICKEN+1].flip = R_is_flipped;  // set directionas flipped

 

The main gameplay is done in the game() procedure

Nothing really fancy, I think comments will be useful.

Just note that the flapping and jumping gameplay is really miles away from standard process (no inerty, no acceleration due to gravity, only +1 or -3). As said before, it is enough for a prototype, but not for a real game.

 

Just a focus on collisions :

image.thumb.png.04ad24a8e78f07ce2c76c69820b48b35.png

As said before, we need to declare objects as can_hit in rapini.s and define a collision box.

But JagStudio will not automatically check collision, you need to call the rapCollide procedure

        rapCollide (CHICKEN,CHICKEN,CHICKS,CHICKS+18);                  // call collision routine between chicken (only) and the 18 chick

It takes 4 parameters :

  • objects list to test 1 - start number
  • objects list to test 1 - end number
  • objects list to test 2 - start number
  • objects list to test 2 - end number

So it will make collision tests between every object insed the "objects list to test 1 - start to end number" and the "objects list to test 2 - start to end number"

Here, as I want to test my main character sprite with the 18 chicks, I declare CHICKEN as start and end of list 1, and CHICKS and CHICKS+18 as start and end of list 2

If Jagstudio detects a collision, it will set the was_hit property at 1, in order to let me know.

I manually reset the value to -1, but I am not sure it is really useful

 

 

 

OK, this is a very long post, I hope someone wil find some useful informations in it.

 

You can also just download the archive and try the rom inside :D

 

 

 

 

image.png

flappyChicken.zip

Edited by Fadest
multiple typos...
  • Like 13
  • Thanks 4
Link to comment
Share on other sites

This is really awesome...thanks so much.

 

I am having a go at manipulating the code to help me understand it. 

 

My thinking is that if i change the number of bombs in rapinit.s this should control how many are in the game? If i change it to 1 i still see 6 bombs when i build the program. What am i missing?

 

image.thumb.png.fb6d66ed0c8f8f43a561afc56abc42bb.png

Thanks

Edited by mdkdue
Link to comment
Share on other sites

49 minutes ago, mdkdue said:

This is really awesome...thanks so much.

 

I am having a go at manipulating the code to help me understand it. 

 

My thinking is that if i change the number of bombs in rapinit.s this should control how many are in the game? If i change it to 1 i still see 6 bombs when i build the program. What am i missing?

 

image.thumb.png.fb6d66ed0c8f8f43a561afc56abc42bb.png

Thanks

It could if my code was clever (ie not using fixed values)

 

Right now, I am using 6 as fixed number of bombs in the code.

 

If you want to change it for more bombs:

You have to change in common.h the offset for elements (as obviously, TITRE, CHICKEN & BOMBS_EXPLOSION value will change as they are the offset of the first element of this kind in the object list defined in rapini.s)

 

In flappyChicken.c, you would have to change theses lines (twice in the the code) :

 

    for (i=BOMBS;i<BOMBS+6;i++

as they consider there are 6 and only 6 bombs.

Also, you probably would have to change the y definition

        sprite[i].y_ = 40+32*(i-BOMBS);                     // - y position depends on sprite number (1 bomb per line / 6 lines)

 

as it would be off screen for bombs n°7, 8 and so on (or in fact would cycle them around the screen, so they would retart from top but on another line offset)

 

And of course tell rapCollide that there are more than 6 bombs to consider for collision

        rapCollide (CHICKEN,CHICKEN,BOMBS,BOMBS+6);                     // call collision routine between chicken (only) and the 6 bombs

 

Other points, you should also declare the same potential number of boms explosion than the number of bombs...

 

If you want to change it for less bombs:

Just keep the 6 value in rapini.s, the best way is to set objects as inactive while initialisation.

So in flappyChicken.c, for example, if you want only 2 bombs, add a first loop to inactivate all bombs, then activate only the desired one

    // initialise bombs
    for (i=BOMBS;i<BOMBS+6;i++)
        sprite[i].active = R_is_inactive;             // put all bombs as inactive
 
    for (i=BOMBS;i<BOMBS+2;i++)             // Only activate 2 bombs
    {
        sprite[i].active = R_is_active;             // - all are visible in prototype (set some as inactive for easier mode)
        sprite[i].was_hit = -1;                     // - reset collision status
        sprite[i].x_ = rand()%320;                  // - x position is random
        sprite[i].y_ = 40+32*(i-BOMBS);                     // - y position depends on sprite number (1 bomb per line / 6 lines)
        if (sprite[i].x_ < 160)
        {
            sprite[i].flip = R_is_normal;           // for sprites on the left side of screen, move to the right
            sprite[i].xadd_ = 2;
        }
        else
        {
            sprite[i].flip = R_is_flipped;          // for sprites on the right side of screen, move to the left
            sprite[i].xadd_ = -2;
        }
    }  
 

No need to change the bomb management routine, it will check against the 6 bombs, but as we have put some of them as inative, it is not an issue.

 

Better option would be to define meta informations for level (n° of chicks, n° of bombs, starting positions, move template...) and use them for initialising each level. This is what I will probably do if I put a little more effort in this for a ROM public release.

 

 

Edited by Fadest
  • Like 1
Link to comment
Share on other sites

16 minutes ago, Fadest said:

It could if my code was clever (ie not using fixed values)

 

Right now, I am using 6 as fixed number of bombs in the code.

 

If you want to change it for more bombs:

You have to change in common.h the offset for elements (as obviously, TITRE, CHICKEN & BOMBS_EXPLOSION value will change as they are the offset of the first element of this kind in the object list defined in rapini.s)

 

In flappyChicken.c, you would have to change theses lines (twice in the the code) :

 

    for (i=BOMBS;i<BOMBS+6;i++

as they consider there are 6 and only 6 bombs.

Also, you probably would have to change the y definition

        sprite[i].y_ = 40+32*(i-BOMBS);                     // - y position depends on sprite number (1 bomb per line / 6 lines)

 

as it would be off screen for bombs n°7, 8 and so on (or in fact would cycle them around the screen, so they would retart from top but on another line offset)

 

And of course tell rapCollide that there are more than 6 bombs to consider for collision

        rapCollide (CHICKEN,CHICKEN,BOMBS,BOMBS+6);                     // call collision routine between chicken (only) and the 6 bombs

 

Other points, you should also declare the same potential number of boms explosion than the number of bombs...

 

If you want to change it for less bombs:

Just keep the 6 value in rapini.s, the best way is to set objects as inactive while initialisation.

So in flappyChicken.c, for example, if you want only 2 bombs, add a first loop to inactivate all bombs, then activate only the desired one

    // initialise bombs
    for (i=BOMBS;i<BOMBS+6;i++)
        sprite[i].active = R_is_inactive;             // put all bombs as inactive
 
    for (i=BOMBS;i<BOMBS+2;i++)             // Only activate 2 bombs
    {
        sprite[i].active = R_is_active;             // - all are visible in prototype (set some as inactive for easier mode)
        sprite[i].was_hit = -1;                     // - reset collision status
        sprite[i].x_ = rand()%320;                  // - x position is random
        sprite[i].y_ = 40+32*(i-BOMBS);                     // - y position depends on sprite number (1 bomb per line / 6 lines)
        if (sprite[i].x_ < 160)
        {
            sprite[i].flip = R_is_normal;           // for sprites on the left side of screen, move to the right
            sprite[i].xadd_ = 2;
        }
        else
        {
            sprite[i].flip = R_is_flipped;          // for sprites on the right side of screen, move to the left
            sprite[i].xadd_ = -2;
        }
    }  
 

No need to change the bomb management routine, it will check against the 6 bombs, but as we have put some of them as inative, it is not an issue.

 

Better option would be to define meta informations for level (n° of chicks, n° of bombs, starting positions, move template...) and use them for initialising each level. This is what I will probably do if I put a little more effort in this for a ROM public release.

 

 

Brilliant explanation, thank you so much.

 

I am going to test this out and see how i go :)

 

One other question, how would you make the chicks and bombs regenerate once they are all gone?

Edited by mdkdue
  • Like 1
Link to comment
Share on other sites

You want a kind of infinite game ?

 

Right now, the gameloop ends if the 18 chicks are gone.

So you would have to remove this test.

 

And add code to regenerate chicks.

It depends of the gameplay option you choose, you could :

  • respawn a chick each time the player catch an egg: it is probably the easiest solution, just set corresponding chick to is_active when you set the egg to is_inactive (so just the reverse of what is done when an eg pop_up). No need to set x,y and xadd as they are already done, the chick would just spawn at the position it has been destroyed (or set x to a value outside screen to make it enter)
  • add a timer to inactive chicks and respawn them...
  • better gameplay option in my opinion: add a timer to eggs, and after a while, respawn the chick (like a new birth). This is something I plan to add (you need to catch the egg soon enough, otherwise, the chick reappears). This is also compatible with the current end game (you just have to compare with eggs catched to end game instead of chicks destroyed). But be careful, this would broke the crappy code part I commented as "do not do this at home". As the chicks would not be on the same line...

 

For bombs, just check inactive bombs, and set them to active after a timer or with a random test.

 

One easy thing to do with bombs is also to change their direction, vertical instead of horizontal for example. In the initialise bomb part, replace sprite[i].xadd_ by sprite[i].yadd_

(edit - I have just tested, it is not fun :D )

 

 

Edited by Fadest
  • Like 2
Link to comment
Share on other sites

35 minutes ago, Fadest said:

You want a kind of infinite game ?

 

Right now, the gameloop ends if the 18 chicks are gone.

So you would have to remove this test.

 

And add code to regenerate chicks.

It depends of the gameplay option you choose, you could :

  • respawn a chick each time the player catch an egg: it is probably the easiest solution, just set corresponding chick to is_active when you set the egg to is_inactive (so just the reverse of what is done when an eg pop_up). No need to set x,y and xadd as they are already done, the chick would just spawn at the position it has been destroyed (or set x to a value outside screen to make it enter)
  • add a timer to inactive chicks and respawn them...
  • better gameplay option in my opinion: add a timer to eggs, and after a while, respawn the chick (like a new birth). This is something I plan to add (you need to catch the egg soon enough, otherwise, the chick reappears). This is also compatible with the current end game (you just have to compare with eggs catched to end game instead of chicks destroyed). But be careful, this would broke the crappy code part I commented as "do not do this at home". As the chicks would not be on the same line...

 

For bombs, just check inactive bombs, and set them to active after a timer or with a random test.

 

One easy thing to do with bombs is also to change their direction, vertical instead of horizontal for example. In the initialise bomb part, replace sprite[i].xadd_ by sprite[i].yadd_

(edit - I have just tested, it is not fun :D )

 

 

I was thinking more simply, if you clear the screen of chicks and eggs and still have lives left it just regenerates everything (bombs, chicks) so you can keep going till all lives are lost? Is that easier maybe?

  • Like 1
Link to comment
Share on other sites

So you should put the initialise eggs and chicken and initialise bombs inside an init() procedure

And call it a beginning of game, and when you detect screen is cleared of eggs & chicks.

Just be careful, as it done now, it would respawn in middle of screen, not sure it is what you want (would have to change the initial coordinate setup)

 

I also found a bug in my code, and use of rapCollide() (and also explanations in 1st post, but I can't edit it anymore)

The explanation is correct (it takes from start number to end number). But, when you have 18 chicks to test, you must make CHICKS+17 (as 1st value is consider as 0, so 0 to 17 = 18 values).

Stupid coder :(

Quote


        rapCollide (CHICKEN,CHICKEN,CHICKS,CHICKS+17);                  // call collision routine between chicken (only) and the 18 chick

It takes 4 parameters :

  • objects list to test 1 - start number
  • objects list to test 1 - end number
  • objects list to test 2 - start number
  • objects list to test 2 - end number

So it will make collision tests between every object insed the "objects list to test 1 - start to end number" and the "objects list to test 2 - start to end number"

Here, as I want to test my main character sprite with the 18 chicks, I declare CHICKEN as start and end of list 1, and CHICKS and CHICKS+18 as start and end of list 2

If Jagstudio detects a collision, it will set the was_hit property at 1, in order to let me know.

 

 

 

 

I also find it more enjoyable is you set bomb move speed at +1 or -1

 

I also corrected the crappy part, I will probably repush a new sourcecode, probably tomorrow

  • Like 1
Link to comment
Share on other sites

10 minutes ago, Fadest said:

So you should put the initialise eggs and chicken and initialise bombs inside an init() procedure

And call it a beginning of game, and when you detect screen is cleared of eggs & chicks.

Just be careful, as it done now, it would respawn in middle of screen, not sure it is what you want (would have to change the initial coordinate setup)

 

I also found a bug in my code, and use of rapCollide() (and also explanations in 1st post, but I can't edit it anymore)

The explanation is correct (it takes from start number to end number). But, when you have 18 chicks to test, you must make CHICKS+17 (as 1st value is consider as 0, so 0 to 17 = 18 values).

Stupid coder :(

 

 

 

I also find it more enjoyable is you set bomb move speed at +1 or -1

 

I also corrected the crappy part, I will probably repush a new sourcecode, probably tomorrow

Thank you for this. I really appreciate your detailed explanations.

 

I actually have zero coding experience and am learning everything from scratch which is very daunting. I tend to find things make more sense to me if I have something to reference, such as your code, that I can manipulate.

 

I change and add things and see if it works. For me this is how I learn best.

 

I have no idea how to do an init procedure so will study your code and see if it has one for reference.

 

Thank you 

Edited by mdkdue
  • Like 1
Link to comment
Share on other sites

On 1/18/2023 at 9:26 AM, SlidellMan said:

That was well said, but there are still some typos that you didn't get the first time.

 

Update: @CyranoJ mentioned that you can use HWIDTH if you want to use horizontal strip spritesheets.

I actually meant to say gwidth, and you can also write a proper sprite table with each sprite having an index.

@Fadest This looks like something you can look into.

  • Like 1
Link to comment
Share on other sites

Thanks, yes, gwidth should work, you just need to set the gfxbase accordingly to start adress + id of sprite*size of a line sprite, but from my understanding, RAPTOR API is the underlying API of JagStudio, and CJ explicitely say vertically is the way he choosed for RAPTOR API

 

And it makes sense if you look at animation & R_sprite_framesz (size of byte to load next sprite in animation), it is the size of 1 sprite line multiply by number of lines. So referring to my very old Atari ST/68000 ASM memory, it seems to me it is done for maximum performance, so spritesheet should be vertical (ie the width of sprite sheet = the width of 1 sprite) if you want to use it, and RAPTOR "just" have to add the size of a sprite in bytes to the file pointer to get next sprite.

Putting them horizontal even in JagStudio seems to be possible with gwidth, but I am not sure automatic animations could be done via RAPTOR API. Maybe by setting framesz with same value than gwidth should be enough... if framesz is only used via the animation routine, and not by something else.

If it does not work, this would means setting the graphical pointer manually at each frame (not a big deal, after all, this is what I used to do when I used the SebRMV libraries - putting all sprites adress inside an array to access them, but when things can be done hidden and optimised, it is still better)

 

So probably it would work, I don't know, my mind says maximum performance with Jagstudio/Raptor API is via using vertical spritesheet (if you need automatic animation, or easy way to jump to a given sprite frame without storing each sprite adress or rewriting internal Raptor routines), and I am too lazy to test other method...

 

I guess it depends which part of the API you want to use, if you don't care for animations (for items spritesheet for example), putting them horizontal can make sense.

You can also put the sprite where you want in the bitmap file, you just need to know how to calculate the offset from the start of the file in bytes.

 

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

Thanks to Reboot for this great piece of tool
Thanks to Fadest for its tuto


I just did a test. I'm a bit confused but the compilation works! However, I think it is not the correct output... strange (see screenshot)
This is my very first test on Jaguar ;)

 

I continue to search :)

see you

Capture d’écran 2023-05-08 000254.jpg

  • Like 2
Link to comment
Share on other sites

On 5/7/2023 at 6:17 PM, Eric M said:

Thanks to Reboot for this great piece of tool
Thanks to Fadest for its tuto


I just did a test. I'm a bit confused but the compilation works! However, I think it is not the correct output... strange (see screenshot)
This is my very first test on Jaguar ;)

 

I continue to search :)

see you

Capture d’écran 2023-05-08 000254.jpg

Have you tried running the binaries in BigPEmu? Sometimes it something going wrong with Virtual Jag from what I've encountered.

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

ZeroPage Homebrew is playing Flappy Chicken on tomorrow's ZPH stream LIVE on Twitch, hope you can join us!

 

Games:

 WATCH AT 1080P FOR BEST QUALITY

 

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...