Discuss Scratch

mgrobbel
Scratcher
9 posts

Beginner with many questions.

I've recently found Scratch and am an Elementary tech teacher. I have no programming skills, but am learning some basics and trying to show students some of the things I've learned. On the side, I wanted to see if I could make something a little more “advanced” that my 7 year old would be interested in. I've copied Wreck-It-Ralph for lack of inspiration hoping that that's not a legality issue, and have started having many problems that seem to stem from broadcasting. As I was making different parts, they all seemed to work, but then I put in broadcasts to try and make them run in order, and together, and things stopped working. There are a lot of problems with this project and it is very basic, as is my knowledge. I was wondering if someone could help me with a topic or two?

Why do my bricks not show up?
How come my windows don't stay visible?
Why is my cloud appearing much later after the start of the game and not cloning itself?

http://scratch.mit.edu/projects/10352728/
Dundil
New to Scratch
11 posts

Beginner with many questions.

Hi:

Congratulations for the project. It looks really cool!

The problem you have with the bricks and the windows is exactly the same: you have reached the maximum number of clones! There's a limit of 300 clones in the scene, so be careful with that.

And why are you making so many clones? Because the “1” key press event. In the scene, there's a code executed when the green flag is pressed. In that code, you're forever checking the key “1”. The problem is that the loop is fast, and when I press the key, “intro” message is sent not once, but at least 3 times. Every time that message is called, many windows are created, reaching the 300 clone limit.

Instead of doing it in that way, I'd recommend to put a “1” key event and a “gameInPlay” variable. When key “1” is pressed, you check “gameInPlay” variable (at the beginning, 0). If it's 0 (game not running), you change it to 1 and send the “intro” message. If not, ignore the event. Just remember, at the end of the game, to change the “gameInPlay” variable again to 0.

I haven't checked the cloud problem, but I guess it's the same.

Nice job. Regards
drmcw
Scratcher
1000+ posts

Beginner with many questions.

Looks good what you have. Further to the previous answer you can just use wait until key 1 pressed so you don't have to resort to variables.

Some of the questions you have as comments in the code I'd answer as;

To make the clouds go behind the building then, in the looks category, use the go back block and set the number of layers to a high number e.g 1000 they should then be drawn behind everything else.

To get a random number between -90 and 90 in increments of ten then just use a random number between -9 and 9 and then multiply by 10.

You should change the broadcast message and give message1 a more meaningful name just to make things easier to read.

Last edited by drmcw (June 4, 2013 11:52:48)


10 !
ScratchVaders or Galaga?
Maybe Eliza can help you decide?
mwiedmann
Scratcher
100+ posts

Beginner with many questions.


For someone with no programming skills this is quite an accomplishment. Nice job! drmcw is right, if you fix that “key 1 pressed” broadcast issue, the game seems to be largely playable. Very nice! I have a few suggestions on coding practices:

On freddy, you have 2 “when I receive ‘game start’” blocks. A lot of people do this but it is a bad practice. The reason is that you can't control what order those are running and it can cause some weird synch issues where one of those blocks may be trying to do something like go to the next level for instance while the other block is still doing it's thing. In a more complicated program it can be a nightmare to deal with those things. It's better to combine them together. Since you are teaching it you want to teach the best practices. In this case one of those blocks is just controlling the hammer, so I would just slide them together. As a rule, each sprite should only have 1 “event handler” for a given type.

When you broadcast messages, the message is sent and the code that sends the message just keeps running. In some cases it is useful to use “broadcast and wait”. That gives you a little more control over the flow of the code. Like when freddy dies, you should use “broadcast and wait” so your main loop on freddy stops running until the death animation is complete. Change the number of lives and hide freddy first, then broadcast. Again, what you have seems to work but as the program grows it will be more important to be able to control the flow of the code. Also, your “freddy died” event handler broadcasts “freddy alive” at the end. You have to be careful with events broadcasting other events because you can end up in an infinite loop if you aren't careful. Better idea is to use “broadcast and wait” from 1 location and call the events in order.

Use the “make a block” feature and move some of your code into those. It just cleans things up a bit and makes the code more readable and reusable. for instance, move your code on freddy that checks for brick collisions into a “Brick Check” block, and move the hammer code into a “Hammer Check” block. Then your main loops just says:

Brick Check
Hammer Check

and everyone knows exactly what the code does (or at least what your intent is).

Program looks great though. Looking forward to seeing where it goes.

mgrobbel
Scratcher
9 posts

Beginner with many questions.

Thank you for the information! If I understand what you're saying, it's like making an on/off switch for the game to start instead of always looking for someone to hit “1”? And you're saying when key 1 is pressed it can register more than one press sometimes, sending multiple intro messages that make many clones. I was unaware of the 300 clone limit. (I didn't know if it would be more efficient to make window clones or many duplicated sprites.) So, in essence, if I make a variable that starts at 0 and changes to 1 when a “start key” is pressed, that start key would then trigger the variable that controls the intro broadcast instead of the actual key press controlling the intro broadcast. Less chance for repetition.

The reason I made the intro start with the press of the “1” key is because the space bar was already used by Freddy to fix windows and I couldn't figure out how to make space bar both start the game and fix windows. Essentially, Freddy would try to fix a window and end up restarting the game every time.

Dundil wrote:

Hi:

Congratulations for the project. It looks really cool!

The problem you have with the bricks and the windows is exactly the same: you have reached the maximum number of clones! There's a limit of 300 clones in the scene, so be careful with that.

And why are you making so many clones? Because the “1” key press event. In the scene, there's a code executed when the green flag is pressed. In that code, you're forever checking the key “1”. The problem is that the loop is fast, and when I press the key, “intro” message is sent not once, but at least 3 times. Every time that message is called, many windows are created, reaching the 300 clone limit.

Instead of doing it in that way, I'd recommend to put a “1” key event and a “gameInPlay” variable. When key “1” is pressed, you check “gameInPlay” variable (at the beginning, 0). If it's 0 (game not running), you change it to 1 and send the “intro” message. If not, ignore the event. Just remember, at the end of the game, to change the “gameInPlay” variable again to 0.

I haven't checked the cloud problem, but I guess it's the same.

Nice job. Regards
mgrobbel
Scratcher
9 posts

Beginner with many questions.

Thank you for your help.

I tried to make the clouds go behind the building by using the “go back x layers” block. When I made the background image with the building on it, I used a black square to make the background black and then put MANY layers of building in front of that. Would the cloud sprite recognize the different layers of the stage background I drew, or just the background as one layer? What exact does SCRATCH recognize as a layer? Are only sprites counted as layers? If the cloud can distinguish between the MANY layers of the stage background that I drew, then there is an exact number of layers for me to find that would put the cloud between the building layers and the very back black square layer. I've been too lazy to try and find out with trial and error just how many building layers I did. When I set the could to go back 1000 layers it should be behind everything right, but that doesn't happen. ??

I'm going to use the random (-9 to 9) * 10. That's a brilliant and simple solution, thank you.

I'm in the process of changing the message1 to “game over” or something like that. At one point I had created a broadcast message called game over and I couldn't select it from the drop down list on the broadcast brick. I found that odd. It happened with my windows too, when I tried to use a sensing brick “touching x”, the drop down menu doesn't have all my sprites. Not sure why that is. ??

drmcw wrote:

Looks good what you have. Further to the previous answer you can just use wait until key 1 pressed so you don't have to resort to variables.

Some of the questions you have as comments in the code I'd answer as;

To make the clouds go behind the building then, in the looks category, use the go back block and set the number of layers to a high number e.g 1000 they should then be drawn behind everything else.

To get a random number between -90 and 90 in increments of ten then just use a random number between -9 and 9 and then multiply by 10.

You should change the broadcast message and give message1 a more meaningful name just to make things easier to read.
drmcw
Scratcher
1000+ posts

Beginner with many questions.

Ah, no the stage is the background and sprites always go in front of it. The go to back is just to control the ordering of sprites. You'd need to have a black sprite to be the background of the building if you want the clouds to go behind that.

Clones are better than duplicating sprites. The one potential disadvantage they have is that they can't be used in version 1,4!

10 !
ScratchVaders or Galaga?
Maybe Eliza can help you decide?
mgrobbel
Scratcher
9 posts

Beginner with many questions.

This is a very helpful and supportive community, which is very nice. I see you answering everyone's questions. Thank you for taking the time.

I'm going to work on the “key 1 pressed” broadcasting and change that to a variable. I'll have to figure out how that works.

Good catch on the two flag scripts in one sprite. I try and point that out to students. Thank you. Fixed.

I'm trying to wrap my brain around the broadcast and wait. I put in the broadcast and wait blocks for the Freddy sprite when he dies. It didn't seem to make a difference with running the “died” event. The first time he dies, sound plays, ‘falls down’, fades, and regenerates. The second and third time, all those events don't happen. If I understand you, the main loop waits until the script receiving the broadcast finishes before it will do anything, even if there is a forever script in the main loop? I'm not sure how to make all the “died” events happen before he reappears.

If I take off the “Freddy alive” broadcast from the “died” event, how do I make sure that he regenerates, or will that happen automatically? It's hard to debug because I haven't fixed the bricks which is making it hard for me to get hit by them. ;-)

I'm going to try the “make a block”, something I've never done, but seen in high end projects. Thanks.


mwiedmann wrote:

For someone with no programming skills this is quite an accomplishment. Nice job! drmcw is right, if you fix that “key 1 pressed” broadcast issue, the game seems to be largely playable. Very nice! I have a few suggestions on coding practices:

On freddy, you have 2 “when I receive ‘game start’” blocks. A lot of people do this but it is a bad practice. The reason is that you can't control what order those are running and it can cause some weird synch issues where one of those blocks may be trying to do something like go to the next level for instance while the other block is still doing it's thing. In a more complicated program it can be a nightmare to deal with those things. It's better to combine them together. Since you are teaching it you want to teach the best practices. In this case one of those blocks is just controlling the hammer, so I would just slide them together. As a rule, each sprite should only have 1 “event handler” for a given type.

When you broadcast messages, the message is sent and the code that sends the message just keeps running. In some cases it is useful to use “broadcast and wait”. That gives you a little more control over the flow of the code. Like when freddy dies, you should use “broadcast and wait” so your main loop on freddy stops running until the death animation is complete. Change the number of lives and hide freddy first, then broadcast. Again, what you have seems to work but as the program grows it will be more important to be able to control the flow of the code. Also, your “freddy died” event handler broadcasts “freddy alive” at the end. You have to be careful with events broadcasting other events because you can end up in an infinite loop if you aren't careful. Better idea is to use “broadcast and wait” from 1 location and call the events in order.

Use the “make a block” feature and move some of your code into those. It just cleans things up a bit and makes the code more readable and reusable. for instance, move your code on freddy that checks for brick collisions into a “Brick Check” block, and move the hammer code into a “Hammer Check” block. Then your main loops just says:

Brick Check
Hammer Check

and everyone knows exactly what the code does (or at least what your intent is).

Program looks great though. Looking forward to seeing where it goes.

mwiedmann
Scratcher
100+ posts

Beginner with many questions.


For the Freddy died problem, your code should say:
broadcast ‘freddy died’ and wait
broadcast ‘freddy alive’ and wait - although I think the main freddy is the only one that handles this event, so you should move this code into a “make a block” and just call that instead. Only use broadcast if you need to communicate with another sprite.

Remove the “broadcast ‘freddy alive’” from the freddy that spins. Just have your “main” freddy make both broadcasts.

When “broadcast and wait” is called, that code will wait at that exact spot until everyone who handles that event is done. Then the code will continue to the next line. So it doesn't matter if it is in a forever loop because it is just waiting for the broadcast to finish.

I noticed your code that checks how many lives freddy has left is copy/pasted. You can shorted that by saying:
if touching brick AND lives > 1
Your final if in that section is also basically the same, so you might be able to refactor them all into 1 if/then.

mgrobbel
Scratcher
9 posts

Beginner with many questions.

I think I cleaned up Freddy. I'm only broadcasting to the Freddy2 sprite from the main Freddy to make him lay down and disappear, although he only seems to do that on the first death, not the second or third. ???

Thank you for explaining the broadcast and wait block. Makes sense. Just didn't know for sure how it worked.

Now my problem continues to be my clones I think. I tried to make a variable that controlled the flow of the script. 0 means nothing is happening. 1 means that the intro starts where windows appear and Randy enters and destroys building. 2 means game starts where Freddy shows up, clouds and bricks start. I'm thinking my problem is that I didn't create the variable right. It should function like an on/off switch, but I think I have the same problem as before. My windows scripts will forever make clones when on variable 1 and then I don't get clouds and bricks. When I don't let the windows scripts run, clouds and bricks work fine when things change to variable 2. How do I tell my clouds to forever look for variable 1 to turn “on” but only make a clone of themselves once instead of forever? Again, assuming this is my problem.

Thank you again for your help. I'm very open to any other suggestions, problems you see, or ways to “tighten” things up.


mwiedmann wrote:

For the Freddy died problem, your code should say:
broadcast ‘freddy died’ and wait
broadcast ‘freddy alive’ and wait - although I think the main freddy is the only one that handles this event, so you should move this code into a “make a block” and just call that instead. Only use broadcast if you need to communicate with another sprite.

Remove the “broadcast ‘freddy alive’” from the freddy that spins. Just have your “main” freddy make both broadcasts.

When “broadcast and wait” is called, that code will wait at that exact spot until everyone who handles that event is done. Then the code will continue to the next line. So it doesn't matter if it is in a forever loop because it is just waiting for the broadcast to finish.

I noticed your code that checks how many lives freddy has left is copy/pasted. You can shorted that by saying:
if touching brick AND lives > 1
Your final if in that section is also basically the same, so you might be able to refactor them all into 1 if/then.

mwiedmann
Scratcher
100+ posts

Beginner with many questions.

I remixed your “Wreck It” program so I could rework a few things and patch up some of the bugs.

Wreck It - remix with bug fixes

One problem with your clouds is that a sprite can never go behind the Stage background, so the clouds will always be in front of the building. You will have to make the building a sprite, then it should be fine.

Here are the changes (I changed a fair amount of stuff and can't remember it all, so just open it side-by-side with your version and compare). here are a few highlights though:

1. You had “When Green Flag Clicked” handlers on most of your objects. Problem is that you can't control the order those will run, so sometimes the code in the sprites was running before some of the main variables were initialized back to 0. This was causing some weird behavior when the game started. A good idea is to only have 1 “When GF Clicked” in your entire program (on the Stage). Then, that handler can initialize some of the main variables before everyone else starts running. Once the initialization is done, he can do a “broadcast start game” or something like that to signal that all the other sprites can start doing their thing.

2. I added a few broadcasts to signal when the intro should start, and when the actual game should start. This is sometimes easier than having all of your sprites looping and waiting for a variable to change.

3. I removed most of the forever loops and replaced with “repeat until game=0”. This will at least cause those loops to stop when the game is over.

Hope this helps!
mgrobbel
Scratcher
9 posts

Beginner with many questions.

I went through all the fixes and cleaned things up. I understand the broadcasts you put in. I would have never thought of the “repeat until game” block to solve problems.

Makes sense then that the combination of repeat until and broadcasting could solve my clone problem.

As for the “When GF clicked” I put them all back in for each sprite to make everything hide. There were times when I would have things linger on screen without them. Is there a better way to make things hide upon start? Sometimes I have to click on the green flag two times to hide things. ???

I'm going to work on sound, jumping, maybe level 2, and may add that 1 sprite menu you created if okay with you.

Thank you.

mwiedmann wrote:

I remixed your “Wreck It” program so I could rework a few things and patch up some of the bugs.

Wreck It - remix with bug fixes

One problem with your clouds is that a sprite can never go behind the Stage background, so the clouds will always be in front of the building. You will have to make the building a sprite, then it should be fine.

Here are the changes (I changed a fair amount of stuff and can't remember it all, so just open it side-by-side with your version and compare). here are a few highlights though:

1. You had “When Green Flag Clicked” handlers on most of your objects. Problem is that you can't control the order those will run, so sometimes the code in the sprites was running before some of the main variables were initialized back to 0. This was causing some weird behavior when the game started. A good idea is to only have 1 “When GF Clicked” in your entire program (on the Stage). Then, that handler can initialize some of the main variables before everyone else starts running. Once the initialization is done, he can do a “broadcast start game” or something like that to signal that all the other sprites can start doing their thing.

2. I added a few broadcasts to signal when the intro should start, and when the actual game should start. This is sometimes easier than having all of your sprites looping and waiting for a variable to change.

3. I removed most of the forever loops and replaced with “repeat until game=0”. This will at least cause those loops to stop when the game is over.

Hope this helps!
mwiedmann
Scratcher
100+ posts

Beginner with many questions.

mgrobbel wrote:

As for the “When GF clicked” I put them all back in for each sprite to make everything hide. There were times when I would have things linger on screen without them. Is there a better way to make things hide upon start? Sometimes I have to click on the green flag two times to hide things. ???

Using the “When GF Clicked” to hide sprites at the start or do some initial positioning is fine. I was pruning your code kind of quickly and may have pruned a bit too much…sorry. You just don't want to be checking any variables that might not have been initialized yet. Sometimes just have the Stage “broadcast init”, and have all the sprites listen for that event to do their setup.

You shouldn't have to click the GF twice. There must be something else going on there. Work on the program a bit and I can take a look if you are still having an issue with that later.

Feel free to use the menu.
dracae
Scratcher
1000+ posts

Beginner with many questions.

mgrobbel wrote:

As for the “When GF clicked” I put them all back in for each sprite to make everything hide. There were times when I would have things linger on screen without them. Is there a better way to make things hide upon start? Sometimes I have to click on the green flag two times to hide things. ???


I don't like being the bearer of bad news, but…
This is usually caused by using, say, broadcast hat blocks.
Though it might be difficult, you can solve this problem (double click flag to hide) by using variables instead.
For example, instead of having a StartGame broadcast, you could use a startgame variable, with 1 for yes, 0 for no, etc.
Forever and ifs you can use to check the state of the variable, and so on and so forth.
Anyways, the point is that it is recommended to have all of your hat blocks to be: When Green Flag is clicked.

Hope I helped!

drmcw
Scratcher
1000+ posts

Beginner with many questions.

Just as an afterthought about the cloud sprite problem. They don't necessarily have to be sprites. They could be part of the background. The background can be animated so you could have a number of backgrounds and just use a forever and next costume (or is it next background now?) instead.

10 !
ScratchVaders or Galaga?
Maybe Eliza can help you decide?
mwiedmann
Scratcher
100+ posts

Beginner with many questions.

dracae wrote:

I don't like being the bearer of bad news, but…
This is usually caused by using, say, broadcast hat blocks.
Though it might be difficult, you can solve this problem (double click flag to hide) by using variables instead.
For example, instead of having a StartGame broadcast, you could use a startgame variable, with 1 for yes, 0 for no, etc.
Forever and ifs you can use to check the state of the variable, and so on and so forth.
Anyways, the point is that it is recommended to have all of your hat blocks to be: When Green Flag is clicked.
Hope I helped!

dracae - I'm going to disagree with you on this. You should really limit the use of “When GF clicked” blocks because of the reasons I gave above. You can't control the order that they run and often times people are checking variables in those blocks. If those variables haven't been set yet they you are in trouble (this was one of the problems in the Wreck it freddy program).

When you have a clear change in the state of your game (like going from the main menu to starting the game), you should use a broadcast. For one thing it wastes CPU cycles to have all your sprites spinning in a loop waiting for the change.If you use broadcasts, it is clear what the change is and who is listening for the change. What if you never hit that gameState that your sprites are waiting for? What if you jump to a different gameState because of a new game option you added? Those sprites may be stuck waiting for a gameState that won't happen.

Once your game is running, you can use a gameState variable to signal smaller changes to the sprites (like in Donkey Kong when mario gets the hammer).
dracae
Scratcher
1000+ posts

Beginner with many questions.

mwiedmann wrote:

dracae wrote:

I don't like being the bearer of bad news, but…
This is usually caused by using, say, broadcast hat blocks.
Though it might be difficult, you can solve this problem (double click flag to hide) by using variables instead.
For example, instead of having a StartGame broadcast, you could use a startgame variable, with 1 for yes, 0 for no, etc.
Forever and ifs you can use to check the state of the variable, and so on and so forth.
Anyways, the point is that it is recommended to have all of your hat blocks to be: When Green Flag is clicked.
Hope I helped!

dracae - I'm going to disagree with you on this. You should really limit the use of “When GF clicked” blocks because of the reasons I gave above. You can't control the order that they run and often times people are checking variables in those blocks. If those variables haven't been set yet they you are in trouble (this was one of the problems in the Wreck it freddy program).

When you have a clear change in the state of your game (like going from the main menu to starting the game), you should use a broadcast. For one thing it wastes CPU cycles to have all your sprites spinning in a loop waiting for the change.If you use broadcasts, it is clear what the change is and who is listening for the change. What if you never hit that gameState that your sprites are waiting for? What if you jump to a different gameState because of a new game option you added? Those sprites may be stuck waiting for a gameState that won't happen.

Once your game is running, you can use a gameState variable to signal smaller changes to the sprites (like in Donkey Kong when mario gets the hammer).

I agree with what you said, and that may be true in this case. and in many other cases.
But for almost all of my projects, I have found broadcasting to be inefficient/laggy.
I suppose whatever works.

(EDIT: I'm just trying to say that I prefer variables over broadcasts)

Last edited by dracae (June 6, 2013 18:39:36)


manwithmanykids
Scratcher
67 posts

Beginner with many questions.

As a dev in many other languages, I can tell you what Mwiedmann is saying makes sense. In any code, its always preferred to have a sigle entry point that controls initialization of variables etc, then passes control to a main event listener of some sort.

This does 3 things:

1) ensures variables are initialized before they are used
2) allows new initializations of objects/variables in a easy manner
3) makes managing the starting sequences etc alot easier, because you don't have to worry about rogue events occurring until your program/script id ready to handle them

I am a new scratcher, but that my 2 cents worth

Heres my Pokemon Battle Project

http://scratch.mit.edu/projects/10433760/

mgrobbel
Scratcher
9 posts

Beginner with many questions.

After some time off to work on other things, I'm looking for a little more help. I have a question regarding clones:

I'm trying to find a way to detect that all my windows are “fixed”. This will then end the game, but I can change that to end a level in the future. I have made clone windows in my game. Each window is a clone and randomly chooses a costume at the start of the game showing either fixed or two different broken costumes. The main character, Ralph, fixes windows by changing broken ones (costume 2 or 3) to fixed windows (costume 1). I'm not sure if my script for detecting all windows are fixed (costume 1) is faulty or if because the windows are clones, Scratch doesn't keep track of each clones costume. Do clones register as individual sprites to the point where Scatch would know which costume each clone is currently on or does it just track the original sprite?

If Scratch does not know the costume of each clone, is there a different way to end the game/complete the level upon the fixing of each window?

http://scratch.mit.edu/projects/10352728
ErnieParke
Scratcher
1000+ posts

Beginner with many questions.

mgrobbel wrote:

After some time off to work on other things, I'm looking for a little more help. I have a question regarding clones:

I'm trying to find a way to detect that all my windows are “fixed”. This will then end the game, but I can change that to end a level in the future. I have made clone windows in my game. Each window is a clone and randomly chooses a costume at the start of the game showing either fixed or two different broken costumes. The main character, Ralph, fixes windows by changing broken ones (costume 2 or 3) to fixed windows (costume 1). I'm not sure if my script for detecting all windows are fixed (costume 1) is faulty or if because the windows are clones, Scratch doesn't keep track of each clones costume. Do clones register as individual sprites to the point where Scatch would know which costume each clone is currently on or does it just track the original sprite?

If Scratch does not know the costume of each clone, is there a different way to end the game/complete the level upon the fixing of each window?

http://scratch.mit.edu/projects/10352728
No, Scratch cannot simply access each clones costumes (nor variables), which I heard has been an issue with various Scratchers in their programs. Although you can't access the costumes directly, you can still access them with a bit of code. It's late where I am, though I'll come back by tomorrow morning. ;)

With regards,

ErnieParke

P.S. I hadn't gotten a chance to say this yet, but hello mgrobbel and welcome to Scratch! I hope that you have a wonderful time here!

Powered by DjangoBB