GameData: Save value of variable after player death

Post here for help and support regarding LunaLua and SMBX2's libraries and features.
Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

GameData: Save value of variable after player death

Postby Just_Thomas » Sat Jan 13, 2024 10:09 am

Code: Select all

local Routine = API.load("Routine")
local inputs2 = API.load("inputs2")

local myGameData
do
	local levelstartwarp
	GameData = GameData[levelstartwarp] or {}
	myGameData = GameData[levelstartwarp]
end

function onStart()
   	local defaultLayer = Layer.get("Default")
	defaultLayer:show(true)
	local lvlstartLayer = Layer.get("LevelScreenPlattform")
	lvlstartLayer:show(true)
end

function onTick()
	 Text.print(myGameData, 100, 100)

	if player.y < -180032 and player.section == 0 then
		Routine.run(levelStartScreen)
	end

	if player.section == 1 then
		Routine.run(IncreaseCounter)
end

function levelStartScreen()
	local lvlstartLayer = Layer.get("LevelScreenPlattform")
	inputs2.locked[1].all = true
	player.speedX = 0
	lvlstartLayer.speedY = 2.5
	Routine.waitFrames(200)
	lvlstartLayer.speedY = 0
	inputs2.locked[1].all = false
end

function IncreaseCounter()
	myGameData = myGameData +1
end
Once you reach a checkpoint the "global value" gets changed and because different layers get hidden or shown, it would mean the player would get teleported to the "last reached" checkpoint.

In case context is needed: I try to integrate some kind of "fake checkpoints" (without powerup and sfx).
At the beginning of the level a fake loading screen is visible (works fine, not the problem here) and after a bunch of seconds the player is supposed to get warped to the last "checkpoint". HOWEVER I need a variable which does store the right and last value instead to reset every time after the player death.
Since this should work like in the origional SMB without savepoints and worldmap I need a variable which does save after player death.
I want to use GameData because if you close SMBX you have to restart with the first level
(I plan to use Auto-loading next level after winning • levellist.lua
myGameData or levelstartwarp could be used beyond the corresponding level as follows.
World 1-1: Player reaches first "checkpoint" -> Value: 1
player dies
Value stays 1
player restarts at last checkpoint
player dies (before next checkpoint)
Value stays 1, no progress of the player
player reaches second "Checkpoint" -> Value: 2
Player reaches World 1-2 (Value for safety reasons: 3)
player dies
Value still 3, player restarts from levelstart of World 1-2
player reaches first "Checkpoint" (of 1-2): Value 4
player dies
player restarts at last checkpoint (first one of 1-2)
...
I think you get it now

I am honest: I do not really know what I am doing here. I barely understood some basic things from the Demolevels and and try to find the grain here like a blind hen. I hope that by showing something here, someone will be willing to tell me how it works. These documentaries are a bit difficult for people like me to understand. I'm not really the scripting type (never have been in my life).

LooKiCH
Tweeter
Tweeter
Posts: 159
Joined: Tue Jun 13, 2017 11:28 am
Pronouns: he/him
Contact:

Re: GameData: Save value of variable after player death

Postby LooKiCH » Sat Jan 13, 2024 1:38 pm

use Misc.saveGame()
Just_Thomas wrote:
Sat Jan 13, 2024 10:09 am

Code: Select all

local Routine = API.load("Routine")
local inputs2 = API.load("inputs2")

local myGameData
do
	local levelstartwarp
	GameData = GameData[levelstartwarp] or {}
	myGameData = GameData[levelstartwarp]
end

function onStart()
   	local defaultLayer = Layer.get("Default")
	defaultLayer:show(true)
	local lvlstartLayer = Layer.get("LevelScreenPlattform")
	lvlstartLayer:show(true)
end

function onTick()
	 Text.print(myGameData, 100, 100)

	if player.y < -180032 and player.section == 0 then
		Routine.run(levelStartScreen)
	end

	if player.section == 1 then
		Routine.run(IncreaseCounter)
end

function levelStartScreen()
	local lvlstartLayer = Layer.get("LevelScreenPlattform")
	inputs2.locked[1].all = true
	player.speedX = 0
	lvlstartLayer.speedY = 2.5
	Routine.waitFrames(200)
	lvlstartLayer.speedY = 0
	inputs2.locked[1].all = false
end

function IncreaseCounter()
	myGameData = myGameData +1
end
Once you reach a checkpoint the "global value" gets changed and because different layers get hidden or shown, it would mean the player would get teleported to the "last reached" checkpoint.

In case context is needed: I try to integrate some kind of "fake checkpoints" (without powerup and sfx).
At the beginning of the level a fake loading screen is visible (works fine, not the problem here) and after a bunch of seconds the player is supposed to get warped to the last "checkpoint". HOWEVER I need a variable which does store the right and last value instead to reset every time after the player death.
Since this should work like in the origional SMB without savepoints and worldmap I need a variable which does save after player death.
I want to use GameData because if you close SMBX you have to restart with the first level
(I plan to use Auto-loading next level after winning • levellist.lua
myGameData or levelstartwarp could be used beyond the corresponding level as follows.
World 1-1: Player reaches first "checkpoint" -> Value: 1
player dies
Value stays 1
player restarts at last checkpoint
player dies (before next checkpoint)
Value stays 1, no progress of the player
player reaches second "Checkpoint" -> Value: 2
Player reaches World 1-2 (Value for safety reasons: 3)
player dies
Value still 3, player restarts from levelstart of World 1-2
player reaches first "Checkpoint" (of 1-2): Value 4
player dies
player restarts at last checkpoint (first one of 1-2)
...
I think you get it now

I am honest: I do not really know what I am doing here. I barely understood some basic things from the Demolevels and and try to find the grain here like a blind hen. I hope that by showing something here, someone will be willing to tell me how it works. These documentaries are a bit difficult for people like me to understand. I'm not really the scripting type (never have been in my life).

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Sat Jan 13, 2024 1:58 pm

First of all, thanks for bothing to help me.
How would I use it? It does read like "loading a save-state" instead (emulator or Nintendo Switch Online), which is not what I would want.
I mean, if the player dies, he has to start again but will be "warped" to the last "checkpoint" via toggling of warp layers.
So, how do I use that?
Let`s say each warp to a checkpoint uses a different layer

e.g. Level has 2 checkpoints
First config would be:
warpstart:show(true)
warp1layer:hide(true)
warp2layer:hide(true)

then after activating the checkpoint:
warpstart:hide(true)
warp1layer:show(true)
warp2layer:hide(true)

and after second one:
warpstart:hide(true)
warp1layer:hide(true)
warp2layer:show(true)

I mean, do I not need a variable for checking, to which warp the player will be brought?

Edit: Nope, ...
local Routine = API.load("Routine")
local inputs2 = API.load("inputs2")
local test = 0

function onStart()
local defaultLayer = Layer.get("Default")
defaultLayer:show(true)
local lvlstartLayer = Layer.get("LevelScreenPlattform")
lvlstartLayer:show(true)
end

function onTick()
Text.print(test, 100, 100)

if player.y < -180032 and player.section == 0 then
Routine.run(levelStartScreen)
end

if player.section == 1 then
Routine.run(IncreaseCounter)

end
end

function levelStartScreen()
local lvlstartLayer = Layer.get("LevelScreenPlattform")
inputs2.locked[1].all = true
player.speedX = 0
lvlstartLayer.speedY = 2.5
Routine.waitFrames(200)
lvlstartLayer.speedY = 0
inputs2.locked[1].all = false
end

function IncreaseCounter()
if test ==0 then
test = test +1
end

Misc.saveGame()
end
test value shows each restart (yes, I test that ingame NOT from the editor) 0 at the beginning, which is not supposed to be.
After I reached section 1 for the first time the value 1 should stay...
unless there is a huge flaw in that "code", which also might be possible of course.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: GameData: Save value of variable after player death

Postby Emral » Sat Jan 13, 2024 6:50 pm

if you wanna remove powerups and sounds from checkpoints you can just do that

function onStart()
for k,v in ipairs(NPC.get({400, 430}) do
v.data._basegame.checkpoint.sound = nil
v.data._basegame.checkpoint.powerup = nil
end
end

or you can load the checkpoints library

local checkpoints = require("checkpoints")
local cp1 = checkpoints.create{x = 400, y = 300, section = 1}

-- collect it with onEvent for example
function onEvent(eventName)
if eventName == "collectCP1" then
cp1:collect()
end
end

-- you can also check starting cp in onStart
function onStart()
local c = checkpoints.getActive()
if c == cp1 then -- if the player starts at cp1
Layer.get("AAAA"):show(true)
end
end

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Sun Jan 14, 2024 5:39 am

LooKiCH wrote:
Sat Jan 13, 2024 1:38 pm
use Misc.saveGame()
Just_Thomas wrote:
Sat Jan 13, 2024 10:09 am
Emral wrote:
Sat Jan 13, 2024 6:50 pm
if you wanna remove powerups and sounds from checkpoints you can just do that

function onStart()
for k,v in ipairs(NPC.get({400, 430}) do
v.data._basegame.checkpoint.sound = nil
v.data._basegame.checkpoint.powerup = nil
end
end

or you can load the checkpoints library

local checkpoints = require("checkpoints")
local cp1 = checkpoints.create{x = 400, y = 300, section = 1}

-- collect it with onEvent for example
function onEvent(eventName)
if eventName == "collectCP1" then
cp1:collect()
end
end

-- you can also check starting cp in onStart
function onStart()
local c = checkpoints.getActive()
if c == cp1 then -- if the player starts at cp1
Layer.get("AAAA"):show(true)
end
end
Thanks for the reply.
I definitely wouldn't have been able to figure it out myself with the code. But now I really would like to combine that with that "fake loading screen" here:
(yes, it is a working parallaxing background, this only shows the preview for the editor).
I got the idea from the SMB2 expanded GFX-Pack.
So, the players have to use that "moving plattform" not able to move at all until they reach player.y < -180032 of that section... which works fine (code "stolen" from the wario demo stage). A previous post shows that piece of code.
Picture:
Image

Until that point is reached the player is not supposed to get warped to the last "checkpoint", which is why I wondered, if I need some kind of "global" variable and GameData did sound like to me, it is what I was looing for.

Now I thought I understood the layer class
as long as I set up
local cp1warpLayer = Layer.get("checkpoint1warp")
e.g. I can hide it "onstart" and then just show it again, before the player.y < -180032 is "true". Of course .. nope :D
Looks like I was wrong about "understanding" it.

Actually, it was always my primary goal to create an SMB1-like level pack (since years to be honest where 2.0.0 was not even a thing back then), where you have to complete the levels without a save point like early NES or gameboy times (Super Mario Land). I really like that classic SMB1 feeling where a gameover means punishment to start over, where extra lifes and coins are still valuable.
Due to a lack of features or possibilities - so far - I've always been half frustrated and switched to something else, but then always realized that the project might be a little too big for me. Now, however, I am much closer to this goal than before. Firstly, thanks to "heartsforall" (from AppleTheTomato) I've found a working configuration where I finally don't have that reserve item box any more or I can replace the graphic with an "invisible empty" graphic. And then of course there is levellist.lua itself (which was actually the primary reason why I was able to formally unpack this "dream" again). There is not that much missing anymore or rather only a few smaller things left (which I could even ignore).

If this however not really possible in the way I imagine it, I will gladly stick with your "power-up- and sfx-less" solution. But for the experience I would prefer that loading screen after each death to the player again.

Also anway: I'm glad that I'm halfway able to understand it. Ultimately, these are exactly the kind of examples I missed on the "wiki". I personally find pure theory here unspeakably difficult, but as I said, I'm absolutely not a coder type (unlike you). Maybe something like this can be written down somewhere in general. You can't imagine how many solutions or approaches to solutions I have found from you coders in the forum for various things that were apparently not defined anywhere else, hidden treasures so to speak (which is why I sometimes "bumped" a thread with a ready-to-use-solution, as I know myself how much time it does save instead to trying to figure something out or to fix something somebody else already did with ease).

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: GameData: Save value of variable after player death

Postby Emral » Sun Jan 14, 2024 9:25 am

My recommendation would be to not do that whole thing as a section but instead as a routine run in onStart and a png overlay.
With a bit of finagling you can offload this routine into a library too and automatically apply it to every level without having to copy that section setup everywhere. But copypasting the code is also fine and still saves a lot of time and trouble.

Code: Select all

local introImg = Graphics.loadImage("intro.png")
local showingIntro = true

local function introRoutine()
	Audio.SeizeStream(player.section)
	Audio.MusicPause()
	Misc.pause()
	Routine.waitSeconds(3, true) -- true makes it advance while paused
	Misc.unpause()
	showingIntro = false
	Audio.MusicResume()
	Audio.ReleaseStream(player.section)
end

function onStart()
	Routine.run(introRoutine)
end

function onDraw()
	if showingIntro then
		Graphics.drawImageWP(intro, 0, 0, 10)
	end
end
I don't consider myself a coder "type" either I've just been at it for a decade.

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Sun Jan 14, 2024 9:46 am

Emral wrote:
Sun Jan 14, 2024 9:25 am
My recommendation would be to not do that whole thing as a section but instead as a routine run in onStart and a png overlay.
With a bit of finagling you can offload this routine into a library too and automatically apply it to every level without having to copy that section setup everywhere. But copypasting the code is also fine and still saves a lot of time and trouble.

Code: Select all

local introImg = Graphics.loadImage("intro.png")
local showingIntro = true

local function introRoutine()
	Audio.SeizeStream(player.section)
	Audio.MusicPause()
	Misc.pause()
	Routine.waitSeconds(3, true) -- true makes it advance while paused
	Misc.unpause()
	showingIntro = false
	Audio.MusicResume()
	Audio.ReleaseStream(player.section)
end

function onStart()
	Routine.run(introRoutine)
end

function onDraw()
	if showingIntro then
		Graphics.drawImageWP(intro, 0, 0, 10)
	end
end
I don't consider myself a coder "type" either I've just been at it for a decade.
I added an image called "intro" (PNG format) in the folder of the code. Nothing, nothing is happening, no error, no crush, just ... nothing.
Apart form that while I can of course do without parallaxing backgrounds, I hope that animations are generally possible with them (at least the "graphics" section of codehaus says something about this). In my test I added the grastiles to the visible area. I would then have to compensate for this somehow with an animation. But the basic structure would first have to work for me somehow.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: GameData: Save value of variable after player death

Postby Emral » Sun Jan 14, 2024 10:14 am

if nothing is happening you should share more information, because that indicates your code isn't running. are there any warnings? errors? is this in luna.lua? are there multiple onStarts?
you can add animation and such, yeah.

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Sun Jan 14, 2024 10:21 am

Really, there is not anything. I feel stupid now ...

https://www.file-upload.net/download-15 ... e.zip.html
or
https://file.io/GvRazaI5RYgy
or
https://fastupload.io/A1x0LjlQxNzggxu/file
or
https://filebin.net/5vg1cz6ezktt50h7

... ok I am stupid ... I did not correctly copy the WHOLE thing as it seems ... JESUS, I try again.


Edit, but now 2 debugs:
Image
Image

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: GameData: Save value of variable after player death

Postby Emral » Sun Jan 14, 2024 6:02 pm

Oops, typo on my end. Change "intro" in onDraw to "introImg" to match the variable name.

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Mon Jan 15, 2024 1:27 am

Thanks a lot, mistakes like these just do happen. Actually with some proper looking (and well some experience in general) I might have been able to figure that one as well in the second I would have gotten these errors.

Code: Select all

for k,v in ipairs(NPC.get({400, 430})) do
	v.data._basegame.checkpoint.sound = nil
	v.data._basegame.checkpoint.powerup = nil
	end
And for those who want to use the powerup-less and sound-less checkpoints, at least I was able to recognize here that a closed bracket was missing.

And now there is Graphics.drawImageWP left:
Graphics dimension are 800 x 600 (so a full screen) and it has 4 frames (so actually a height of 2400 pixels - as example, I will most likely need more "frames" for sure), I actually tried to set more variables here.
but I do not get that:
By varying the parameters across frames, animation can be created.
It does work differently than anything releated to frames and framespeed as it seems, or do I have to use several Graphics.drawImageWP with appropriate breaks to "fake" an animation?
Graphics.drawImageWP(introFrame1, 0, 0, 10)
-- show that for a second then
Graphics.drawImageWP(introFrame2, 0, 0, 10)
-- show that for a second then
Graphics.drawImageWP(introFrame3, 0, 0, 10)
-- show that for a second then

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: GameData: Save value of variable after player death

Postby Emral » Mon Jan 15, 2024 5:58 am

Something you can do is stack the frames vertically like blocks, npcs and other SMBX assets do, and then use a timer to "vary parameters across frames".

But before I get to that I recommend we get rid of the black on the image and instead render it separately, because that part doesn't animate. Then your image can be less tall. Then, let's say you have a 4-frame image, your new onDraw wouild look something like this:

Code: Select all

function onDraw()
	if showingIntro then
		-- this just draws a black overlay
		Graphics.drawScreen{color = Color.black, priority = 10}
		
		-- breaking down the draw process step by step
		local imgWidth = introImg.width
		local frames = 4
		local framespeed = 8
		local imgHeight = introImg.height / frames
		-- this next line makes the drawtime timer 8x slower than it usually is, eliminates any resulting decimal numbers from the division, and makes sure the frames properly loop by taking it % frames (so the output is 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,0,0,0,0,... and so forth)
		local frame = math.floor(lunatime.drawtime() / framespeed) % frames
		-- Graphics.drawImageWP(image, x, y, sourceX, sourceY, sourceWidth, sourceHeight, priority)
		-- The math in the x and y effectively centers the image to the screen
		-- The math for sourceY offsets the drawn section of the image by the current frame times the number of pixels in height. This is how you create a frame animation
		Graphics.drawImageWP(introImg, 400 - 0.5 * imgWidth, 300 - 0.5 * imgHeight, 0, imgHeight * frame, imgWidth, imgHeight, 10)
	end
end

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Mon Jan 15, 2024 9:33 am

Emral wrote:
Mon Jan 15, 2024 5:58 am
Something you can do is stack the frames vertically like blocks, npcs and other SMBX assets do, and then use a timer to "vary parameters across frames".

But before I get to that I recommend we get rid of the black on the image and instead render it separately, because that part doesn't animate. Then your image can be less tall. Then, let's say you have a 4-frame image, your new onDraw wouild look something like this:

Code: Select all

function onDraw()
	if showingIntro then
		-- this just draws a black overlay
		Graphics.drawScreen{color = Color.black, priority = 10}
		
		-- breaking down the draw process step by step
		local imgWidth = introImg.width
		local frames = 4
		local framespeed = 8
		local imgHeight = introImg.height / frames
		-- this next line makes the drawtime timer 8x slower than it usually is, eliminates any resulting decimal numbers from the division, and makes sure the frames properly loop by taking it % frames (so the output is 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,0,0,0,0,... and so forth)
		local frame = math.floor(lunatime.drawtime() / framespeed) % frames
		-- Graphics.drawImageWP(image, x, y, sourceX, sourceY, sourceWidth, sourceHeight, priority)
		-- The math in the x and y effectively centers the image to the screen
		-- The math for sourceY offsets the drawn section of the image by the current frame times the number of pixels in height. This is how you create a frame animation
		Graphics.drawImageWP(introImg, 400 - 0.5 * imgWidth, 300 - 0.5 * imgHeight, 0, imgHeight * frame, imgWidth, imgHeight, 10)
	end
end
Once again, thanks for your patience.

Picture does load, background is black, but it is not animated and stays on "frame 1" :/
This wohle thing here now is starting to get troublesome somehow, I guess?!
Image

Just realized: Removing the black background did not make any sense, considering I used these white double boarders, but whatever.
It was not a big deal anyway, since I used a lot of layers. :mrgreen:

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: GameData: Save value of variable after player death

Postby Emral » Mon Jan 15, 2024 9:42 am

Just_Thomas wrote:
Mon Jan 15, 2024 9:33 am

Just realized: Removing the black background did not make any sense, considering I used these white double boarders, but whatever.
It was not a big deal anyway, since I used a lot of layers. :mrgreen:
My mistake. I mixed up drawtick and drawtime. Replace drawtime with drawtick.
For reference, drawtime is measured in seconds, drawtick in frames. So right now you would see it animate after 8 seconds pass lol.

You could also render the double white border separately with a second drawImage call and a second image with just one frame.

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Mon Jan 15, 2024 9:51 am

Emral wrote:
Mon Jan 15, 2024 9:42 am
Just_Thomas wrote:
Mon Jan 15, 2024 9:33 am

Just realized: Removing the black background did not make any sense, considering I used these white double boarders, but whatever.
It was not a big deal anyway, since I used a lot of layers. :mrgreen:
My mistake. I mixed up drawtick and drawtime. Replace drawtime with drawtick.
For reference, drawtime is measured in seconds, drawtick in frames. So right now you would see it animate after 8 seconds pass lol.

You could also render the double white border separately with a second drawImage call and a second image with just one frame.
Still funny, that you do not think yourself as a coder.
@"Double Boarder": I think I will pass on this one, at the end we are talking about an image of a filesize 50 kb.
@Drawtime/drawtick: Well, while you mention it now, it somehow makes sense, although I wouldn't be able to apply it accordingly.

And yes, now it is working. This was quite a journey. Maybe somebody else can find this thread and its contents helpful.
For that you will definitely get a place of honor in my credits list.

Emral
Cute Yoshi Egg
Cute Yoshi Egg
Posts: 9722
Joined: Mon Jan 20, 2014 12:58 pm
Flair: Phoenix

Re: GameData: Save value of variable after player death

Postby Emral » Mon Jan 15, 2024 10:05 am

nono, "coder" checks out. just not "coding type". i just do it as a means to an end, not because it's fun or some mysterious semblance of talent or anything.

good to see the code working

Just_Thomas
Snifit
Snifit
Posts: 233
Joined: Sat Dec 16, 2023 3:32 am
Pronouns: he/him

Re: GameData: Save value of variable after player death

Postby Just_Thomas » Tue Jan 16, 2024 2:09 am

I know this is not related to the problem - which you solved - anymore:

I tried to expand the code like shown below: No error or anything.
(by pressing JUMP or maybe also the start button the player and skip the waiting time, at least this is what is supposed to happen)

I thought ontick() gets checked all the time but it looks like the moment skipIntro is 1 and the player would press JUMP the routine stuff with the waiting time of 3 can not be done anymore and somehow the graphics does not even show up anymore. This stuff is a lot harder than I thought it would be, or is that actually "right" but because of the other piece of code the players JUMP press pressing simply get ignored and therefore can not be processed?
However then this would not explain, why the graphic does not show up anymore.

Looks like my code addition has a logic flaw through. Do you see it?

Anything else not shown here is still the same BTW

Code: Select all

local skipIntro = 0

function onTick()
	if(player.JumpKeyPressing) and skipIntro == 1 then
	skipIntro = 2
	end
end

local function introRoutine()
	Audio.SeizeStream(player.section)
	Audio.MusicPause()
	Misc.pause()
	skipintro = 1

		if skipIntro == 1 then
		Routine.waitSeconds(3, true) -- true makes it advance while paused
		end

	Misc.unpause()
	showingIntro = false
	Audio.MusicResume()
	Timer.activate()
	Audio.ReleaseStream(player.section)
end
Also this is also not possible as it seems, I thought this was a legit way to control the timer value and if reached 100, well ... tried to find a way to use the hurry up music (which I have as a file - this would not be the issue), so it is about timercontrol:

Code: Select all

Timer.set(400)
Timer.setSecondLength(40)

local timercontrol = timer

function onTick()
	if timercontrol < 100 then
	player:kill()
	end
end
Then I tried to limit myself to SHOW the value on screen via text.print but not even this seems to be possible?

function onTick()
Text.print(timer.getValue, 100, 100)
end

tried around with timer.get, timer.get() and timer.getvalue() ... nope.
So, "timer.hurryTime" and function timer.onEnd() are the only exceptions?



EDIT 17.01.2024


Ok, considering people explained the missing "hurry up" themes and text.print can not display the current timer value, no matter what (either error or NIL) I guess it is simply not possible. Ok, not really cool, but nothing can be done about that.

About the skipping intro thingy, I tried to give the player the option to cancel most of the intro, but still no button input does get recognized.
(while outside of the intro it would work)
So, does somebody know?

Code: Select all

local introImg = Graphics.loadImage("intro.png")
local showingIntro = true


local function introRoutine()
	Audio.SeizeStream(player.section)
	Audio.MusicPause()
	Routine.waitSeconds(0.5, true) -- true makes it advance while paused

	if player.keys.jump == KEYS_PRESSED and showingIntro == true then
		showingIntro = false
	else
		Misc.pause()
		Routine.waitSeconds(2.5, true) -- true makes it advance while paused	
		Misc.unpause()
		showingIntro = false
	end

	Audio.MusicResume()
	Timer.activate()
	Audio.ReleaseStream(player.section)
end


function onStart()
	Routine.run(introRoutine)

	for k,v in ipairs(NPC.get({400, 430})) do
	v.data._basegame.checkpoint.sound = nil
	v.data._basegame.checkpoint.powerup = nil

	Defines.player_grav = 0.55
	Defines.player_grabSideEnabled = false
	Defines.player_grabTopEnabled = false
	Defines.player_grabShellEnabled = false
	end
end

function onDraw()
	if showingIntro then
		-- this just draws a black overlay
		Graphics.drawScreen{color = Color.black, priority = 10}
		
		-- breaking down the draw process step by step
		local imgWidth = introImg.width
		local frames = 4
		local framespeed = 8
		local imgHeight = introImg.height / frames
		-- this next line makes the drawtick timer 8x slower than it usually is, eliminates any resulting decimal numbers from the division, and makes sure the frames properly loop by taking it % frames (so the output is 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,0,0,0,0,... and so forth)
		local frame = math.floor(lunatime.drawtick() / framespeed) % frames
		-- Graphics.drawImageWP(image, x, y, sourceX, sourceY, sourceWidth, sourceHeight, priority)
		-- The math in the x and y effectively centers the image to the screen
		-- The math for sourceY offsets the drawn section of the image by the current frame times the number of pixels in height. This is how you create a frame animation
		Graphics.drawImageWP(introImg, 400 - 0.5 * imgWidth, 300 - 0.5 * imgHeight, 0, imgHeight * frame, imgWidth, imgHeight, 10)
	end
end


Return to “LunaLua Help”

Who is online

Users browsing this forum: No registered users and 1 guest

SMWCentralTalkhausMario Fan Games GalaxyKafukaMarioWikiSMBXEquipoEstelari