My friend and I have been working on a game in love2d recently, but in the early stages of developing my computer hard drive stopped working meaning only my friend could work on it. Now I have a computer and I want to make a main menu in Love2d but There is alot of code in the love.load function (generation of the world and such). My question is can I change what is in love.load when the game is running? e.g The main menu loads up, then the generation of the world loads up when the start button is pressed.
The love.load function runs only once. As you mention, it's generally used to set up data structures and pre-load other resources. You can use it to handle both the world pre-load and the menu pre-load. Then, control what is active via some sort of state. A simplified example:
local state = "menu"
function love.load()
preLoadMenu()
preLoadWorld()
end
function love.update(dt)
if state == "menu" then
updateMenu()
else
updateWorld()
end
end
function love.draw()
if state == "menu" then
drawMenu()
else
drawWorld()
end
end
function love.mousepressed(x, y, button)
if startClicked(x,y,button) then
state = "world"
end
end
It's conceivable that you won't want to pre-load absolutely everything for your game on load. Maybe your game is just too big. If that's the case, consider working with an active scene. A scene might be the menu or maybe it's a game level. Again, a simplified example:
local currentScene
function love.load()
currentScene = loadMenu()
end
function love.update(dt)
currentScene.update(dt)
end
function love.draw()
currentScene.draw()
end
function love.mousepressed(x, y, button)
if startClicked(x,y,button) then
currentScene = loadWorld()
end
end
This second option is much more flexible in the long run. It can handle any number and type of scenes without conditional logic for each. It will require a little "object" thinking. All scenes need a consistent way to update and draw.
If your world takes a while to load, you may want to display a temporary "world is loading" scene so your users don't get impatient.
Related
I have a macro called Setup and inside it I have a function called Game. The macro start executing when a button is pressed, and then he calls Game, now, the macro continues to run without waiting for Game to finish, and then the calculations I do after Game are invalid because the game haven't finished yet.
I want my macro to wait for Game to finish and then calculate the score based on the game.
Sub Setup()
Game
CalculateHighestScore
End Sub
As you can see by the code above, CalculateHighestScore start without waiting for the game to finish and then the stats are just wrong
You need to make sure the variable/data required by CalculateHighestScore are GLOBAL, so that after Game function is executed the data is still valid and accessible to CalculateHighestScore function
if the function is extracting data from excel range, try adding
Sub Setup()
Game
Application.calculate
CalculateHighestScore
End Sub
and check if it works, this will recalculate all excel formulas before processing CalculateHighestScore
In my Corona SDK project, I have a composer scene called "menu.lua" (created with composer.newScene()) that is the first scene, called by main.lua file. I have a background track only for this scene, loaded in scene:create() with audio.loadSound() in a local variable. When I load another scene (let's suppose it's a "credit" scene, static, with no music, sounds, animations, timers, etc.) and then come back to menu scene, audio is still played, but with a lower volume.
Audio is played in loop on channel 2, I use audio.play() in scene:show "did" phase. I use audio.fadeOut() in scene:hide "will" phase, and stop it with audio.stop() in "did" phase, then dispose it with audio.dispose() in scene:destroy.
In "menu.lua" file
local composer=require("composer")
local scene=composer.newScene()
local theme --this is the variable for audio
function scene:create(event)
local sceneGroup=self.view
theme=audio.loadSound("sfx/theme_short.mp3")
end
function scene:show(event)
local sceneGroup=self.view
if event.phase=="will"
audio.play(theme,{loops=-1,channel=2})
end
end
function scene:hide(event)
local sceneGroup=self.view
if event.phase=="will" then
audio.fadeOut(theme,{500})
end
elseif event.phase=="did" then
audio.stop(2)
end
end
function scene:destroy(event)
local sceneGroup=self.view
audio.dispose(theme)
end
The other scene (let's suppose it's "credits.lua") is called by a button with a "tap" event attached. In "credits.lua" I use this function to go back to "menu.lua" scene (function is called with a "tap" event attached to a button)
local function goMenu()
composer.removeScene("menu")
composer.gotoScene("menu","slideUp",500)
return true
end
I've already tried to play audio in scene:show "did" phase and in scene:create, but the problem persists. The problem happens with all the scenes, all static (3 in total). Any idea?
You should replace
audio.fadeOut(theme,{500})
with
audio.fadeOut( { channel=2, time=500 } )
since you use wrong syntax.
See audio.fadeOut()
Make sure you read the "Gotcha" section of the docs:
When you fade the volume, you are changing the volume of the channel. This value is persistent and it's your responsibility to reset the volume on the channel if you want to use the channel again later (see audio.setVolume()).
You're responsible for setting the channel volume back because fadeOut changes the volume of the channel.
I am trying to play background sound, only during one scene. When this scene is destroyed, the sound should fade out and then stop. Then when the scene is re-created, the sound should start playing again.
Here is what I am trying:
local backgroundMusic
local backgroundMusicChannel
local function stopSound(event)
audio.stop(event.channel)
audio.dispose(event.handle)
backgroundMusic = nil
end
function scene:create(event)
backgroundMusic = audio.loadSound("music/intro.mp3")
backgroundMusicChannel = audio.play(backgroundMusic, {loops = -1, fadein = 3000, onComplete = stopSound})
end
function scene:destroy(event)
audio.fadeOut({channel = backgroundMusicChannel, time=2000})
end
The sound plays when the scene is created initially, and fades out correctly, but does not start again when the scene is created again.
When I change the destroy function to:
function scene:destroy(event)
audio.fadeOut({channel = backgroundMusicChannel, time=2000})
audio.stop(backgroundMusicChannel)
end
the sound does not fade out, because it stops immediately, but it DOES start again correctly the next time the scene is created.
I have also tried using audio.stopWithDelay, which fades out correctly, but similarly, does not begin playing again when the scene is created once more.
If anyone has any insights on what's going on here please let me know!
Could the problem be you cannot (re)play the sound if it isn't stopped yet?
You also never dispose of the audio when the scene ends.
Inside create, stop the previous audio if it already exists.
You're better off creating the sound once and reusing it when needed.
If you use loadStream, you'll have to use audio.rewind() after playing it.
The documentation on this also states that you should probably use loadStream:
https://docs.coronalabs.com/guide/media/audioSystem/index.html
I'm new in games development, am trying to create a simple game in flash-cs5. I created 3 motion tweens in timeline. i'm trying to stop a specific motion tween, when that tween's movieclip is clicked while other tweeens are running and also when the stopped movieclip is clicked again i want to resume the tween while other tweeens are running.
thanking in advanced.
The following is assuming you have each motion tween inside its own movieclip. I am not aware of any method of stopping one tween while leaving the other playing on a single movieclip (or if they are each on the main stage).
That said, you can stop and start animations fairly easily. Below is an example of how to stop a motion tween where it is in playback, and then resume it from that point.
In the example, "myMovieClip" is the movie clip we're working with. We're going to leave the rest of the movieclips alone, as they'll keep playing on their own. I'm also assuming that myMovieClip is playing by default.
The following is in AS3. Place it on the Actions panel for your main stage (first frame if you have multiple frames.)
Also, ensure you have named your MovieClip. To do this, click the MovieClip on your stage in design mode, and then click Properties. There should be a text entry box towards the box. Write the name you want for your MovieClip there.
//Declare a boolean variable that determines whether or not the movieclip timeline is playing.
var ClipPlaying:Boolean = true;
//Add the mouse click event listener to the movie clip.
myMovieClip.addEventListener(MouseEvent.CLICK, StopOrStartClip);
//Declare the function for the above event listener.
function StopOrStartClip(evt:MouseEvent):void
{
//Switch statements are my personal favorites...they're more streamlined than if statements.
switch(ClipPlaying)
{
//If the clip is playing it, we stop it and set ClipPlaying to false.
case true:
myMovieClip.stop();
ClipPlaying = false;
break;
//If the clip is not playing, we start it and set ClipPlaying to true.
case false:
myMovieClip.play();
ClipPlaying = true;
break;
}
}
The most important functions to remember here are:
myMovieClip.stop();
This freezes your animation at its current position.
myMovieClip.play();
This resumes your animation playback from its current position.
When you use either, remember to replace "myMovieClip" with the name of your movie clip!
By the way, slightly unrelated, I highly recommend the book ActionScript 3.0 Game Programming University to learn how to create Flash games.
You wouldn't actually need 5 different event listeners, or functions, or variables; you could just make one function to handle it all:
stage.addEventListener(MouseEvent.CLICK, stageClick);
function stageClick(event:MouseEvent):void {
//I prefer "if" statements
if (event.target == myMovieClip1) stuff here;
else if (event.target == myMovieClip2) stuff here;
else if (event.target == myMovieClip3) stuff here;
else if (event.target == myMovieClip4) stuff here;
else if (event.target == myMovieClip5) stuff here;
}
I can add more details if needed, but this question was from three years ago so probably not.
I have a render loop that I want to run in the background so that I can control the speed of the playback loop making it animate either slow or fast. Right now I'm using sleep and calling begin and end on the CCRenderTexture in the main thread each time I want to use the sprite:
[self performSelectorOnMainThread:#selector(visit) withObject:nil waitUntilDone:YES];
- (void)visit {
[target begin];
[[self.currentLine.brush sprite] visit];
[target end];
}
This was a hack that got it working but of course makes it run very slow. calling begin and end in the background thread just causes nothing to render at all
I want to be able to call begin, do all my drawing in the background thread and then call end but everything I've tried has either done nothing or made my EAGLView flip out.
The CCRenderTexure works by redirecting the opengl output onto itself so that the drawing that gets done is saved on your sprite. This means that in a single operation you need to call begin do all your drawing and then call end.
When running on a background thread the CCDirector is making it's own draw calls in the main thread so that when you call begin and try to do multiple functions in that state the director is drawing too causing all sorts of strange errors.
end needs to be called before normal rendering operations resume.