Tuesday, December 30, 2008

Breakout example code using Python and Pygame

Python is a great language that puts the 'fun' back in programming. Here's an example that uses the Pygame library to create a game Breakout in 159 lines of code.

"""
A Simple Breakout Example
Paul Vincent Craven
"""


# --- Import libraries used for this program
# System libraries that come with python
import os, sys
import math
# Pygame library from http://www.pygame.org/
import pygame
from pygame.locals import *

# Define some colors
black = (0,0,0)
white = (255,255,255)
blue = (0,0,255)
green = (0,255,0)
red = (255,0,0)
purple = (0xBF,0x0F,0xB5)

# This function loads a sound
def load_sound(name):
try:
sound = pygame.mixer.Sound(name)
except pygame.error, message:
print 'Cannot load sound:', name
raise SystemExit, message
return sound

# This class represents each block that will get knocked out by the ball
# It derives from the "Sprite" class in Pygame
class Block(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block, and its x and y position
def __init__(self,color,x,y,setspeed,setscore):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Class variables to hold the height and width of the block
self.width=20
self.height=15
self.speed=setspeed
self.score=setscore
# Create the image of the block of appropriate size
# The width and height are sent as a list for the first parameter.
self.image = pygame.Surface([self.width, self.height])
# Fill the image with the appropriate color
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
self.rect = self.image.get_rect()
# Move the top left of the rectangle to x,y.
# This is where our block will appear..
self.rect.topleft = (x,y)

# This class represents the ball
# It derives from the "Sprite" class in Pygame
class Ball(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block, and its x and y position
def __init__(self):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Class attributes for width and height
self.width=10
self.height=10
self.speed=.2
# A list with the x and y of our ball. (This is the starting position)
self.mypos = ([0.0,180.0])
# Direction in degrees (zero is straight up)
self.direction=200
# Speed in pixels per cycle
self.speed=0.3
# Create the image of the ball
self.image = pygame.Surface([self.width, self.height])
# Color the ball
self.image.fill((white))
# Get a rectangle object that shows where our image is
self.rect = self.image.get_rect()
# Get attributes for the height/width of the screen
self.screenheight = pygame.display.get_surface().get_height()
self.screenwidth = pygame.display.get_surface().get_width()

# This function will bounce the ball off a horizontal surface (not a verticle one)
def bounce(self,diff):
self.direction = (180-self.direction)%360
self.direction -= diff

# Update the position of the ball
def update(self):
# Sine and Cosine work in degrees, so we have to convert them
direction_radians = math.radians(self.direction)
# Change the position (x and y) according to the speed and direction
self.mypos[0] += self.speed * math.sin(direction_radians)
self.mypos[1] -= self.speed * math.cos(direction_radians)
# Update the rectangle of the ball so that it is at mypos
self.rect.left=self.mypos[0]
self.rect.top=self.mypos[1]
# Do we bounce off the top of the screen?
if self.mypos[1] <= 0:
self.bounce(0)
self.mypos[1]=1
# Do we bounce off the left of the screen?
if self.mypos[0] <= 0:
self.direction = (360-self.direction)%360
self.mypos[0]=1
# Do we bounce of the right side of the screen?
if self.mypos[0] > self.screenwidth-self.width:
self.direction = (360-self.direction)%360
self.mypos[0]=self.screenwidth-self.width-1

if self.mypos[1] > 600:
return True
else:
return False

# This class represents the bar at the bottom that the player controls
class Player(pygame.sprite.Sprite):
# Constructor function
def __init__(self):
# Call the parent's constructor
pygame.sprite.Sprite.__init__(self)

self.width=75
self.height=15
self.image = pygame.Surface([self.width, self.height])
self.image.fill((white))

# Make our top-left corner the passed-in location.
self.rect = self.image.get_rect()
self.screenheight = pygame.display.get_surface().get_height()
self.screenwidth = pygame.display.get_surface().get_width()
print "Screen height",self.screenheight
self.rect.topleft = (0,self.screenheight-self.height)

# Update the player
def update(self):
# Get where the mouse is
pos = pygame.mouse.get_pos()
# Set the left side of the player bar to the mouse position
self.rect.left = pos[0]
# Make sure we don't push the player paddle off the right side of the screen
if self.rect.left > self.screenwidth - self.width:
self.rect.left = self.screenwidth - self.width

# This is the main function where our program begins
def main():
score = 0
# Call this function so the Pygame library can initialize itself
pygame.init()
# Create an 800x600 sized screen
screen = pygame.display.set_mode([800, 600])
# Set the title of the window
pygame.display.set_caption('Breakout')
# Enable this to make the mouse dissappear when over our window
#pygame.mouse.set_visible(0)
# This is a font we use to draw text on the screen (size 36)
font = pygame.font.Font(None, 36)

# Create a surface we can draw on
background = pygame.Surface(screen.get_size())
# Used for converting color maps and such
background = background.convert()
# Fill the screen with a black background
background.fill(black)

# Create the player paddle object
player = Player()
# Create the ball
ball = Ball()
# Create a group of 1 ball (used in checking collisions)
balls = pygame.sprite.Group()
balls.add(ball)

# Create a group that will hold the blocks we are about to create
blocks=pygame.sprite.RenderPlain()
# The top of the block (y position)
top = 80
# Number of blocks to create
blockcount = 40

# Create a row of purple blocks
for i in range(0,blockcount):
# Create a block (color,x,y,new ball speed,points)
block=Block(purple,i*20,top,.85,30)
blocks.add(block)
top += 15
#Blue
for i in range(0,blockcount):
block=Block(blue,i*20,top,.7,20)
blocks.add(block)

top += 15
# Green
for i in range(0,blockcount):
block=Block(green,i*20,top,.55,15)
blocks.add(block)
top += 15
#Yellow
for i in range(0,blockcount):
block=Block(([255,255,0]),i*20,top,.4,10)
blocks.add(block)
top += 15
# Red
for i in range(0,blockcount):
block=Block(red,i*20,top,.3,5)
blocks.add(block)


movingsprites = pygame.sprite.RenderPlain((player,ball))
clock = pygame.time.Clock()
block_hit_sound = load_sound('chink.wav')
block_hit_sound.play()
done = False
while 1:
clock.tick(1000)

for event in pygame.event.get():
if event.type == QUIT:
return

if not done:
# Update the player and ball positions
player.update()
done = ball.update()

# If we are done, print game over
if done:
text=font.render("Game Over", 1, (200, 200, 200))
textpos = text.get_rect(centerx=background.get_width()/2)
textpos.top = 300
background.blit(text, textpos)
print "Game Over"

# See if the ball hits the player paddle
if pygame.sprite.spritecollide(player, balls, False):
# The 'diff' lets you try to bounce the ball left or right depending where on the paddle you hit it
diff = (player.rect.left + player.width/2) - (ball.rect.left+ball.width/2)
# Set the ball's y position in case we hit the ball on the edge of the paddle
ball.rect.top = screen.get_height() - player.rect.height - ball.rect.height -1
ball.bounce(diff)

# Check for collisions between the ball and the blocks
deadblocks = pygame.sprite.spritecollide(ball, blocks, False)
# For every block we hit:
for b in deadblocks:
# Speed up the ball if we hit a block that causes ball speed up
if ball.speed < b.speed:
ball.speed = b.speed
# Add to our score
score += b.score
# Remove the block from the list of blocks
blocks.remove(b)
# If we actually hit a block, bounce the ball and play a sound
if len(deadblocks) > 0:
block_hit_sound.play()
ball.bounce(0)

# Print the score
scoreprint = "Score: "+str(score)
clearrect = Rect(0,0,250,30)
pygame.draw.rect(background,black,clearrect)
text = font.render(scoreprint, 1, white)
textpos = (0,0)
background.blit(text, textpos)

#Draw Everything
screen.blit(background, (0, 0))
movingsprites.draw(screen)
blocks.draw(screen)
pygame.display.flip()

#this calls the 'main' function when this script is executed
if __name__ == '__main__': main()

Monday, December 15, 2008

Spying On The Homefront

This article in Newsweek is a nice summary of Thomas Tamm's work as a whistle-blower. The U.S. Government set up rooms in major telecoms that allowed them to wiretap virtually everyone in the United States. Is was illegal, as wiretaps require a court order.

So if it was illegal, why isn't anyone in jail? Congress passed a law giving retro-active immunity to telecoms. The constitutionality of that law is in question.

Tamm's life has been ruined, with mounting debt from hiring lawyers to defend him. The government would like him to plead guilty for disclosure of classified information. The fact that the U.S. was breaking the law was classified.

Technological advances in data-mining have created new tools that can be used for law enforcement. Tools that our current law does not support. Have we gotten anything useful by having the government wiretaps? Frontline did a great piece on how New Year's Eve parties were almost canceled in Las Vegas because of a translation error with a wiretap. But I'm unaware if any legitimate plot has been uncovered in return for no longer requiring a warrent.

We need to have a rational conversation as a country about the new tools technology supplies our society, and how to balance it against citizen rights.

Wednesday, December 3, 2008

Dad makes the paper

My dad made the paper today for his volunteer work helping seniors choose the best drug plan.

Friday, November 14, 2008

Salisbury House

Last night the Central Iowa IEEE chapter had their annual meeting at the Salisbury House. IEEE got one of the electricians who worked on the house restoration to give a tour. We got to see parts of the Salisbury house you don't normally get to tour. It was an impressive job. The Salisbury house has a lot of concrete, so outfitting the place with sprinklers, an alarm system, security cameras, and modern wiring was no easy task. They did a good job, in the places where the restoration is complete, you don't really notice their work.

The Salisbury House is a worth-while stop for anyone in the Des Moines area. If you haven't been there in a few years, it is worth checking out the restoration work.

While I'd like to have a house like that, there is no way I could afford their $12,000 per month heating bill in the winter.

Saturday, October 25, 2008

Excellent Logitech Harmony Customer Service

A few months ago we bought a Logitech Harmony 670 Remote. We had an older Harmony remote before this, and really liked it.

Unfortunately the new remote stopped working properly after about a month. About four of the buttons failed to do anything at all.

After having me go though several reasonable attempts at trying to fix the remote, the tech support individual concluded it was a bad unit, and had a new one shipped out to me. I was surprised, good customer service is hard to come by.

So not only do I recommend the Logitech Harmony 670 Remote, I'll also recommend them for their customer support. Well done Logitech!

Wednesday, October 8, 2008

Ballooning Photos

Several years back, I got camera-happy at one of the National Balloon Classic events. This was before digital cameras were popular. The cost of the film and printing was over $200. But the real issue was, what do I do with all those photos?

Well, that question is easier to answer today. Not only has digital photography made taking photos cheaper, it has also opened up great ways to share the photos. You can create slide shows, like a relative of mine did with photos from the 2008 National Balloon Classic. You can see them here. I've also gotten a book created by Shutterfly with these photos. Shutterfly allows you to create a very high-quality book with your photos. And of course, sites like flickr, pbase, and picasa easily allow sharing photos on-line.

Sunday, October 5, 2008

The Hobbit

Today our family went to see The Hobbit, a play put on at The Des Moines Playhouse. As usual, it was a good production. I really liked the stage construction, particularly with the dragon. The acting was well done too.

The KG Children's Theater does a really good job. For many years I thought they put on some lame puppet shows or something. Quite the contrary, they put a massive amount of work into it. I highly recommend their plays, even if you aren't a kid anymore.

Wednesday, August 20, 2008

Using NBC.com to watch the Olympics

Shawn Johnson's gold-winning balance beam routine was too late for my daughter to watch. So I thought I could cruise to the Internet to watch it. Here's what it took:
  1. Search on-line for the video.
  2. Find lots of You-Tube videos
  3. All the You-Tube videos want you to go to some blog to watch. No thanks, probably a trick to download malware. I'll go the legit route and try to watch at NBC.com
  4. Go to NBC.com.
  5. Click on Olympic coverage, right up front.
  6. Click on 'find by sport'
  7. Scroll way down to gymnastics.
  8. See Shawn Johnson, click 'download'
  9. Oops, no download. I got a 'DRM' check screen.
  10. I'm told it doesn't support Firefox without a Windows Media Player plug-in.
  11. Search for WMP on-line.
  12. Find the 'official' plug-in at a place that isn't Microsoft.
  13. Try to see if this is malware or not.
  14. Cross fingers and install.
  15. Repeat steps 4-9.
  16. Plug-in doesn't work at all.
  17. Bitch about having to use IE. Thankfully, I'm not on my Linux computer at work.
  18. Open IE. Repeat steps 4-9.
  19. At DRM screen, I can now click 'play test video'
  20. Now I can finally click 'Download now'! (Didn't I already do this a few times?)
  21. Oops, no download. I have to install "NBC Direct"
  22. Grumble about adding more crap to my computer just because I want to watch a video
  23. Tell IE it is ok to install a new program
  24. Click 'run'
  25. Tell Vista's User Access Control it is ok to run the program
  26. Read ra-ra intro screen from NBC.
  27. Click 'continue'
  28. Read 3,500 word license agreement.
  29. Click 'I agree'
  30. Wait while some progress bars flash
  31. Get presented with a screen to sign in, or create an account.
  32. Bitch that after all this, now I have to create an account so they can spam me with e-mail too.
  33. Click 'Create New Account'.
  34. Get scary alert box saying I have chosen to receive "HIGH QUALITY" video downloads. Oh, any I'll be joined to an NBC P2P network. Am I sure I want to proceed?
  35. I'm not, but I click 'Yes' anyway.
  36. I get a form to fill out. Some fields are yellow, some white.
  37. Figure only the yellow is required.
  38. Bitch I have to give a 'descriptive name' for this computer. WTF? I just want to watch one video?
  39. Enter required info.
  40. Oh, no the white fields are required too. I have to tell my zip code and birth date.
  41. Make up a zip code and birth date.
  42. Click continue.
  43. Get a message that the registration servers are down. No account was created.
  44. Click my only option, quit.
  45. Cuss a lot.
  46. Repeat steps 17-42.
  47. Pray servers are up.
  48. Get message that my e-mail is already registered.
  49. Hit back a lot, and log in with the account I was told in step 43 that wasn't created.
  50. Again, I have to enter a descriptive name for this computer.
  51. Scary dialog saying ATTENTION! and HIGH QUALITY pops up again.
  52. Click 'Yes'
  53. Wait while progress bars flash. Something about "OpenCASE". Hopefully other customer know more about what that is than I do.
  54. Get "Install is about to start" dialog. Crap, I'm just now starting to install? It says it should take about 10 minutes.
  55. Cuss.
  56. Click 'continue'
  57. Notice this whole NBC Direct thing is 'Beta'. Is that safe?
  58. Oh, great, the install puts another icon on my desktop. It didn't even ask. Kind of arrogant to assume it is so important that it deserves to live on my desktop, isn't it?
  59. Congratulations, I'm not ready to start using NBC direct.
  60. Oh, if you skip registration you get STANDARD QUALITY video. Not that HIGH QUALITY they talked about before. Hm, did I register or not?
  61. Click 'close'
  62. Oh, now I can register. What the hell was I doing before, if I wasn't registering?
  63. Click 'register'
  64. Says I haven't registered my e-mail, please click 'resend'
  65. Click close, because there is no 'resend'
  66. Now I can click 'resend'
  67. Ooh boy, my request is being process. And they spell "You'll" with a box in place of the apostrophe. Classy.
  68. Open my email.
  69. Find registration confirmation.
  70. Click on link
  71. Get a page saying I'm confirmed. Click to customize my profile to get started. Hey folks, this is step 71, and I haven't even started yet?
  72. Ignore that web page. Switch apps and go back to Direct Beta, click close
  73. Click 'register'
  74. A new dialog pops up. Hey! Important update. An operating system patch is required to use this beta!
  75. What? I keep my OS up with the required Microsoft patches. Why do I have to download an OS patch from NBC to watch one silly 3 minute video? Should NBC be patching my operating system?
  76. It says I just have to 'click here' to get the required patch
  77. I get a dialog warning me I'll have to restart the machine after installing the patch.
  78. Oh, and after the restart, please try running NBC direct again.
  79. Click on the link. Get option to open a file. Also get warning about running files downloaded from the Internet from untrusted sources.
  80. My wife come in, asks what I'm up to.
  81. I tell her.
  82. My wife points out I've been home an hour, and have yet to help my daughter with her homework.
  83. Finally I give up. I then try to explain to my daughter why she can't watch Shawn on the balance beam.
  84. "That's ok," my daughter says. "While I was waiting for you, they showed it again on TV."

Friday, August 15, 2008

Creating Presentations with Beamer

I like to use Beamer to create presentations with LaTeX. I love the slides it creates, and I'm not a big PowerPoint fan.

I have found this simple page of examples to be of more use than the 224 page Beamer manual. I mean, really, who has the time to read that?

Saturday, July 26, 2008

The wicker and nylon rods to form my new balloon basket.
Posted by Picasa
Here we show how the nylon rod will come up through the basket floor. The wicker will be woven around the nylon rods.
Posted by Picasa
In this photo, I'm staining a piece of 3/4" Ash plywood that will be the floor of my new basket.
Posted by Picasa
2008 National Balloon Classic
Posted by Picasa
2008 National Balloon Classic
Posted by Picasa
2008 National Balloon Classic
Posted by Picasa
2008 National Balloon Classic Parade
Posted by Picasa
2008 National Balloon Classic
Posted by Picasa

Thursday, July 17, 2008

Updated design


Ok, Don Piccard has informed me that cross-braces with a basket have been tried before, and they don't work so well. I've had other suggestions of using nylon webbing as a 'cross-brace' to prevent sagging. I like that idea. So here's an updated design, showing the nylon rods for basket weaving:

Designing a balloon basket

I've been spending a fair bit of time trying to design a new basket for my balloon.

Originally, I wanted to make a rounded bottom on the basket. Basically, a 6" quarter circle arc on the bottom. That led to so many complications, I gave up on it.

The next question is how to frame the basket. Baskets can be susceptible to 'sag'. Unless something in the basket design works against shearing stress, this can be a problem.

My Balloon Works basket has six vertical wooden rods about 1.25" in diameter. This has worked OK, but it there are no cross pieces to really prevent shearing. Head Balloons appears to use an aluminum top bar, with some extensions that go down.

I'm thinking of the design below. It uses a 2" wide ash board, 13/16" thick. The vertical pieces would be woven into the wicker, but not the cross beams. The cross beams would be on the inside.


The frame should be about 30.2 pounds. If I use boards 1.5" wide instead, it takes the weight down to 22.6 pounds. I used Google Sketchup and this table for wood weights. The basket will be a lot heavier than a going with a composite basket. I need to do a final calculation and see if it will be close to my current Balloon Works.

For the wicker, I'm figuring 3/8" nylon rod every 2". I note that Head uses two 1/4" nylon rods.

I'm not sure about the load cables yet. Wire cables would conduct electricity. Rope might give way in a fire. Nylon webbing definitely would. I'd like the cables connected somehow so if one side fails, the opposite side doesn't go with it.

I also have to plan out how to mount the burners. I'm thinking semi-rigid with a commercial burner that uses a liquid pilot light.

The jury's still out to lunch on what I'll do, but I hope to start Monday.

Sunday, June 22, 2008

Balloons in June

This weekend Clinton Iowa had their Balloons in June festival. We had a nice night-glow Friday. Saturday was weathered out. Sunday morning had wonderful weather.

For Sunday morning, we took off out of Clinton, and flew over the flooded Mississippi river. Here is a photo looking back at the Clinton airport:

2008 Clinton 030

And one looking down the Mississippi:

2008 Clinton 060

The rest of the Balloons in June photos are on Flickr.

Wednesday, June 4, 2008

Creating Web-Based Flash Games

Another student created a Flash game called Air Battle. I really love the sound effects that he uses. Probably the biggest surprise was managing ActionScript 2 vs. ActionScript 3.

Click to play Air Battle Game.

Creating a 3D movie using Blender

Over Simpson's May term (a full class taught in three weeks), seven students created a 3D computer generated movie. The movie was created with software called Blender. Most of them had little, if any, experience with Blender.

The results were great. I'd love to see what could be done if they had longer than three weeks. This video talks about how it was made:



And this is the video itself:

Wednesday, May 14, 2008

Fish husbandry

Earlier this year I bought a porcupine puffer fish for my home fish tank. I got the fish from the local Petco rather than Adam's Aquatics. Petco is much cheaper, although their selection is poor.

Well, the Petco fish had "Ich", or something similar. I should have put the fish in a quarantine tank before putting it in my main tank, because soon all my fish got it. My Regal Tang really got hit.

I set up a 55 gal tank in the basement, and moved all the fish to it. Then I added copper sulfate, available as some kind of snail killing product in the fish store. That cleared the ich up in a couple weeks. Unfortunately the Regal Tang continued to fair poorly.

After five and a half weeks, I moved all the fish back to the main tank, in hopes to get the Regal Tang feeling better. Unfortunately I lost that fish, and the ich came back. I should have waited longer to break the parasite's cycle.

Now "Dory" rests in peace, buried in our garden. She has her own sign, courtesy of my daughter. The other fish are back in the quarantine tank, and the ich appears to be clearing up. This time I'll probably wait eight weeks.

The fish tank I maintain at Simpson has had serious problems with red slime. That tank doesn't have a protein skimmer, which is one of the best defenses against it. I finally tried Chemi-Clean. I don't know what is in it, but it did manage to clear up most of the red slime after a couple treatments. I didn't lose any fish or snails either, which is good.

Later this summer, I should be upgrading that tank to one with an in-tank overflow, and a protein skimmer in the sump.

Monday, May 12, 2008

Blender and cloth simulations

I've found Blender 2.46 RC4 to be a bit buggy when dealing with cloth. Here's one of the more obvious looking ones:

video

Sunday, May 11, 2008

Jello Cubes From Heaven 2.0

Multi-colored Jello Cubes:

video

Saturday, May 10, 2008

Jello Cubes From Heaven

Short movie created with Blender 2.46 RC 4:

video

I have a 640x480 resolution version of the video at 198 MB. The ray tracing looks pretty good with it. But it is too big to post.

Creating 3D Movies

Have you enjoyed watching movies such as Ice Age, The Incredibles, or Toy Story? Want to know how you can do it too, for free? By using Blender - the free 3D modeling program! Attend the premier showing of "Recursion" and learn more about how a student-lead May Term class created their own 3D animation with Blender in just 3 weeks. Come on over and watch this movie, eat some pizza, and learn about what you may be able to do in the years to come.

Following the presentation Alejandro Saenz will also be showing off the project he has been working on this May Term. Alejandro has been busy creating a web-based game utilizing Adobe Flash.

CIS-290 Presents "Recursion" by:
-Patrick Carlson
-Steve Pilling
-Tim Fairfield
-Clinton Bradfield
-Heather Elliot
-Carl Davidson
-Wes Kocher

Alejandro Presents "A Flash Game."

Date:
Thursday, May 15, 2008
Time:
8:00pm - 9:00pm
Location:
Jordan Lecture Hall - Carver
City/Town:
Indianola, IA

Friday, April 25, 2008

Web development

I enjoyed "The Mother of all Interfaces" posting at The Daily WTF. With a lot of fancy high-paid architects, a simple application can be made horribly complex, slow, and unreliable.

In my day, we created a fully user-customizable portal with full session fail-over, that processed user requests in less than 10 ms. All this while running on a Pentium Pro. (We also had to walk to work, uphill, both ways.)

I dislike many web frameworks for the multitude of unnecessary abstractions and layers they add to a system. KISS.

Saturday, April 19, 2008

Earthquakes & TV

Well, I got a chance to experience an earthquake. I woke up at 4:30 am on Friday, but wasn't sure if it really was an earthquake. Later I saw in the news that it was an earthquake.

Alyssa's become quite fascinated by Mythbusters lately. Even to the point where she wants to watch it over Disney later. I've liked Build It Bigger lately. I like the show's host, although it is hard to find it on.

Battlestar Galactica is off to a strong fourth season. The third season ended rather weakly.