之前发过两篇学习用pygame 编程制作小游戏大战外星人的帖子,今天收个尾,做到有始有终。
剩下的工作分别是如何生成多个敌人,显示得分。加入游戏结束的逻辑。这样一个简单的小游戏基本就完整了。
整个游戏就是玩家要对付6个外星飞船,要尽可能把它们阻止在最后防线外面,一旦有一艘外星飞船突破最后防线,玩家就输掉游戏,Game Over。
一、如何生成多个敌人
如果对编程有了解的,碰到这种问题一般会想到面向对象编程,先编写一个内,里面包括敌人的各个属性,比如图片,运动方式,等等。然后用这个类生成一个一个的实例。不过面向对象只是一种编程思想,并不是一定要按这个来。也可以用简单的数组加循环来实现多个敌人。
#enemy
enemyImg=[]
enemyx=[]
enemyy=[]
enemyx_change=[]
enemyNum=6
for i in range(enemyNum):
enemyImg.append(pygame.image.load('enemy.png'))
enemyx.append(randint(0,704))
enemyy.append(randint(50,150))
enemyx_change.append(0.2)
将敌人的属性分别设置成空数组,然后用循环语句为每个敌人赋值,数组中的每一个元素都对应一个敌人。
然后再在主while循环中编写敌人的行动逻辑,并在屏幕上更新显示:
for i in range(enemyNum):
enemyx[i] += enemyx_change[i]
if enemyx[i] <= 0.8:
enemyx_change[i]=0.3
enemyy[i] += 40
if enemyx[i] >= 704:
enemyx_change[i]=-0.3
enemyy[i] += 40
if enemyy[i]>=300:
for i in range(enemyNum):
enemyy[i] = 1000
show_gameover()
enemy(enemyx[i],enemyy[i],i)
敌人的逻辑包括:
碰到屏幕边界后x轴反向运动,y轴前进40个像素。
敌人突破y轴=300这条最后防线后,玩家失败,游戏结束。
二、显示分数
显示分数很简单,不过先要生成显示内容,而把文本信息转化成文字信息转化成类似图像的对象。这个需要载入字体。载入字体有两种方式1种是直接用系统字体,可以先用pygame.font.get_fonts()命令看看系统里安装了那些字体,再用pygame.font.SysFont()来调用。然后用blit()把显示结果打印在屏幕上。
三、完整的源代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygame
from random import randint
import math
# init
pygame.init()
# create screen
screen=pygame.display.set_mode((800,600))
score_font=pygame.font.SysFont('simhei',48)
#title and icon
pygame.display.set_caption('大战外星人')
icon=pygame.image.load('ufo.png')
pygame.display.set_icon(icon)
#player
playerImg=pygame.image.load('f18.png')
playerx=370
playery=460
playerx_change=0
def player(x,y):
screen.blit(playerImg,(x,y))
#background
backgroundImg=pygame.image.load('background.jpg')
#enemy
enemyImg=[]
enemyx=[]
enemyy=[]
enemyx_change=[]
enemyNum=6
for i in range(enemyNum):
enemyImg.append(pygame.image.load('enemy.png'))
enemyx.append(randint(0,704))
enemyy.append(randint(50,150))
enemyx_change.append(0.2)
score = 0
def enemy(x,y,i):
screen.blit(enemyImg[i],(x,y))
#bullet
bulletImg=pygame.image.load('bullet.png')
bulletx=370
bullety=460
bullety_change=0.8
bullet_state='ready'
def bullet(x,y):
global bullet_state
bullet_state='fire'
screen.blit(bulletImg,(x+5,y+10))
def isCollision(enemyx,enemyy,bulletx,bullety):
distance=math.sqrt((enemyx+52.5-bulletx)**2+(enemyy+60-bullety)**2)
if distance <50 :
return True
else :
return False
def show_score(text):
score_text=score_font.render(text,True,(255,255,255))
screen.blit(score_text,(10,10))
def show_gameover():
score_font=pygame.font.SysFont('simhei',96)
score_text=score_font.render('游戏 结束',True,(255,255,255))
screen.blit(score_text,(100,250))
running=True
while running:
screen.fill((0,0,128))
screen.blit(backgroundImg,(0,0))
#检查左右键是否被按下
for event in pygame.event.get():
if event.type == pygame.QUIT:
running=False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
playerx_change -= 0.4
if event.key == pygame.K_RIGHT:
playerx_change += 0.4
if event.key == pygame.K_SPACE and bullet_state == 'ready':
bullet(playerx,bullety)
bulletx=playerx
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
playerx_change=0
playerx += playerx_change
if playerx <= 0.8:
playerx=0.8
if playerx >= 704:
playerx=704
player(playerx,playery)
for i in range(enemyNum):
enemyx[i] += enemyx_change[i]
if enemyx[i] <= 0.8:
enemyx_change[i]=0.3
enemyy[i] += 40
if enemyx[i] >= 704:
enemyx_change[i]=-0.3
enemyy[i] += 40
if enemyy[i]>=300:
for i in range(enemyNum):
enemyy[i] = 1000
show_gameover()
enemy(enemyx[i],enemyy[i],i)
if bullet_state == 'fire':
bullet(bulletx,bullety)
bullety -= bullety_change
if bullety <= 0:
bullet_state = 'ready'
bullety=460
if isCollision(enemyx[i],enemyy[i],bulletx,bullety) :
bullet_state = 'ready'
bullety=460
score += 1
enemyx[i]=randint(0,704)
enemyy[i]=randint(50,150)
show_score('得分:'+str(score))
pygame.display.update()
额,我记得大战外星人好像是安装pygame模块后,自带的检测是否安装的机制!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
是吗?像彩蛋?我去查查。
[WhereIn Android] (http://www.wherein.io)
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
老哥这行动力没得说,我一直想做一个太空大战的游戏出来,结果哎,卡住了,这几天打算复习一下面向对象的方法,看看能不能做出来
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit