Catgirl Pool Party [Work in progress]

Announce (tech) demos or games releases

Moderator: Mask of Destiny

User avatar
SegaTim
Very interested
Posts: 90
Joined: Thu Nov 19, 2015 1:59 pm
Location: East Prussia
Contact:

Re: Catgirl Pool Party [Work in progress]

Post by SegaTim » Thu Nov 17, 2016 9:27 pm

Kega Fusion 3.51 or 3.64 - bad emulation. Use a Regen emulator - it's good!Or GENS versions...

User avatar
Stef
Very interested
Posts: 2775
Joined: Thu Nov 30, 2006 9:46 pm
Location: France - Sevres
Contact:

Re: Catgirl Pool Party [Work in progress]

Post by Stef » Thu Nov 17, 2016 11:40 pm

SGDK provides an event callback for that: at each controller state change you receive the given controller current state and changed state.

User avatar
Sik
Very interested
Posts: 709
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Catgirl Pool Party [Work in progress]

Post by Sik » Fri Nov 18, 2016 4:24 pm

Miquel wrote:No more complex if's, you just have to live with different input variables.
To be fair, having separate "it's held down" and "was just pressed" variables isn't any inconvenience at all (given how in practice you need both things). Just make sure it gets updated every frame everywhere (this is why I tend to wrap those do-it-every-frame things around neatly in a "NextFrame" function that also does the vsync :v).
Sik is pronounced as "seek", not as "sick".

User avatar
Miquel
Very interested
Posts: 329
Joined: Sat Jul 30, 2016 12:33 am

Re: Catgirl Pool Party [Work in progress]

Post by Miquel » Fri Nov 18, 2016 6:43 pm

I agree, it should be updated every frame (no matter what) and accessible everywhere.

Hik
Very interested
Posts: 62
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Catgirl Pool Party [Work in progress]

Post by Hik » Fri Nov 18, 2016 8:10 pm

I actually have a pretty good code for the buttons which works just fine. I made a flowchart which gives an idea of what it looks like.

I just had to chart it out and make small modifications to make it work for jumping. But the jumping state isn't working like it should.
On my experimental code it now jumps fine and doesn't jump constantly like before while the button is held ,but visually the jumping frame is off.

I have the action buttons mapped and when the button for jump is pressed and its not moving vertically ,it puts in jump speed.
Then I put in a proxy variable which says its jumping and when it hits the ground (or just before it hits the ground) I switch the proxy off.

I'm using some code from the sprite sample for physics since it works.

Sample of how I mapped the buttons;

Code: Select all

    if(c == 1)actions[2] = 1; //(state & BUTTON_C) is used for jump
    if(c == 0)actions[2] = 0; //(changed) when jump button is released
Here the button mapped is used to do something;

Code: Select all

void commandFunction()
{
...
    if(actions[2] == 1) //Button configured for jump is active
    {
        VDP_drawText("C", 16, 2); //Button C is mapped for jump in experimental code
        if(jump==0 && movy == 0)
        {
            movy = JUMP_SPEED; //Jumps
            jump = 1;
        }
    }
    if(actions[2] == 0)
    {
        VDP_clearText(16, 4, 4);
        jump = 0;
    }
This is just a simple code snippet for the jumping state;

Code: Select all

void stateMachine()
{
    if(jump == 1)
    {
        st = 1; //This is the proxy variable
    }
}
Some physics from the sprite sample with small modifications/additions;

Code: Select all

void updatePhysics()
{
...
    if (movy != 0) // != 0
    {
        if (pos1y > MAX_POSY)
        {
            pos1y = MAX_POSY;
            movy = 0;
            st = 0;
        }
        else movy += GRAVITY;
        if (movy <= FIX32(-0.1)&& movy >= FIX32(-2)) //Trying to catch in the air to exit jumping state before landing
        {
            st = 0;
        }
    }
...
}
This is a switch which does a bunch of things for getting the soaker to point in 8 directions;

Code: Select all

void motionToward() //
{
    switch(jyp)
    {
        case 0:  //No direction
        {
            if(st == 1)frame = 12;
            else frame = 0;
	     ...
        }
        break;
        case 1:
        {
            facingleft = 0; //
            if(st == 1)frame = 12;
            else if(aim == 1)frame = 3; //RIGHT
            else frame = 6;
	     ...
        }
        break;
    ...
    }
}
These are all the frames used for the catgirl in this version of the demo;

Code: Select all

#define CATGIRL_WU		0 //Walk
#define CATGIRL_W		1
#define CATGIRL_WD		2
#define CATGIRL_NULL	3 //Stand
#define CATGIRL_U		4 //Aim
#define CATGIRL_SU		5
#define CATGIRL_S		6
#define CATGIRL_SD		7
#define CATGIRL_D		8
#define CATGIRL_AU		9 //In the air / falling
#define CATGIRL_ASU		10
#define CATGIRL_AS		11
#define CATGIRL_ASD		12
#define CATGIRL_AD		13
And here's the experimental rom from the experimental code I use for testing;
https://www.dropbox.com/s/fc81uqrlabfgc ... t.bin?dl=1

User avatar
Miquel
Very interested
Posts: 329
Joined: Sat Jul 30, 2016 12:33 am

Re: Catgirl Pool Party [Work in progress]

Post by Miquel » Sat Nov 19, 2016 11:39 am

Ok, after reviewing your code, things I want to say:

- Use a state machine for the "stages" of your character. Using speedY to know if you are jumping is a very bad idea. This code is going to grow exponentially while you are adding more features and typically is not nice to read, so pay special attention to it, spend some time. Your "jump" and "st" variables are just 2 states, being "Jumping" and "Falling". The passing from "Falling" to "Standing"/"Walking" is done by the collision function, so be creative here meanwhile.

- Try to not mix animation with state changes.

- Using a position to limit character jump also is a very bad idea, use a frame counter instead (or displacement counter).

- ¿ Do you want to change direction in mid jump/falling ? Usually it enhances playability, is a good idea to at least leave it ready. Then your code dealing with 8 directions doesn't seem to be a good thought. Usually is good to break motion response in the two axis (don't mix them). And don't think of your game as a physics simulator, is not.

Normally I will do something like this:

Code: Select all

// Code for MD int/uint/enum is 2 bytes

uint buttons;			// data is refreshed at the begining of the frame
uint newPressButtons;	// "

typedef enum _ActorState // 
{
	Stand,
	Walk,
	JumpBegin,
	Jump,
	FallBegin,
	Fall,
} ActorState;

typedef struct _Actor
{
	//... a lot of things go here....
	// among these:
	ActorState state;
	u8 stateCount;
	fixedPoint speedX, speedY;
} Actor;

void ActorStateChange( Actor* pActor )
{
	switch( pActor->state )
	{
		case Stand:
			if( newPressButtons & BUTTON_JUMP )
			{
				pActor->state = JumpBegin;
			}
			break;
		case Walk:
			if( newPressButtons & BUTTON_JUMP )
			{
				pActor->state = JumpBegin;
			}
			if( buttons & BUTTON_LEFT )
			{
				pActor->speedX = -0.5;
			}
			else if( buttons & BUTTON_RIGHT )
			{
				pActor->speedX = 0.5;
			}
			break;
		case Jump:
			if( (--pActor->stateCount == 0) || !(buttons & BUTTON_JUMP) )
			{
				pActor->state = FallBegin;
			}
			break;
		case Fall:
			break;
	}
	switch( pActor->state )
	{
		case JumpBegin:
			pActor->state = Jump;
			pActor->speedY = -5.5;
			pActor->stateCount = 32;
			break;
		case FallBegin:
			pActor->state = Fall;
			pActor->speedY = 5.5;
			break;
	}
}

void ActorMove( Actor* pActor )
{
	ActorStateChange( pActor );
	ActorAnimate( pActor );
}

User avatar
Sik
Very interested
Posts: 709
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Catgirl Pool Party [Work in progress]

Post by Sik » Sat Nov 19, 2016 11:59 am

Miquel wrote:- Use a state machine for the "stages" of your character. Using speedY to know if you are jumping is a very bad idea. This code is going to grow exponentially while you are adding more features and typically is not nice to read, so pay special attention to it, spend some time. Your "jump" and "st" variables are just 2 states, being "Jumping" and "Falling". The passing from "Falling" to "Standing"/"Walking" is done by the collision function, so be creative here meanwhile.
My experience is the exact opposite, I never store the current action and just figure out what's going on from the current physics values and such and never ever had any sort of issues. In fact, a lot of the glitches in modern AAA games tend to come from using a state machine then the state going out of sync with the current situation of the object. They're extremely prone to introducing bugs basically. The only reason they're used so often is that they look more intuitive, but that's it.

What I prefer to do is to rely on two things: stuff like the current physics and timers, and a bunch of flags to indicate special situations (e.g. an "on floor" flag to tell when you're standing on something (since Y speed == 0 could also just mean the middle point between going upwards and downwards), a "hurt" flag that when set makes the player object disregard joypad input and also prevents it from being hurt again until the flag gets cleared - but since it only affects a few specific things the rest of the logic remains unchanged, so physics and the like work normally). This tends to work pretty well and it's horribly hard to go out of sync (or prone to resync itself quickly if that ever happens).

Also don't forget: usually you don't want behavior based on what the object looks to be doing, you want responses based on specific generic events to ensure as much as possible simply works "as-is" (without special cases). State machines are not helpful here.
Sik is pronounced as "seek", not as "sick".

User avatar
Miquel
Very interested
Posts: 329
Joined: Sat Jul 30, 2016 12:33 am

Re: Catgirl Pool Party [Work in progress]

Post by Miquel » Sat Nov 19, 2016 2:29 pm

What's the difference between "the current action" and "figure out what's going on" at the creative level?

I'm confuse:
- Are we talking about 68000 or i5 games? Old 2D or 3D games? MD/Genesis or PC games?
- first you say "flags to indicate special situations", then "as much as possible simply works "as-is" (without special cases)".
- first you say "figure out what's going on from the current physics values", but then you say "bunch of flags to indicate special situations".

What's the diference between "bunch of flags" to a state machine, really?

User avatar
Sik
Very interested
Posts: 709
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Catgirl Pool Party [Work in progress]

Post by Sik » Sat Nov 19, 2016 5:54 pm

Miquel wrote:What's the difference between "the current action" and "figure out what's going on" at the creative level?
We're talking about the programming though. One thing is determining the current state on the fly each frame, another is literally storing it in a variable that's explicitly altered to make the object do something different (and then risking it going out of sync because something didn't get updated properly on a not-so-edge case).
Miquel wrote:- Are we talking about 68000 or i5 games? Old 2D or 3D games? MD/Genesis or PC games?
This matters on either case.
Miquel wrote:- first you say "figure out what's going on from the current physics values", but then you say "bunch of flags to indicate special situations".
The flags are complements (and can take effect simultaneously if needed), they don't directly indicate what's going on. The direction you're currently looking at is another such flag.
Miquel wrote:What's the diference between "bunch of flags" to a state machine, really?
The states in a state machine can't be combined, the flags can (and are expected to). Unless you want to have stuff like WalkLeft vs WalkRight. Actually your example already has some kind of redundancy like that (Jumping vs Falling, even though they're literally the same thing except for the sign of the Y speed, and the physics engine wouldn't care about that difference).


EDIT: also for what matters, on how I normally handle jumps: what I do is there's an OnFloor flag that gets set whenever an object is standing on something. This is set by the physics engine (if it updates and notices the object is right on a floor and not moving upwards). Then the player code would determine if it's in the air or not just by looking at this flag, and jumping would be simply a matter of checking if the jump button is pressed when not in the air and if so setting the Y speed upwards (the OnFloor flag will get updated the next time physics are handled). If I really care about jumping being handled different from non-jumping (e.g. for variable jumps to not trigger with springs and such), then there'd be an OnJump flag that gets set when you jump and cleared the moment OnFloor is found to be set, and is only used for jump-specific behavior (again, usually just the variable jump stuff).

As for variable jump, what I do these days is if 1) in the air moving upwards and 2) the jump button is not pressed, then apply gravity twice (i.e. fall twice as fast). Seems to work quite well. As for changing horizontal speed mid-air, well just let the horizontal movement code work as usual for the most part. When in the air, divide acceleration/friction by 2 for more intuitive behavior, and that's it.
Sik is pronounced as "seek", not as "sick".

Hik
Very interested
Posts: 62
Joined: Thu Jul 30, 2015 11:39 pm
Location: Iceland

Re: Catgirl Pool Party [Work in progress]

Post by Hik » Sun Nov 20, 2016 5:39 pm

Thanks for the feedback. I almost have the jumping working properly now.
The only thing left to fix with it is that when the button is held down it doesn't leave the jumping frame
until the jumping button is released. Other than that it seems to work perfect. To fix the sync issue
with getting into the jump I just put it into the correct frame in the same place I set the jump speed.

https://www.dropbox.com/s/7lf8vhzdws56n ... 2.bin?dl=1

Edit: I've fixed the jumping and updated it into the rom in the first post

User avatar
Miquel
Very interested
Posts: 329
Joined: Sat Jul 30, 2016 12:33 am

Re: Catgirl Pool Party [Work in progress]

Post by Miquel » Mon Nov 21, 2016 7:35 pm

Current animation should be set accordingly with current state, and has noting to do directly with buttons. Meaning: buttons can change state, and state determines animation.
Sik wrote: We're talking about the programming though. One thing is determining the current state on the fly each frame, another is literally storing it in a variable that's explicitly altered to make the object do something different (and then risking it going out of sync because something didn't get updated properly on a not-so-edge case).
So at the end you work with states. The problem is another one: One idea can be expressed with an incountable number of expressions.

User avatar
Sik
Very interested
Posts: 709
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Catgirl Pool Party [Work in progress]

Post by Sik » Mon Nov 21, 2016 10:41 pm

But then at that point we could argue that the X coordinate is a state in a state machine and the whole discussion went to hell :P (a state machine is literally storing the current action in a dedicated variable like that whole JumpBegin/Jump/FallBegin/Fall mess)
Sik is pronounced as "seek", not as "sick".

User avatar
Miquel
Very interested
Posts: 329
Joined: Sat Jul 30, 2016 12:33 am

Re: Catgirl Pool Party [Work in progress]

Post by Miquel » Mon Nov 21, 2016 11:56 pm

Yes, an state can be any concatenation of values that you desire, including an enumeration of course, the only thing: they have to be unique.

Put a code example about how you would do it, and perhaps we will understand each other.

User avatar
Sik
Very interested
Posts: 709
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: Catgirl Pool Party [Work in progress]

Post by Sik » Tue Nov 22, 2016 1:02 am

Some awful quick pseudocodish mock-up since I don't have time now (and proper code would be quite complex due to being mixed in with a lot of the player logic) but should help give an idea. The closest it gets to a state machine is the animation stuff at the very end, and that only controls the animation rather than the actual logic (i.e. that state machine is for the final outcome rather than for the behavior behind it).

Code: Select all

   // To let left+right work
   if (button_left && button_right) {
      button_left = FALSE;
      button_right = FALSE;
   }
   
   // Running
   accel = on_floor ? ACCEL : ACCEL/2;
   
   if (button_right) {
      x_speed += accel;
      if (x_speed > MAX_SPEED)
         x_speed = MAX_SPEED;
   }
   else if (button_left) {
      x_speed -= accel;
      if (x_speed < -MAX_SPEED)
         x_speed = -MAX_SPEED;
   }
   else if (x_speed > 0) {
      x_speed -= accel;
      if (x_speed < 0) x_speed = 0;
   }
   else if (x_speed < 0) {
      x_speed += accel;
      if (x_speed > 0) x_speed = 0;
   }
   
   // Falling (handles variable jump too)
   y_speed += WEIGHT;
   if (!on_floor && !button_jump && y_speed < 0)
      y_speed += WEIGHT;
   
   // Do collision against map and such
   // This is where x_speed and y_speed are used
   // on_floor gets updated after the fact too
   do_physics();
   
   // Jumping
   if (on_floor && button_jump) {
      y_speed = -JUMP_FORCE;
      play_sfx(SFX_JUMP);
   }
   
   // Set animation
   // Animation wouldn't restart if it was the same as before
   // Yes animation should be handled separately from logic
   if (!on_floor) {
      set_anim(y_speed < 0 ? ANIM_JUMP : ANIM_FALL);
   } else if (abs(x_speed) >= RUN_SPEED) {
      set_anim(ANIM_RUN);
   } else {
      set_anim(ANIM_IDLE);
   }
Sik is pronounced as "seek", not as "sick".

User avatar
Miquel
Very interested
Posts: 329
Joined: Sat Jul 30, 2016 12:33 am

Re: Catgirl Pool Party [Work in progress]

Post by Miquel » Wed Nov 23, 2016 3:14 pm

Sik wrote:Some awful quick pseudocodish mock-up since I don't have time now (and proper code would be quite complex due to being mixed in with a lot of the player logic) but should help give an idea. The closest it gets to a state machine is the animation stuff at the very end, and that only controls the animation rather than the actual logic (i.e. that state machine is for the final outcome rather than for the behavior behind it).
- What about getting state from physics status ?

- Do you really want me to tell you what I truly think ? Or it was just a discussion without meaning?

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest