# 程式設計期末報告
## Pygame實作 Flappy Bird
---
# pygame是什麽
----
-跨平台的python庫
-專為電子游戲設計
---
# 代碼
---
# 游戲對象
----
## 玩家
```
class Player(pygame.sprite.Sprite):
def __init__(self):
self.pos = pygame.Vector2(100,100)
self.death = False
self.rect = self.draw()
def draw(self):
return pygame.draw.circle(screen,"black",self.pos,10)
def fly(self):
self.pos.y -= FLY
def update(self):
self.pos.y += GRAVITY
self.rect = self.draw()
if 0 >= self.pos.y or self.pos.y >= SCREEN_HEIGTH:
self.death = True
def get_PosX(self):
return self.pos.x
def get_death(self):
return self.death
def set_death(self):
self.death = True
```
----
## 墻壁
```
walls = pygame.sprite.Group()
class Wall(pygame.sprite.Sprite):
def __init__(self,y,h,p):
pygame.sprite.Sprite.__init__(self,walls)
self.image = pygame.Surface([40,h])
self.image.fill('red')
self.rect = self.image.get_rect()
self.rect.x = SCREEN_WIDTH
self.rect.y = y
self.scored = True
self.pos = p
if self.pos == 'b':
self.scored = False
def update(self):
self.rect.x -= 1
if self.rect.x == -40:
self.kill()
def get_Pos(self):
return self.rect.x
def set_scored(self):
self.scored = False
def get_scored(self):
return self.scored
```
----
## 按鈕
```
class button(pygame.sprite.Sprite):
def __init__(self,x,y,color='white',text='button',onclickFunction=None,onePress=False):
pygame.sprite.Sprite.__init__(self,ui)
self.buttonSurf = pygame.Surface([x,y])
self.buttonSurf.fill(color)
self.caption = text
self.rect = self.buttonSurf.get_rect()
self.buttonCap = font.render(self.caption,True,color)
self.alreadyPressed = False
self.clicked = False
self.onclickFunction = onclickFunction
def process(self):
mousePos = pygame.mouse.get_pos()
if self.rect.collidepoint(mousePos):
if pygame.mouse.get_pressed(num_buttons=3)[0]:
if not self.alreadyPressed:
self.onclickFunction()
self.alreadyPressed = True
else:
self.alreadyPressed = False
self.buttonSurf.blit(self.buttonSurf, [
self.rect.width/2 - self.buttonSurf.get_rect().width/2,
self.rect.height/2 - self.buttonSurf.get_rect().height/2
])
screen.blit(self.buttonSurf, self.rect)
```
---
## 游戲機制
----
## 飛行
```
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
player.fly()
```
----
## 生成墻壁
```
if pygame.time.get_ticks()- t > 2000:
t = pygame.time.get_ticks()
h = random.randint(SCREEN_HEIGTH*0.2,SCREEN_HEIGTH*0.8)
Wall(0,h,'t')
Wall(h+SCREEN_HEIGTH*0.1,SCREEN_HEIGTH,'b')
```
----
## 碰撞偵測
#### 分數和死亡
```
for w in walls:
if w.get_Pos()+40 < player.get_PosX() and w.get_scored():
w.set_scored()
score += 1
if player.rect.colliderect(w.rect):
player.set_death()
```
```
def update(self):
self.pos.y += GRAVITY
self.rect = self.draw()
if 0 >= self.pos.y or self.pos.y >= SCREEN_HEIGTH:
self.death = True
```
----
## GAME OVER
```
if player.get_death() == True:
death_surface = font.render("GAME OVER",True,'red')
screen.blit(death_surface,(SCREEN_WIDTH*0.5,SCREEN_HEIGTH*0.5))
running = False
```
----
## 刷新畫面
```
#wall
self.image = pygame.Surface([40,h])
self.image.fill('red')
self.rect = self.image.get_rect()
```
```
score_surface = font.render("Score = %d" %(score), True, 'black')
screen.blit(score_surface,(SCREEN_WIDTH*0.1,SCREEN_HEIGTH*0.1))
pygame.display.flip()
```
---
# Pygame的優缺點
### 缺點
-性能弱
-資源少
### 優點
—易上手
-學習游戲開發的機制
---
# 完整代碼
```
import pygame,random
'''constant'''
SCREEN_WIDTH = 800
SCREEN_HEIGTH = 720
dt = 0
FLY = 5
GRAVITY = 2
pygame.font.init()
font = pygame.font.SysFont('arial', 36)
run = True
# pygame setup
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGTH))
ui = pygame.sprite.Group()
class Player(pygame.sprite.Sprite):
def __init__(self):
self.pos = pygame.Vector2(100,100)
self.death = False
self.rect = self.draw()
def draw(self):
return pygame.draw.circle(screen,"black",self.pos,10)
def fly(self):
self.pos.y -= FLY
def update(self):
self.pos.y += GRAVITY
self.rect = self.draw()
if 0 >= self.pos.y or self.pos.y >= SCREEN_HEIGTH:
self.death = True
def get_PosX(self):
return self.pos.x
def get_death(self):
return self.death
def set_death(self):
self.death = True
walls = pygame.sprite.Group()
class Wall(pygame.sprite.Sprite):
def __init__(self,y,h,p):
pygame.sprite.Sprite.__init__(self,walls)
self.image = pygame.Surface([40,h])
self.image.fill('red')
self.rect = self.image.get_rect()
self.rect.x = SCREEN_WIDTH
self.rect.y = y
self.scored = True
self.pos = p
if self.pos == 'b':
self.scored = False
def update(self):
self.rect.x -= 1
if self.rect.x == -40:
self.kill()
def get_Pos(self):
return self.rect.x
def set_scored(self):
self.scored = False
def get_scored(self):
return self.scored
class button(pygame.sprite.Sprite):
def __init__(self,x,y,color='white',text='button',onclickFunction=None,onePress=False):
pygame.sprite.Sprite.__init__(self,ui)
self.buttonSurf = pygame.Surface([x,y])
self.buttonSurf.fill(color)
self.caption = text
self.rect = self.buttonSurf.get_rect()
self.buttonCap = font.render(self.caption,True,'black')
self.alreadyPressed = False
self.clicked = False
self.onclickFunction = onclickFunction
def process(self):
mousePos = pygame.mouse.get_pos()
if self.rect.collidepoint(mousePos):
if pygame.mouse.get_pressed(num_buttons=3)[0]:
if not self.alreadyPressed:
self.onclickFunction()
self.alreadyPressed = True
else:
self.alreadyPressed = False
self.buttonSurf.blit(self.buttonSurf, [
self.rect.width/2 - self.buttonSurf.get_rect().width/2,
self.rect.height/2 - self.buttonSurf.get_rect().height/2
])
screen.blit(self.buttonSurf, self.rect)
'''
the groups of wall
and the sprite should add player together
'''
def flappyBird():
player = Player()
t = 0
score = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
print(pygame.mouse.get_pos())
screen.fill("white")
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
player.fly()
player.update()
if pygame.time.get_ticks()- t > 2000:
t = pygame.time.get_ticks()
h = random.randint(SCREEN_HEIGTH*0.2,SCREEN_HEIGTH*0.8)
Wall(0,h,'t')
Wall(h+SCREEN_HEIGTH*0.1,SCREEN_HEIGTH,'b')
if player.get_death() == True:
death_surface = font.render("GAME OVER",True,'red')
screen.blit(death_surface,(SCREEN_WIDTH*0.5,SCREEN_HEIGTH*0.5))
running = False
walls.draw(screen)
walls.update()
for w in walls:
if w.get_Pos()+40 < player.get_PosX() and w.get_scored():
w.set_scored()
score += 1
if player.rect.colliderect(w.rect):
player.set_death()
score_surface = font.render("Score = %d" %(score), True, 'black')
screen.blit(score_surface,(SCREEN_WIDTH*0.1,SCREEN_HEIGTH*0.1))
pygame.display.flip()
dt = 300 * clock.tick(60) / 1000
for w in walls:
w.kill()
button(50 ,50 ,'yellow','START',flappyBird)
while run:
screen.fill('white')
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
print(pygame.mouse.get_pos())
for obj in ui:
obj.process()
pygame.display.flip()
dt = 300 * clock.tick(60) / 1000
pygame.quit()
```
{"metaMigratedAt":"2023-06-18T04:30:26.111Z","metaMigratedFrom":"YAML","title":"程式設計期末報告","breaks":true,"contributors":"[{\"id\":\"ee37cc63-c7a0-42f0-abc2-ea87d4f77359\",\"add\":8783,\"del\":51}]"}