Showing posts with label pygame. Show all posts
Showing posts with label pygame. Show all posts

Saturday, January 31, 2015

4th Grade Girl Python Coder - Tiled Map Creation


As fathers and mothers, we protect our children from disappointment.  In our quest to shield them from failure, we expect too little from them.  Every week, I am amazed by an ordinary 9 year old girl, banging out Python code in PyCharm from a blank screen.  Girl Coder represents one possible future of America.  Although in 20 years, she may be a baker, ballerina, housewife, or teacher, today she is a coder.

For many years, I had under the mistaken impression that kids under age 12 could not learn to program effectively.  I was wrong.  They can do it.  I made many mistakes as a parent-as-teacher with my first child.   The breakthrough insight for me came when I realized that almost all the books and curriculum out there was designed for adults.  At the time, back in 2011, most of the curriculum for children was still based on Java.  The bigger problem was that the curriculum was designed for adults, not children.  

Today, is just another Saturday stay-at-home morning for Girl Coder, age 9.  No surfing today as her brother took off to Tahoe for snowboarding and we decided to relax indoors for a change.  Piano and Python got her attention, not necessarily in that order.  :-)

She built a tile map using Tiled today.  She then used PyCharm to write a Pygame program to move a  girl around a map. This is a modification of PyChildren Lesson 3, The Moving Square.



The first step to make the lesson easier for young children is to use Tiled to output a png file instead of a TMX or JSON file.  In this game, she is using one large image as the entire map.  By using an image instead of JSON or TMX data, we don't have to parse the data.  Girl Coder uses Tiled like a paint program.  She likes the stamps and bucket fills.  Within about 20 minutes, kids can build a pretty snazzy looking map for their games.

The modification to lesson 3 starts off pretty simply.  For this lesson, the girl stays in the center of the screen.  The map moves.   The first tricky part is that she needed to move the map to the left in order to move the girl to the right.   That's not too bad since you can immediately test and see that the girl is moving in the wrong direction and just change things from addition to subtraction.





The goal is to get the girl to appear to move to the right.

In order to do this, the girl remains stationary and the map moves to the left.



In order to move an image to the left, subtract 1 from the x-axis.


At this stage, I'm not sure if she understands the concept of moving the map to the left to get the girl to appear to be moving to the right.  I think it's okay if she doesn't get it.  I'll plan on going through the map lesson again from the beginning and have her implement bounds detection.  She's developing a story with the map.  There are scary places and places with treasure.

The sequence for this lesson.

  1. Blank Screen
  2. Stationary Square
    1. Modify lesson to blit the background map to the screen
  3. Moving Square
    1. Modify lesson to move the map around instead of the player
  4. Keyboard Input
    1. Using the keyboard instead of the touchscreen

At this stage you can stop.  it's cool to see the character move around a map that the child made.  it is somewhat unsettling to not have bounds detection and run out of map.   Since Girl Coder has completed this same drill a number of times, I added bounds detection to the lesson.

Challenge of Bounds Detection

The main challenge with the lesson is how to get the girl to stay on the screen.  To prevent the girl from moving left, it is relatively easy.  Remember, to give the appearance that she's moving left, you're moving the map to the right.  You move things to the right by adding 1 to the x coordinate.  If you name the x coordinate map_x, then you move the character to the right by adding 1 every time through the loop.  

So, what number does map_x need to be less than?  Well, if you started map_x at 0, then when you moved the map to left, you subtracted 1 every time through the loop.  map_x then existed only as a negative number.  As long as map_x is less than zero, you can add one to it.  As soon as the number gets to zero, stop adding numbers to it.

As this is confusing, let's look at the code.

The size of the map is 1216 pixels by 826 pixels. The size of the Pygame window that the game is played in is 480 by 320.  You'll need to help the child with this section.
Here's the entire code listing.

Read Previous Adventures of Girl Coder

Other Options If You Can't Teach Your Own Kids

My daughter also takes classes at LearningTech.org in Palo Alto.  The class is great.  It's run by Dr. Mark Miller and Dr. Len Erickson.  There are two levels, grades 1-3 and grades 4-5.  You may wonder if a 2nd grader can code.  Can they even type?  Yes, they can.  


At the beginning of 2015, it's more common to teach children to program.  The curriculum at LearningTech.org is great.  It resembles my PyChildren curriculum, though my curriculum is designed for one-to-one teaching.  I'm not sure which method is more effective for teaching, but the PyChildren method is designed to bond your kids, not just to teach them programming. 

Sunday, November 2, 2014

Pygame Virtual Controller Update

I worked with my son for about 2 hours today on the Pygame virtual controller for Android.   The main challenge with the controller is the use of sine, cosine, and tangent.  Although we all learn trigonometry in school, how often do you use it?  Outside of making games, I never use it.

Another challenge is getting comfortable with sprites and sprite groups for the bullets.  Since the bullets are simple, we could easily make the game without sprites.  It's possible to use rectangles stored in lists.  Sprites have a number of advantages over rectangles.  I like to use sprites because its a concise way to organize all the bullets into a single sprite group and then use bullet_group.update() and bullet_group.draw() to manage all the bullets on the screen.

The first time you type in a sprite class, it looks a bit odd.  I think the oddness of the line pygame.sprite.Sprite.__init__(self) makes the sprite more intimidating than it really is.



class Bullet(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((6,6))
        self.rect = self.image.get_rect()



After getting the bullets to fire properly with sprite groups, the next challenge was to get the player to move around the screen with a secondary virtual controller.  Although we built the code to calculate the angle of the controller for firing in the previous lesson, the player wasn't moving.  Once the player starts moving, the angle needs to be calculated from the center point of the player.  The modification to the code is minimal, but the conceptual leap of thinking of the opposite, adjacent and hypotenuse sides can be daunting when the triangle is moving all around the screen.  

Once you get the angle and the center, the code to move the player is straightforward.

def move(angle, center):
    hypotenuse = 10.0
    adjacent = math.cos(angle) * hypotenuse
    x = int(adjacent + center[0])
    opposite = math.sin(angle) * hypotenuse
    y = int(center[1] - opposite)
    return ((x, y))
At the end of the lesson, he had a working app with 360 degree firing and movement.

The next step is to get this working on his accelerometer game.  We're bumping up into the limitations of single-point touch and are trying to use the accelerometer for movement.  It's easy to access the Android accelerometer, but it's uncertain how playable the game will be.  We're using Cube Runner as a model for playability.


Saturday, October 25, 2014

Virtual Controller Angle Tutorial


This is part of an educational curriculum to teach 9th and 10th grade students how to build mobile games on Android. The student needs to be familiar with trigonometry. The primary target student is in 10th grade.
There are two examples. The main lesson is in main.py and focuses on the getting the angle from the virtual controller. The second lesson is in bullet.py and shows how to fire bullets from a moving player. There is sound generated each time a bullet is fired.
Here's a video snippet showing the 360 degree movement and independent firing.
Screen shot of virtual controller with bullets
Additional sounds can be downloaded from SoundBible.
Since the player is moving, I also implemented a rudimentary bounds detection so that the player doesn't move off the screen.

Create the Controller

In this lesson, the controller is a circle of radius 50. The main objective is to calculate the angle of the player's right thumb in relation to the center of the circle. Since we're running this on a desktop computer before loading it onto an Android phone, the mouse will represent the point the thumb touches the screen.
 pygame.draw.circle(SCREEN, RED, v_control.center, 50, 2)
 pygame.draw.circle(SCREEN, RED, v_control.center, 3)
There is a rectangle called, v_control that I'm using with colliderect.
 v_control = pygame.Rect(650, 450, 100, 100)
Before I calculate the angle, I make sure that the thumb is inside of the rectangle for the virtual controller.
if v_control.collidepoint(pos):
    rad = get_angle(pos, v_control.center)

Review Your Trigonometry

You'll need to use arc tangent to calculate the angle in radians. You'll also need to use sine and cosine. If your trigonometry is a rusty, review it now.
math.atanmath.sin, and math.cos are in the python math standard library. You'll need to addimport math at the top of your program.
Review of sine, cosine, and tangent
To use arc tangent you'll need to calculate the lengths of the opposite and adjacent sides of a right triangle. Since the formulas to calculate the lengths of the sides of a triangle are slightly different depending on where the thumb is on the controller, I've divided the controller into four quadrants, starting with quadrant one in the upper right and rotating counter-clockwise.
For each quadrant, you'll need to adjust the formula to calculate the opposite and adjacent sides of the triangle. For example, if the mouse is above the center of the controller, you'll need to subtract the mouse y position from the centery of the controller.

Define Each Quadrant

Diagram of characteristics of each quadrant
For the y-axis, the mouse point is either:
  1. above the center of the controller
  2. below the center of the controller
  3. at the same height of the center of the controller

Quandrants 1 and 2

Mouse Point Located Above Controller Center
If the mouse point is above the center of the controller, than check for one of three conditions:
  1. x is to the right of the controller
  2. x is to the left of the controller
  3. x is at the same point as the centerx of the controller

Quadrant 1

Mouse point is located above and to the right of controller
Diagram of Quadrant 1
Example code. Note that you need to convert to floating point.
center is a two number tuple (400,300), the center of the player. x, y is the mouse position.
    opposite = float(center[1] - y)
    if x > center[0]:
        adjacent = float(x - center[0])
        rad = math.atan(opposite/adjacent)
Here's what it looks like with the game running. Note that the angle of the mouse pointer relative to the center of the virtual controller is the same as the angle of the beam relative to the center of the player.
Screenshot of game with beam in quadrant 1


Quadrant 3

Mouse point is below and to the left of the controller center
If the mouse pointer is not in quadrant 1, add the appropriate radian value. For example, if the mouse pointer is in quadrant 3, then add pi (3.14) to the radian value.
calculation of quadrant 3

Using Radian Angle to Control Beam

Creating a beam is easier than a bullet. It is a line with the starting point at the center of the player and the end point 30 pixels out from the center.  In the next lesson, the beam becomes the gun turret.  I increased the width of the line to 6 pixels.  The end point of the gun turret will become the starting point of the bullet.  
Once you have the angle, use sine and cosine to calculate the length of opposite and adjacent sides of the triangle.
def beam(angle, center):
    """
    :param angle: radians calculated from the virtual controller
    :return: x,y coordinates of the end-point
    Start with the center of the player.  The end of the beam is 100 pixels
    away from the center.  To make a bullet instead of beam, create a class
    for bullet and have the hypoteneuse be an attribute that increases
    in size.  Remember to delete the bullet from the sprite group or list
    when it goes off the screen.
    """
    hypoteneuse = 30.0
    adjacent = math.cos(angle) * hypoteneuse
    x = adjacent + center[0]
    opposite = math.sin(angle) * hypoteneuse
    y = center[1] - opposite
    beam_end = (x, y)
    return beam_end

Shoot Bullets Instead of a Beam

If you want to shoot bullets, I'm using sprites. Don't be intimidated by sprites even though the code looks a bit funky. The bullet moves forward by increasing the length of the hypotenuse by 5 pixels.
class Bullet(pygame.sprite.Sprite):
    def __init__(self, angle, p_pos):
        YELLOW = (250, 223, 65)
        RED = (200, 10, 10)
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((6,6))
        pygame.draw.circle(self.image, YELLOW, (3, 3), 3)
        pygame.draw.circle(self.image, RED, (3,3), 1)
        self.rect = self.image.get_rect()
        self.hypotenuse = 30.0
        self.angle = angle
        self.cent = p_pos

    def update(self):
        adjacent = math.cos(self.angle) * self.hypotenuse
        x = adjacent + self.cent[0]
        opposite = math.sin(self.angle) * self.hypotenuse
        y = self.cent[1] - opposite
        self.rect.center = (x, y)
        self.hypotenuse += 5

You'll need to set up a timer for the creation of new bullets so that the bullets don't clump together in a mass of destruction every time you press the fire button.  See the code in bullet.py for an example in how to create the delay between bullet creation.

Move The Player

In the second example, I'm using almost the same code to move the player around the screen.
Move on to the second lesson on virtual controller angle tutorial.


More games with Python, Pygame, and pgs4a written by a boy in middle school and high school are available for reference to see what a typical child is doing.  It's important to understand that the examples don't show the best way to do things.  They just show a way that a child is getting stuff done. One of the problems I've found with most tutorials is that the examples are best-practice perfect for adults.  I have a theory that children also learn by thinking about how to improve on another child's code.  Additional examples are available
The most likely scenario is to start with Swarm and build from there.
My son is planning to try something with the Android accelerometer.

Saturday, October 11, 2014

Using Android Accelerometer with Pygame

My son recently started to use the accelerometer functions in his Android phone to develop games with Python. He's building a variation of Swarm, a 2D tile map game that he wrote in middle school.

The accelerometer is easy to get working with pgs4a.

To pull the x,y,z axis, use this:


You will get a floating point number for each of the three axises.

Here's a simple way to set four directions, up, down, left, right:


In the example above, I'm holding the phone sideways, in landscape mode.  The left-right movement is controlled by the 2nd value in the list and the up-down movement is controlled by the 1st item in the list.

It would easy to set up 8 direction movement or even a greater range of movement.  Unlike Swarm, which used only 8 directions for bullets, we're using sin and cos to give the bullets a greater range of movement.

In order to test the application on my desktop, I've also created a virtual controller to simulate the accelerometer.

Here's the application running on my desktop with the virtual controller.


After you install the application on your Android phone, it is a bit more difficult to debug and test the accelerometer.   You can print out the value of the accelerometer and then tune your game so that the player moves with the sensitivity that works for your game. If you print out the accel_reading, you will see a three number tuple, with the numbers all in floating point.


I/python  (21058): Initialize Python for Android
I/python  (21058): ['/data/data/org.pychildren.accel/files/lib/python2.7/site-packages', '/data/data/org.pychildren.accel/files/lib/site-python']
I/python  (21058): Opening APK '/data/app/org.pychildren.accel-1.apk'
I/python  (21058): (-3.8019924163818359, -0.31603461503982544, 8.7819318771362305)
I/python  (21058): (-3.8019924163818359, -0.31603461503982544, 8.7819318771362305)
I/python  (21058): (-3.8019924163818359, -0.31603461503982544, 8.7819318771362305)

If you don't know how to see the output from your app when it is running on your phone, read my   post explaining how you can see the output of your print statements with adb.

Here's a demo of the character running on an old Samsung phone without the flock.   The controller in the lower right is for 360 degree bullet firing.


Organizing Pygame Programs Into Separate Files - Getting Started With Basics

Everyone starts off with one long block of code in a main.py file. At some point, we break the program into separate files. In python, the separate file is called a module. Within each module, you can put functions and classes. As soon as you start to break up the program into separate files, everyone wonders how to get the variables from the main while loop in pygame to the module that is drawing something to the screen.  There are many ways to do this.  The easiest is to pass the main screen to your module as a global variable.

In this example, I call my main program main.py and I call my module draw.py.

craig@ubuntu-desktop:~/Development/dad/screens$ lsdraw.py  draw.pyc  main.py 
Ignore the file, draw.pyc.  It is created automatically when you run the program.

From main.py, you can access draw.py using import draw



My draw module just puts two graphics to the screen, one with a function and with with a class.

To access the module from the program, you can either call the function directly with draw.dot(SCREEN) or instantiate the class.
Here's the full code listing:



Image of program showing how main.py calls up the draw function from draw.py.


Sunday, September 21, 2014

Pygame on Android - What to Do When Your Android App Dies Soon After Startup

You can use adb to get console error messages and print statement output from your pygame app on Android phones.  One of the most frustrating thing for beginners to pygame on Android is when the app runs fine on their desktop, but dies soon after startup on their Android phone.  Usually, you click on the app, the splash screen comes up, then the Android app silently dies.  Unless you're using adb, corrently you could be stuck.

With the usb cable connected between your phone and desktop, run 

adb logcat |grep python

Here's the output I got today.

I/python  (  580): 
Opening APK '/data/app/org.pychildren.surfsc-2.apk'I/python  (  580): 
Traceback (most recent call last):I/python  (  580):   
File "main.py", line 323, in <module>I/python  (  580):     
main()I/python  (  580):   
File "main.py", line 296, in mainI/python  (  580):     
pprint.pprint(weather.w_dict)I/python  (  580): 
NameError: global name 'pprint' is not definedI/python  (  580): 
Python for android ended.I/ActivityManager( 7163): Process org.pychildren.surfsc:python (pid 580) has died.

It is clear that there's a problem with the pprint.pprint statement that I was using to display the Python dictionary of weather data.  It even gives me the line number in my source code.  I simply commented out the line and the app started working again on my Android phone.



I've added basic weather information to my version.  My son's version has a cleaner interface and better colors.


Monday, September 15, 2014

Overview of Teaching Python to Graph Output from Cloud API - Spitcast Surf


I've been working with my son to build a mobile app that displays graphs of tide charts and tables of surf forecasts for the Santa Cruz region.  The app runs on his Android Motorola Moto-G phone and my Samsung Galaxy Note 2.  He grabs the data using the Spitcast API and displays the output using Pygame.


The tide has a huge influence on the quality of surf in Eastside Santa Cruz.  The optimal tide conditions at my favorite spot is a tide that is rising from 2 feet to 3.5 feet.  The swell height and direction also plays a big role.  In the future, we'll use the API from OpenWeatherMap to pull the sunrise, sunset, and wind.

The steps are:
  1. Pull data from Spitcast using urllib2
  2. Read JSON data from API into program and then convert to a list of Python dictionaries using the json library


The lesson gets off to an exciting start. The student will realize the potential of accessing cloud-based APIs. Assuming the student has a basic understanding of Python data structures lists and dictionaries, they'll also understand how easy it is to parse the data. The simple idea to convert the tide values of feet into pixels is just to multiply feet by a constant number. In this case, I multiply the height of the wave in feet by 50 to get a pixel value. For example, a wave height of 5 feet will correspond to a screen height of 250 pixels. To generate the y coordinate for the Pygame screen, I subtract the pixel height from 550. Remember that a y value of 0 is the top of the screen. I set my screen height on the phone to 500 pixels. A wave height of 1 foot will equal screen height of 50 pixels. Subtracting this from 550 will yield a y position of 500.
  1. Build start and end points for a series of 23 vertical lines spaced evenly apart to create the x axis grid. 
  2.  Create a point list that will be used by pygame.draw.lines in a future section.



At this point, the student will have a list of points that they can then draw with pygame.draw.lines for the tide graph or pygame.draw.line x, y axis grids.
Here's the basic algorithms with a bit more bells and whistles.

In the main while loop, I have this code.
This is the android-presplash.jpg screen of the application.


In the future, we'll merge the features from my son's Weather App project into Santa Cruz Surf.





Below is a shot of the app developer benefiting from the application.




Monday, March 17, 2014

Python Android App Debugging Tip: adb and python print statements

With the phone connected to the USB cable and in debug mode, open a new terminal window and type:

  $ adb logcat |grep python

Update 10/11/2014. Windows users, see below. An alternative to using grep:

$ adb  logcat python *:s


You can now view standard python output from applications running on your android phone with python print statements. Output of logcat
I/python  ( 2392): play sounds
I/python  ( 2392): play sounds
I/python  ( 2392): play sounds



The most common problems with Python Subset for Android Apps dying on the Android phone at startup:
  1. you didn't import the sound mixer module properly
  2. your fonts are not in the main program directory
  3. your sound files are not in the main program directory
  4. your graphic files or map files are not in the main program directory
  5. you are using a python module that is not in your main program directory
Note that there's a common theme here of a desktop program working because the assets exist somewhere on your desktop machine, but those assets don't get transferred to your phone.  Look at your sound, graphic, and font files to make sure they are in your main directory.

In the problems above, the adb logcat command will usually show you what asset the program fails to load.

You'll save time in the debugging process if you open up two terminals at once.  In one terminal, run the adb output.  In the other terminal, build and install your program onto your phone.  With the USB cable connected, run your application on your phone.

Check to make sure you are initializing the android library.


Make sure you are importing the mixer module as shown below. In previous versions of pgs4a, I had problems with audio files that weren't in *.wav format. I only use wav files now.

Another common problem is that your application is not named main.py.

Make sure you have called the application main.py and that you are building the application with the name of the directory that contains your application.

if you are using the sgc gui toolkit with android, you need to make sure that the fonts are loaded prior to setting up the sgc screen. I've had several occasions when I got the order wrong the my application worked on the desktop and crashed on the phone. This code below is only relevant if you use sgc, which is definitely not needed to make games on android. However, if you do use sgc to make your buttons and sliders, it can be a bit tricky to use on android.




Update: 10/11/2014 As my son is starting to do some development on Windows 8.1, I realized that he didn't have grep installed and didn't really need to go through the hassle of installing grep with cygwin. I looked at the filter options for adb logcat. The key is to set everything to silent except for strings containing python. Here's some docs built into adb that are somewhat difficult to understand. The only one that you need to use is the -s or *:s
Usage: logcat [options] [filterspecs]
options include:
  -s              Set default filter to silent.
                  Like specifying filterspec '*:s'
  -f    Log to file. Default to stdout
  -r []   Rotate log every kbytes. (16 if unspecified). Requires -f
  -n       Sets max number of rotated logs to , default 4
  -v      Sets the log print format, where  is one of:

                  brief process tag thread raw time threadtime long

  -c              clear (flush) the entire log and exit
  -d              dump the log and then exit (don't block)
  -t       print only the most recent  lines (implies -d)
  -g              get the size of the log's ring buffer and exit
  -b      Request alternate ring buffer, 'main', 'system', 'radio'
                  or 'events'. Multiple -b parameters are allowed and the
                  results are interleaved. The default is -b main -b system.
  -B              output the log in binary
filterspecs are a series of
  [:priority]

where  is a log component tag (or * for all) and priority is:
  V    Verbose
  D    Debug
  I    Info
  W    Warn
  E    Error
  F    Fatal
  S    Silent (supress all output)

'*' means '*:d' and  by itself means :v

If not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.
If no filterspec is found, filter defaults to '*:I'

If not specified with -v, format is set from ANDROID_PRINTF_LOG
or defaults to "brief"

Monday, March 10, 2014

Program Arcade Games Pygame/Pygame Book by Dr. Paul Craven


Dr. Paul Craven has written a nice book and site for college students learning to program.  He focuses on Python and Pygame.

It looks like a great curriculum for adults.

It's quite different from my curriculum which is targeted at children between 9 and 16.   The upper end of my curriculum is a moving target as my son gets older.

Since Dr. Craven is teaching computer science at Simpson College, he has a great pool of students ages 18 to 22 to experiment with and refine his curriculum.  It looks like a great class for college students.

His lessons on classes and sprites look like they're a nice next steps for more advanced children that have completed my curriculum.  I've been teaching my son about modules and libraries.  I've taken a different approach from Dr. Craven, but his approach seems fine for adults and possibly some children.



Sunday, March 9, 2014

Update on 9 Year Old Girl Learning Python

March 5th and 6th, 2014

Lessons focused on using blit to get a graphic of a girl onto the screen instead of a rectangle.  The lessons went smoothly.  I was surprised that she wasn't as excited about the graphic as I had thought she was going to be.  The standard rectangle may be sufficient to keep her attention.

She's still having challenges with manipulating the mouse for copy and paste techniques.  Her use of the keyboard is improving.

I realized that the use of pos = pygame.mouse.get_pos() to control onscreen graphics is easier than using the keyboard and then manipulating  x +=1 , y +=1 to move the rectangle around the screen.

Other tasks she accomplished:

  • created map background with Tiled map editor.  Began to learn about game tiles.  The map background does not have collision detection.  It is just one image that is blitted to the screen.
  • basics of map layers and graphic layers


March 9, 2014

I'm starting to learn more about her personality based on what graphics and sounds she chooses.  A big part of the lessons is the experience of a father/daughter bonding activity.  In a way, it doesn't matter if she learns programming or not.  Though, it is gratifying that she is interested in the activity and seems to have a knack for it.

Mouse manipulation and typing ability are vastly improved.  I'm shocked at how fast she's learning things, including the physical skill of typing.  If I didn't actually see a kid this age use PyCharm, I wouldn't believe that it was possible.  As I don't have another 9 year old kid to experiment with, I am assuming that she is typical and am using her as the baseline with only one data point.

Topics covered:
  • Use of gimp to edit graphic files.  
    • Add alpha transparency layer to graphics by using magic select and deleting the background.  
    • Scale image to fit on screen.  Learn more about pixel size for both image and screen.
  • Use of audacity to record and edit sound files
  • Load sound files with mixer.Sound()
  • Play sound files with name.play()
  • Collision detection with rect.collidepoint(pos)
  • I loaded the game on an Android phone for her so that she can see how easy it is to create these game on a mobile device.  She seemed to favor the desktop.  She's too young to use a mobile phone and doesn't have too much experience using them.
Video with sounds.



Game running on Android phone.





The code that the 9 year old girl wrote in PyCharm is shown below. Note that she starts with a completely blank editor screen at the start of each lesson. This means that she's repeated typing in the exact same base code from lesson 2 five times so far and has typed in the base code from lesson 1 an additional five times. I've started to modify the lesson so that she can extend the base code of lesson 2 to do what she wants.  It is important to note that up to this point, she has not used any math.  There are no addition or subtraction formulas.

The primary mathematical concept so far is for her to understand which of two numbers are greater than the other.  I am purposely using a screen that is 480 x 320 so that she can deal with manageable numbers, keeping integers under 1,000.

In the example below, she just needs to understand the following:

  • screen is 320 pixels high and 480 pixels wide
  • the middle point of the height is 160 pixels
  • the middle point of the width is 240
  • if the she wants the heart, zebra, and chipmunk to be at the same height, the center y coordinates need to all be 160 pixels down from the top of the screen
  • making the x axis smaller moves things to the left (note that be aware that the child may not know left and right.  Take this into account in your teaching.  Point to the appropriate direction if needed).
  • making the x axis larger moves things to the right (IMO, still too early for addition at this lesson.  Just use a single point.  In this case, heart, zebra, chipmunk)
  • similar concept to for the y axis
  • variable is used to hold the image after loading (handle)
  • variable is used to hold the sound after loading (handle)
  • once the image and sound are loaded, she can use the asset handle to make it do things like display to the screen or play the sound
  • collision detection is used to trigger an action.
There's quite a bit of concepts here.  I suggest repeating these concepts multiple times before extending it to addition and subtraction.


Monday, March 3, 2014

Day 8 Girl Learning Python at Age 9

I’m surprised that I’ve needed to increase the difficulty of the lessons for my daughter. Her typing is getting better. The code completion of PyCharm is awesome.
I’ve developed five drills based on this experience.

Drill 2.5

import pygame,sys  import random    pygame.init()  clock = pygame.time.Clock()    size = (480,320)  screen = pygame.display.set_mode(size)    while True:      for event in pygame.event.get():          if event.type == pygame.QUIT:              pygame.quit()              sys.exit()      p = pygame.mouse.get_pos()      c1 = random.randrange(20, 255)      c2 = random.randrange(20, 255)      c3 = random.randrange(20, 255)      color = (c1, c2, c3)      pygame.draw.circle(screen, color, p,10)      clock.tick(30)      pygame.display.update()  

Drill 2.4

import pygame,sysimport random    pygame.init()  clock = pygame.time.Clock()    size = (480,320)  screen = pygame.display.set_mode(size)    while True:      for event in pygame.event.get():          if event.type == pygame.QUIT:              pygame.quit()              sys.exit()      c1 = random.randrange(20, 255)      c2 = random.randrange(20, 255)      c3 = random.randrange(20, 255)      color = (c1, c2, c3)      x = random.randrange(0, 480)      y = random.randrange(0, 320)      pygame.draw.circle(screen, color, (x,y),20)      clock.tick(3)      pygame.display.update()