1. 程式人生 > >Tkinter做彈球遊戲

Tkinter做彈球遊戲

要求:小球撞擊到牆壁的時候,會反彈,當碰到球拍的時候,也會反彈,如果碰到底部的時候,遊戲結束,輸出總共碰撞了多少次。

控制程式執行的類(paddleball.py)

#!/usr/bin/python
#coding: utf-8

#from __future__ import unicode_literals

from Tkinter import *
# from the_ball import Ball
import random
import time

class Paddle:
	'球拍類'
	def __init__(self, canvas, color):
		self.canvas = canvas
		self.id = canvas.create_rectangle(0, 0, 100, 10, fill = color)
		self.canvas.move(self.id, 250, 400)
		
		# x為左右移動的時候每一步的距離
		self.x = 0
		# 左右移動的速度
		self.speed = 2
		# 獲取畫布的寬度
		self.canvas_width = self.canvas.winfo_width()
		
		# 處理事件,當點擊向左向右的時候作出反應
		self.canvas.bind_all('<KeyPress-Left>', self.turn_left)
		self.canvas.bind_all('<KeyPress-Right>', self.turn_right)
		
		self.canvas.bind_all('<KeyPress-Down>', self.reduce_speed)
		self.canvas.bind_all('<KeyPress-Up>', self.increase_speed)
	
	def draw(self):
		self.canvas.move(self.id, self.x, 0)
		pos = self.canvas.coords(self.id)
		
		# 設定如果碰到邊界就自動反彈
		if pos[0] <= 0:
			self.x = self.speed
		elif pos[2] >= self.canvas_width:
			self.x = -self.speed
	
	def turn_left(self, event):
		self.x = -self.speed
	
	def turn_right(self, event):
		self.x = self.speed
	
	# 注意:速度的更新只有在碰到牆壁或者是改變移動方向的時候才有用,不然的話不會對速度改變產生影響
	
	def increase_speed(self, event):
		'增加移動的速度'
		if self.speed == 5:
			self.speed = 5
		elif self.speed < 5:
			self.speed += 1
	
	def reduce_speed(self, event):
		'減少移動的速度'
		if self.speed == 1:
			self.speed = 1
		elif self.speed > 1:
			self.speed -= 1
		

小球的類(the_ball.py)
#!/usr/bin/python
#coding: utf-8

#from __future__ import unicode_literals

from Tkinter import *
# from the_paddle import Paddle
import random
import time

class Ball:
	'''
	球類
	接收傳遞過來的兩個引數,畫布和小球的顏色
	'''
	def __init__(self, canvas, paddle, color):
		self.canvas = canvas
		self.paddle = paddle
		# 畫圓
		self.id = canvas.create_oval(10, 10, 25, 25, fill = color)
		self.canvas.move(self.id, 245, 245)
		
		# 設定起始時的x的所有可能取值
		self.starts = [-3, -2, -1, 1, 2, 3]
		# 重排,
		random.shuffle(self.starts)
		# 初始變數x為starts[0],y為-1
		self.x = self.starts[0]
		self.y = -3
		# winfo_height 函式用來獲取畫布當前的高度
		self.canvas_height = self.canvas.winfo_height()
		self.canvas_width = self.canvas.winfo_width()
		# 判斷輸贏,通過是否撞擊到底部判斷
		self.hit_bottom = False
		
		# 統計撞擊次數
		self.sum = 0
	
	def hit_paddle(self, pos):
		# 獲得木板此時的id
		paddle_pos = self.canvas.coords(self.paddle.id)
		# 判斷是否相撞
		if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
			if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
				self.sum += 1
				return True
		return False
	
	def draw(self):
		'draw函式中每次轉換方向的時候都使用了random函式的方法,目的是增加隨機性'
		self.canvas.move(self.id, self.x, self.y)
		# 畫布函式coords,通過id來返回畫布上任何畫好的東西的當前的x和y的座標
		# 返回四個值
		# 前兩個表示的是左上角的座標
		# 後兩個表示的是右下角的座標
		# 都是先x後y
		pos = self.canvas.coords(self.id)
		#print(pos)
		if pos[1] <= 0: # 表示的是左上角的y
			self.y = abs(self.starts[random.randrange(6)])
		elif pos[3] >= self.canvas_height:
			self.hit_bottom = True
			# self.y = -abs(self.starts[random.randrange(6)])
		elif pos[0] <= 0:
			self.x = abs(self.starts[random.randrange(6)])
		elif pos[2] >= self.canvas_width:
			self.x = -abs(self.starts[random.randrange(6)])
		
		# 如果撞擊到木板,把y軸的方向反轉
		if self.hit_paddle(pos) == True:
			self.y = -self.y

球拍的類(the_paddle.py)
#!/usr/bin/python
#coding: utf-8

#from __future__ import unicode_literals

from Tkinter import *
# from the_ball import Ball
import random
import time

class Paddle:
	'球拍類'
	def __init__(self, canvas, color):
		self.canvas = canvas
		self.id = canvas.create_rectangle(0, 0, 100, 10, fill = color)
		self.canvas.move(self.id, 250, 400)
		
		# x為左右移動的時候每一步的距離
		self.x = 0
		# 左右移動的速度
		self.speed = 2
		# 獲取畫布的寬度
		self.canvas_width = self.canvas.winfo_width()
		
		# 處理事件,當點擊向左向右的時候作出反應
		self.canvas.bind_all('<KeyPress-Left>', self.turn_left)
		self.canvas.bind_all('<KeyPress-Right>', self.turn_right)
		
		self.canvas.bind_all('<KeyPress-Down>', self.reduce_speed)
		self.canvas.bind_all('<KeyPress-Up>', self.increase_speed)
	
	def draw(self):
		self.canvas.move(self.id, self.x, 0)
		pos = self.canvas.coords(self.id)
		
		# 設定如果碰到邊界就自動反彈
		if pos[0] <= 0:
			self.x = self.speed
		elif pos[2] >= self.canvas_width:
			self.x = -self.speed
	
	def turn_left(self, event):
		self.x = -self.speed
	
	def turn_right(self, event):
		self.x = self.speed
	
	# 注意:速度的更新只有在碰到牆壁或者是改變移動方向的時候才有用,不然的話不會對速度改變產生影響
	
	def increase_speed(self, event):
		'增加移動的速度'
		if self.speed == 5:
			self.speed = 5
		elif self.speed < 5:
			self.speed += 1
	
	def reduce_speed(self, event):
		'減少移動的速度'
		if self.speed == 1:
			self.speed = 1
		elif self.speed > 1:
			self.speed -= 1
		

在命令列中輸入

python paddleball.py

執行以後執行的環境,



當然,也可以把上面的程式碼進行打包,生成可執行的exe檔案,使用py2exe,

百度下載py2exe即可

打包要用的setup.py檔案如下

#!/usr/bin/python
#coding: utf-8


#from __future__ import unicode_literals

from distutils.core import setup
import py2exe

setup(console = ['paddleball.py'])

進入到setup.py檔案所在的資料夾,執行python setup.py py2exe

如果沒有錯誤的話會生成dist和build這兩個資料夾。

在dist資料夾下面有一個paddleball.exe的exe檔案,雙擊執行即可。

提示:對於所有的程式碼,最好都放在同一個資料夾,避免不必要的錯誤