pygame入门小工程——大战外星人(三)

in STEEM CN/中文3 years ago

无标题.gif

之前发过两篇学习用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()
Sort:  

额,我记得大战外星人好像是安装pygame模块后,自带的检测是否安装的机制!

是吗?像彩蛋?我去查查。

[WhereIn Android] (http://www.wherein.io)

老哥这行动力没得说,我一直想做一个太空大战的游戏出来,结果哎,卡住了,这几天打算复习一下面向对象的方法,看看能不能做出来

Coin Marketplace

STEEM 0.17
TRX 0.15
JST 0.028
BTC 62227.11
ETH 2400.78
USDT 1.00
SBD 2.50