=== Zami_ is now known as Zami | ||
qwased | how can i look at past irc classroom logs? | 10:05 |
---|---|---|
mbudde | http://irclogs.ubuntu.com/ | 10:06 |
qwased | thanks | 10:06 |
=== tux_race1 is now known as tux_racer | ||
=== yofel_ is now known as yofel | ||
=== screen-x is now known as hds | ||
=== hds is now known as screen-x | ||
=== ghost is now known as Guest97661 | ||
reida010 | s | 16:08 |
didrocks | jono: did you receive my slides? (and for generating the translation string, just quickly package or quickly share/release) | 16:18 |
jono | didrocks, yep, they are in there :) | 16:20 |
jono | didrocks, isnt there an argument to pass setup.py if I remember right? | 16:20 |
jono | I remember dpm did something | 16:20 |
RainCT | not sure if it's related at all with what you are talking about, but there is: python setup.py build_i18n | 16:21 |
jono | RainCT, thats it! | 16:22 |
jono | woo! | 16:22 |
didrocks | jono: if you want to do that outside of quickly yes (but the previous command calls that). It's ./setup.py --build-i18n | 16:22 |
didrocks | let me check for the syntax exactly :) | 16:22 |
didrocks | one sec | 16:22 |
jono | thats cool for updating the translations template without packaging | 16:22 |
jono | thanks RainCT, didrocks! | 16:22 |
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - http://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Event: Ubuntu Opportunistic Developer Week - Current Session: Creating stunning interfaces with Cairo - Laszlo Pandy - Instructor: laszlok || Questions in #ubuntu-classroom-chat | ||
laszlok | Hello everyone, i'm gonna be talking about using cairo with python today | 17:01 |
laszlok | I haven't prepared any slides, but I'll be using some links | 17:02 |
laszlok | and it will be less structured than usual, so feel free to shout out or ask questions at any time in #ubuntu-classroom-chat | 17:02 |
laszlok | I won't mind taking a large detour, we'll probably have plenty of time for it | 17:03 |
laszlok | So cairo is a drawing API | 17:03 |
laszlok | if you know about SVG graphics, it does the same sort of thing | 17:04 |
laszlok | it has strokes, fills, gradients, etc | 17:04 |
laszlok | Its also a very modern drawing api | 17:04 |
laszlok | the library was written quite recently | 17:04 |
laszlok | I mean modern in that it has good alpha support, and really good antialiasing | 17:05 |
laszlok | so when you draw graphics they scale well and look very clean | 17:05 |
laszlok | unlike previous generation APIs like Java graphics (don't get me started) | 17:06 |
laszlok | Cairo integrates really well with GTK, in fact most widgets in GTK are now drawn using cairo | 17:07 |
laszlok | I will show you how to use it with GTK and also how to use some other cairo backends like svg, pdf, and png | 17:07 |
laszlok | In terms of creating stunning interfaces, it can be done with cairo. If you create a stunning GTK app then you are doing it with cairo anyway ;) | 17:08 |
laszlok | however cairo is low level | 17:08 |
laszlok | if you are using cairo directly you are drawing all the lines and calculating all the geometry yourself | 17:09 |
laszlok | There was a talk yesterday about goocanvas, which uses cairo and gives a much higher level view. You can deal with objects instead of geometry calculations. | 17:10 |
laszlok | But if anyone has questions about that, please ask | 17:10 |
laszlok | http://www.cairographics.org/samples/ | 17:10 |
laszlok | here is a page on the cairo website with some sample code and how it will look | 17:11 |
laszlok | the code is in C, but it is quite similar to python as you will see | 17:11 |
laszlok | QUESTION: Can we build all the application interface using Cairo (except for the Window container)? | 17:12 |
laszlok | yes you can, but it will involve a lot of trickiness if you want to detect mouse clicks on many different objects | 17:14 |
laszlok | it will work fine for a simple drawing, but once you start using lots of objects you might find the geometry to figure out which one is clicked it too much | 17:14 |
laszlok | this is why things like goocanvas were invented; to automate those things | 17:14 |
laszlok | QUESTION: can we use cairo to create the interface separate from the logic that runs the program? | 17:15 |
laszlok | yes, in the same way that you would have a GTK interface separate from the program logic | 17:15 |
laszlok | QUESTION: maybe for later, is there a preferred way of doing animations in cairo? | 17:16 |
laszlok | cairo does not provide support for animations, so it has to be done essentially the same as animations in other drawing apis | 17:16 |
laszlok | that means having a timer to redraw the screen and have code to redraw the whole screen (or just the parts that change) | 17:17 |
laszlok | so as you can see in the samples, cairo has primitives for arcs, lines, etc. | 17:18 |
laszlok | Thinking about an interface in these primitives is a bit low level, but it gives you the great flexibility | 17:18 |
laszlok | QUESTION: Does the animation redraw method you just described use a lot of cpu power? | 17:19 |
laszlok | if your drawing is complex, it probably will | 17:19 |
laszlok | but cairo is quite efficient, and allows you flexibility for caching drawings | 17:19 |
laszlok | for example if you have a background which requires a long time to draw, you can draw it to an ImageSurface in memory instead | 17:20 |
laszlok | and then it is one operation to draw it on screen | 17:20 |
laszlok | QUESTION: would like to add to performance that strokes are the ones that are expensive. | 17:21 |
laszlok | that's not a question ;) | 17:21 |
laszlok | http://www.cairographics.org/documentation/pycairo/reference/index.html | 17:22 |
laszlok | here is the python documentation for cairo | 17:22 |
laszlok | that is good reference when looking at the next link | 17:22 |
laszlok | http://laszlopandy.com/files/drawing_interface.html | 17:23 |
laszlok | here is some poorly commented python code I prepared | 17:23 |
laszlok | QUESTION: waht are all the required components to start working on cairo+python? | 17:23 |
laszlok | only cairo, python and pycairo | 17:23 |
laszlok | if you want to render directly on screen (as opposed to png or svg) you should have pygtk installed as well | 17:24 |
laszlok | for example, in the code i prepared I am importing both gtk and cairo | 17:24 |
laszlok | copy and paste this code into your editor | 17:25 |
laszlok | if you run it with no arguments you will get a gtk window | 17:25 |
laszlok | if you give it 'png', 'svg' or 'pdf' as an argument, it will generate that kind of file | 17:25 |
laszlok | so lets take a look at the GTK code, in the DrawingInterface class | 17:25 |
laszlok | it creates a window, and adds a gtk.DrawingArea | 17:26 |
laszlok | the DrawingArea is a widget which is like a blank canvas we can draw to | 17:27 |
laszlok | then we set the size of the window, and show it | 17:28 |
laszlok | not much to see there | 17:28 |
laszlok | the expose event is the event when the X server tells the window to redraw itself | 17:28 |
laszlok | so this is what we are using to trigger our drawing code | 17:28 |
laszlok | also notice that in the GTK code the cairo context is created directy from the widget. GTK is integrated with cairo and makes it easy | 17:29 |
laszlok | the context is what holds all the information about your drawing as you add lines and shapes | 17:29 |
laszlok | the draw_rounded_rentangle() method is converted from the C example on http://www.cairographics.org/samples/ | 17:30 |
laszlok | if you compare them you can see it is mostly identical code | 17:30 |
laszlok | QUESTION: please explain the underlying functiosn used in on_expose | 17:31 |
laszlok | http://laszlopandy.com/files/drawing_interface.html | 17:31 |
laszlok | in on_expose we create the cairo context associated with the widget | 17:31 |
laszlok | so when we draw using that context, it will draw on the widget | 17:32 |
laszlok | widget.get_allocation() returns a renctangle with the width and height of the window, so we know how much space we have to draw | 17:32 |
laszlok | and self.drawing.draw() calls the method on the drawing class three lines below that | 17:32 |
laszlok | QUESTION: will the get_allocation be called only after drawing.draw is called? | 17:33 |
laszlok | this is equivalent to: | 17:33 |
laszlok | rectangle = widget.get_allocation() | 17:33 |
laszlok | self.drawing.draw(ctx, rectangle) | 17:33 |
laszlok | so the draw() method can know the size of the widget | 17:34 |
laszlok | by default, the DrawingArea widget is the default gtk colour | 17:34 |
laszlok | so in the draw() method I create a rectangle the size of the widget and fill it with white | 17:35 |
laszlok | the context remembers things like rectangles i have created, and also what colour i set it | 17:35 |
laszlok | after I call fill() the rectangle is removed from the context and put on the screen, but the colour is still set | 17:36 |
laszlok | so remember to change your colour or it will be whatever you set it previously | 17:36 |
laszlok | QUESTION: Is it possible to do some basic 3d transformation? (Like perspective on GIMP) | 17:36 |
laszlok | cairo is a 2d canvas, but you can do transformation | 17:36 |
laszlok | to fake a perspective | 17:36 |
laszlok | take a look at http://www.cairographics.org/documentation/pycairo/reference/matrix.html#class-matrix | 17:37 |
laszlok | In get_gradient() http://laszlopandy.com/files/drawing_interface.html | 17:38 |
laszlok | you can see cairo makes gradients really simple | 17:38 |
laszlok | you create a gradient with a start and end point to define how long the colour change will be and in what direction | 17:38 |
laszlok | and then you set stops on the gradient, just like you would do on inkscape or other graphics programs | 17:39 |
laszlok | the first argument to add_color_stop_rgb is the offset between 0 and 1 | 17:39 |
laszlok | so i set two colour stops. One at the beginning and one at the end | 17:39 |
laszlok | you can easily add a third one in set it to offset 0.5 and your gradient will blend three colours | 17:40 |
laszlok | now look at the bottom part of the code where it says if arg == 'pdf': | 17:41 |
laszlok | i mentioned earlier about using image surfaces to store your drawing in memory | 17:41 |
laszlok | surfaces also allow you do store in files | 17:41 |
laszlok | QUESTION: can you set the gradient to go through the hues in the opposite direction? | 17:42 |
laszlok | yes | 17:42 |
laszlok | either reverse the offsets | 17:42 |
laszlok | (set the first one to offset 1, and second to offset 0) | 17:42 |
laszlok | or reverse the pairs of (x,y) parameters to the LinearGradient constructor | 17:43 |
laszlok | QUESTION: does the context variable acts as a placeholder or as a memory buffer? | 17:44 |
laszlok | it is the same as the drawing context created from the GTK widget except it writes to a file | 17:44 |
laszlok | so it will store your drawing in memory and write it to the file when you complete a fill() or stroke() | 17:45 |
laszlok | QUESTION: How to make it write to a jpg file? | 17:45 |
laszlok | JPG file compression is meant for pictures where there are not perfectly smooth lines | 17:46 |
laszlok | PNG compression works much better for drawings, things with smooth and sharp borders | 17:46 |
laszlok | so cairo does not support JPG directly, i would write to svg or png and use imagemagick to convert it | 17:46 |
laszlok | so as you can see, cairo surfaces make it really easy to export to other formats | 17:48 |
laszlok | and if you were writing on windows or mac, you would use a surface specifically for the platform and the rest of the api would be the same | 17:49 |
laszlok | any questions? | 17:50 |
laszlok | QUESTION: does cairo do that "redraw only changed parts" automagically, or do we manually tell what changed ? | 17:50 |
laszlok | you could have to do that manually | 17:50 |
laszlok | in this case i redraw the white rectangle each time, therefore blanking the entire screen | 17:51 |
laszlok | this is something that goocanvas would also automate for you | 17:51 |
laszlok | QUESTION: How difficult is it to use cairo in combination with pygoocanvas? (For example, if I wanted to draw/animate something like a progress indicator on top of my goocanvas while waiting for goocanvas to update during a slow operation.) | 17:52 |
laszlok | that seems like a strange use case, but it should work | 17:52 |
laszlok | theoretically you can use cairo to draw on top of any GTK widget | 17:52 |
laszlok | as long as the proper flags are set | 17:53 |
laszlok | QUESTION: What are the advantages of using cairo directly instead of through goocanvas? | 17:55 |
laszlok | goocanvas is much higher level | 17:55 |
laszlok | and cairo is very lightweight | 17:55 |
laszlok | if you are doing something simple and want the flexibility, or don't mind doing the drawing manually then cairo is the way to go | 17:56 |
laszlok | its really easy to get started with, and can work with GTK mouse clicks, etc well for simpler things | 17:56 |
laszlok | if you know you have a bunch of objects you want to drag around on the screen, goocanvas will probably make your life much easier | 17:57 |
laszlok | QUESTION: the png format uses the format_argb32 constant. the manual shows 3 more. can u tell the formats they specify? | 17:57 |
laszlok | referring to http://www.cairographics.org/documentation/pycairo/reference/constants.html#constants-format | 17:58 |
laszlok | FORMAT_ARGB32 is colour surface with alpha support | 17:58 |
laszlok | FORMAT_RGB24 is the same without alpha support so you will not be able to do transparency | 17:59 |
laszlok | the others are for alpha only masks and do not store colour values | 17:59 |
laszlok | these formats are for image surfaces. You may need to specify alpha only if you want to make a transparency mask | 18:00 |
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - http://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Event: Ubu ntu Opportunistic Developer Week - Current Session: What's new in Quickly 0.4 - Didier Roche - Instructor: didrocks || Questions in #ubuntu-classroom-chat | ||
didrocks | awesome laszlok, thanks for your session :) Just a question, when will you do a Quickly template for a cairo project? :p (kidding) | 18:01 |
didrocks | so, welcome everyone on the session about Quickly 0.4 | 18:01 |
didrocks | [SLIDE 1] | 18:02 |
didrocks | who is interested on what we backed for Quickly 0.4? hands up in -chat! | 18:02 |
didrocks | nice | 18:03 |
didrocks | so, I'm Didier Roche, one of the Quickly developer and also desktop team member | 18:03 |
didrocks | (and fresh ubuntu core dev :)) | 18:04 |
didrocks | for people not seeing the slide, you can get them at http://people.canonical.com/~didrocks/Quickly-0.4.pdf | 18:04 |
didrocks | it should be on the Session tab in lernid | 18:04 |
didrocks | so, first, what this session is *not* about | 18:05 |
didrocks | this session isn't a presentation of Quickly. This has already been done later this week by Rick Spencer. logs availabled at https://wiki.ubuntu.com/MeetingLogs/OpWeek1003/Quickly | 18:05 |
didrocks | [SLIDE 2] | 18:06 |
didrocks | (at least, it works me in lernid :p) | 18:06 |
didrocks | (and that's not Quickly's fault ;)) | 18:06 |
didrocks | so, 0.4 is unfortunately still in development | 18:06 |
=== yofel_ is now known as yofel | ||
didrocks | it still needs some stuff to be added in launchpad to make things easier | 18:07 |
didrocks | and I prefer to do that the right way than a quickly screenscrapping | 18:07 |
didrocks | so, warning, it's unstable, the current version is 0.3.5 | 18:07 |
didrocks | I hope to release the stable version before lucid beta 1 | 18:07 |
didrocks | in any case, Quickly 0.4 will be in lucid :) | 18:08 |
didrocks | so, a little about stats | 18:08 |
didrocks | last version which is 0.2.6 has been release approximately 6 months before | 18:08 |
didrocks | and a lot happens in 6 months :) | 18:08 |
didrocks | you can see some stats for the addicts: 250 commits and 12930 changed lines | 18:09 |
didrocks | to be honest, some file had been moved, so if we want to be fair, I would say 4000 code of code have been really impacted | 18:09 |
didrocks | it's a lot, and I'll show you now what are in those lines :) | 18:09 |
didrocks | [SLIDE 3] | 18:10 |
didrocks | souces: how to be informed of what's new? | 18:10 |
didrocks | well, this session is dedicated to that, so that's a good first step :) | 18:10 |
didrocks | (I'll probably blog on planet ubuntu too when Quickly 0.4 will be out) | 18:10 |
didrocks | a more detailed sources the NEWS file in trunk | 18:11 |
didrocks | I try to keep it pretty complete | 18:11 |
didrocks | and of course, if you want full details, you have to read the 250 commits :) | 18:11 |
didrocks | let's first see what's the most noticeable changes | 18:13 |
didrocks | the first thing is that the ubuntu-project template (the only one which existed in 0.2.x) is no more… | 18:13 |
didrocks | don't be panic, it has just been renamed ubuntu-application | 18:13 |
didrocks | of course, existing project will be transitionned appropriately so that you don't have to change anything for existing Quickly users | 18:13 |
didrocks | Quickly 0.4 will welcome at least one new template, and even maybe a third one in trunk :) | 18:13 |
didrocks | ubuntu-cli template is to create a command line soft with all the ubuntu-application intgration | 18:14 |
didrocks | (a lot of people asked for a cli template :)) | 18:14 |
didrocks | ubuntu-game (or pygame, or whatever) will be detailed later in this week by Rick, you should be already aware of that if you read planet ubuntu | 18:14 |
didrocks | also, artfwo (thanks to the template inheritance I'll described later) is beginning to implement a gedit-plugin template | 18:15 |
didrocks | so, a lot of goodness to come in a very short time :) | 18:15 |
didrocks | [SLIDE 4] | 18:15 |
didrocks | as there is no question, let's dive a little bit more on what's interest most of you: ubuntu-project… hum… ubuntu-application new capability ;) | 18:16 |
didrocks | first thing (and I'll come back later on that) you have to understand is that your existing app will be converted for 0.4 | 18:17 |
didrocks | it will be the first time you run a quickly command on it | 18:17 |
didrocks | (also if you proceed some tab completion) | 18:17 |
didrocks | that's needed and it's a new Quickly core capability | 18:17 |
didrocks | that implies that projects which will be converted to Quickly 0.4 won't work anymore with a previous version of Quickly | 18:18 |
didrocks | (it's still possible to convert back by hand, but complicated) | 18:18 |
didrocks | as I wrote, ubuntu-application in 0.4 has a new versionning scheme | 18:19 |
didrocks | that means that project will follow by default ubuntu way of versionning thing | 18:19 |
didrocks | for instance, if I run "quickly release" just now, my release will be 10.03 | 18:19 |
didrocks | if I run quickly release again, it will be 10.03.1 | 18:19 |
didrocks | and so on :) | 18:19 |
didrocks | you are still able to provide your release version yourself | 18:20 |
didrocks | the second point is the most tricky one but the one on the top priority list | 18:20 |
didrocks | did you have some troubles setting up your gpg and ssh key on LP to make your first quickly share/quickly release? | 18:20 |
didrocks | that will be (we hope) part of the past in 0.4! | 18:21 |
didrocks | this is what I'm currently working and that needs a lot of work on launchpad side… and I'm not a LP hacker | 18:22 |
didrocks | so, normally, if you don't have one, Quickly will do everything for your | 18:22 |
didrocks | you* | 18:22 |
didrocks | also, selecting the right email adress through some algorithms :) | 18:23 |
didrocks | moving on… | 18:23 |
didrocks | quickly license has been totally reshaped | 18:23 |
didrocks | no more Copyright file which populate an AUTHOR file, you will only have to edit the AUTHOR one | 18:23 |
didrocks | (this confused some people before) | 18:23 |
didrocks | the next one is more interesting | 18:24 |
didrocks | when you quickly release, your changelog will automatically be collected with all the messages you provided in "quickly save <your message>" from the last release | 18:24 |
didrocks | it will create a release and milestone on launchpad | 18:24 |
didrocks | upload your tarball too to be available on the first page | 18:24 |
didrocks | and create an annoucement with your changelog | 18:25 |
didrocks | of course, as a good upstream, it signs the tarball file too (as it's recommended as a best practice) | 18:25 |
didrocks | you can see what it gives on my test project: https://edge.launchpad.net/fooby | 18:26 |
didrocks | next point is ppa | 18:26 |
didrocks | when Quickly 0.2 was released, launchpad only enabled you to have one ppa | 18:27 |
didrocks | which was called… "ppa" | 18:27 |
didrocks | things have changed now and you can have multiple ppa | 18:27 |
didrocks | also, some people would like to upload the package to a team ppa | 18:27 |
didrocks | and to be honest, that makes sense :) | 18:27 |
didrocks | so, now, you can upload to any ppa you want | 18:27 |
didrocks | either by providing --ppa <ppa_name> | 18:28 |
didrocks | to quickly share and release | 18:28 |
didrocks | or to put it as a default with quickly configure ppa <ppa_name> | 18:28 |
didrocks | of course, shell completion still works there and give you the list of all ppa you have access | 18:28 |
didrocks | (/!\ it's slow on LP side, can take more than 10s) | 18:29 |
didrocks | ppa_name can be: "myppa" or "team/ppaname" | 18:29 |
didrocks | and shell completion works for everycase :) | 18:29 |
didrocks | on another aspect, as I wrote some commands have been rename to be more consistent | 18:30 |
didrocks | quickly dialog is now quickly add dialog | 18:30 |
didrocks | (that will avoid in the futur to have 50 commands in a template) | 18:30 |
didrocks | quickly lp-project is quickly configure lp-project | 18:30 |
didrocks | and quickly glade is now quickly design | 18:30 |
didrocks | of course, as always, statement completion is here to help you to find commands name and arguments to the commands :) | 18:31 |
didrocks | for instance quickly configure [tab][tab] will show you all available options like ppa, lp-project, bzr | 18:31 |
didrocks | [SLIDE 5] | 18:32 |
didrocks | ah, I like very much next option :) | 18:32 |
didrocks | when you "quickly release", now, you will have the about dialog automatically refreshed | 18:32 |
didrocks | that means, your logo, but also the new version number appears, the Copyright holder, the homepage, the Credit (authors) button and license one | 18:33 |
didrocks | so, no need to before or to think about them, Quickly is handling that for you :) | 18:33 |
didrocks | that avoid to make a .1 release with "I forgot to…" | 18:34 |
didrocks | next item (no, not the blank one) had been asked also by a lot of persons | 18:34 |
didrocks | being able to add manual dependencies | 18:34 |
didrocks | "why care, quickly already grab all the depends for us?" you will tell me… | 18:35 |
didrocks | that's both true and false to be honest :) | 18:35 |
didrocks | for instance, if you launch a command yourself as a subprocess pythondistutils-extra won't find it and you will have a missing dependency | 18:35 |
didrocks | so now, for that, you can just fire away $ quickly configure dependencies | 18:36 |
didrocks | as "dependencies" is typo-prone, think about using shell completion for that too :) | 18:36 |
didrocks | next thing is bzr branch, as for ppa, you can tell where you can push and pull your code if you are interested in :) | 18:37 |
didrocks | quickly configure bzr of course :) | 18:37 |
didrocks | maybe the tutorial which (I'm afraid) is still not internationalized will be thanks to fagan. But nothing sure yet, still ongoing work :) | 18:38 |
didrocks | of course, this was only the most important things I can list for that session for ubuntu-application template, but there are a lot of various fixes, new licenses available, packagin tweak, internationalized application, and so on :) | 18:39 |
didrocks | [SLIDE 6] | 18:39 |
didrocks | oh btw, I forgot about the apport hook! | 18:39 |
didrocks | all project will come (but you can still disabling that if you don't want) an apport hook by default | 18:40 |
didrocks | and the menu will have the launchpad addition for translation and help in the help menu | 18:40 |
didrocks | ok, so, now, really slide 6 :) | 18:40 |
didrocks | this is for prospective template developers and people interested in making a GUI for Quickly | 18:41 |
didrocks | first thing is importing commands between templates is available | 18:41 |
didrocks | QUESTION: does having an apport hook mean that if the program crashes and stuff you can send a detailed report to the launchpad project? | 18:41 |
didrocks | dbell: exactly :) | 18:41 |
didrocks | and you get that for free :) | 18:42 |
didrocks | so, back on importing commands | 18:42 |
didrocks | if one day you want to look at the ubuntu-cli template | 18:42 |
didrocks | you will see that there is 0 line of code | 18:42 |
didrocks | yes, no typo, I said 0! | 18:42 |
didrocks | it's just a new boiler plate, and I import all commands from ubuntu-application | 18:43 |
didrocks | so, basically, there is a commandsconfig with: | 18:43 |
didrocks | [ubuntu-application] | 18:43 |
didrocks | IMPORT=configure;create;edit;license;package;release;run;save;shar | 18:43 |
didrocks | (for obvious reason for a cli template, I don't import design and add dialog :)) | 18:44 |
didrocks | and then, I can create a ubuntu-cli application, edit, licence, package… | 18:44 |
didrocks | and get statement completion for all of those using the new boiler plate code :) | 18:44 |
didrocks | so, creating a template from an existing one is really really easy | 18:45 |
didrocks | QUESTION: Will apps still work if python-launchpad-integration isn't installed (eg. on other distros) | 18:45 |
didrocks | RainCT: we try to include that as a patch, so that pristine tarball doesn't have that code and so other distros aren't impacted | 18:45 |
didrocks | (it's basically a try: pass) | 18:45 |
didrocks | well, other functions (quickly ;)) | 18:46 |
didrocks | you can now pass option to template | 18:46 |
didrocks | we have apport integration | 18:46 |
didrocks | so ubuntu-bug quickly is your friend :) | 18:46 |
didrocks | as I told you, you can now quickly configure [tab][tab] --ppa [tab][tab] | 18:47 |
didrocks | that means that the core has now option completion for you | 18:47 |
didrocks | we handle template upgrade | 18:47 |
didrocks | (even if you launch a command from one template into another project) | 18:47 |
didrocks | like quickly --template my-awesome-template foocommand | 18:47 |
didrocks | we have also now an API | 18:48 |
didrocks | so, if you want to build a GUI or integrate it into an IDE, that's the way to go :) | 18:48 |
didrocks | of course, in addition to thing, many fixes and refactoring | 18:48 |
didrocks | [SLIDE 7] | 18:48 |
didrocks | I've already talked about the ubuntu-cli template | 18:49 |
didrocks | the most important thing is that it's a new boiler plate for no code for the commands :) | 18:49 |
didrocks | if you want to implement your own template with import of ubuntu-application command, that's where to look for examples | 18:49 |
didrocks | QUESTION: Any examples on the API? | 18:50 |
didrocks | osteenbergen47: basically, you just have to "from quickly import api" and then, look at the api file | 18:50 |
didrocks | if you are interested in that, join #quickly and I can help you :) | 18:50 |
didrocks | QUESTION: is there a tutorial on how to do own/custom templates ? | 18:50 |
didrocks | oskude: I've written one for Quickly 0.2, let me find the link | 18:51 |
didrocks | http://blog.didrocks.fr/index.php/post/Build-your-application-quickly-with-Quickly%3A-Inside-Quickly-part-6 | 18:51 |
didrocks | (and now, I kill my Internet connexion as I host myself my server ;)) | 18:52 |
didrocks | this is quite outdated | 18:52 |
didrocks | I will refresh that once 0.4 out | 18:52 |
didrocks | [SLIDE 8] | 18:52 |
didrocks | so, you want to try Quickly 0.4? (well, 0.3.5) | 18:52 |
didrocks | as I mentionned before, we warned, you can't convert back your project to the previous format | 18:53 |
didrocks | and I don't have the time to ensure that everycommand works at each commit, but I try to fix the issue within the day | 18:53 |
didrocks | so, jump into #quickly, so that you can yell at me that it's broken :) | 18:53 |
didrocks | and if you want to test, branch the trunk | 18:54 |
didrocks | bzr branch lp:quickly | 18:54 |
didrocks | export PATH=<path_to_your_trun>/bin:$PATH | 18:54 |
didrocks | (note the /bin :)) | 18:54 |
didrocks | quickly --version should normally answer you about the current version | 18:54 |
didrocks | [SLIDE 9] | 18:54 |
didrocks | of course special thanks to Rick to have the idea of this project | 18:55 |
didrocks | and he will do the two next session, stay around :) | 18:55 |
didrocks | also some contributors are really awesome and help pushing the project further :) | 18:55 |
didrocks | [SLIDE 10] | 18:55 |
didrocks | so, taking questions now in the 5 remaining minutes | 18:55 |
didrocks | QUESTION: Is there an easy way to try fresh quickly on Karmic? The straightforward setup.py build/install way results in a lot of errors. | 18:56 |
didrocks | right, there is a bug logged about that | 18:56 |
didrocks | I don't see anything preventing for backporting to karmic | 18:56 |
didrocks | BUT | 18:56 |
didrocks | you need last distutils-extra version | 18:56 |
didrocks | (else you can't add depends, nor you have the automated changelog goodness) | 18:57 |
didrocks | and I probably have to fix setup.py | 18:57 |
didrocks | I think I'll try to provide a package in the quickly ppa for karmic | 18:57 |
didrocks | QUESTION: Is there a ppa-daily of Quickly for auto installing the last one? | 18:57 |
didrocks | there is a daily ppa, jcastro was the owner IIRC, I don't know the current state to be honest | 18:58 |
didrocks | I think export PATH is more convenient :) | 18:58 |
didrocks | and that's what I do everyday :) | 18:58 |
didrocks | well, of course the day we can do "quickly release lucid", I think Quickly will take some thousands lines of code :) | 18:59 |
jcastro | The dailies work, if they don't work for you just poke me. | 18:59 |
didrocks | but as I still like my job, it won't happen :) | 18:59 |
didrocks | I guess it's time :) | 18:59 |
didrocks | and thanks jcastro | 18:59 |
didrocks | thanks all for your attention | 19:00 |
didrocks | now, stage is to you rickspencer3 | 19:00 |
didrocks | and thanks for having launched Quickly once more :) | 19:00 |
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - http://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Event: Ubuntu Opportunistic Developer Week - Current Session: Create games with PyGame - Rick Spencer - Instructor: rickspencer3 || Questions in #ubuntu-classroom-chat | ||
rickspencer3 | hi all | 19:01 |
rickspencer3 | ready for some pygame stuff? | 19:01 |
rickspencer3 | great | 19:02 |
rickspencer3 | as usual, I got my notes ready before hand and stuck them on the wiki: | 19:02 |
rickspencer3 | https://wiki.ubuntu.com/UbuntuOpportunisticDeveloperWeek/PyGameClassNotes | 19:02 |
rickspencer3 | so I'll go through each section and take questions | 19:03 |
rickspencer3 | Pygame is a library for making arcade style sprite games | 19:03 |
rickspencer3 | It features very easy blitting and colision detection | 19:03 |
rickspencer3 | I have some sample code to help with understanding pygame here: | 19:03 |
rickspencer3 | https://code.edge.launchpad.net/~rick-rickspencer3/pygame-template/trunk | 19:03 |
rickspencer3 | I think you can go: | 19:03 |
rickspencer3 | bzr branch lp:pygame-template too | 19:04 |
rickspencer3 | note that some of this code is a bit old, and I need to reformat it and such | 19:05 |
rickspencer3 | but it | 19:05 |
rickspencer3 | s failry readable | 19:05 |
rickspencer3 | however, it will eventually be a quickly template, hopefully in time for lucid | 19:05 |
rickspencer3 | if you want to grab that it might help you follow the class a bit, but it is not required | 19:05 |
rickspencer3 | it comes with some basic game play that you can study and modify | 19:05 |
rickspencer3 | essentially, it is kind of like asteroids | 19:05 |
rickspencer3 | you control the black triangle in the middle, and there are two enemies | 19:05 |
rickspencer3 | Of course you will want some docs | 19:05 |
rickspencer3 | Pygame has good docs here: | 19:05 |
rickspencer3 | http://www.pygame.org/docs/ | 19:05 |
rickspencer3 | before we discuss how to set up a game | 19:06 |
rickspencer3 | any questions? | 19:06 |
rickspencer3 | ok, then let us rock | 19:06 |
rickspencer3 | so, you're going to set up a game | 19:06 |
rickspencer3 | first thing you need to do is set up a game surface | 19:06 |
rickspencer3 | and do other initalizations | 19:07 |
rickspencer3 | so .. | 19:07 |
rickspencer3 | initialize pygame libraries | 19:07 |
rickspencer3 | pygame.font.init() | 19:07 |
rickspencer3 | pygame.mixer.init() | 19:07 |
rickspencer3 | (assuming you are using fonts and sound of course) | 19:07 |
rickspencer3 | then create a screen | 19:07 |
rickspencer3 | the screen will be the surface on which your sprites will be drawn, essentially where your game will occur | 19:07 |
rickspencer3 | screen = pygame.display.set_mode((800, 480)) | 19:07 |
rickspencer3 | that's for an 800 x 400 pixel game | 19:08 |
rickspencer3 | also, create a couple of variable you will need later | 19:08 |
rickspencer3 | like a background image | 19:08 |
rickspencer3 | background = pygame.image.load(path_to_background) | 19:08 |
rickspencer3 | notice the image is a PyGame image | 19:08 |
rickspencer3 | and a clock | 19:08 |
rickspencer3 | clock = pygame.time.Clock() | 19:08 |
rickspencer3 | you'll see why we need the clock next | 19:08 |
rickspencer3 | pygame games use a good old fashioned input loop | 19:09 |
rickspencer3 | don't know if you all ever programmed with an event loop | 19:09 |
rickspencer3 | but it was very common for writing GUI apps back around when dinosaurs used computers | 19:09 |
rickspencer3 | essentially, you tell your app to keep looping | 19:09 |
rickspencer3 | and whenever it goes through the loop do a few things | 19:09 |
rickspencer3 | 1. respond to user input | 19:10 |
rickspencer3 | 2.update data for any sprites on the screen | 19:10 |
rickspencer3 | this includes seeing if any sprites have collided | 19:10 |
rickspencer3 | 3. redraw everything | 19:10 |
rickspencer3 | let's look at setting up a game loop | 19:10 |
rickspencer3 | while 1: | 19:10 |
rickspencer3 | clock.tick(15) | 19:10 |
rickspencer3 | if ControllerTick() == 0: | 19:10 |
rickspencer3 | return | 19:10 |
rickspencer3 | if not game.paused: | 19:10 |
rickspencer3 | ViewTick() | 19:10 |
rickspencer3 | if CheckCollisions() == 0: | 19:10 |
rickspencer3 | return | 19:10 |
rickspencer3 | you can see this code in the crashteroids file at line 169 | 19:10 |
rickspencer3 | so first, the loop just runs and runs until etiher ControllerTick or CheckCollisions returns 0 | 19:11 |
rickspencer3 | the first line in the loop basically says to have 15 frames per second | 19:11 |
rickspencer3 | this is not like a sleep function where the argument says how long to sleep | 19:11 |
rickspencer3 | make sure that you pick a number that is low enough that a lower powered computer can keep up, if you care about that kind of thing | 19:11 |
rickspencer3 | The next line calls ControllerTick() | 19:11 |
rickspencer3 | This function checks for user input, which I will explain in a moment, and the updates all the game data | 19:11 |
rickspencer3 | this is a function that *you* write | 19:11 |
rickspencer3 | it's not built into PyGame | 19:12 |
rickspencer3 | then next in the loop | 19:12 |
rickspencer3 | assuming that the game is not paused, it will go ahead and update the view and do collision detection | 19:12 |
rickspencer3 | The reason that controllertick is always called is because this function controlls pausing and unpausing of the game | 19:12 |
rickspencer3 | if you didn't call it every time through, the user couldn't unpause | 19:12 |
rickspencer3 | we'll look at each of these functions in more detail | 19:12 |
rickspencer3 | but first, questions? | 19:12 |
ClassBot | mhall119 asked: what file is that in? | 19:13 |
rickspencer3 | it's in crashteroids/bin/crashteroids | 19:13 |
ClassBot | ryzrecreel asked: What kind of image formats can you use? | 19:13 |
rickspencer3 | dunno for sure | 19:13 |
rickspencer3 | I always use png | 19:13 |
rickspencer3 | ok, no more questions, so moving on | 19:14 |
rickspencer3 | let's start by handling user input | 19:14 |
rickspencer3 | pygame basically queues up input events | 19:14 |
rickspencer3 | you can then loop through them and respond to each event | 19:14 |
rickspencer3 | at line 93, you can see how the loop is set up | 19:14 |
rickspencer3 | for event in pygame.event.get(): | 19:14 |
rickspencer3 | if event.type == pygame.QUIT: | 19:14 |
rickspencer3 | return 0 | 19:14 |
rickspencer3 | pygame.QUIT is called when the window closes or such | 19:14 |
rickspencer3 | of course you could also do something smart and save game state or such | 19:14 |
rickspencer3 | but this code returns 0, which causes the main event loop to quit | 19:15 |
rickspencer3 | now, let's say what I want to do is make the ship go forward when the user presses the j key | 19:15 |
rickspencer3 | (which is what crashteroids does by default) | 19:15 |
rickspencer3 | first I ask what kind of event it was | 19:15 |
rickspencer3 | if event.type == pygame.KEYDOWN: | 19:15 |
rickspencer3 | yup, I want to respond to key down events | 19:15 |
rickspencer3 | so this I'll write some code here | 19:16 |
rickspencer3 | and then if it was a key event, what key was pressed | 19:16 |
rickspencer3 | if event.key == pygame.K_l: | 19:16 |
rickspencer3 | #do something | 19:16 |
rickspencer3 | oops | 19:16 |
rickspencer3 | that's for l key :) | 19:16 |
rickspencer3 | I guess l is for move, and j is to shoot | 19:16 |
rickspencer3 | in any case, you can probably guess that the correct event.key is pygame.k_j to respond to the j key | 19:17 |
rickspencer3 | ;) | 19:17 |
rickspencer3 | you can see the whole tree of if, else statements starting at line 89 | 19:17 |
rickspencer3 | there are also events for the mouse and joysticks even | 19:17 |
rickspencer3 | so it's easy to create games that aren't only using the keyboard if you want | 19:17 |
rickspencer3 | so that's how to handle input | 19:17 |
rickspencer3 | let's look at sprites, but first, any questions? | 19:17 |
ClassBot | mhall119 asked: any kind of vector graphics? | 19:18 |
rickspencer3 | could be, but PyGame is really sprite based | 19:18 |
rickspencer3 | vector graphics is how games like asteroids and battlezone, and starcastle and stuff were created | 19:18 |
rickspencer3 | but sprites are when you use images | 19:18 |
ClassBot | M49 asked: Does pygame have any dialog for key configuration? | 19:19 |
rickspencer3 | not that I know of | 19:19 |
rickspencer3 | that would be a nice thing to add to a quickly template though, wouldn't it | 19:19 |
rickspencer3 | I would guess that you would just use PyGtk for this | 19:19 |
rickspencer3 | create it yourself | 19:19 |
rickspencer3 | ok | 19:19 |
rickspencer3 | let's move on to sprites | 19:19 |
rickspencer3 | A sprite is basically an image in an arcade game | 19:20 |
rickspencer3 | pygame handles blitting for you, which is quite nice | 19:20 |
rickspencer3 | I'll discuss blitting in a bit | 19:20 |
rickspencer3 | If you wrote games long ago, you may remember rendering a sprite strip to an offscreen graphics world | 19:20 |
rickspencer3 | and then selecting bits of that strip and copying them to the onscreen graphics world | 19:20 |
rickspencer3 | pygame does not reqiure that at all | 19:20 |
rickspencer3 | it is much more fun and easy | 19:20 |
rickspencer3 | you just subclass the Sprite class | 19:21 |
rickspencer3 | one key thing a sprite has is an Pygame.Image member, called image | 19:21 |
rickspencer3 | I usually like to keep the original image around, as if you keep rotating the image and such, it will get more and more distorted over time | 19:21 |
rickspencer3 | so when I create a sprite object, I set up the image member like this: | 19:22 |
rickspencer3 | self.masterImage = pygame.image.load(path_to_image_file) | 19:22 |
rickspencer3 | self.image = self.masterImage | 19:22 |
rickspencer3 | this is all in the BastSprite class, btw, if you want to see the code in situ | 19:22 |
rickspencer3 | a sprite also has a "virtual" function, called update | 19:22 |
rickspencer3 | update is supposed to be called to tell a sprite to update it's data for a tick | 19:22 |
rickspencer3 | you set things like the sprite's x, y coordinates in this function, and such | 19:22 |
rickspencer3 | all your sprites should use this because you can then add a sprite to a RenderUpdates sprite group | 19:22 |
rickspencer3 | don't add your own custom named method to do this, or you will lose a lot of benefits of PyGame | 19:23 |
rickspencer3 | call update for that group, which will call update for each sprite | 19:23 |
rickspencer3 | you create a sprite group like this: | 19:23 |
rickspencer3 | enemies = pygame.sprite.RenderUpdates() | 19:23 |
rickspencer3 | and then you can add an sprite to that group | 19:24 |
rickspencer3 | enemies.add(create_enemy()) | 19:24 |
rickspencer3 | you can also empty a sprite group | 19:24 |
rickspencer3 | enemies.empty() | 19:24 |
rickspencer3 | useful when you are resetting a level or something | 19:24 |
rickspencer3 | as we'll see later, sprite groups also help lots with collision detection | 19:24 |
rickspencer3 | back to sprites though | 19:24 |
rickspencer3 | so you have an image on a sprite | 19:24 |
rickspencer3 | you also need to define an x and y for your sprite | 19:24 |
rickspencer3 | I in my sprite subclass, I might set x and y randomly like this: | 19:25 |
rickspencer3 | self.x = random.randint(0,300) | 19:25 |
rickspencer3 | self.y = random.randint(0,140) | 19:25 |
rickspencer3 | (only when the sprite is created, of course) | 19:25 |
rickspencer3 | but then on each call to update(), just change the x and/or y if the sprite is moving | 19:25 |
rickspencer3 | sprites also have a "kill()" member function | 19:25 |
rickspencer3 | calling kill causes the sprite to be removed from the playing surface | 19:25 |
rickspencer3 | questions before we talk about updating the display? | 19:25 |
ClassBot | mhall119 asked: can you change the image on update? | 19:26 |
rickspencer3 | yes | 19:26 |
rickspencer3 | absolutely | 19:26 |
rickspencer3 | you can also rotate it and other things | 19:26 |
rickspencer3 | my sprites usually have an "explode" method | 19:26 |
rickspencer3 | which causes a stage of an explosion to be displayed with each tick in update | 19:27 |
rickspencer3 | so if you look at crashteroids, changing images on update is how I get the explosion effect | 19:27 |
ClassBot | mhall119 asked: Like, to animate your sprite | 19:27 |
rickspencer3 | totally | 19:27 |
rickspencer3 | like if you had a tank | 19:27 |
rickspencer3 | and it was going to shoot a missle | 19:27 |
rickspencer3 | you could have swap in images that make it look like a little guy loading the turret or something | 19:28 |
ClassBot | mhall119 asked: can you layer images to make a single sprite image? | 19:28 |
rickspencer3 | hmmm | 19:28 |
rickspencer3 | not that I know of | 19:28 |
rickspencer3 | I don't think a sprite can composit images like that | 19:28 |
rickspencer3 | ok | 19:29 |
rickspencer3 | so now you have your event loop running, your game surface set up, and some sprites created | 19:29 |
rickspencer3 | now we need to actually draw the sprites | 19:29 |
rickspencer3 | for sprites that are not in a sprite group, we need to blit them | 19:29 |
rickspencer3 | fortunately this does not involve the crazy gworld hackery of days of hold | 19:29 |
rickspencer3 | pygame gives us a blit method | 19:29 |
rickspencer3 | blitting is essentially the act of repainting parts of the screen that have changed | 19:29 |
rickspencer3 | without blitting, the whole screen repaints and appears to flash | 19:29 |
rickspencer3 | so to blit the blackgroud, we'll use the screen to blit | 19:30 |
rickspencer3 | remember when we created teh screen object? now it's time to use it | 19:30 |
rickspencer3 | screen.blit(background, [0,0]) | 19:30 |
rickspencer3 | I think that blitting the background like this basically repaints the whole background image over everything | 19:30 |
rickspencer3 | if you are tuning for a very slow platform, or a game with lots and lots of sprites, you may not want do it this way or you get flashing | 19:30 |
rickspencer3 | in those cases you might need to track the parts of the background exposed by moving sprites | 19:30 |
rickspencer3 | this is a bit of work, but probably will not be necessary for you to do | 19:31 |
rickspencer3 | I certainly have never run into trouble with this | 19:31 |
=== mohi1 is now known as mohi_ | ||
rickspencer3 | for all I know, blit() is smart enough to not cause flashing | 19:31 |
=== mohi_ is now known as mohi1 | ||
rickspencer3 | to blit an individual sprite, you have to tell the screen the image to use and the rect, or xy coords and dimensions, for hte sprite to blit | 19:31 |
rickspencer3 | So if we have a sprite object called "g", we blit it like this: | 19:31 |
rickspencer3 | screen.blit(g.image, g.rect) | 19:31 |
rickspencer3 | sprites in a sprite group are a bit easier to blit | 19:31 |
rickspencer3 | you can tell the sprite group to blit them all: | 19:32 |
rickspencer3 | enemies.draw(screen) | 19:32 |
rickspencer3 | this blits all the enemies for you | 19:32 |
rickspencer3 | we do this each time through the loop | 19:32 |
rickspencer3 | in ViewTick() | 19:33 |
rickspencer3 | question before we discuss collision detection? | 19:33 |
ClassBot | w1nGNUtz asked: will you explain anitmations? I'd like to understand how to animate an sprite using the clock | 19:33 |
rickspencer3 | yeah | 19:33 |
rickspencer3 | so let's say you want have an animation that shows a guy walking | 19:33 |
rickspencer3 | create enough images to show taking a step smoothly | 19:33 |
rickspencer3 | I'll guess it will take 8 frames to show smooth step | 19:34 |
rickspencer3 | in the sprites update method | 19:34 |
rickspencer3 | swap in the next image each time through | 19:34 |
rickspencer3 | for example | 19:34 |
rickspencer3 | when I show a guy exploding | 19:34 |
rickspencer3 | I have 8 frames or so showing the explosion | 19:34 |
rickspencer3 | named ship_explode_1.png to ship_explode_8.png | 19:35 |
rickspencer3 | (or named similary, I forget exactly what I named them) | 19:35 |
rickspencer3 | then I keep track in the update method of a counting variable | 19:35 |
rickspencer3 | let me get the exact code, hold on | 19:35 |
rickspencer3 | if self.exploding: | 19:36 |
rickspencer3 | #do an explosion image for each tick | 19:36 |
rickspencer3 | self.explodestage += 1 | 19:36 |
rickspencer3 | e = self.explodestage | 19:36 |
rickspencer3 | if e < 8:#there are 7 explosion images | 19:36 |
rickspencer3 | e = str(e) | 19:36 |
rickspencer3 | self.masterImage = pygame.image.load(crashteroidsconfig.guy_explode_stage + e + ".png") | 19:36 |
rickspencer3 | self.updateImage() | 19:36 |
rickspencer3 | updateImage is a function I wrote that rotates the image and does some other stuff | 19:36 |
rickspencer3 | but essentially sets the sprites image member, like this: | 19:37 |
rickspencer3 | self.image = pygame.transform.rotate(self.masterImage,self.orientation) | 19:37 |
rickspencer3 | (if you weren't doing rotation and stuff, you could just assign the new image directly) | 19:37 |
ClassBot | mhall119 asked: does pygame offer any kind of "damage" data to tell what parts of the screen should be repainted? | 19:37 |
rickspencer3 | I don't know | 19:38 |
rickspencer3 | I always let the sprites blit() method take care of that for me | 19:38 |
rickspencer3 | I don't think you'll to track this | 19:38 |
rickspencer3 | back in the day, you would always track the previous rect for the sprites location | 19:38 |
rickspencer3 | so that you could repaint it with the background | 19:38 |
rickspencer3 | but I don't think PyGame requires this | 19:39 |
ClassBot | gooomba asked: Is pygame also suited for non-arcade games like chess for example? | 19:39 |
rickspencer3 | yes | 19:39 |
rickspencer3 | it wuold be good for board games for sure | 19:39 |
rickspencer3 | ok, so collision detection | 19:40 |
rickspencer3 | so let's say when an enemy rams our guy, we want both to be killed | 19:40 |
rickspencer3 | but how to tell when an ememy hits? | 19:40 |
rickspencer3 | detecting overlapping sprites is called "collision detection" and is handled quite well by PyGame | 19:40 |
rickspencer3 | this saves you tons of work | 19:40 |
rickspencer3 | (believe me, tracking rects and writing code to detect overlapping rects is not fun or easy!) | 19:40 |
rickspencer3 | you can detect if two sprites have collided using pygame.sprite.spritecollide (), collideany, or groupcollide | 19:41 |
rickspencer3 | so let's see if our guy, called g, has collided with an enemy | 19:41 |
rickspencer3 | e = pygame.sprite.spritecollideany(g, enemies) | 19:41 |
rickspencer3 | call this each tick | 19:41 |
rickspencer3 | I always have specific function to handle collision detection | 19:41 |
rickspencer3 | if the guy has not collided with any enemies, e will be None | 19:41 |
rickspencer3 | but when e is not None, that means boom | 19:42 |
rickspencer3 | "boom" | 19:42 |
rickspencer3 | let's say your guys shoots bullets | 19:42 |
rickspencer3 | those bullets will most likely be managed in a sprite group | 19:42 |
rickspencer3 | so we should also see if any enemies were killed by bullets | 19:42 |
rickspencer3 | hits_dict = pygame.sprite.groupcollide(bullets, enemies, False, False) | 19:42 |
rickspencer3 | since we are asking for a collision between groups of sprites | 19:42 |
rickspencer3 | here you get back a dictionary | 19:42 |
rickspencer3 | the keys are sprites from the first sprite group | 19:42 |
rickspencer3 | and the values are keys from the second sprite group | 19:42 |
rickspencer3 | so then we can just go through and kill each bullet and enemy for the collision: | 19:42 |
rickspencer3 | for b in hits_dict: | 19:43 |
rickspencer3 | for e in hits_dict[b]: | 19:43 |
rickspencer3 | e.kill() | 19:43 |
rickspencer3 | b.kill() | 19:43 |
rickspencer3 | ok, next and last section is on playing sounds | 19:43 |
rickspencer3 | any questions first? | 19:43 |
ClassBot | mhall119 asked: does pygame have any kind of scene-graph, to animate sprites without writing a whole bunch of python code? | 19:43 |
rickspencer3 | if I know what that meant, I would give you a pithy answer | 19:43 |
rickspencer3 | unfortunately, I have to say "I don't know" | 19:43 |
ClassBot | M49 asked: Does it track only bounding boxes or does it use trasparency information from sprites? | 19:44 |
rickspencer3 | the bounding box one | 19:44 |
rickspencer3 | actually, you can set the rect for the sprite specifically | 19:44 |
rickspencer3 | I often set the rect for the sprite to be slightly smaller than the image itself | 19:44 |
rickspencer3 | this give a nice effect where two sprites can just touch | 19:44 |
rickspencer3 | and not explode | 19:44 |
rickspencer3 | it gives a nice "near miss" effect | 19:44 |
rickspencer3 | it also lets you tune each rect to different shaped sprites | 19:45 |
rickspencer3 | note that the rect is only used for collision detection so far as I know | 19:45 |
rickspencer3 | so the whole image will always be displayed | 19:45 |
rickspencer3 | ok, finally, sounds | 19:46 |
rickspencer3 | we use the Pygame.mixer module to manage sounds | 19:46 |
rickspencer3 | we need to initialize it before we use it: | 19:46 |
rickspencer3 | pygame.mixer.init() | 19:46 |
rickspencer3 | now I'll load an explosion sound to play when my guy explodes: | 19:46 |
rickspencer3 | self.explosionSound = pygame.mixer.Sound(path_to_sound_file) | 19:46 |
rickspencer3 | let's assume this sound is a bit loud, we can adjust the volume as we like: | 19:47 |
rickspencer3 | self.explosionSound.set_volume(.2) | 19:47 |
rickspencer3 | then we can play the sound: | 19:47 |
rickspencer3 | self.explosionSound.play() | 19:47 |
rickspencer3 | we can stop it too if it's going too long: | 19:47 |
rickspencer3 | self.explosionSound.stop() | 19:47 |
rickspencer3 | the mixer module is quite rich | 19:47 |
rickspencer3 | there are channels, fades, and all kinds of stuff | 19:47 |
rickspencer3 | so | 19:48 |
rickspencer3 | that was the last "chapter" for the class | 19:48 |
rickspencer3 | we're a bit early | 19:48 |
rickspencer3 | any questions? | 19:48 |
ClassBot | gooomba asked: what are the "False"-arguments in groupcollide() for? | 19:48 |
rickspencer3 | shucks, I forget | 19:48 |
* rickspencer3 looks at docs | 19:48 | |
rickspencer3 | huh | 19:49 |
rickspencer3 | http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.groupcollide | 19:49 |
rickspencer3 | no longer seems part of the API | 19:49 |
rickspencer3 | I guess I can just remove that from the template | 19:49 |
ClassBot | mhall119 asked: what audio formats does mixer support? | 19:50 |
rickspencer3 | I know ogg and wav | 19:50 |
rickspencer3 | don't know what else, sorry | 19:50 |
rickspencer3 | there are nine minutes left | 19:51 |
rickspencer3 | any last questions, requests? | 19:51 |
rickspencer3 | (otherwise I'll grab some soda and get ready for my next session ;) ) | 19:51 |
ClassBot | oskude asked: how do i use the examples on that pygame site ? | 19:52 |
rickspencer3 | I'm not sure what you are asking specifically | 19:52 |
rickspencer3 | but I don't think they are set up as runable samples, but rather like code snippets | 19:52 |
rickspencer3 | I used those samples heavily back when I was learning PyGame tough | 19:53 |
rickspencer3 | ok, looks like no more questions | 19:53 |
rickspencer3 | please feel free to join us in #quickly | 19:53 |
rickspencer3 | any feedback on the PyGame template and how to improve it, what's wrong with it, etc... | 19:54 |
rickspencer3 | is much appreciated | 19:54 |
rickspencer3 | thanks all! | 19:54 |
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - http://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Event: Ubuntu Opportunistic Developer Week - Current Session: SHOWCASE: Photobomb - Rick Spencer - Instructor: rickspencer3 || Questions in #ubuntu-classroom-chat | ||
=== enli is now known as enli|away | ||
rickspencer3 | hi all | 20:02 |
rickspencer3 | soooo | 20:02 |
rickspencer3 | I'm here to talk about photobomb | 20:02 |
rickspencer3 | jono thought some folks might be interested in hearing about some of the technology that I used and such | 20:02 |
rickspencer3 | to make it easier to walk through, I put some screenshots and some notes: | 20:03 |
rickspencer3 | here: | 20:03 |
rickspencer3 | http://theravingrick.blogspot.com/2010/03/photobomb-featured-app-for-opp-dev-week.html | 20:03 |
rickspencer3 | shall I begin with photobomb? | 20:04 |
rickspencer3 | I wrote the first iteration of Photobomb one Saturday afternoon. | 20:05 |
rickspencer3 | does everyone know what it does? | 20:05 |
rickspencer3 | it's basically a hacked together photo editor | 20:05 |
rickspencer3 | that let's you mash up images from sources like your feeds, your computer, the web, your web cam, etc... | 20:06 |
rickspencer3 | do some fun stuff | 20:06 |
rickspencer3 | and then you can save the image or tweet it | 20:06 |
rickspencer3 | I wrote this totally just for the fun of it in my spare time | 20:06 |
rickspencer3 | during January, I set the goal of writing one new feature a night | 20:06 |
rickspencer3 | so I got pretty far with it that way | 20:06 |
rickspencer3 | of course, it's a bit buggy still | 20:06 |
rickspencer3 | but it's kinda fun to use | 20:07 |
rickspencer3 | anyone who wants to contribute to it, fork it, whatever | 20:07 |
rickspencer3 | by all means, have a go | 20:07 |
rickspencer3 | anyway ... | 20:07 |
rickspencer3 | I used Quickly to get the project started, so it was just a matter of laying out some UI in Glade, and then figuring out how to manipulate images. | 20:07 |
rickspencer3 | I used Python Imaging Library (PIL) to create a cropped version of that little squirrel, and to paste it onto the picture. | 20:07 |
rickspencer3 | PIL is a complete and power library. It was a bit tough figuring out the masking to crop the squirrel image as desired, but I eventually managed. | 20:08 |
rickspencer3 | I ended up moving away from PIL, but from what I saw, I was impressed | 20:08 |
rickspencer3 | any questions do far? | 20:08 |
ClassBot | mhall119 asked: where can we get the code? | 20:09 |
rickspencer3 | it's in a junk branch | 20:09 |
* rickspencer3 gets | 20:09 | |
rickspencer3 | https://code.edge.launchpad.net/~rick-rickspencer3/+junk/photobomb | 20:09 |
rickspencer3 | party on! | 20:09 |
rickspencer3 | I think it might be in my ppa too | 20:09 |
rickspencer3 | ok | 20:10 |
rickspencer3 | so following along to the next screen shot | 20:10 |
rickspencer3 | I added the ability to choose an image to stick in there | 20:10 |
rickspencer3 | and photobomb with that little squirrel | 20:11 |
rickspencer3 | It turned out to be tedious to write code to open an image file. | 20:11 |
rickspencer3 | So I added a prompt to quickly.widgets to handle opening files. | 20:11 |
rickspencer3 | Having your own library of reusable widgets is quite a luxury. | 20:11 |
rickspencer3 | if you look closely at the screenshot ... | 20:11 |
rickspencer3 | Note that I didn't know the gtk.FileChooser API that well, so made a couple of early mistakes, such as handling the existing file replace functionality myself. | 20:11 |
rickspencer3 | Didn't realize that the API could handle it | 20:11 |
rickspencer3 | but in any case, the shell of photobomb is PyGtk of course | 20:12 |
rickspencer3 | and I had to learn a bit about some areas of Gtk that I hadn't used too much | 20:12 |
rickspencer3 | any questions about that one? | 20:12 |
ClassBot | mhall119 asked: Did you already know Glade before you started this? | 20:13 |
rickspencer3 | oh yes | 20:13 |
rickspencer3 | quite | 20:13 |
rickspencer3 | at first, you think Glade is your enemy | 20:13 |
rickspencer3 | but after a while, you learn it is our friend | 20:13 |
rickspencer3 | but Glade can be a bit hard to learn | 20:13 |
rickspencer3 | and it isn't designed to do everything | 20:14 |
rickspencer3 | so writing gtk.UIBuilder code is still part of hte process | 20:14 |
rickspencer3 | quickly makes this a bit easier, by giving each window a builder function | 20:14 |
rickspencer3 | I mean builder member | 20:14 |
rickspencer3 | so you can go: | 20:14 |
rickspencer3 | self.builder.get_object("hbox1").pack_start(my_widget) | 20:14 |
ClassBot | mhall119 asked: does photobomb run on Karmic? or just Lucid? | 20:15 |
rickspencer3 | well | 20:15 |
rickspencer3 | it's packaged for Lucid | 20:15 |
rickspencer3 | because it uses quickly-widgets | 20:15 |
rickspencer3 | which is in the quidgets project | 20:15 |
rickspencer3 | however, if you want to run it | 20:15 |
rickspencer3 | it shouldn't be too hard | 20:15 |
rickspencer3 | just branch photobomb | 20:15 |
rickspencer3 | then branch quidgets | 20:16 |
rickspencer3 | then stick quidgets/quickly dir in photobomb/photobomb, and it might work | 20:16 |
rickspencer3 | or just put quidgets somewhere on disk and set the python path when you run it | 20:17 |
rickspencer3 | !PYTHONPATH="~/quidgets/quickly" python photobomb/bin/photobomb | 20:17 |
rickspencer3 | for example | 20:17 |
ClassBot | mhall119 asked: Any good tutorials on learning to make Glade my friend? | 20:17 |
rickspencer3 | mmm | 20:17 |
rickspencer3 | not really | 20:17 |
rickspencer3 | there are a bunch of tutorials | 20:18 |
rickspencer3 | but many are out of date, since PyGtk moved form LibGlade to UI Builder | 20:18 |
rickspencer3 | if you have Quickly installed, there is a bit in there to help you get started | 20:18 |
rickspencer3 | #ubuntu-app-devel is a good place to ask specific gladey questions | 20:18 |
rickspencer3 | unless it's about workign with a quickly template, in which case #quickly might be better | 20:19 |
rickspencer3 | ok | 20:19 |
rickspencer3 | so next section | 20:19 |
rickspencer3 | When I tried to implement some captioning and other features, I came to realize that PIL was just not designed for the kind of stuff I wanted to do with it. | 20:19 |
rickspencer3 | When I switched to GooCanvas, it became much easier to add features. | 20:19 |
rickspencer3 | I was able to add resizing, rotation, and drag to move in a matter of an hour or so. | 20:19 |
rickspencer3 | A couple of days later I fixed an issue with dragging rotated items that resulted from the craziness involved with items in goocanvas maintaining their own coordinate system seperate from the goocanvas they are in. | 20:20 |
rickspencer3 | questions about PIL, GooCanvas, or anything else so far? | 20:21 |
ClassBot | mhall119 asked: it doesn't look like you did much with glade, do you find yourself doing most UI building directly in python? | 20:21 |
rickspencer3 | yes | 20:21 |
rickspencer3 | I genreally use glade to set up containers | 20:22 |
rickspencer3 | then I target those container from code | 20:22 |
rickspencer3 | especially for custom images and such' | 20:22 |
rickspencer3 | also, I use subclassing a lot | 20:22 |
rickspencer3 | and I haven't done much work to make my own widgets work within glade | 20:22 |
rickspencer3 | ok | 20:22 |
rickspencer3 | I could then go and the ability for users to use a pen tool in photobomb. | 20:22 |
rickspencer3 | This required managing mouse events and creating a PolyLine object from the collected mouse points. | 20:23 |
rickspencer3 | Later I found that a Path worked better than a PolyLine for creating the Ink. I still have not figured out how to add points to an existing Path. | 20:23 |
rickspencer3 | As a result, Photobomb recreates the Path with each mouse move. This gets slow if the Path is not short. | 20:23 |
rickspencer3 | I did a session on GooCanvas yesterday, but can take some quick questions on it today | 20:23 |
rickspencer3 | I used the gtk.ColorChooserDialog for color selection. | 20:24 |
rickspencer3 | I also added color button and ink width button. | 20:24 |
rickspencer3 | originally, These hosted a goocanvas, and I just added a path to each and set the properties of the Path to display the selected color and width. | 20:24 |
rickspencer3 | later I changed the color button to change it's background to show the correct color | 20:25 |
rickspencer3 | I mean, selected color | 20:25 |
rickspencer3 | there's a "color selection" button in Gtk, but it didn't quite suite my UI | 20:25 |
rickspencer3 | in terms of getting settings from users | 20:25 |
rickspencer3 | I had already created quickly.prompts to make it easy to collect a line width from the user. (quickly.prompts.integer()). | 20:25 |
rickspencer3 | I could handle this with a GooCanvas.Widget object embedded in situ, but that's a lot of work and using quickly.prompts.string() is a one-liner. | 20:26 |
rickspencer3 | questions so far? | 20:26 |
rickspencer3 | following along, the next thing I implemented was adding text to the goocanvas | 20:26 |
rickspencer3 | I added a gtk.STOCK_EDIT button to collect text from the user. | 20:26 |
rickspencer3 | well, that was just to manage the correct icon | 20:27 |
rickspencer3 | since i wanted buttons to be compact | 20:28 |
rickspencer3 | I used toolbar buttons, and just setting them to stock worked well | 20:28 |
rickspencer3 | later, I had to hack around some limitations to how "stock" works | 20:28 |
rickspencer3 | I used a quickly.prompts.string() to collect the string to display from the user. | 20:29 |
rickspencer3 | next I added the some feedback about the current selection | 20:29 |
rickspencer3 | To display selection, I simply used a GooCanvas.Rect with a bit of buffer around the selected object. | 20:29 |
rickspencer3 | I could have added stock selection points from gtk, but that sounded like a lot of work. | 20:30 |
rickspencer3 | questions so far? | 20:30 |
rickspencer3 | I added a bit of opacity to the selection box. This works better, as you can see what is behind the selected item | 20:32 |
rickspencer3 | Then I added opacity to other selectable items. | 20:32 |
rickspencer3 | I sniped some code from segphault's grabbersnap app to figure out how to set up rgba colors. | 20:32 |
rickspencer3 | It's a bit of a hack, but seems to work well. | 20:33 |
rickspencer3 | At this point in the project I also switched from having the user open individual images to add, to iterating through the Pictures directory and adding a button for each encountered image. | 20:33 |
rickspencer3 | I accomplished this asynchronously by putting this on a thread, using quickly.widgets.asynch_task_progressbox() | 20:33 |
rickspencer3 | This simplifies threaded coding a bit, but I am finding that threads + Python + PyGtk don't work out as well as I want, no matter how carefully I code it | 20:33 |
rickspencer3 | happy to take questions now if you've gottem' | 20:33 |
rickspencer3 | so moving on to the web cam feature | 20:34 |
rickspencer3 | Web Cam support is an important feature for Photobomb, | 20:34 |
rickspencer3 | but the available APIs looked daunting. | 20:34 |
rickspencer3 | That is, until I discovered that Pygame had a simplified web cam interface. | 20:35 |
rickspencer3 | I created a quickly.widget to handle web cam integration and added that widget to Photobomb. | 20:35 |
rickspencer3 | Note that this means quickly.widgets depends on PyGame. | 20:35 |
rickspencer3 | I think I shall move the webcam widget out of the default install and make it available in some other manner. | 20:35 |
rickspencer3 | Having another source of images meant that I needed to add a gtk.Notebook to handle switching between the two sources. | 20:35 |
rickspencer3 | I later went on to use icons for the notebook tabs, but labels worked fine when there were only 2 sources | 20:36 |
rickspencer3 | Questions so far? | 20:36 |
ClassBot | w1nGNUtz asked: It seems some programs take too long to evolve. How could it be if you manage to do this so quickly? | 20:36 |
rickspencer3 | hmm | 20:36 |
rickspencer3 | interesting quetsion | 20:36 |
rickspencer3 | I guess I just did one new feature a night | 20:37 |
rickspencer3 | I refactored as I went | 20:37 |
rickspencer3 | to support adding new features | 20:37 |
rickspencer3 | this was a really fun project to work on | 20:37 |
rickspencer3 | so I don't know | 20:37 |
rickspencer3 | I guess PyGtk + GooCanvas are just really productive libraries | 20:37 |
ClassBot | titeuf_87 asked: is there any reasons you went with pygame instead of gstreamer? | 20:38 |
rickspencer3 | for the simple reason that I discovered the PyGame api, and it looked like I could do it | 20:38 |
rickspencer3 | I would switch to gstreamer if I saw sample code that convinced me it would be easy to do | 20:38 |
rickspencer3 | I would love to break the PyGame dependency | 20:38 |
rickspencer3 | ok | 20:39 |
rickspencer3 | so Web image searching | 20:39 |
rickspencer3 | I added this next | 20:39 |
rickspencer3 | so you could search for a term, and then get back a list of related images | 20:39 |
rickspencer3 | I ended up using the Yahoo! image search api for this | 20:39 |
rickspencer3 | for the sole reason that the API was dead simple to use and well documented | 20:40 |
rickspencer3 | around this time, someone picked up another program I wrote, and added good support for extracting image urls from a web page | 20:40 |
rickspencer3 | so I sniped that code and made it so that if you entered a URL | 20:41 |
rickspencer3 | instead of doing an image search, it would scrape images from that page | 20:41 |
rickspencer3 | while I was at it, I also let the user type in a url directly to a photo and loaded that | 20:41 |
rickspencer3 | I think the web image search functionality is really fun to use | 20:41 |
rickspencer3 | like, "it would be funny if a picture of a cat were here" | 20:41 |
rickspencer3 | type "cats" | 20:42 |
rickspencer3 | and then you can get the cat, use the clipping tool, and drag it where you want | 20:42 |
rickspencer3 | I'll pause to see if there are questions now | 20:42 |
rickspencer3 | ok | 20:42 |
rickspencer3 | so the next major change I made was from toolbar buttons to normal buttons | 20:43 |
rickspencer3 | the motivation was this: | 20:43 |
rickspencer3 | Changing size, rotation, and opacity required the user to click the button once for each increment. | 20:43 |
rickspencer3 | So rotating something to be upside required the user to go "click click click click", etc... | 20:43 |
rickspencer3 | What I wanted was the user to click the button, and hold it down as the image rotated, and then to stop when it was positioned as desired. | 20:43 |
rickspencer3 | Sadly, there is no "key-down" event on gtk.Toolbars. | 20:43 |
rickspencer3 | well, gtk.ToolButtons, I mean | 20:43 |
rickspencer3 | So I had to switch Photobomb from using toolbars to using regular gtk.Button. | 20:43 |
rickspencer3 | I achieved the layout by using a gtk.Table | 20:44 |
rickspencer3 | I also created a new quickly.widget.PressAndHold widget to add press and hold functionality | 20:44 |
rickspencer3 | I accomplish the asynch behavior with gobject.timeout_add(250, self.__tick). | 20:44 |
rickspencer3 | At each tick the button emits a signal telling the consuming app to do something. | 20:44 |
rickspencer3 | Questions? | 20:44 |
ClassBot | M49 asked: Does it check license metadata for pictures? | 20:45 |
rickspencer3 | nope | 20:45 |
rickspencer3 | that might be a nice feature to add though | 20:45 |
rickspencer3 | especially if this is something that concerns you | 20:45 |
rickspencer3 | but I don't think it's pertinent to the way I envisioned folks using photobomb | 20:46 |
rickspencer3 | basically, making funny pictures from themselves and their friends | 20:46 |
rickspencer3 | ok | 20:46 |
rickspencer3 | last section is on the Social Network Integration | 20:46 |
rickspencer3 | this was almost all achieved with Gwibber | 20:46 |
rickspencer3 | Because Gwibber uses desktopcouch to store messages in Lucid, | 20:46 |
rickspencer3 | I could add the feature to grovel through the messages and extract images coming from social feeds to display. | 20:47 |
rickspencer3 | Of course, this will only work in Lucid ;) | 20:47 |
rickspencer3 | I also sniped Gwibber's fb credentials from desktopcouch, and used that and some FML to get images from Facebook. | 20:47 |
rickspencer3 | so your gwibber tab of the notebook loads up all the images in feeds you subscribe to, and also any images in facebook ... | 20:47 |
rickspencer3 | that are tagged with any of your friends so long as the image has been modified in the last 5 days | 20:48 |
rickspencer3 | I think this aspect of photobomb is really fun | 20:48 |
rickspencer3 | converging your personal feeds into an app that is designed to mash 'em all up | 20:48 |
rickspencer3 | I used the Gwibber API to add broadcasting Photobomb images. | 20:48 |
rickspencer3 | The GooCanvas renders a png that is saved to a temp location. | 20:49 |
rickspencer3 | Then pycurl uploads the image to imgur.com, which returns a url. | 20:49 |
rickspencer3 | Gwibber's GwibberPosterVBox to broadcast the URL. | 20:49 |
rickspencer3 | So that | 20:49 |
rickspencer3 | s the photobomb showcase | 20:49 |
rickspencer3 | I would love finish off photobomb sometime and let folks have fun with it | 20:49 |
rickspencer3 | but I've been a bit busy | 20:49 |
rickspencer3 | there are few bugs here and there, some of them quite annoying, as they involve frozen UI | 20:50 |
rickspencer3 | so, 10 minutes left | 20:50 |
rickspencer3 | happy to discuss anything now, answer any questions | 20:50 |
rickspencer3 | ok | 20:51 |
rickspencer3 | I'm going to call that a wrap, then | 20:51 |
rickspencer3 | thanks all for coming! | 20:51 |
rickspencer3 | and if anyone wants to contribute to photobomb in any way | 20:51 |
rickspencer3 | I am totally open to that' | 20:51 |
rickspencer3 | it's more fun working on these things together ;) | 20:51 |
=== ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - http://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi |
Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!