Blog for the Victoria University of Wellington Faculty of Engineering Outreach activities
Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts
Friday, 25 July 2014
Tkinter - Random Backgrounds with Python, version 2!
Our original random background generator was rife with errors so we've restructured it to make it a little better. See if you can follow the math and where I went wrong in the last one!
Tuesday, 15 July 2014
Python - Level 3 Material
Level 3 Python Topics
- Review Python Level 1 Topics
- Review Python Level 2 Topics
- Tkinter (GUIs)
- Object Orientation (classes)
Tkinter
Tkinter is a python module for creating simple graphical user interfaces (windows and elements). Whilst I covered the basics of making a Tkinter canvas and drawing shapes here, I'll also mention how to add buttons and text fields etc. Here's something we might start off with:Now to add a button:
But this button doesn't do anything. To attach some functionality to it (in this case we're going to overwrite the blue rectangle with a white one) we use the 'command='statement in the Button() method and then we write a method linked to that (in our case called doClear).
But we can also add more than buttons - for instance here's a text_field with an associated label:
And here's a dropdown menu that allows users to pick from a series of predetermined choices:
Challenge:
Make a Tkinter GUI that allows the user to pick from a list of countries and then draws out their flags using the Tkinter canvas create_rectangle/arc/oval commands when the 'Draw' button is pushed. I suggest starting with Japan, Germany, Norway and Scotland.
Object Oriented Programming
Object orientation is a way of re-organising your code in such a way that it makes doing lots of complicated things much easier (a bit like we did with methods in the Level 2 section). The only way I managed to wrap my head around it (and it took me ages!) is to think of an illustrative example. Imagine you were writing a simple game like pong for instance.
Essentially you need to create two paddles and a ball (ignoring scoring), remember where each is, what direction it's travelling in and at what speed, where its edges are etc. You can do this pretty easily with only 3 items (although it will require a fair few variables). But imagine what would happen if you tried to extend pong in any way; What if you decided to add 2 balls? Or 3? What if you just wanted to add in a third dimension? The number of variables and complexity gets huge! And we're just doing more of the same, so instead we write a Class for the ball and paddles and then we just say how many of each we want. Each class remembers its own set of variables, which means we only have to define each one once and every new copy already has its own variables. For instance the Ball class might be defined like this:
The full code of a ball class might look like this:
and now if we want to add bouncing functionality off the walls (and generally clean up the code)
Challenge:
First, extend the code above to have >100 balls all starting at different locations (this should only take about 5 more lines of code). Make Pong using Tkinter and a class for the GUI, paddles and ball(s).Final Challenge:
Build a 'mosaic maker' program - a program that generates a grid of squares in a GUI canvas and allows the user to change their colour by clicking on them (example shown below). The GUI should have 2 buttons that allow the user to select either red or blue for the colour of the clicked square (the default should be black) and one that allows the user to clear the grid to white. Finally you may want to extend your program to allow the user to replace a square with a .png image of their choice or to choose particular colours by entering their numeric RGB values, and write a doctest that tests your programs ability to deal with non-RGB inputs. Finally re-structure your program so that you have a class for the GUI.
Python - Level 2 material
Level 2 Python Topics
- Review Python Level 1 Topics
- Methods
- Importing Text files
- Navigating Lists
- Sanitising user input
Methods
In the Level 1 material we used a number of 'methods' already (like rantint() and range()). These were predefined by other people - but we can just as easily write our own to do what ever we want, is particular this comes in really handy when you want to do the same or similar things multiple times. Rather than copy pasting our code - we can just repeat a method with different inputs.
Challenge:
Construct a method that picks a random number between 2 numbers passed to the method but that DOESN'T include the numbers themselves.Importing Text files
Importing text files and processing them is how I actually got into python, it's certainly some of the simplest functionality that allows you to do a huge amount!
As with everything we can also wrap it into a neat little method to use again later:
Lets say you're interested in global companies performance - you can get data from Wikipedia about their financial performance and turn it into a csv or txt file using Google spreadsheets (tutorial here), but in this just download this data as a csv.
Navigating Lists
Now we've converted our text file to a list we can now navigate it's rows and columns easily
Challenge:
Using this table from Wikipedia (and a Python program), determine what's the most common starting letter for the name of one of Snow White's 7 dwarves (or just the most common name).
(N.B. you can also use python to automatically get the data from the net for you using a module called urllib2 and the method urlopen(url) but it's far easier to start with a text file.)
Sanitising User input
Here's a few nice tricks for sanitising user input - can you figure out what each line does?Challenge:
Wrap the above code into a method that takes a text question and a list of acceptable responses and returns the user's answer when they give an appropriate one.
Final Challenge
Create a program that counts all the individual letters in a book and how many times each one occurs, then prints the results (I suggest a copy of Charles Dickens' 'A Tale of Two Cities' which you can get free here). Why? You might be able to use the frequency of certain letters as a sort of 'fingerprint' for the language of that book (i.e. is it in Modern English, Old English, German, French or Latin?), but also this 'frequency analysis' is the most basic method of code cracking. Lets say you receive some encoded text that has been encoded with a simple substitution cypher (i.e. one letter has just been replaced with another). A frequency analysis like this will show (roughly) which letters are which in the encoded message allowing you to start to decode it (for example in English the most common letter is 'e' so the most common character in the encrypted message is probably also 'e'). If you want to test your cracking skills find a nice long string and encode it with the command 'encode':
Then do a frequency analysis on the encoded string and see if you can figure out what character has been replaced with what (ideally you would have someone else encode the message so that you didn't know what the original message was!).
Python - Level 1 material
I've been running introductory Python sessions with students and teachers from around Wellington for the last few months looking at the material relevant to NCEA level 1, 2 and 3 digital technologies achievement standards. In the interests of discussion and improvement I'm going to post what I cover here along with the Challenges I pose to participants along the way to get people to use the knowledge I'm allegedly imparting to them over the course of the session. So without further ado here's Elf short, sweet foray into Level 1 Python (I'll cover level 2 and 3 in other posts). Feel free to copy and paste this code into ipython or a python script and run it as you go so you get a feel of what each block does.
Level 1 Python Topics
- User information (input())
- String editing and concatenation
- For Loops (for i in range():)
- Counting (i+=1)
- Random numbers and modules (import)
- Conditional logic (if:)
- While Loops (while True:)
User Information and string editing
Challenge:
Ask the user for their name, address, phone number and the colour of their house. Then print out a description in the form of: "Your name is <name> and you live in a <colour> house at <address> and I can call you on <phone_number>".For Loops
Challenge:
Using a for loop within a for loop print the numbers 0-10 3 times.
Counting/Iterating
Challenge:
Ask the user for a number then count down from that number.
Random and modules
Challenge:
Ask the user for a number and then print that many random numbers between 10 and 100. Hint: you will need to convert your user unput from a string to an integer using the int() command.
Conditional Statements
Challenge:
Pick a random number. If less than 10, or if equal to 30, or if it's not greater than 50 print 'Yes'.
Otherwise print 'No'.
While Loops
Challenge:
Set a while loop that picks and prints a random number that has a 1/100 chance of breaking from the loop.
Final Challenge:
I find the best way to learn these concepts is to have a challenge that uses them all. A nice simple example is creating a computer game of Rock, paper, scissors which you should be able to make using only the coding elements I've described above. You will need to ask the user for their choice of rock, paper or scissors (can you allow the user to ONLY select from these somehow?) - then get the computer to pick as well (those random commands might come in handy) - then compare the two inputs and decide who wins and (as games usually run the best of 3) you will need to count each players score and decide which player has won. And once the game has completed you might want to ask your players if they want to play again?
Finally - if that's all too easy for you I suggest creating an 'expansion' to your game that plays rock, paper, scissors, lizard, spock following this logic:
Tuesday, 3 June 2014
Pyglet - Keymapping and Sound effects
For any real game however you probably want some conditional events - like controlling an object or causing something to happen when a button is pressed. In the below example we map three keys; a, left arrow and the left mouse button to 3 separate actions.
A couple of things to note:
A couple of things to note:
- to ensure the sound effect plays at the same time as the key is clicked we load the resource into memory instead of streaming the audio file as we did in the earlier example.
- for keymapping the 'modifiers' field indicates where Caps, Shift or Ctrl is held.
- Finally for mouse events and x and y is returned giving the location of the mouse cursor in the window when pressed.
Challenge!
Using this sounds effect, create a game that creates yellow ovals at the mirrored mouse location when the left button is pressed. I.e. if a mouse click was at (200, 100) in a 600x800 window then the 'mirrored' location should be at (600-200, 800-100).
Pyglet - placing images, text and playing background music
Continuing on our Pyglet introduction you can use the basic environment we set up earlier to place external images (in a few different formats), display text and to add some atmospheric background music. This code is pretty self explanatory so I'll just post the lot and let you dig through it yourself - but one thing to notice is that by itself pyglet/Python can't decode and play .mp3 audio files. It requires an external library called AVBin. So if you get an error when trying to play .mp3 files try installing the AVBin library (see the link below for details).
There are a few other commands in here that are worth pointing out:
There are a few other commands in here that are worth pointing out:
- image.blit(0,0) - the (0,0) is the location of the centre of the image in x and y co-codinates. 'Blitting' is the process of drawing an image into our window. Otherwise we only load it into memory and never display it.
- we also use the window.height and the window.width commands to return the current height/width of the window which is a far nicer way of defining the location of things. (N.B. the height and width methods also work on image objects!)
Challenge!
Find some nice atmospheric music for your game (and yes check it's Creative Commons licenced for you to use first!) and setup a background image you want to use and display it in the centre of your image in such a way that if you resize your window it appears in the the same place. I highly recommend checking out the wonderful local composer Rhian Sheehan's Soundcloud for inspiration (and yes you can download some of his .mp3s but make sure to attribute them if you use them!).
References
Thursday, 29 May 2014
Installing Python, pip, Pyglet and OpenGL
I made the slight mistake of assuming that everyone would have Python and the various libraries installed before starting - or at least know how to get them, completely forgetting of course that I had no idea how to do any of this either!
So firstly go to the Python site, download and install python. I would recommend getting Python3 if you have the choice (although the difference won't make much difference for these tutorials). Just be aware if you're planning on using lots of old libraries or Pygame that you will likely want Python2 instead. Run the installer and, if you see the option, choose to update the system Path variable. (If not don't worry we will solve that later).
Next we're going to get python and pip running from the command line. Why? It will make it far easier to install any other external libraries you might want to use in the future - such as matplotlib, numpy, pyglet, ipython or sympy (all of which I'll use a lot in other tutorials!). So open a command line (or terminal if you're on a Unix system), type 'python', hit enter and see what happens! If you're on windows, to launch the command prompt, click the windows icon on the bottom left corner of the screen, then type 'cmd' in the search box and hit enter. If you're on OSX go to launchpad in the doc -> Other/Utilities -> Terminal. If you're on linux i'll assume you can either do it already or can google it :p
If the command prompt has changed from a dollar symbol to these: >>> then congratulations! Skip the next bit and go straight to the Installing Pyglet section below (type exit() and hit enter to get rid of the >>> symbols and go back to the normal $ prompt). If instead you got 'python is not a recognised command' then follow the instructions below. (it just means that whilst you have python installed your computer doesn't know where to run it from - we can fix that!)
So firstly go to the Python site, download and install python. I would recommend getting Python3 if you have the choice (although the difference won't make much difference for these tutorials). Just be aware if you're planning on using lots of old libraries or Pygame that you will likely want Python2 instead. Run the installer and, if you see the option, choose to update the system Path variable. (If not don't worry we will solve that later).
Next we're going to get python and pip running from the command line. Why? It will make it far easier to install any other external libraries you might want to use in the future - such as matplotlib, numpy, pyglet, ipython or sympy (all of which I'll use a lot in other tutorials!). So open a command line (or terminal if you're on a Unix system), type 'python', hit enter and see what happens! If you're on windows, to launch the command prompt, click the windows icon on the bottom left corner of the screen, then type 'cmd' in the search box and hit enter. If you're on OSX go to launchpad in the doc -> Other/Utilities -> Terminal. If you're on linux i'll assume you can either do it already or can google it :p
If the command prompt has changed from a dollar symbol to these: >>> then congratulations! Skip the next bit and go straight to the Installing Pyglet section below (type exit() and hit enter to get rid of the >>> symbols and go back to the normal $ prompt). If instead you got 'python is not a recognised command' then follow the instructions below. (it just means that whilst you have python installed your computer doesn't know where to run it from - we can fix that!)
Windows
Open an new windows explorer window, navigate to your desktop, right click on 'My Computer', choose 'properties', then Advanced System Settings on the left hand side. The click the Environmental Variables button, and from the bottom list scroll down until you find a line called 'Path'. Select it and click 'edit'. Then add "; C:\Python34\Scripts; C:\Python34" without the quotation marks and including the starting semicolon, to the end of the text that's already. Hit save, re-start your command prompt and you're good to go! Alternatively, you can just replace 'pip' in the commands below with:
C:\Python34\Scripts\pip
UPDATE: If you're using python2.7 the the commands above should use Python27 instead of Python34
Other OSs
Google how to change your Path variable. Then add /usr/local/bin/pip and /usr/local/bin to it. Alternatively, you can just replace 'pip' in the commands below with: /usr/local/bin/pip
Installing Pyglet
So now that we have pip installed we can now install a bunch of useful libraries by opening a command prompt and typing: pip install <package_name> i.e. pip install numpy
We're going to install pyglet for Python 3 by using the command:
pip install --upgrade http://pyglet.googlecode.com/archive/tip.zip
The reason the command is so long is that we're using a 'development' bit of code (i.e. code that hasn't been exhaustively tested yet). If we were in Python2.7 then we could just type pip install pyglet but sadly that won't work here! Now wait a little while while the library downloads and installs for you and then you will be all good to go.
Final note while the package installs
Think about what you've just done. If you successfully updated your path variable you have just taught your computer how to find and run a particular program from the command prompt. That will work the same for any executable program from your computer - you can run them all from the command line by either changing your Path variable or using the full program location. This turns out to be super useful if/when you end up using the command line a lot. And I say that knowing this is most people's reaction to using the command line:
References
Wednesday, 28 May 2014
Pyglet - moving, rotating and translating images in 2D
Continuing on from the previous tutorial, now we can dig into moving things around in 2D. Why bother learning this when I've covered the same thing in Tkinter tut and when I'm going to cover it again in a pygame tut? Because in pyglet, the same commands for movement and rotation in 2D ALSO APPLY TO 3D, so once we make the jump to 3D we will automatically have access to all the colours, motion and movement actions we're already learned rather than having to grapple with all of them together at once. *
glRotatef(10.0,0.0,0.0,1.0)
They're:
ry=0
The update() command every time pyglet's internal clock 'ticks', so if we change the position just a little with every 'tick' as long as it happens fast enough this will look like movement. Here's we're probably better to explain by example:
The details are - we create a global variable called rz (the rotation around the z direction)
Challenge!
What happens if you set rz to be constant??? Why? What would you need to add to get translation working?
*I'm certain this can also be achieved in pygame with or without external libraries (see examples here) and if I ever learn how with that I'll post a tutorial on it.
Translation
The translation command takes an object you've created and then moves it by a certain amount. In the previous tut, we controlled the shape and size of our triangle by where we placed it, but imagine if we wanted to move it after we had created it. Then we would have to calculate the location of all the vertices of the object every time it moved. So instead, we create an image close to our origin and use that to control its size and shape and then we move it to where we want in a separate command. This comes in really handy in 3D when figuring out where things are in 3D space and describing that in detail does my head in - so i cheat and use this command instead:
glTranslatef()
The three numbers we pass the method tell OpenGL how far and in what direction we want to move our shape in the order x,y,z. Some helpful tips to remember:
- x = left or right motion. Negative numbers move left, positive moves right.
- y = up or down motion. Negative numbers move down, positive moves up.
- z = motion into or out of the screen (3D only), Negative numbers move into the screen, positive moves out of it.
And yes, because we're in 2D all our transformations currently will leave z =0.0. Try changing it if you like and see what happens, but it's likely your image will disappear because we haven't quite set our system up to display 3D well yet.
Rotation
Rotation is similar to translation except it requires some serious math. So once again, rather than bothering with the details we use an OpenGL command to do all the heavy thinking for us. This time though we have 4 input options:glRotatef(10.0,0.0,0.0,1.0)
They're:
- the number of degrees to move
- 1.0 if rotating around the x axis, 0.0 if not
- 1.0 if rotating around the y axis, 0.0 if not
- 1.0 if rotating around the z axis, 0.0 if not
So a full program making use of both translation and rotation would looks something like:
Note: We've also included 2 other commands
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
These aren't explicitly necessary - take them out and everything will still work fine. However, once we move into more complicated motion these will become really important, because we're going to have to change between viewpoints and these are the command that 'bring us home' (i.e. back to where we started). For those that are interested, OpenGL works by using a matrix to transform/move/rotate our objects depending of our starting position. If we move to a new location then the same matrix will have a different effect - so we 'come home' by loading the identity matrix in case we've accidentally changed location without realising it. Yes this is why linear algebra is important for computer graphics. No it's not the only reason - but it's one of the prettiest. :)
Challenge!
Does the order of the translation and the rotation commands matter? Is that weird? Can you figure out why or why not? What happens to your image if you rotate it around the x or y axis? Why?
Movement
Time for another method that I mentioned earlier - update().
def update(dt):
global rz
rz += dt * 10
rz %= 360
ry=0
pyglet.clock.schedule(update)
The update() command every time pyglet's internal clock 'ticks', so if we change the position just a little with every 'tick' as long as it happens fast enough this will look like movement. Here's we're probably better to explain by example:
The details are - we create a global variable called rz (the rotation around the z direction)
Challenge!
What happens if you set rz to be constant??? Why? What would you need to add to get translation working?
*I'm certain this can also be achieved in pygame with or without external libraries (see examples here) and if I ever learn how with that I'll post a tutorial on it.
Intro to pyglet and OpenGL
After taking a look at this awesome Minecraft demo written in Python, I decided to do a little digging and playing with the library it uses to use the OpenGL graphics renderer with the ultimate goal of making a 3D game from scratch as an outreach project. Predictably 'having a play' took quite a while to get working because I'd never seen much OpenGL before so I thought I would put together a step by step guide to getting started for those NOT familiar with OpenGL but with some experience of Python.
Here's a minimum working example of a pyglet window using the openGL commands to draw something simple:
Looking at this step by step, we're importing our library as per usual, creating a window, defining an method called 'on_draw' and then initialising the entire program using the line: pyglet.app.run()
You may notice that the one method we have defined isn't actually called anywhere - that's because it's called automatically within the pyglet.app.run() method. There are other functions that are automatically called as well; update() and on_resize() which we will come back to - but they're there to make things easier for the programmer. They trigger at particular time intervals and when the window is resized (or created) respectively.
Looking at the OpenGL commands, we first declare what shape of object we're going to draw with glBegin(GL_TRIANGLES) (we could also pick GL_POINTS, GL_LINES, GL_QUADS and more)
then we specify the location of the vertices, and then we declare the glEnd() so our program knows we're finished drawing and can start rendering for us.
So what's a vertex? It's a point or a corner. If you're drawing points then the 'vertex' is just the location of the point. If you're drawing more complicated shapes then the vertices are the locations of the corners (so a triangle will have 3, a quad [a shape with 4 sides] will have 4 and a polygon can have as many as you want). Pyglet then 'fills' in the rest of the shape for you by filling in the locations between the corners. So what's with the '2i' bit? That's how many dimensions your drawing in. In this tutorial (for simplicity's sake) we will stick to making and moving things in 2D but the next tut will show you how to generalise into 3D.
Challenge!
Using only what I've used above, a couple of other commands below, the power of google (and educated guesses!) try making something impressive out of ONLY the simple shapes described above.
One point to know is that the location (0,0) corresponds to the lower left-hand corner of your window, hence if your window is 400 x 400 pixels, the then upper-right corner is going to be at location (400,400), the upper-left at (0,400) and the lower-right at (400, 0).
Colours
Everything is more impressive with colours, and our image is sorely lacking them. Adding colours in is simple - just add in the commands, and play with the numbers to change the colours:
That said, if you have overlapping triangles then colouring can be a real pain - so if you want to just display outlines of your triangles (to start with anyway) just put in this command and then comment it out when you don't need it.
Challenge!
What happens if you give different corners of the same triangle different colours?
Shortcuts
Ok, defining every point by trial and error quickly gets really tiresome. Conveniently there's a few shortcut commands to speed up the process thanks to pyglet:
This command cuts out the need for the glBegin and glEnd and the individual vertex commands and just gives pyglet a list of locations to connect into a triangle. Here's a working example of its use:
Methods
To do really cool stuff with pyglet (and programming in general!) we're going to have to wrap our code up into nice little chunks called 'methods' which we can call again and again rather than copy-pasting our code all the time. The on_draw bit from the code above is a method that is run every time the program loops. We're going to define another one for making triangles:
Try including this in your code (Hint: put the method BEFORE the on_draw function and call the method INSIDE the on_draw function instead of the current code we have in there).
Extension Challenge!
Given your experience with these shapes now - what's the most complicated design/shape/image you can represent using only triangles? Here's a clue - the below image is called a Voronoi tessellation (google it - there's some amazing art out there based on this technique).
Next tutorial we will use the OpenGL rotation and motion tools in 2D
References:
http://www.pyglet.org/doc/api/pyglet.graphics-module.html
https://github.com/fogleman/Minecraft
http://stackoverflow.com/questions/7681899/moving-an-image-around-in-3d-space
http://stackoverflow.com/questions/4269079/mixing-2d-and-3d-in-opengl-using-pyglet
Here's a minimum working example of a pyglet window using the openGL commands to draw something simple:
Looking at this step by step, we're importing our library as per usual, creating a window, defining an method called 'on_draw' and then initialising the entire program using the line: pyglet.app.run()
You may notice that the one method we have defined isn't actually called anywhere - that's because it's called automatically within the pyglet.app.run() method. There are other functions that are automatically called as well; update() and on_resize() which we will come back to - but they're there to make things easier for the programmer. They trigger at particular time intervals and when the window is resized (or created) respectively.
Looking at the OpenGL commands, we first declare what shape of object we're going to draw with glBegin(GL_TRIANGLES) (we could also pick GL_POINTS, GL_LINES, GL_QUADS and more)
then we specify the location of the vertices, and then we declare the glEnd() so our program knows we're finished drawing and can start rendering for us.
So what's a vertex? It's a point or a corner. If you're drawing points then the 'vertex' is just the location of the point. If you're drawing more complicated shapes then the vertices are the locations of the corners (so a triangle will have 3, a quad [a shape with 4 sides] will have 4 and a polygon can have as many as you want). Pyglet then 'fills' in the rest of the shape for you by filling in the locations between the corners. So what's with the '2i' bit? That's how many dimensions your drawing in. In this tutorial (for simplicity's sake) we will stick to making and moving things in 2D but the next tut will show you how to generalise into 3D.
Challenge!
Using only what I've used above, a couple of other commands below, the power of google (and educated guesses!) try making something impressive out of ONLY the simple shapes described above.
One point to know is that the location (0,0) corresponds to the lower left-hand corner of your window, hence if your window is 400 x 400 pixels, the then upper-right corner is going to be at location (400,400), the upper-left at (0,400) and the lower-right at (400, 0).
Colours
Everything is more impressive with colours, and our image is sorely lacking them. Adding colours in is simple - just add in the commands, and play with the numbers to change the colours:
That said, if you have overlapping triangles then colouring can be a real pain - so if you want to just display outlines of your triangles (to start with anyway) just put in this command and then comment it out when you don't need it.
Challenge!
What happens if you give different corners of the same triangle different colours?
Shortcuts
Ok, defining every point by trial and error quickly gets really tiresome. Conveniently there's a few shortcut commands to speed up the process thanks to pyglet:
This command cuts out the need for the glBegin and glEnd and the individual vertex commands and just gives pyglet a list of locations to connect into a triangle. Here's a working example of its use:
Methods
To do really cool stuff with pyglet (and programming in general!) we're going to have to wrap our code up into nice little chunks called 'methods' which we can call again and again rather than copy-pasting our code all the time. The on_draw bit from the code above is a method that is run every time the program loops. We're going to define another one for making triangles:
Try including this in your code (Hint: put the method BEFORE the on_draw function and call the method INSIDE the on_draw function instead of the current code we have in there).
Extension Challenge!
Given your experience with these shapes now - what's the most complicated design/shape/image you can represent using only triangles? Here's a clue - the below image is called a Voronoi tessellation (google it - there's some amazing art out there based on this technique).
Next tutorial we will use the OpenGL rotation and motion tools in 2D
References:
http://www.pyglet.org/doc/api/pyglet.graphics-module.html
https://github.com/fogleman/Minecraft
http://stackoverflow.com/questions/7681899/moving-an-image-around-in-3d-space
http://stackoverflow.com/questions/4269079/mixing-2d-and-3d-in-opengl-using-pyglet
Monday, 26 May 2014
Tkinter - Random Backgrounds with Python
Ever tried to design your own game? It can
be a tricky process though so I’ll walk you through it using an example.
You can either copy the example and modify it to make it more like what
you want or try something different. I would recommend following along
with these examples first though to see what you can expect.
We’re
going to start by creating a 2D game, with a randomly generated
background that you have to move your character through to get to the
exit. Once that’s done we will add some monsters to chase your character
and then the sky’s the limit! Diagrammatically it might look like this:
I’m
going to start by creating a randomly generated forest with some rocks
and trees (similar to what you might find in old school pokemon games).
First off go find some objects you want to randomly scatter around your
map. Remember they should be .gif images!
If you’re looking for some code to use an example try this (yes I used stones and trees because I’m a farm boy)
So
you now have a randomly generated background each time you run the
programme. The problem is that, well, it kinda sucks. It would be better
if we could stop trees and rocks from appearing in the same place
wouldn’t it? And if they didn’t disappear off the edge of the map?
Whoa!
That got really horrible really quickly didn’t it. If you poke through
the code above you might be able to understand what I was doing. I made a
list of all the locations I had placed each tree and just checked that
the distance between those locations and any new location was greater
than the width of the new image I was adding. Unfortunately it’s easy
for this sort of structure to get stuck in an infinite loop (as the
computer is just randomly guessing each time where to place things).
CHALLENGE #5!
Can
you imagine a better way to decide where to place our new trees? Is
there a maximum number of trees/rocks we can fit into our window? How
might we figure it out? (Hint: this becomes a lot easier if we re-visit this after we’ve learned object orientation)
CHALLENGE #6!
If
we were creating a real level we wouldn’t want things placed randomly.
Objects have rules. Imagine trying to create a river through our field.
The rule is that from a starting location the river can only be extended
into a location that’s next to a bit that’s already river. Can you
think about how we might some code to figure this out?
Tkinter - Python games with Tkinter
Note: I would only use Tkinter to create games if you have an issue installing external python libraries to your system or if you're using Python 3 rather than Python 2. Otherwise the specific game libraries pygame or pyglt are both superior and easier to learn. There are introductory tutorials to both of these in the sidebar.
Tkinter is a python library that comes standard with both Python 2 and Python 3 for generating Graphical user interfaces (GUIs). It's ubiquity is its strength more than anything else and I frequently resort to Tkinter when I can't get other libraries installed (a common problem for many Digital Technology classes here in NZ).
Open IDLE (if you don’t have it download and install it from here - you want the Python 3.4.0), select a ‘New File’ from the file menu. This is where we will write the majority of our code. the other window is called a ‘shell’ and allows you to interact with your program - but it will make things more complicated than they need to be so we’ll leave it alone for now.
If this is your first time programming - here are 4 things to know:
1) spelling and capitalization are crucially important. If your code doesn’t work check your spelling
2) in python, indentation is important. Code from this tut should be copied directly with indents preserved. If your code doesn’t work, check your indents are right.
3) Patience. You will make mistakes. Lots of them. They will irritate you. You will stop making them, but only through practice. If you’re getting irritated stop and try something else for a while!
4) Google it. Seriously. Any problem you have - google it and pick the result (look for a website called stack overflow) and chances are you will find a solution.
Then select ‘Run’ from the file menu above or push F5 on your keyboard (or fn and F5 on OSX). If you get an import error (i.e. your console says something like 'cannot find Tkinter module') try changing the import statement from import Tkinter (for Python 2.7) to import tkinter (Python3)
You made a window!
You’re doing several things:
creating a window:
Window = Tk()
filling the window with something you can draw on:
canvas = Canvas(height=500, width=500, bg='red')
canvas.pack()
creating a rectangle in that canvas:
canvas.create_rectangle(200,200,300,300, fill='blue', activefill='green') #x1,y1,x2,y2
(N.B. you can make lots of other shapes using: create_oval, create_arc, create_line etc)
then running our program:
Window.mainloop()
If you care about any of this (or want to know more!) - justask Elf google it.
Good news: you don’t need to understand it to use it!
Make a 400x 400 pixel window with a green background that has a smiley face on it.
Find an image from somewhere that is in .gif format (or find an online converter). Put it in the same directory as where your python file is saved and give it the name ‘image.gif’
Now try this code:
What do you need to change to move your image around your canvas?
OK now we’re going to do some more advanced programming. Why? Because we want lots of images in lots of places rather than just one. We’re going to use a loop to do that (specifically a for loop). Here’s your code:
Now to explain that ‘import’ statement up the top. When programming it’s common to use bits of code other people have made. These are called libraries and we’re already using one called Tkinter. Now we need to use another one called random which will allow us to generate random numbers (yes exactly like playing calculator cricket). Try this:
and now your images are randomly located all over the map :) Note that we’ve also slightly changed our for loop.
Make 20 ovals of random sizes and locations all over your canvas
So random placement is ok - but movement would be better. To start we’re going back to moving one image at a time in the interest of simplicity. We’re going to do this by DEFINING two VARIABLEs for the position of our image. Then we’re going to re-draw our image each time it moves and updates our canvas.
So moving things is ok - but when really want them to move forever, not just for a set period of time. For this we will need a new structure called a while loop.
Now we can add another kind of programming tool called an if statement (or a conditional statement). These allow us to specify different actions depending on what’s going on! Try this:
Whoa?! That’s a bunch of new code. All it’s doing is saying that whenever your object gets to the edges of our window we change it’s speed. See if you can follow through the logic (but again don’t worry if you can’t). To give you a clue - the x and y are position VARIABLES (they remember where on the screen our object is) and the dx and dy are how fast to move in either the left or right direction or the up and down direction respectively.
To really make this a game though we want you to be able to control aspect of your character with either the mouse or keyboard. We’re going to do this by making the up arrow on the keyboard make the object move faster and the down key do the opposite.
Try it out. What do you notice? Can you find the bug?
Once again - if this doesn't work and your error message say something about '<key>' in the .bind() command above change <key> to <Key> and it should work.
We’ve used a heap more code this time and something called a ‘method’. It’s quite a bit more complicated and so once again - if you don’t understand don’t worry! However, the bad news is that we’ve reached the limit of what we can do programming as we have been. To go further we’re going to have to think about our programs in a way called ‘Object Oriented Programming’. Think about it like this: in our example above we keep variables for the speed and position of our character. If we had multiple characters we would have to make all these again for all of them and the number would quickly become unmanageable (so would the code for that matter!) - so we need a new way of thinking about things. We will do this by creating objects and getting each object to remember its own speed and position.
From here you have a few choices - continue with the more complicated programming (which will be useful for any language or game you use in the future), move onto something else like unity or blender, or spend some time designing your game and use what you’ve learned above to make a randomly generated background.
Why Tkinter and what is it?
Tkinter is a python library that comes standard with both Python 2 and Python 3 for generating Graphical user interfaces (GUIs). It's ubiquity is its strength more than anything else and I frequently resort to Tkinter when I can't get other libraries installed (a common problem for many Digital Technology classes here in NZ).
Making windows and objects
Open IDLE (if you don’t have it download and install it from here - you want the Python 3.4.0), select a ‘New File’ from the file menu. This is where we will write the majority of our code. the other window is called a ‘shell’ and allows you to interact with your program - but it will make things more complicated than they need to be so we’ll leave it alone for now.
If this is your first time programming - here are 4 things to know:
1) spelling and capitalization are crucially important. If your code doesn’t work check your spelling
2) in python, indentation is important. Code from this tut should be copied directly with indents preserved. If your code doesn’t work, check your indents are right.
3) Patience. You will make mistakes. Lots of them. They will irritate you. You will stop making them, but only through practice. If you’re getting irritated stop and try something else for a while!
4) Google it. Seriously. Any problem you have - google it and pick the result (look for a website called stack overflow) and chances are you will find a solution.
Get started - make a window
Copy and paste the following code into the window:Then select ‘Run’ from the file menu above or push F5 on your keyboard (or fn and F5 on OSX). If you get an import error (i.e. your console says something like 'cannot find Tkinter module') try changing the import statement from import Tkinter (for Python 2.7) to import tkinter (Python3)
You made a window!
Filling the window
Try replacing your code with this instead, and hit Run. Time for a bit of explanation!You’re doing several things:
creating a window:
Window = Tk()
filling the window with something you can draw on:
canvas = Canvas(height=500, width=500, bg='red')
canvas.pack()
creating a rectangle in that canvas:
canvas.create_rectangle(200,200,300,300, fill='blue', activefill='green') #x1,y1,x2,y2
(N.B. you can make lots of other shapes using: create_oval, create_arc, create_line etc)
then running our program:
Window.mainloop()
If you care about any of this (or want to know more!) - just
Good news: you don’t need to understand it to use it!
CHALLENGE #1!
Make a 400x 400 pixel window with a green background that has a smiley face on it.
Adding images
Find an image from somewhere that is in .gif format (or find an online converter). Put it in the same directory as where your python file is saved and give it the name ‘image.gif’
Now try this code:
What do you need to change to move your image around your canvas?
Duplicates
OK now we’re going to do some more advanced programming. Why? Because we want lots of images in lots of places rather than just one. We’re going to use a loop to do that (specifically a for loop). Here’s your code:
Random
Now to explain that ‘import’ statement up the top. When programming it’s common to use bits of code other people have made. These are called libraries and we’re already using one called Tkinter. Now we need to use another one called random which will allow us to generate random numbers (yes exactly like playing calculator cricket). Try this:
and now your images are randomly located all over the map :) Note that we’ve also slightly changed our for loop.
CHALLENGE #2!
Make 20 ovals of random sizes and locations all over your canvas
Movement!
So random placement is ok - but movement would be better. To start we’re going back to moving one image at a time in the interest of simplicity. We’re going to do this by DEFINING two VARIABLEs for the position of our image. Then we’re going to re-draw our image each time it moves and updates our canvas.
Advanced movement
So moving things is ok - but when really want them to move forever, not just for a set period of time. For this we will need a new structure called a while loop.
Boundaries
Now we can add another kind of programming tool called an if statement (or a conditional statement). These allow us to specify different actions depending on what’s going on! Try this:
Whoa?! That’s a bunch of new code. All it’s doing is saying that whenever your object gets to the edges of our window we change it’s speed. See if you can follow through the logic (but again don’t worry if you can’t). To give you a clue - the x and y are position VARIABLES (they remember where on the screen our object is) and the dx and dy are how fast to move in either the left or right direction or the up and down direction respectively.
Keyboard control!
To really make this a game though we want you to be able to control aspect of your character with either the mouse or keyboard. We’re going to do this by making the up arrow on the keyboard make the object move faster and the down key do the opposite.
Try it out. What do you notice? Can you find the bug?
Once again - if this doesn't work and your error message say something about '<key>' in the .bind() command above change <key> to <Key> and it should work.
We’ve used a heap more code this time and something called a ‘method’. It’s quite a bit more complicated and so once again - if you don’t understand don’t worry! However, the bad news is that we’ve reached the limit of what we can do programming as we have been. To go further we’re going to have to think about our programs in a way called ‘Object Oriented Programming’. Think about it like this: in our example above we keep variables for the speed and position of our character. If we had multiple characters we would have to make all these again for all of them and the number would quickly become unmanageable (so would the code for that matter!) - so we need a new way of thinking about things. We will do this by creating objects and getting each object to remember its own speed and position.
From here you have a few choices - continue with the more complicated programming (which will be useful for any language or game you use in the future), move onto something else like unity or blender, or spend some time designing your game and use what you’ve learned above to make a randomly generated background.
Subscribe to:
Posts (Atom)