Python是一門(mén)非常簡(jiǎn)單的語(yǔ)言访忿,快速入門(mén)之后可以做很多事情橱乱!比如爬蟲(chóng)啊,數(shù)據(jù)分析啊,自動(dòng)化運(yùn)維啊伴网,機(jī)器學(xué)習(xí)麦箍,量化分析等等应闯!
但是入門(mén)到進(jìn)階的過(guò)程有時(shí)會(huì)非常痛苦期丰,如果有一些好玩有趣的例子就好了。比如通過(guò)游戲來(lái)學(xué)編程是一個(gè)非常好的途徑敌完,大概就200多行储耐,非常不錯(cuò)!
1滨溉、打飛機(jī)的游戲
打飛機(jī)的游戲估計(jì)很多人都玩過(guò)什湘,雷霆戰(zhàn)機(jī)相信很多80后的小伙伴都玩過(guò)!Python也能開(kāi)發(fā)這樣的飛機(jī)射擊游戲晦攒,而且代碼量還不大.
2闽撤、代碼量200多行
看起來(lái)打飛機(jī)的游戲應(yīng)該蠻復(fù)雜的吧,結(jié)果我看了作者的源代碼之后脯颜,發(fā)現(xiàn)才200多行哟旗!而且結(jié)構(gòu)非常清晰完整,最重要的人家不僅代碼寫(xiě)的漂亮,注釋非常完整闸餐,讓別人看的一目了然饱亮,好的代碼習(xí)慣真的很重要,德藝雙馨耙锞蕖近尚!
1.代碼的結(jié)構(gòu)
2.游戲的角色文件gameRole
整個(gè)游戲分三個(gè)角色,下面我一一來(lái)解釋一下场勤,思路其實(shí)非常清晰的。
1).一個(gè)是子彈:
初始化子彈的圖片歼跟,然后得到它在畫(huà)布上的坐標(biāo)和媳,并控制它的移動(dòng)速度
2).敵機(jī)
會(huì)隨機(jī)出一堆敵人的飛機(jī),直管往前沖哈街,從屏幕的上方往下方蜂擁而至留瞳,不需要考慮其他的行為!
敵機(jī)有幾個(gè)重要的屬性骚秦,比如它的飛行圖片和擊落的圖片她倘,然后獲取的屏幕上的坐標(biāo)。敵機(jī)的行為就一個(gè)飛作箍,而且是只會(huì)往前飛硬梁。
3).我方戰(zhàn)機(jī)
# 玩家類(lèi)
class Player(pygame.sprite.Sprite):
def __init__(self, plane_img, player_rect, init_pos):
pygame.sprite.Sprite.__init__(self)
self.image = [] # 用來(lái)存儲(chǔ)玩家對(duì)象精靈圖片的列表
for i in range(len(player_rect)):
self.image.append(plane_img.subsurface(player_rect[i]).convert_alpha())
self.rect = player_rect[0] # 初始化圖片所在的矩形
self.rect.topleft = init_pos # 初始化矩形的左上角坐標(biāo)
self.speed = 8 # 初始化玩家速度,這里是一個(gè)確定的值
self.bullets = pygame.sprite.Group() # 玩家飛機(jī)所發(fā)射的子彈的集合
self.img_index = 0 # 玩家精靈圖片索引
self.is_hit = False # 玩家是否被擊中
def shoot(self, bullet_img):
bullet = Bullet(bullet_img, self.rect.midtop)
self.bullets.add(bullet)
def moveUp(self):
if self.rect.top <= 0:
self.rect.top = 0
else:
self.rect.top -= self.speed
def moveDown(self):
if self.rect.top >= SCREEN_HEIGHT - self.rect.height:
self.rect.top = SCREEN_HEIGHT - self.rect.height
else:
self.rect.top += self.speed
def moveLeft(self):
if self.rect.left <= 0:
self.rect.left = 0
else:
self.rect.left -= self.speed
def moveRight(self):
if self.rect.left >= SCREEN_WIDTH - self.rect.width:
self.rect.left = SCREEN_WIDTH - self.rect.width
else:
self.rect.left += self.speed
我方的戰(zhàn)機(jī)稍微復(fù)雜一點(diǎn)胞得,因?yàn)槭悄兄鹘锹镉梗∷羞@么幾個(gè)主要的屬性,飛行的圖片阶剑,被擊落的圖片跃巡,屏幕坐標(biāo),它的子彈等等牧愁!然后我們需要控制它的飛機(jī)方向素邪,向上,向下猪半,左邊和右邊兔朦,發(fā)射子彈。
3.主游戲部分文件mainGame
1).先是初始化游戲的界面大小办龄,字體等等烘绽,讀取聲音和圖片和基本配置:
# 初始化游戲
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('飛機(jī)大戰(zhàn)')
# 載入游戲音樂(lè)
bullet_sound = pygame.mixer.Sound('resources/sound/bullet.wav')
enemy1_down_sound = pygame.mixer.Sound('resources/sound/enemy1_down.wav')
game_over_sound = pygame.mixer.Sound('resources/sound/game_over.wav')
bullet_sound.set_volume(0.3)
enemy1_down_sound.set_volume(0.3)
game_over_sound.set_volume(0.3)
pygame.mixer.music.load('resources/sound/game_music.wav')
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)
# 載入背景圖
background = pygame.image.load('resources/image/background.png').convert()
game_over = pygame.image.load('resources/image/gameover.png')
filename = 'resources/image/shoot.png'
plane_img = pygame.image.load(filename)
2).游戲的邏輯部分
其實(shí)用一個(gè)大的while 循環(huán)來(lái)寫(xiě)整個(gè)游戲的邏輯部分
while running:
# 控制游戲最大幀率為60
clock.tick(60)
# 控制發(fā)射子彈頻率,并發(fā)射子彈
if not player.is_hit:
if shoot_frequency % 15 == 0:
bullet_sound.play()
player.shoot(bullet_img)
shoot_frequency += 1
if shoot_frequency >= 15:
shoot_frequency = 0
# 生成敵機(jī)
if enemy_frequency % 50 == 0:
enemy1_pos = [random.randint(0, SCREEN_WIDTH - enemy1_rect.width), 0]
enemy1 = Enemy(enemy1_img, enemy1_down_imgs, enemy1_pos)
enemies1.add(enemy1)
enemy_frequency += 1
if enemy_frequency >= 100:
enemy_frequency = 0
# 移動(dòng)子彈,若超出窗口范圍則刪除
for bullet in player.bullets:
bullet.move()
if bullet.rect.bottom < 0:
player.bullets.remove(bullet)
# 移動(dòng)敵機(jī)俐填,若超出窗口范圍則刪除
for enemy in enemies1:
enemy.move()
# 判斷玩家是否被擊中
if pygame.sprite.collide_circle(enemy, player):
enemies_down.add(enemy)
enemies1.remove(enemy)
player.is_hit = True
game_over_sound.play()
break
if enemy.rect.top > SCREEN_HEIGHT:
enemies1.remove(enemy)
# 將被擊中的敵機(jī)對(duì)象添加到擊毀敵機(jī)Group中安接,用來(lái)渲染擊毀動(dòng)畫(huà)
enemies1_down = pygame.sprite.groupcollide(enemies1, player.bullets, 1, 1)
for enemy_down in enemies1_down:
enemies_down.add(enemy_down)
# 繪制背景
screen.fill(0)
screen.blit(background, (0, 0))
# 繪制玩家飛機(jī)
if not player.is_hit:
screen.blit(player.image[player.img_index], player.rect)
# 更換圖片索引使飛機(jī)有動(dòng)畫(huà)效果
player.img_index = shoot_frequency // 8
else:
player.img_index = player_down_index // 8
screen.blit(player.image[player.img_index], player.rect)
player_down_index += 1
if player_down_index > 47:
running = False
# 繪制擊毀動(dòng)畫(huà)
for enemy_down in enemies_down:
if enemy_down.down_index == 0:
enemy1_down_sound.play()
if enemy_down.down_index > 7:
enemies_down.remove(enemy_down)
score += 1000
continue
screen.blit(enemy_down.down_imgs[enemy_down.down_index // 2], enemy_down.rect)
enemy_down.down_index += 1
# 繪制子彈和敵機(jī)
player.bullets.draw(screen)
enemies1.draw(screen)
上面這一堆代碼其實(shí)就是干下面幾個(gè)事情:
- 先繪制出背景幕布
- 再繪制出玩家的戰(zhàn)機(jī),敵機(jī)
- 綁定戰(zhàn)機(jī)和敵機(jī)的鼠標(biāo)和鍵盤(pán)響應(yīng)事件
- 發(fā)射子彈,通過(guò)坐標(biāo)來(lái)判斷子彈和敵機(jī)的碰撞盏檐,以及敵機(jī)和玩家戰(zhàn)機(jī)的碰撞
- 最后還要計(jì)算得分:
整個(gè)源碼量很小歇式,非常簡(jiǎn)潔!大家可以試著讀一讀源碼胡野,然后運(yùn)行一下材失,可以做一些修改,這樣的有趣的小游戲代碼硫豆,難度適中龙巨!對(duì)菜鳥(niǎo)快速了解Python的類(lèi),模塊的使用非常有幫助熊响,然后自己可以增加一些功能旨别!
歡迎大家加入小編創(chuàng)建的Python行業(yè)交流群,有大牛答疑汗茄,有資源共享秸弛,有企業(yè)招人!是一個(gè)非常不錯(cuò)的交流基地洪碳!群號(hào):556370268