Page 1 of 1

Pausing

Posted: Mon Dec 04, 2017 3:50 am
by rrTea
One thing I was thinking of implementing manually was the ability to pause the game...

...but this turned to be impractical (absolutely everything in App.OnUpdate, Model.OnUpdate and Model.Sate.OnUpdate would have to be individually wrapped in a special and maybe customized Condition) or impossible (particles and certain sounds are impossible to control directly, there are probably other aspects that I don't know of). Explosions and RenderParticle background effects are the ones most affected, because it looks weird if everything on the screen stops but the explosion renders on. Also I guess that if it's done manually I'd probably have to also save some values on start of the pause and load it back on exit (for example certain Model.Velocity properties etc) which further complicates the idea.

How would an eventual "engine-supported" pause work (a specialized State? Model? scripting?) and is it even "compatible" with ZGE?

Re: Pausing

Posted: Mon Dec 04, 2017 9:15 am
by VilleK
I think some of Jphs games have pause feature but I don't know how he implemented it.

I would probably make a AppState called "PlayingState" and another "PausedState" but I can guess there are some issues like those you explained, yes. If there was a full "engine stop" feature then at least it would have to still run something to let the user unpause again. Note that AppState has "ModelUpdatesEnabled" property so that it you uncheck that then time will freeze for all existing model instances, I think I designed that to enable pause.

Re: Pausing

Posted: Mon Dec 04, 2017 11:03 am
by rrTea
I made a very quick test and it works well if I toggle "ModelUpdatesEnabled" during runtime (models freeze as if paused). It even stops the RenderParticle if it's inside a model - excellent! I'll test it a bit more tomorrow in some trickier situations (unless I get knocked out by a virus) and report back!

Re: Pausing

Posted: Tue Dec 05, 2017 8:20 am
by rrTea
This is great, it turns out I didn't even have to use two states. Tested it in different situations and it all works perfectly!

Re: Pausing

Posted: Thu Jun 21, 2018 10:49 pm
by Ats
Hi, I'm back in the game after a VERY long time... And I forgot a few things about how ZGE works...
How do you toggle the AppState "ModelUpdatesEnabled" from a ZExpression?

Re: Pausing

Posted: Thu Jun 21, 2018 11:05 pm
by Kjell
Hi Ats,
Ats wrote:How do you toggle the AppState "ModelUpdatesEnabled" from a ZExpression?
You can use the following expression ..

Code: Select all

MyAppState.ModelUpdatesEnabled = MyAppState.ModelUpdatesEnabled ? 0 : 1;
Below is a simple example ( press space-bar to toggle ) :wink:

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" FileVersion="2">
  <OnLoaded>
    <SetAppState State="Demo"/>
  </OnLoaded>
  <States>
    <AppState Name="Demo">
      <OnStart>
        <Repeat Count="8" WhileExp="//">
          <OnIteration>
            <SpawnModel Model="Sprite"/>
          </OnIteration>
        </Repeat>
      </OnStart>
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[//

Key[1] = Key[0];
Key[0] = 0;]]>
          </Expression>
        </ZExpression>
        <KeyPress Keys=" ">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Key[0] = 1;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
        <ZExpression>
          <Expression>
<![CDATA[//

if(Key[0] && !Key[1])
{
  Demo.ModelUpdatesEnabled = Demo.ModelUpdatesEnabled ? 0 : 1;
}]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
    </AppState>
  </States>
  <Content>
    <Array Name="Key" Type="4" SizeDim1="2"/>
    <Model Name="Sprite">
      <OnSpawn>
        <ZExpression>
          <Expression>
<![CDATA[//

Sprite.Position.X = random(0, 6);
Sprite.Position.Y = random(0, 4);

Sprite.RotationVelocity.Z = random(0, 1);]]>
          </Expression>
        </ZExpression>
      </OnSpawn>
      <OnRender>
        <RenderSprite/>
      </OnRender>
    </Model>
  </Content>
</ZApplication>
K

Re: Pausing

Posted: Fri Jun 22, 2018 12:50 am
by Ats
Thanks Kjell, glad to see you are still here :)
Pause is working like a charm !

By the way, using:

Code: Select all

init:
 Key[1] = Key[0];
 Key[0] = 0;
pressing key:
 Key[0] = 1;
resolution:
 if(Key[0] && !Key[1])
is so simple compared to what I did in the game I'm trying to resurect... It's time for some code refactoring.

Re: Pausing

Posted: Fri Jun 22, 2018 1:57 am
by Kjell
Hi Ats,

I've been using ( variations of ) the following approach for as long as i can remember ..

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" ClearColor="0.5 0.5 0.5 1" FileVersion="2">
  <OnLoaded>
    <SpawnModel Model="Sprite"/>
  </OnLoaded>
  <OnUpdate>
    <Repeat Name="AxisRepeat">
      <OnIteration>
        <ZExpression>
          <Expression>
<![CDATA[//

int i = AxisRepeat.Iteration;

//

Axis[i,1] = Axis[i,0];
Axis[i,0] = 0;

//

AxisPositive.CharCode = AxisMap[i,0];
AxisNegative.CharCode = AxisMap[i,1];]]>
          </Expression>
        </ZExpression>
        <KeyPress Name="AxisPositive" CharCode="38">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration,0]++;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
        <KeyPress Name="AxisNegative" CharCode="40">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Axis[AxisRepeat.Iteration,0]--;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
        <ZExpression>
          <Expression>
<![CDATA[//

int i = AxisRepeat.Iteration;

//

Axis[i,2] = Axis[i,0] && !Axis[i,1] ? Axis[i,0] : 0;]]>
          </Expression>
        </ZExpression>
      </OnIteration>
      <WhileExp>
<![CDATA[//

return Iteration < Axis.SizeDim1;]]>
      </WhileExp>
    </Repeat>
    <Repeat Name="ButtonRepeat">
      <OnIteration>
        <ZExpression>
          <Expression>
<![CDATA[//

int i = ButtonRepeat.Iteration;

//

Button[i,1] = Button[i,0];
Button[i,0] = 0;

//

ButtonPress.CharCode = ButtonMap[i];]]>
          </Expression>
        </ZExpression>
        <KeyPress Name="ButtonPress" CharCode="68">
          <OnPressed>
            <ZExpression>
              <Expression>
<![CDATA[//

Button[ButtonRepeat.Iteration,0] = 1;]]>
              </Expression>
            </ZExpression>
          </OnPressed>
        </KeyPress>
        <ZExpression>
          <Expression>
<![CDATA[//

int i = ButtonRepeat.Iteration;

//

Button[i,2] = Button[i,0] && !Button[i,1];
Button[i,3] = Button[i,1] && !Button[i,0];]]>
          </Expression>
        </ZExpression>
      </OnIteration>
      <WhileExp>
<![CDATA[//

return Iteration < Button.SizeDim1;]]>
      </WhileExp>
    </Repeat>
  </OnUpdate>
  <Content>
    <Array Name="Axis" Dimensions="1" SizeDim1="2" SizeDim2="3"/>
    <Array Name="AxisMap" Type="4" Dimensions="1" SizeDim1="2" SizeDim2="2" Persistent="255">
      <Values>
<![CDATA[78DA535755D300000183009B]]>
      </Values>
    </Array>
    <Array Name="Button" Type="4" Dimensions="1" SizeDim1="3" SizeDim2="4"/>
    <Array Name="ButtonMap" Type="4" SizeDim1="3" Persistent="255">
      <Values>
<![CDATA[78DA730C76010001B000D9]]>
      </Values>
    </Array>
    <Model Name="Sprite">
      <OnUpdate>
        <ZExpression>
          <Expression>
<![CDATA[/*
 * Axis[0,?] = X axis
 * Axis[1,?] = Y axis
 *
 * Axis[?,0] = Current state
 * Axis[?,1] = Previous state
 * Axis[?,2] = Delta ( when current value is non-zero )
 */

Sprite.Position.X += Axis[0,2];
Sprite.Position.Y += Axis[1,2];

/*
 * Button[0,?] = A button
 * Button[1,?] = S button
 * Button[2,?] = D button
 *
 * Button[?,0] = Current state
 * Button[?,1] = Previous state
 * Button[?,2] = Pressed state
 * Button[?,3] = Released state
 */

if(Button[0,2])SpriteColor.Color.R = SpriteColor.Color.R ? 0 : 1;
if(Button[1,2])SpriteColor.Color.G = SpriteColor.Color.G ? 0 : 1;
if(Button[2,2])SpriteColor.Color.B = SpriteColor.Color.B ? 0 : 1;]]>
          </Expression>
        </ZExpression>
      </OnUpdate>
      <OnRender>
        <RenderSetColor Name="SpriteColor"/>
        <RenderSprite/>
      </OnRender>
    </Model>
  </Content>
</ZApplication>
Use the arrow keys to move the sprite and the A/S/D keys to toggle the sprites' RGB components. Also, make sure to check the ZExpression in Sprite.OnUpdate.

Still .. the KeyPress component should have OnTrue / OnFalse / OnPressed / OnReleased events instead of just a OnPressed :wink:

K

Re: Pausing

Posted: Sun Jun 24, 2018 9:55 pm
by Ats
Two little notes for my future self when I'll stumble on that problem again:

Pausing the game with ModelUpdatesEnabled isn't pausing the Timer componant, so it needs to be stacked after a Condition componant with

Code: Select all

return GameState.ModelUpdatesEnabled;
Pausing the game in preview mode deactivates the ModelUpdatesEnabled property of the AppState componant. It's weird, but it's not a bug in the game.

Re: Pausing

Posted: Mon Jun 25, 2018 5:05 pm
by Kjell
Hi,
Ats wrote:Pausing the game in preview mode deactivates the ModelUpdatesEnabled property of the AppState componant. It's weird, but it's not a bug in the game.
I'd recommend putting a ZExpression in App.OnClose that resets the ModelUpdatesEnabled property of your AppState(s) so you don't have to think about it during development :wink:

K