[原创]python打小球游戏
jerryfleming
|
1#
jerryfleming 发表于 2007-03-21 16:31
[原创]python打小球游戏
去年国庆节写的
[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/python
# -*- coding: utf-8 -*- ############################################################################### # Brick & Ball in Python Script # # by Jerry Fleming <jerryfleming2006@gmail.com> # # # # This is a small game inspired from similar one in Motorola Mobile C289, # # and my first game in Python Script :) As I am a newbie to Python script, # # please tell me if you have a better implementation or any suggestions. # # # # CONVENSIONS: # # Variable i and j stards for the row and column of bricks, while x and y # # indicates its coordinates. # # # # HISTORY: # # 2006-10-01: second (current) version with tkinter # # 2006-04-19: first version with curses # # # # TODO: # # Nothing to do right now :) If you have any ideas to improve or enhance it, # # please contact me. # ############################################################################### from Tkinter import * from tkMessageBox import askyesno, showinfo from string import split from random import randint # globals for bricks (adjust these values for different board size) {{{ ROWS = 5 COLS = 10 # the row and column of bricks to be displayed WIDTH = 40 HEIGHT = 15 # the size of bricks GAP = 8 # the interval between rows and columns of bricks, and between bricks # and the play board DIAMETER = 10 # the DIAMETER of the ball SPEED = 10 # normal speed of ball BGCOLOR = '#a586ca' FILLCOLOR = '#000000' LINECOLOR = '#000000' GAPCOLOR = '#ff0000' # the following are automatically updated, do not edit BOARD_WIDTH = (WIDTH + GAP) * COLS + GAP # the width of the board BOARD_HEIGHT = (HEIGHT + GAP) * ROWS * 3 # the height of the board CNT = ROWS * COLS # total number of bricks USAGE = "Use left or right arrow to move the pad so as to bounce the ball to hit bricks and score." # }}} globals # functions {{{ def movePad(event): # {{{ ''' Move the pad to catch the ball. This is the only user input. ''' global pad, move if event.keysym == 'Left': move = -10 if event.keysym == 'Right': move = 10 pad = pad + move if pad < - GAP/2: move = 0 pad = - GAP/2 if pad > BOARD_WIDTH - WIDTH + GAP/2: move = 0 pad = BOARD_WIDTH - WIDTH + GAP/2 board.move(padID, move, 0) # }}} def movePad def moveBall(): # {{{ ''' Move the ball to a direction continuously. ''' global CNT board.move(ballID, direction[0], direction[1]) ball[0] = ball[0] + direction[0] ball[1] = ball[1] + direction[1] hits = board.find_overlapping( ball[0], ball[1], ball[0] + DIAMETER, ball[1] + DIAMETER ) # delete the brick if hit for brick in hits: if brick == ballID: continue elif brick == padID: bounceBall() else: board.delete(brick) CNT = CNT - 1 if CNT == 0: quitGame('Level') direction[1] = - direction[1] SCORE.set(SCORE.get() + SPEED/10) # hit right edge if ball[0] + DIAMETER >= BOARD_WIDTH: direction[0] = - direction[0] # hit left edge if ball[0] <= 0: direction[0] = - direction[0] # hit top edge if ball[1] <= 0: direction[1] = - direction[1] # hit the bottom: game over if ball[1] + DIAMETER >= BOARD_HEIGHT: quitGame('Over') if STATE.get() == 'Normal': root.after(SPEED, moveBall) # }}} def moveBall def bounceBall(): # {{{ # hit pad from left if direction[0] > 0 and ball[0] + DIAMETER <= pad + direction[0]: direction[0] = - abs(direction[0]) # hit pad from right if direction[0] < 0 and ball[0] >= pad + WIDTH + direction[0]: direction[0] = abs(direction[0]) direction[1] = - abs(direction[1]) # }}} def bounceBall def quitGame(msg='Quit'): # {{{ ''' Set the game state to and confirm quitting. ''' STATE.set(msg) if msg == 'Quit' and not askyesno(msg, 'Are you sure to quit the game?'): STATE.set('Normal') moveBall() elif msg == 'Level' and askyesno(msg, 'Do you want to continue?'): STATE.set('Normal') moveBall() startGame() else: if msg == 'Over': showinfo('Game Over', 'Game is over. You need more practice!') root.destroy() root.quit() # }}} def quitGame def pauseGame(): # {{{ if PAUSE.get() == 'Pause': PAUSE.set('Resume') STATE.set('Pause') elif PAUSE.get() == 'Resume': PAUSE.set('Pause') STATE.set('Normal') moveBall() # }}} def pauseGame def startGame(): # {{{ ''' Start a new session of the game. ''' global ball, pad, direction STATE.set('Normal') PAUSE.set('Pause') for i in range(1, ROWS + 1): for j in range(1, COLS + 1): bricks[i][j] = board.create_rectangle( j * (WIDTH + GAP) - WIDTH + GAP/2, i * (HEIGHT + GAP) - HEIGHT, j * (WIDTH + GAP), i * (HEIGHT + GAP), outline=LINECOLOR, fill=FILLCOLOR, stipple='gray25', width=1 ) pad = randint(WIDTH, BOARD_WIDTH - WIDTH) ball[1] = BOARD_HEIGHT - DIAMETER * 3 ball[0] = randint(DIAMETER, BOARD_WIDTH - DIAMETER) while abs(ball[0] - pad) < DIAMETER: ball[0] = randint(DIAMETER, BOARD_WIDTH - DIAMETER) board.coords(padID, pad, BOARD_HEIGHT - HEIGHT, pad + WIDTH, BOARD_HEIGHT) board.coords(ballID, ball[0], ball[1], ball[0] + DIAMETER, ball[1] + DIAMETER) direction = [1, -1] # }}} def startGame # }}} functions # window initialization {{{ root = Tk() root.title("Brick & Ball - a Python Game") root.geometry = str(BOARD_WIDTH + 100) + 'x' + str(BOARD_HEIGHT) root.resizable(width = False, height = False) root.iconbitmap('geofuture16.ico') SCORE = IntVar(root) # score over sessions STATE = StringVar(root) # game state: 0 for normal, 1 for pause PAUSE = StringVar(root) # switch to pause and resume board = Canvas( root, width = BOARD_WIDTH, height = BOARD_HEIGHT, borderwidth = 1, background = BGCOLOR, highlightbackground = GAPCOLOR) board.pack(side = LEFT) panel = Frame( root, width = 100, height = BOARD_HEIGHT, borderwidth = 1, background = BGCOLOR, highlightthickness = 2, highlightbackground = GAPCOLOR) panel.pack(side = RIGHT, fill=Y) ballID = board.create_oval( 0, 0, DIAMETER, DIAMETER, outline=LINECOLOR, fill=FILLCOLOR, width=1) padID = board.create_rectangle( 0, 0, WIDTH, HEIGHT, outline=LINECOLOR, fill=FILLCOLOR, width=1) txt1 = Label( panel, text='STATE', font=('Arial', '13', 'bold'), anchor=CENTER, background=BGCOLOR, foreground=FILLCOLOR) txt1.pack() txtState = Label( panel, textvariable=STATE, font=('Arial', '13'), anchor=CENTER, background=GAPCOLOR, foreground=FILLCOLOR) txtState.pack() txt2 = Label( panel, text='SCORE', font=('Arial', '13', 'bold'), anchor=CENTER, background=BGCOLOR, foreground=FILLCOLOR) txt2.pack() txtScore = Label( panel, textvariable=SCORE, font=('Arial', '13'), anchor=CENTER, background=GAPCOLOR, foreground=FILLCOLOR) txtScore.pack() txt3 = Label( panel, text='AUTHOR', font=('Arial', '13', 'bold'), anchor=CENTER, background=BGCOLOR, foreground=FILLCOLOR) txt3.pack() txt3t = Label( panel, text="Jerry\nFleming\n" + u'\u90b5\u52a0\u8d85', font=('Arial', '13'), anchor=CENTER, background=GAPCOLOR, foreground=FILLCOLOR) txt3t.pack() txt4 = Label(panel, text=USAGE, anchor=CENTER, wraplength = 100, background=BGCOLOR, foreground=FILLCOLOR) txt4.pack() btn = Button(panel, textvariable=PAUSE, font=('Arial', '10', 'bold'), pady = 2, command=pauseGame) btn.pack() root.protocol('WM_DELETE_WINDOW', quitGame) board.bind_all('<Right>', movePad) board.bind_all('<Left>', movePad) # global marks for ball and pad ball = [0, BOARD_HEIGHT - DIAMETER] pad = 0 direction = [0, 0] move = 0 bricks = [ [1 for j in range(COLS + 1)] for i in range(ROWS + 1)] # }}} window initialization # game starts here {{{ if __name__ == "__main__": startGame() moveBall() root.mainloop() # }}} game start # mode line {{{ # Local variables: # tab-width: 3 # c-basic-offset: 3 # End: # # vim: tw=80:sw=3:ts=3:ft=python:fdm=marker: # }}} |