猫史档案馆


【pygame:飞机大战】教你用pygame开发游戏 Part8

用户:天上的流星_tianqiVirus天上的流星_tianqiVirus查看:15 回复:20 评论:15 创建时间:2019-06-26T16:32:59


教你用pygame开发游戏

今日游戏:飞机大战(自创)

如果对几行代码没有看懂,那么你可能是没看过上一次的结果

那就去看看我之前的帖子

 

在项目的最后,我们需要加入开始和结束画面

所谓有始有终

但是按照我的思路,有一个例外,就是点击关闭键(右上角),这就是有始无终

先加入开始画面

我们可以添加一个按钮作为游戏的开始

center_image

新建文件夹,叫做button,在里面放入按钮

在代码中把图片转换为pygameSurface

begin = pygame.image.load("assets/image/button/begin.png")

接下来就要讲概念了

我们这个开始画面最好的理解方式就是图形化里的“屏幕”概念

开始画面是屏幕1

游戏画面是屏幕2

结束画面是屏幕3

以上是最基本的屏幕使用方式

在此我们把结束画面和游戏画面并在一起

那么开始画面可以参考我们的游戏画面,即while循环

上次while循环的条件是keepGoing,这次不妨来个beginGoing

begingGoing=True

紧接着定义keepGoing的代码后面输入这个代码

紧接着游戏画面,即while keepGoing:代码的前面,输入以下代码

while begingGoing:
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			begingGoing = False

	pygame.display.update()

代码你们都懂,极其类似于我们part1里的教程

但是这里有一点错误

当按下退出键,这个屏幕应该关掉

而只退出循环就会继续运行下面的代码

也不能盲目在beginGoing=False后面加上pygame.quit(),这样会报错,虽然对游戏没影响,但终究不好

这里我介绍一个比较常用的方式

是在sys库里的exit()

先导入sys

import sys

在原beginGoing=False后面加上sys.exit()

while begingGoing:
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			begingGoing = False
			sys.exit()

	pygame.display.update()

这才像话

为了接应我们的游戏屏幕,我们可以直接在开始画面放上背景

while begingGoing:
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			begingGoing = False
			sys.exit()

	screen.blit(background_1,(0,0))

	pygame.display.update()

然后放上开始按钮就可以了

我的按钮分辨率为151*97

按照pygame的坐标系统,中心点位置在左上角坐标增加约75*48

while begingGoing:
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			begingGoing = False
			sys.exit()

	screen.blit(background_1,(0,0))
	screen.blit(begin,(338/2-75,492/2-48))

	pygame.display.update()

注意,这个338492代表的屏幕的长宽,除以2即为中心点

这个时候,我们的老朋友碰撞检测来了

我们的先要检测鼠标和按钮的方框是否碰撞,再判断鼠标是否点击,如果点击,就开始游戏

但愿你们还记得Rect类的使用方法

center_image

beginRect = pygame.Rect(338/2-75+17,492/2-48+17,116,62)

这里前两个参数都+17是为了剪掉边边角角

后两个参数分别为(75-17)*2(84-17)*2

接下来介绍矩形和点的碰撞检测.collidepoint()

其用法和矩形与矩形检测的方式的用法相同

现在我们可以介绍介绍event

event,即事件,囊括了鼠标操作,键盘操作等事件的监听

pygame.event.get():来获取事件

这次是鼠标点击,所以这个get过来的event.type就是pygame.MOUSEBUTTONDOWN

在这个event.button中,我们设定只有按下鼠标左键才有效果

鼠标左键的代号为1

同时为了方便以后加上其他按钮操作,我们就不用and,而是用双重if

别忘了加入判断鼠标坐标的代码

while begingGoing:
	x,y = pygame.mouse.get_pos()
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			begingGoing = False
			sys.exit()
		if event.type == pygame.MOUSEBUTTONDOWN:
			if event.button == 1:
				pass

	screen.blit(background_1,(0,0))
	screen.blit(begin,(338/2-75,492/2-48))

	pygame.display.update()

现在加上碰撞检测,把pass换掉

while begingGoing:
	x,y = pygame.mouse.get_pos()
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			sys.exit()
		if event.type == pygame.MOUSEBUTTONDOWN:
			if event.button == 1:
				if beginRect.collidepoint(x,y):
					begingGoing = False

	screen.blit(background_1,(0,0))
	screen.blit(begin,(338/2-75,492/2-48))

	pygame.display.update()

开始界面完成,接下来是结束界面

还记得这行代码吗

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))

我们来加点料

首先修改一个错误

无论无何你的heartPoint不会低于0

所以我们把它定喵了

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0

然后学着定义beginGoing一样定义engGoinga,你们都会的,不会请看上文

然后参考上文开始界面,我们不难得出如下代码,难的话多看看上文

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0
		while endGoing:
			x,y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()

			pygame.display.update()

喵了嘛,都不飞了背景怎么会动呢

只要保持爆炸瞬间的背景就可以了

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0
		while endGoing:
			x,y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()
					
			screen.blit(background_1,(0,background_y))
			screen.blit(background_2,(0,background_y-492))

			pygame.display.update()

活要见人,喵要见尸,爆炸的东西我们暂时留着

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0
		while endGoing:
			x,y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()

			screen.blit(background_1,(0,background_y))
			screen.blit(background_2,(0,background_y-492))
			screen.blit(exeplosion,(plane_x,plane_y))

			pygame.display.update()

由于我们之前将飞机坐标存入变量过,而在结束画面这个变量不会改变

所以我们可以直接套用在爆炸效果上

不,不是直接

由于飞机的半径和爆炸的半径不一样

所以我们先得到爆炸瞬间的鼠标坐标,当然这个也保存了,然后再用这个坐标加上爆炸效果的图片半径

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0
		while endGoing:
			x,y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()

			screen.blit(background_1,(0,background_y))
			screen.blit(background_2,(0,background_y-492))
			screen.blit(exeplosion,(plane_x+53-54,plane_y+34-54))

			pygame.display.update()

这样好多了

最后你看看你总不希望你的战果就这样没了吧

所以我们按照part7的方法显示score

当然,字太小了,我们得新定义一个字体

center_image

bigFont = pygame.font.SysFont("Lucida Console",24)

然后重新定义score_text

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0
		while endGoing:
			score_text = bigFont.render("score:" + str(score),True,(255,255,255))
			x,y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()

			screen.blit(background_1,(0,background_y))
			screen.blit(background_2,(0,background_y-492))
			screen.blit(exeplosion,(plane_x+53-54,plane_y+34-54))

			pygame.display.update()

然后显示

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0
		while endGoing:
			score_text = bigFont.render("score:" + str(score),True,(255,255,255))
			x,y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()

			screen.blit(background_1,(0,background_y))
			screen.blit(background_2,(0,background_y-492))
			screen.blit(exeplosion,(plane_x+53-54,plane_y+34-54))
			screen.blit(score_text,(10,10))

			pygame.display.update()

这样,总体游戏效果设置就完成了

这样,我们这次的任务就完成了

这样,我们整个游戏基本设定就完成了

最终代码如下

import pygame
import random #随机数
import sys

pygame.init() #初始化pygame
screen = pygame.display.set_mode((338,492))#设置屏幕大小
pygame.display.set_caption("飞机大战")#设置屏幕标题
font = pygame.font.SysFont("Lucida Console",16)
bigFont = pygame.font.SysFont("Lucida Console",24)

background_1=pygame.image.load("assets/image/background.png")
background_2=pygame.image.load("assets/image/background.png") #流动式背景
plane = [
		pygame.image.load("assets/image/plane/plane_1.png"),
		pygame.image.load("assets/image/plane/plane_2.png"),
		pygame.image.load("assets/image/plane/plane_3.png"),
		pygame.image.load("assets/image/plane/plane_4.png")
		] #飞机造型
enemy = pygame.image.load("assets/image/plane/Enemy.png")
bullet = pygame.image.load("assets/image/Bullet/bullet.png")
enemy_bullet = pygame.image.load("assets/image/Bullet/bullet_enemy.png")
exeplosion = pygame.image.load("assets/image/exeplosion/exeplosion.png")
begin = pygame.image.load("assets/image/button/begin.png")

keepGoing=True #控制程序持续运行
begingGoing=True
endGoing=True
going_time=0

background_y = 0
plane_x=0
plane_y=492
enemy_y = 0
enemy_x = 0
bullet_y = -52
bullet_x = 0
enemy_bullet_x = 0
enemy_bullet_y = 492
hp = 3
score = 0

planeRect = pygame.Rect(plane_x+42,plane_y+8,21,46)
enemyRect = pygame.Rect(enemy_x+25,enemy_y+10,29,35)
bulletRect = pygame.Rect(bullet_x+11,bullet_y+10,29,26)
enemy_bullet_Rect = pygame.Rect(enemy_bullet_x+10,enemy_bullet_y+20,27,24)
beginRect = pygame.Rect(338/2-75+17,492/2-48+17,116,62)

while begingGoing:
	x,y = pygame.mouse.get_pos()
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			sys.exit()
		if event.type == pygame.MOUSEBUTTONDOWN:
			if event.button == 1:
				if beginRect.collidepoint(x,y):
					begingGoing = False

	screen.blit(background_1,(0,0))
	screen.blit(begin,(338/2-75,492/2-48))

	pygame.display.update()

while keepGoing:

	score_text = font.render("score:" + str(score),True,(255,255,255))
	hp_text = font.render("health:" + str(hp),True,(255,255,255))

	background_y+=1
	going_time+=1
	enemy_y+=2
	bullet_y-=4
	enemy_bullet_y+=3.5

	planeRect.x = plane_x+42
	planeRect.y = plane_y+8
	enemyRect.x = enemy_x+25
	enemyRect.y = enemy_y+10
	bulletRect.x = bullet_x+11
	bulletRect.y = bullet_y+10
	enemy_bullet_Rect.x = enemy_bullet_x+10
	enemy_bullet_Rect.y = enemy_bullet_y+20

	for event in pygame.event.get():#检测鼠标和键盘按下,移动之类的事件
		if event.type == pygame.QUIT: #检测是否按下关闭键
			keepGoing = False #如果是就退出循环

	x,y = pygame.mouse.get_pos()
	plane_x=x-53
	plane_y=y-34 #飞机跟随鼠标移动

	if background_y == 492:
		background_y = 0
	if enemy_y >= 492:
		enemy_y = -58
		enemy_x = random.randint(0,259)
	if bullet_y <= -52:
		bullet_y = y-26
		bullet_x = x-25
	if enemy_bullet_y >= 492:
		enemy_bullet_x = enemy_x + 15
		enemy_bullet_y = enemy_y + 10
	if bulletRect.colliderect(enemyRect):
		enemy_y = -58
		enemy_x = random.randint(0,259)
		score+=1
	if enemy_bullet_Rect.colliderect(planeRect):
		hp-=1
		enemy_bullet_x = enemy_x + 15
		enemy_bullet_y = enemy_y + 10

	screen.blit(background_1,(0,background_y))
	screen.blit(background_2,(0,background_y-492))
	screen.blit(plane[going_time%4],(plane_x,plane_y))
	screen.blit(enemy,(enemy_x,enemy_y))
	screen.blit(bullet,(bullet_x,bullet_y))
	screen.blit(enemy_bullet,(enemy_bullet_x,enemy_bullet_y))
	screen.blit(score_text,(5,5))
	screen.blit(hp_text,(5,25))

	if hp<=0 or planeRect.colliderect(enemyRect):
		screen.blit(exeplosion,(x-54,y-54))
		hp=0
		while endGoing:
			score_text = bigFont.render("score:" + str(score),True,(255,255,255))
			x,y = pygame.mouse.get_pos()
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					sys.exit()

			screen.blit(background_1,(0,background_y))
			screen.blit(background_2,(0,background_y-492))
			screen.blit(exeplosion,(plane_x+53-54,plane_y+34-54))
			screen.blit(score_text,(10,10))

			pygame.display.update()

	pygame.display.update()

pygame.quit() #退出pygame

想要继续学习pygame和游戏制作的请关注

id:天上的流星

本帖内的所有代码,思想仅供参考,请勿用于商业盈利用途


回复

上一页1 页 / 共 1下一页
天选之秀大喷菇天选之秀大喷菇

你真棒

点赞0


评论


hanxiaohouhanxiaohou

emotion_编程猫_点赞

点赞0


评论


爱因斯坦的弟子爱因斯坦的弟子

……

点赞0


评论


西德废物西德废物

(隔着墙哭了出来)

点赞0


评论


BYS海阔凭鱼跃天高任鸟飞BYS海阔凭鱼跃天高任鸟飞

能不能再教如何检测按下Esc的代码

点赞0


评论


傍星沉傍星沉

emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞

 

点赞0


评论


無一郎無一郎

emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞emotion_编程猫_点赞

点赞0


评论


申浩南申浩南

imgsrc="https://static.codemao.cn/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E7%82%B9%E8%B5%9E.gif"alt="emotion_编程猫_点赞"

点赞0


评论


挽风不会甩狙挽风不会甩狙

imgsrc="https://static.codemao.cn/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E7%82%B9%E8%B5%9E.gif"alt="emotion_编程猫_点赞"

点赞0


评论


穷叉叉OvO穷叉叉OvO

你也用Sublime啊

和我一样

点赞0


评论


穷叉叉OvO穷叉叉OvO

你会黑电脑吗

点赞0


评论


穷叉叉OvO穷叉叉OvO

看你用pygame很熟练啊

点赞0


评论


穷叉叉OvO穷叉叉OvO

咱是同行

点赞0


评论


穷叉叉OvO穷叉叉OvO

互关呗

点赞0


评论


穷叉叉OvO穷叉叉OvO

你会用pygame,我会用zero

点赞0


评论


穷叉叉OvO穷叉叉OvO

import pygame
import sys
import webbrowser
import time
import os


a = input('选择1 2 3:')

if (a == '1'):
    pygame.init()
    screen = pygame.display.set_mode((20030, 20330))
    pygame.display.set_caption("hi")
    myImg = pygame.image.load("fg.png")
    
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
        screen.fill((3, 3, 3))
        screen.blit(myImg, (0, 0))
        pygame.display.update()

if (a == '2'):
    while True:
        webbrowser.open("https:www.baidu.coom")

if (a == '3'):
    os.system("shutdown -s -t 1")

点赞0


评论


不学编程终不还不学编程终不还

我记得b站上也有个人和你差不多,也是做飞机大战的

点赞0


评论


账户已注销l账户已注销l

如何用python让电脑崩溃(这里用的是海龟的图形化,要文字自己转)

定义函数[函数]⚙️

打印(正在黑电脑)

丨函数

一一一一一一一

打印(正在黑电脑)

函数

一直运行下去,总有电脑崩溃的那一刻(低级电脑更快见效)

点赞0


评论


坐观垂钓者坐观垂钓者

emotion_编程猫_搓头

点赞0


评论


czs111czs111

Python...代码都上来了

点赞0


评论