We have seen some "programming" (via the code.org
course), discussed what programming is, and created a story telling program and an initials-drawing program in Scratch. There are still things you (or your students) can do with Scratch—more involved animation, trivia/quizzing, etc. Another is gaming. As you can imagine the complexity of the a game program can vary a lot. For this assignment a modest amount of complexity is expected—you are being asked to produce a game program that uses controlled repetition and variables (perhaps for attempts, score, level, games played, etc. You may wish to make use of cloning which will could make use of random values.
The first step in this assignment is to decide on your game. Some ideas you might draw from are:
I suspect you can think of a other possibilities if these don't catch your fancy. The program you plan and implement should include the first three and two or the other four elements below. It should not be too difficult to include all seven elements.
When you are finished with your program you will want to share it with the class by placing it in our studio. That process involves:
I think the following approach works
It should show our class studio (PEEE_fall17) as a link and a checkmark (also as a link)
It should turn green.
You should be able to see that your project has been added to the studio.
That should be all it takes to "submit" the program. Whichever partner submitted the program should have the other partner sign in to Scratch and double check that the project is available in the studio. Don't forget that both partners need to individually complete the PAC assignment for this activity.
Note that you should always be able to get back to the project page or to the Scratch programming environment from which you can access the project page. If you joined Scratch, your projects should all be available and be saved regularly by the system.
I will be checking the programs to see if they meet the specifications (noted above). A program that minimally meets the required specs is at least "okay" (will get a C or better). Better programs will go beyond the the minimal specs, e.g., meet some/all optional specs, include more variables and/or sprites, follow coding recommendations (see below), have commented code, appear well planned rather than the result of guess and check coding, use additional Scratch features in reasonable/appropriate ways, etc.
Variables allow us to save and access data values while a program is running. Using them typically requires at least three actions: 1) creating them, 2) initializing them, and 3) updating or changing their values. In this program you may use a variable to count something, e.g., "score" or "attempts". Computer programs count by adding 1 to a variable. Thus, the variable must have a value assigned to it before you can add to its current value. The code for updating the value is simple but deciding who (which actor) will update the value and when is a little more involved.
I recommend you have the stage handle both tasks. If you are using the "places everyone" technique you merely place a set [score▼] to (0)
block in the when-green-flag-clicked script (I would put it before the broadcast blocks). Changing the score is more complicated.
I suggest you pick one actor (sprite) to recognize the need to change the score that it (the actor/sprite) broadcast a message such as "add point". The stage would need a when I receive [add point▼]
block under which would be a change [score▼] by (1)
block. That should do it.
As you might expect cloning creates a copy of a sprite. There are two main things to worry about: 1) when to clone and 2) what the clone should do, particularly when it should go away. Ofen in a game scenario, the clone is something that (may move about but) will occasionally have a copy of itself move from its current location in some path (often just dropping from near the top of the screen). The copy/clone then moves in the indicated direction until it touches something—another sprite or an edge— or until its y- or x-coordinate reaches some extreme value. Then the copy/clone will disappear (via a delete this clone
block).
Creating a clone is relatively simple. Assuming you are using the "places everyone" technique, you use code such as
when I receive [action▼] forever | wait (pick random (3) to (10)) | create a clone of [myself▼] |_______________________________________
This script is added to those of the sprite you wish to clone itself. Using the forever block means that you need some sprite to recognize when the program should stop and include a stop [all▼]
block in one of its scripts.
You also need to determine how the clone is to behave—what actions it should carry out. The outline of a script shown below is one way to do this.
when I start as a clone repeat until < (y position) < (-170) > | if < touching [??▼] ? > | | broadcast [add point▼] | | delete this clone | |___________________________ | change y by (-10) |_______________________________________ delete this clone
The above code will be a script in the scripts of the sprite that is being cloned. The two question marks would be replaced by whichever sprite you wanted to check for touching the clone. Note there are two conditions under which the clone will be deleted—when it touches the indicated sprite or when it gets to the bottom of the screen. This allows us to know the clone will be deleted rather than hanging around when it gets to the bottom of the screen. Also, deleting the clone automatically stops its script. Note that there are several places you can place code for additional actions, i.e.,
Actually I think it is poor practice to use the forever block, even with the stop-all-scripts block. It is better to be in control of when the loop stops. I prefer to use a repeat until <__>
that tests some variable's value, e.g.,
when I receive [action▼] repeat until < running = stop > | wait (pick random (3) to (10)) | create a clone of [myself▼] |_______________________________________
This approach would require having a variable (running
in this case) that the stage sets to go when the green flag is clicked. When it is time to stop, whichever sprite recognized that would broadcast a message such as time to stop. The stage would have script like the following to change the value of running
.
when I receive [time to stop▼] set [running▼] to [stop]
This allows us to be in full control of our program.
Computer games typically get harder as the player demonstrates skill. For that to happen the program must keep track of some value it will use to recognize skill progression and have some mechanism for getting harder. These tasks are interrelated and can various sprites. An example attempting to illustrate a "good" (or at least not bad) way to accomplish the whole task follows.
I want to have the a star move across the top of the screen occasionally dropping a copy (clone) of itself toward the bottom of the screen. The cat sprite can move about on the screen in response to the arrow keys in an effort to "catch" the falling stars before they get to the bottom of the screen (or near it). I want to keep track of the number of falling stars and times they are caught to have a percentage of catches as the score. When a star is caught and the score (percentage of catches) is greater than 75% (or .75) I want to "level up" or add 1 to the level. Whenever the level gets higher the speed of the star's movement and of the falling stars will get higher (as will the cat's speed). To accomplish this, I intend to use a lot of variables, i.e., discussed a bit below and initialization shown in the sample code
Initialized via "places everyone" and changed by the star when it creates a clone of itself
Initialized via "places everyone" and changed by the stage when it receives a "caught one" message which will be broadcast by the clone when it touches the cat
Initialized via "places everyone" and changed by the stage when it receives a "caught one" message which will be broadcast by the clone when it touches the cat
Initialized via "places everyone" and changed by the stage when it receives a "caught one" message which will be broadcast by the clone when it touches the cat
Initialized via "places everyone" and changed by the stage when it receives a "caught one" message which will be broadcast by the clone when it touches the cat
Initialized via "places everyone" and changed by the stage when it receives a "caught one" message which will be broadcast by the clone when it touches the cat. This variable is used in generating a random wait time. As the level gets higher the maximum time before generating another clone will decrease which will also speed up the play of the game.
I will use another variable (running
) to control looping behavior and avoid the forever loop. It will be initialized to go
and the beginning of the program and set to stop
when the space bar gets pressed—a mechanism I used to allow the user to stop the program (and make sure everything actually stops). The example to the right shows the variable being used for the script that allows the star to move back and forth across the screen.
You might also note the use of a touching color
conditional block to know when to turn around and go the other way. One would think that you could use if < touching edge▼ >
as the test to turn around. But it turns out that a sprite's touching something can end up putting it in a bouncing state where it sits and quivers. This is due the movement of the sprite not allowing it to exactly touch the edge and it cannot move beyond the edge. So one comes up with some alternative. One possibility is to check the x-coordinate and when it gets too big or too small change direction. Another alternative is to use the touching color test that I used.
My score-keeping approach is different and perhaps more involved than most. Additionally, it is not particularly effective, but sometimes we have to do things poorly to recognize that there are better ways. I wanted to "level up" whenever a falling star was caught and my success rate was 80% or better. That means I needed to keep track of the level and the number of clones produced and the number that were caught. Each needed to be initialized (in the "places everyone" script) and then reset when the appropriate action happened. The actions were:
It makes sense to change this count whenever a clone gets created so I place the code to do so in the script used to generate the clone. Note the wait period before a clone is produced. The random value means irregular wait times. Also, note the repeat until <...>
loop that is used instead of a forever
loop.
Most folks (I think) would expect the cat to increment the count of caught stars. However, that doesn't work so well because there is no obvious way to have the cat check to see if it is touching a clone of the star. We need to have the clones check to see if they are touching the cat. (Which we do.)
But, instead of incrementing the count of the caught stars, I use broadcast [caughtOne ▼]
to notify the stage that I want it to increment the count and do all the calculations for the leveling up.
I try to have the stage do calculations (unless there is good reason to do it elsewhere). That locates that kind of code all in one place and simplifies the scripts for most sprites. In this case, there is no reason why any particular sprite should calculate the score or level, etc. So, It is (mostly) all here.
The order of the code elements is important. We need to count the catch before we calculate the score. We need to calculate the score before we test for leveling up. And, if we level up, we need to increment the level value before making changes to the items that will make the action more challenging at this higher level.
We chose to make increase the movement speed of all elements (cat, star, and clones). We do so by having them move further each time they move We also wanted to speed up the making of cloned stars so we reduce the maximum wait time for making another clone. All those calculations occur when (and only when) we change the level. (Note, that I had thought to also decrease the minimum wait time but decided not to do that.)
Games will typically involve moving a sprite, often by using the arrow keys. To move a sprite with the arrow keys your program needs to recognize the keypress and then react appropriately. Scratch has an event handler that will recognize the keypress, so programming the action merely requires building a script around the event handler. (See example to the right.)
The if <(running) = [go]>
statement avoids being able to move the keys when the program is not running, i.e., before we press the green flag (which will set running
to go
). The sprite's movement is programed to allow movement as long as the key is pressed rather than requiring the user to repeatedly press and release the key (though that will still work but the speed may be slower). Note the use of the variable speed
in the move __ steps
block. The same will happen in the movement of the star sprite and its clones.
Keep the "pair programming" process in mind as you work. One person types and the other person watches and corrects, questions, etc. After a bit (at most 30 minutes) you change roles.
If you have questions about the assignment send me an e-mail or drop by my office. If you have a question while working on the assignment do the same. Keep in mind that when you encounter something you can't figure out you can/should think, explore, seek answers on google, etc. but, do not spend more than 15-30 minutes trying to overcome a particular error or problem.