安裝 PyGame
In [1]:
!conda install -y --channel https://conda.anaconda.org/CogSci pygame
最簡單的骨架
In [1]:
# import pygame
import pygame
from pygame.locals import *
# 初始化
pygame.init()
# 設定螢幕視窗
DISPLAYSURF = pygame.display.set_mode((640, 480))
# main event loop
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
優雅的結束
In [2]:
import pygame
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
# 設定一個變數 running 用來判斷是遊戲是否在跑
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
# 將 running 設成 False
running = False
一點畫面 (兩個小問題)
In [3]:
import pygame
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
# 設定視窗標題
pygame.display.set_caption('你好!')
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
# 用顏色 (0,0,255) 填滿畫面
DISPLAYSURF.fill( (0,0,255))
#畫一個圓
pygame.draw.circle(DISPLAYSURF, (255,255,0), (100,100), 50)
# 真的更新到硬體
#pygame.display.update()
In [4]:
import pygame
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
# 設定視窗標題
pygame.display.set_caption('你好!')
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
if not running:
break
# 試著畫出一個笑臉
DISPLAYSURF.fill( (0,0,255))
pygame.draw.circle(DISPLAYSURF, (255,255,0), (100,100), 50)
# 畫弧形
pygame.draw.arc(DISPLAYSURF, (255,0,0), (100-25,100, 50, 30), -3.14, 0, 3)
pygame.display.update()
先將畫出笑臉的步驟整理成一個函數
In [5]:
import pygame
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
# 畫圖函數
def draw_smiley(x,y):
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
# 請填入你的畫圖程式碼
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
if not running:
break
# 呼叫函數
DISPLAYSURF.fill( (0,0,255))
draw_smiley(100,100)
draw_smiley(200,200)
pygame.display.update()
In [6]:
import pygame
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
# 取得時鐘
fpsClock = pygame.time.Clock()
def draw_smiley(x,y):
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x-20,y-15), 10)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x+20,y-15), 10)
pygame.draw.arc(DISPLAYSURF, (255,0,0), (x-25,y, 50, 30), -3.14, 0, 3)
# 設定一開始的位置
x,y = 300,300
# 設定初速度。 dx, dy 代表 dt 移動的距離
dx, dy = 2, 2
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
if not running:
break
# 更新位置
x+=dx
y+=dy
# 這裡,增加程式碼,試試看,讓笑臉碰到邊界時可以反彈
# 當 x > 600 或 x < 0 時, 讓 dx = -dx
# 當 y > 400 或 y < 0 時, 讓 dy = -dy
# 在 x,y 位置畫出笑臉
DISPLAYSURF.fill( (0,0,255))
draw_smiley(x,y)
pygame.display.update()
# 等到下一個畫格 (60fps)
fpsClock.tick(60)
增加一點亂數
In [7]:
import pygame
from pygame.locals import *
# import 隨機亂數
from random import random
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
fpsClock = pygame.time.Clock()
def draw_smiley(x,y):
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x-20,y-15), 10)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x+20,y-15), 10)
pygame.draw.arc(DISPLAYSURF, (255,0,0), (x-25,y, 50, 30), -3.14, 0, 3)
x,y = 300,300
dx, dy = 2, 2
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
if not running:
break
x+=dx
y+=dy
# 讓反彈時的速度有點變化
if x > 590 or x < 50:
dx = -dx+0.5*(random()-0.5)
if y > 430 or y < 50:
dy = -dy+0.5*(random()-0.5)
DISPLAYSURF.fill( (0,0,255))
# 因為現在 x,y 是浮點數, 所以要記得轉成整數
draw_smiley(int(x),int(y))
pygame.display.update()
fpsClock.tick(60)
In [8]:
import pygame
from pygame.locals import *
from random import random
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
fpsClock = pygame.time.Clock()
def draw_smiley(x,y):
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x-20,y-15), 10)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x+20,y-15), 10)
pygame.draw.arc(DISPLAYSURF, (255,0,0), (x-25,y, 50, 30), -3.14, 0, 3)
x,y = 300,300
dx, dy = 2, 2
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
# 當 event 是 KEYDOWN 時
elif event.type == KEYDOWN:
# 印出 event
print event
#if event.key == K_RIGHT:
# dx+=1
# 請處理其他方向
if not running:
break
x+=dx
y+=dy
if x > 590 or x < 50:
dx = -dx+0.5*(random()-0.5)
if y > 430 or y < 50:
dy = -dy+0.5*(random()-0.5)
DISPLAYSURF.fill( (0,0,255))
draw_smiley(int(x),int(y))
pygame.display.update()
fpsClock.tick(60)
處理滑鼠輸入
In [9]:
import pygame
from pygame.locals import *
from random import random
pygame.init()
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
fpsClock = pygame.time.Clock()
def draw_smiley(x,y):
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x-20,y-15), 10)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x+20,y-15), 10)
pygame.draw.arc(DISPLAYSURF, (255,0,0), (x-25,y, 50, 30), -3.14, 0, 3)
x,y = 300,300
dx, dy = 2, 2
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
elif event.type == KEYDOWN:
if event.key == K_RIGHT:
dx += 1
elif event.key == K_LEFT:
dx -= 1
elif event.key == K_UP:
dy -= 1
elif event.key == K_DOWN:
dy += 1
# 按下滑鼠按鈕的事件
elif event.type == MOUSEBUTTONDOWN:
# 觀察滑鼠 event
print event
# event,pos[0], event.pos[1] 分別是滑鼠按下去的 x,y 座標
# 下面請寫出程式碼, 讓笑臉從現在的座標 x,y, 慢慢移動到 event.pos
if not running:
break
x+=dx
y+=dy
if x > 590 or x < 50:
dx = -dx+0.5*(random()-0.5)
if y > 430 or y < 50:
dy = -dy+0.5*(random()-0.5)
DISPLAYSURF.fill( (0,0,255))
draw_smiley(int(x),int(y))
pygame.display.update()
fpsClock.tick(60)
加上食物
In [3]:
import pygame
from pygame.locals import *
# import randint 函數
from random import random, randint
pygame.init()
# 設定字型和標籤, 用來顯示分數
font = pygame.font.SysFont("monospace", 32, bold=True)
score_label = font.render("score: 0", 1, (255,255,255))
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
fpsClock = pygame.time.Clock()
def draw_smiley(x,y):
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x-20,y-15), 10)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x+20,y-15), 10)
pygame.draw.arc(DISPLAYSURF, (255,0,0), (x-25,y, 50, 30), -3.14, 0, 3)
x,y = 300,300
dx, dy = 2, 2
# 隨機產生座標
def random_pos():
return (randint(0,639), randint(0,479))
# 產生五個隨機的食物
food_pos = [random_pos() for i in range(5)]
# 定義分數
score = 0
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
elif event.type == KEYDOWN:
if event.key == K_RIGHT:
dx += 1
elif event.key == K_LEFT:
dx -= 1
elif event.key == K_UP:
dy -= 1
elif event.key == K_DOWN:
dy += 1
elif event.type == MOUSEBUTTONDOWN:
dx, dy = event.pos[0]-x, event.pos[1]-y
r = (dx**2+dy**2)**0.5
if r!=0:
dx, dy = dx/r, dy/r
if not running:
break
x+=dx
y+=dy
if x > 590 or x < 50:
dx = -dx+0.5*(random()-0.5)
if y > 430 or y < 50:
dy = -dy+0.5*(random()-0.5)
# 接下來要處理吃掉食物這件事情
# "之後"的食物狀態
new_food_pos = []
for pos in food_pos:
# 如果笑臉和食物的距離夠近, 就吃掉食物
if (pos[0]-x)**2 + (pos[1]-y)**2 < 55**2:
# 增加分數
score += 1
score_label = font.render("score: %d"%score, 1, (255,255,255))
# 生出一個新的食物
pos = random_pos()
# 將 pos 加入新的食物位置狀態
new_food_pos.append(pos)
# 將 food_pos 設定成處理後的狀態
food_pos = new_food_pos
DISPLAYSURF.fill( (0,0,255))
draw_smiley(int(x),int(y))
# 在每個有食物的位置, 畫一個綠色的小圓圈代表食物
for pos in food_pos:
pygame.draw.circle(DISPLAYSURF, (0,255,0), pos, 5)
# 顯示分數
DISPLAYSURF.blit(score_label, (10, 10))
pygame.display.update()
fpsClock.tick(60)
增加敵人
In [1]:
import pygame
from pygame.locals import *
# import randint 函數
from random import random, randint
pygame.init()
font = pygame.font.SysFont("monospace", 32, bold=True)
# 結束的字型
font_gg = pygame.font.SysFont("monospace", 72, bold=True)
score_label = font.render("score: 0", 1, (255,255,255))
# 顯示生命
life_label = font.render("life: 10", 1, (255,255,255))
# Game Over 文字
game_over_label = font_gg.render("Game Over", 1, (255,100, 100))
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
fpsClock = pygame.time.Clock()
def draw_smiley(x,y):
DISPLAYSURF.fill( (0,0,255))
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x-20,y-15), 10)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x+20,y-15), 10)
pygame.draw.arc(DISPLAYSURF, (255,0,0), (x-25,y, 50, 30), -3.14, 0, 3)
x,y = 300,300
dx, dy = 2, 2
def random_pos():
return (randint(0,639), randint(0,479))
food_pos = [random_pos() for i in range(5)]
# 產生隨機的敵人位置和方向
def random_enemy():
if randint(0,1):
direction = (-2,0)
position = (700, randint(20, 460))
else:
direction = (0, -2)
position = (randint(20, 620), 520)
return direction, position
# 產生五個隨機敵人
enemy_dir = []
enemy_pos = []
for i in range(5):
direction, position = random_enemy()
enemy_dir.append(direction)
enemy_pos.append(position)
# 定義分數
score = 0
# 生命數量
life = 10
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
# 生命值 > 0 才可以操作
elif life>0 and event.type == KEYDOWN:
if event.key == K_RIGHT:
dx += 1
elif event.key == K_LEFT:
dx -= 1
elif event.key == K_UP:
dy -= 1
elif event.key == K_DOWN:
dy += 1
# 生命值 > 0 才可以操作
elif life>0 and event.type == MOUSEBUTTONDOWN:
dx, dy = event.pos[0]-x, event.pos[1]-y
r = (dx**2+dy**2)**0.5
if r!=0:
dx, dy = dx/r, dy/r
if not running:
break
x+=dx
y+=dy
if x > 590 or x < 50:
dx = -dx+0.5*(random()-0.5)
if y > 430 or y < 50:
dy = -dy+0.5*(random()-0.5)
new_food_pos = []
for pos in food_pos:
if (pos[0]-x)**2 + (pos[1]-y)**2 < 55**2:
score += 1
score_label = font.render("score: %d"%score, 1, (255,255,255))
pos = random_pos()
new_food_pos.append(pos)
food_pos = new_food_pos
# 處理敵人
for i in range(5):
direction = enemy_dir[i]
position = enemy_pos[i]
# 更新位置
position = (position[0]+direction[0], position[1]+direction[1])
# 超過邊界時, 製造新敵人
if position[0] < 0 or position[1]<0:
direction, position = random_enemy()
# 和笑臉很接近時, 生命減少, 製造新敵人
elif (position[0]-x)**2 + (position[1]-y)**2 < 55**2:
life -= 1
life_label = font.render("life: %d"%life, 1, (255,255,255))
direction, position = random_enemy()
enemy_dir[i] = direction
enemy_pos[i] = position
draw_smiley(int(x),int(y))
for pos in food_pos:
pygame.draw.circle(DISPLAYSURF, (0,255,0), pos, 5)
# 畫出敵人
for pos in enemy_pos:
pygame.draw.circle(DISPLAYSURF, (255,0, 0), pos, 5)
# 生命值 <=0 時結束
if life <= 0:
life = dx = dy = 0
DISPLAYSURF.blit(game_over_label, (150, 200))
# 顯示生命
DISPLAYSURF.blit(life_label, (450, 10))
DISPLAYSURF.blit(score_label, (10, 10))
pygame.display.update()
fpsClock.tick(60)
聲音
In [1]:
import pygame
from pygame.locals import *
from random import random, randint
pygame.init()
font = pygame.font.SysFont("monospace", 32, bold=True)
font_gg = pygame.font.SysFont("monospace", 72, bold=True)
score_label = font.render("score: 0", 1, (255,255,255))
life_label = font.render("life: 10", 1, (255,255,255))
game_over_label = font_gg.render("Game Over", 1, (255,100, 100))
DISPLAYSURF = pygame.display.set_mode((640, 480))
pygame.display.set_caption('你好!')
fpsClock = pygame.time.Clock()
# 讀取聲音
eat_sound_effect = pygame.mixer.Sound('pacman_eatfruit.wav')
damage_sound_effect = pygame.mixer.Sound('pacman_eatghost.wav')
def draw_smiley(x,y):
DISPLAYSURF.fill( (0,0,255))
pygame.draw.circle(DISPLAYSURF, (255,255,0), (x,y), 50)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x-20,y-15), 10)
pygame.draw.circle(DISPLAYSURF, (0,0,0), (x+20,y-15), 10)
pygame.draw.arc(DISPLAYSURF, (255,0,0), (x-25,y, 50, 30), -3.14, 0, 3)
x,y = 300,300
dx, dy = 2, 2
def random_pos():
return (randint(0,639), randint(0,479))
food_pos = [random_pos() for i in range(5)]
def random_enemy():
if randint(0,1):
direction = (-2,0)
position = (700, randint(20, 460))
else:
direction = (0, -2)
position = (randint(20, 620), 520)
return direction, position
enemy_dir = []
enemy_pos = []
for i in range(5):
direction, position = random_enemy()
enemy_dir.append(direction)
enemy_pos.append(position)
score = 0
life = 10
running = True
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
elif life>0 and event.type == KEYDOWN:
if event.key == K_RIGHT:
dx += 1
elif event.key == K_LEFT:
dx -= 1
elif event.key == K_UP:
dy -= 1
elif event.key == K_DOWN:
dy += 1
elif life>0 and event.type == MOUSEBUTTONDOWN:
dx, dy = event.pos[0]-x, event.pos[1]-y
r = (dx**2+dy**2)**0.5
if r!=0:
dx, dy = dx/r, dy/r
if not running:
break
x+=dx
y+=dy
if x > 590 or x < 50:
dx = -dx+0.5*(random()-0.5)
if y > 430 or y < 50:
dy = -dy+0.5*(random()-0.5)
new_food_pos = []
for pos in food_pos:
if (pos[0]-x)**2 + (pos[1]-y)**2 < 55**2:
score += 1
# 撥放聲音
eat_sound_effect.play()
score_label = font.render("score: %d"%score, 1, (255,255,255))
pos = random_pos()
new_food_pos.append(pos)
food_pos = new_food_pos
for i in range(5):
direction = enemy_dir[i]
position = enemy_pos[i]
position = (position[0]+direction[0], position[1]+direction[1])
if position[0] < 0 or position[1]<0:
direction, position = random_enemy()
elif (position[0]-x)**2 + (position[1]-y)**2 < 55**2:
damage_sound_effect.play()
life -= 1
life_label = font.render("life: %d"%life, 1, (255,255,255))
direction, position = random_enemy()
enemy_dir[i] = direction
enemy_pos[i] = position
draw_smiley(int(x),int(y))
for pos in food_pos:
pygame.draw.circle(DISPLAYSURF, (0,255,0), pos, 5)
for pos in enemy_pos:
pygame.draw.circle(DISPLAYSURF, (255,0, 0), pos, 5)
if life <= 0:
life = dx = dy = 0
DISPLAYSURF.blit(game_over_label, (150, 200))
DISPLAYSURF.blit(life_label, (450, 10))
DISPLAYSURF.blit(score_label, (10, 10))
pygame.display.update()
fpsClock.tick(60)
In [ ]: