In 1981 or so, my brother and I were 12 and 13 years old and we both had paper routes. We pooled the fruits of our paper carrier jobs, and Dad took us down to the Alberta Treasury Branch where he co-signed a $1200 personal loan at a whopping 23% interest so that we could buy our first personal computer– a TI-99/4. In fact it was the first personal computer anyone had in our neighbourhood. We poured over the accompanying manuals, got all sorts of books from the library, and subscribed to 99er magazine. These early computer enthusiast magazines offered articles about the future of computing, ads for enticing new peripherals and gadgets, and most importantly programs. Each magazine contained printouts– recipes I guess, for dozens of programs. We learned to program by painstakingly copying programs from printouts in these magazines, even more painstakingly debugging our errors then figuring out how to fix the inevitable mistakes in the magazine’s code.
30 year later, as I make the transition from SCRATCH, to PYTHON, I find myself transported back to the same learning process. As I undertook to learn a new programming language, I found myself seeking out familiar “Teach yourself programming by copying these game’ books. But this time I did not need to go to the magazine stand, or the library, or order in by mail. The resources are all a google away. I think it says something about my personal learning style that I chose the cookbook style of print resources over the many multimedia and video tutorials available on youtube.
I’ve spent most of the last week trying to understand some of the basic structure and commands of python, as I worked my way through a variety of tutorial programs. First impression is compared to scratch there is alot more fiddly typing and figuring out exactly how to initialize then execute each step. Unlike scratch, it is much harder in python to just poke around and see what will happen. If you don`t know the precise order, structure, and syntax for any small part… the whole program may not even start. I think here is a fundamental difference between Scratch and python. Constructivist philosophy is at the core SCRATCH. It is designed to be explored, tinkered with and discovered. On the other hand, Python is designed to be functional, readable, and infinitely extensible. Alex Martelli, author of the Python Cookbook, summed up the Python Philosophy:
To describe something as clever is not considered a compliment in the Python culture.” Python’s philosophy rejects the Perl “there is more than one way to do it” approach to language design in favor of “there should be one—and preferably only one—obvious way to do it”. From: Python Programming Language on Wikipedia.
Bricka by codeNtronix
and here is my revised source code for Bricka.
''' bricka (a breakout clone) Developed by Leonel Machava <firstname.lastname@example.org> http://codeNtronix.com with revisions by Sean McGaughey http://edalchemy.mcgaughey.ca during Creative Computing Online Workshop ''' import sys, pygame from pygame.locals import * SCREEN_SIZE = 640,480 # Object dimensions BRICK_WIDTH = 60 BRICK_HEIGHT = 15 PADDLE_WIDTH = 60 PADDLE_HEIGHT = 12 BALL_DIAMETER = 16 BALL_RADIUS = int(BALL_DIAMETER / 2) #source code was just BALL_DIAMETER / 2 This through an error of floating point vs Int error # I added an int function to make sure it is an integer value MAX_PADDLE_X = SCREEN_SIZE - PADDLE_WIDTH MAX_BALL_X = SCREEN_SIZE - BALL_DIAMETER MAX_BALL_Y = SCREEN_SIZE - BALL_DIAMETER # Paddle Y coordinate PADDLE_Y = SCREEN_SIZE - PADDLE_HEIGHT - 10 # Color constants BLACK = (0,0,0) WHITE = (255,255,255) BLUE = (0,0,255) BRICK_COLOR = (200,200,0) # State constants STATE_BALL_IN_PADDLE = 0 STATE_PLAYING = 1 STATE_WON = 2 STATE_GAME_OVER = 3 mousex = 0 #x coordinate of mouse event mousey = 0 # y coordinate of mouse event class Bricka: def __init__(self): pygame.init() self.screen = pygame.display.set_mode(SCREEN_SIZE) pygame.display.set_caption('bricka (a breakout clone by codeNtronix.com)') self.clock = pygame.time.Clock() if pygame.font: self.font = pygame.font.Font('freesansbold.ttf',20) else: self.font = None self.init_game() def init_game(self): self.lives = 3 self.score = 0 self.state = STATE_BALL_IN_PADDLE self.paddle = pygame.Rect(300,PADDLE_Y,PADDLE_WIDTH,PADDLE_HEIGHT) self.ball = pygame.Rect(300,PADDLE_Y - BALL_DIAMETER,BALL_DIAMETER,BALL_DIAMETER) self.ball_vel = [5,-5] self.create_bricks() def create_bricks(self): y_ofs = 35 self.bricks =  for i in range(7): x_ofs = 35 for j in range(8): self.bricks.append(pygame.Rect(x_ofs,y_ofs,BRICK_WIDTH,BRICK_HEIGHT)) x_ofs += BRICK_WIDTH + 10 y_ofs += BRICK_HEIGHT + 5 def draw_bricks(self): for brick in self.bricks: pygame.draw.rect(self.screen, BRICK_COLOR, brick) def check_input(self): for event in pygame.event.get(): # event handling loop if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE): pygame.quit() sys.exit() elif event.type == MOUSEMOTION: # I added these mouse controls. It works well. mousex, mousey = event.pos if mousex >= MAX_PADDLE_X: self.paddle.left = MAX_PADDLE_X else: self.paddle.left = mousex elif event.type == MOUSEBUTTONUP: mousex, mousey = event.pos self.paddle.left = mousex mouseClicked = True if self.state == STATE_BALL_IN_PADDLE: self.state = STATE_PLAYING keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.paddle.left -= 5 if self.paddle.left < 0: self.paddle.left = 0 if keys[pygame.K_RIGHT]: self.paddle.left += 5 if self.paddle.left > MAX_PADDLE_X: self.paddle.left = MAX_PADDLE_X if keys[pygame.K_SPACE] and self.state == STATE_BALL_IN_PADDLE: self.state = STATE_PLAYING elif keys[pygame.K_RETURN] and (self.state == STATE_GAME_OVER or self.state == STATE_WON): self.init_game() def move_ball(self): self.ball.left += self.ball_vel self.ball.top += self.ball_vel if self.ball.left <= 0: self.ball.left = 0 self.ball_vel = -self.ball_vel elif self.ball.left >= MAX_BALL_X: self.ball.left = MAX_BALL_X self.ball_vel = -self.ball_vel if self.ball.top < 0: self.ball.top = 0 self.ball_vel = -self.ball_vel elif self.ball.top >= MAX_BALL_Y: self.ball.top = MAX_BALL_Y self.ball_vel = -self.ball_vel def handle_collisions(self): for brick in self.bricks: if self.ball.colliderect(brick): self.score += 3 self.ball_vel = -self.ball_vel self.bricks.remove(brick) break if len(self.bricks) == 0: self.state = STATE_WON if self.ball.colliderect(self.paddle): self.ball.top = PADDLE_Y - BALL_DIAMETER self.ball_vel = -self.ball_vel elif self.ball.top > self.paddle.top: self.lives -= 1 if self.lives > 0: self.state = STATE_BALL_IN_PADDLE else: self.state = STATE_GAME_OVER def show_stats(self): if self.font: font_surface = self.font.render('SCORE: ' + str(self.score) + ' LIVES: ' + str(self.lives), False, WHITE) self.screen.blit(font_surface, (205,5)) def show_message(self,message): if self.font: size = self.font.size(message) font_surface = self.font.render(message,False, WHITE) x = (SCREEN_SIZE - size) / 2 y = (SCREEN_SIZE - size) / 2 self.screen.blit(font_surface, (x,y)) def run(self): while 1: for event in pygame.event.get(): # I added these lines from Sweigart, making Games with Python if event.type == pygame.QUIT: sys.exit # To check for Quit self.clock.tick(50) self.screen.fill(BLACK) self.check_input() if self.state == STATE_PLAYING: self.move_ball() self.handle_collisions() elif self.state == STATE_BALL_IN_PADDLE: self.ball.left = self.paddle.left + self.paddle.width / 2 self.ball.top = self.paddle.top - self.ball.height self.show_message('PRESS SPACE TO LAUNCH THE BALL') elif self.state == STATE_GAME_OVER: self.show_message('GAME OVER. PRESS ENTER TO PLAY AGAIN') elif self.state == STATE_WON: self.show_message('YOU WON! PRESS ENTER TO PLAY AGAIN') self.draw_bricks() # Draw paddle pygame.draw.rect(self.screen, BLUE, self.paddle) # Draw ball pygame.draw.circle(self.screen, WHITE, (self.ball.left + BALL_RADIUS, self.ball.top + BALL_RADIUS), BALL_RADIUS) self.show_stats () pygame.display.flip() if __name__ == '__main__': Bricka().run()
Here is my first attempt at programming a game in Scratch from November of 2011.