前天闲来无事,刚好群里有人问谁会做pygame,老惯例,先把牛逼吹出去,拍胸脯说没问题,然后当晚赶紧开始刺激的学习pygame之旅。
学了两天也把项目搞定了,感觉我亏了,代码量不小,也头秃。
pygame这个引擎我感觉是有点out了,很少有人真正做点好东西,这个时代本来2d游戏就快被淘汰了,可选择的游戏开发引擎那么多,为啥非要想不开用pygame啊,只有一种可能性,那就是用来锻炼一下编程思维。。。这个目的确实也达到了。
中间处理了一坨又一坨的难点,每个都得去网上一顿搜,感觉网上pygame可能也不火,资源都很一般般。
想起来的知识点简单罗列一下:
整个游戏流程
素材缩放
时间处理
游戏编程思维(面向对象)
pygame种的timer
碰撞处理(这个到现在还是迷糊,分为矩形圆形和mask)
把代码整上吧,万一以后心血来潮还想用pygame做个界面啥的,兴许用得上。。。
写了三百多行。。。
import sys
import pygame
import time
import datetime
import random
import matplotlib.pyplot as plt
pygame.init()
screen = pygame.display.set_mode((1920,1080),pygame.FULLSCREEN)
#screen = pygame.display.set_mode((920,880)) #debug
pygame.display.set_caption('绿色星球改造计划')
font = pygame.font.Font('C:/Windows/Fonts/simhei.ttf',50)
font2 = pygame.font.Font('C:/Windows/Fonts/simhei.ttf',30)
file='bgm.mp3'
pygame.mixer.init()
bgm = pygame.mixer.music.load(file)
RED = (255, 0, 0)
WHITE = (255, 255, 255)
BLACK = (0,0,0)
timestart=0
SHOWTEXT = pygame.USEREVENT + 1
ALARM = pygame.USEREVENT + 2
def getday(n,y=2321,m=1,d=1):
the_date = datetime.datetime(y,m,d)
result_date = the_date + datetime.timedelta(days=n)
d = result_date.strftime('%Y-%m-%d')
return d
def draw_plt(listdata,days):
plt.figure(figsize=(7.5,3),dpi=100)
x=listdata[-12:]
y=days[-12:]
plt.grid(b=None, which='major', axis='both')
plt.rcParams["font.sans-serif"]=["SimHei"]
plt.rcParams["axes.unicode_minus"]=False
plt.xlabel('日期')
plt.ylabel('温度(°C)')
plt.bar(y,x)
plt.savefig('chart.jpg',bbox_inches = 'tight')
plt.clf()
class Button(object):
def __init__(self, text, color, x=None, y=None, **kwargs):
self.surface = font.render(text, True, color)
self.WIDTH = self.surface.get_width()
self.HEIGHT = self.surface.get_height()
if 'centered_x' in kwargs and kwargs['centered_x']:
self.x = display_width // 2 - self.WIDTH // 2
else:
self.x = x
if 'centered_y' in kwargs and kwargs['cenntered_y']:
self.y = display_height // 2 - self.HEIGHT // 2
else:
self.y = y
def display(self):
screen.blit(self.surface, (self.x, self.y))
def check_click(self, position):
x_match = position[0] > self.x and position[0] < self.x + self.WIDTH
y_match = position[1] > self.y and position[1] < self.y + self.HEIGHT
if x_match and y_match:
return True
else:
return False
class PLANET():
def __init__(self):
self.tree_list=[]
self.temp_list=[]
self.date_list=[]
self.tree_time=[]
self.people=12
self.green=0
self.oxygen=0
self.derc=0
self.spi=0
self.lower=-100
self.upper=100
self.temp=0
self.date=0
def draw_text(self):
global timestart
treenum=len(self.tree_list)
dc=int((pygame.time.get_ticks()-timestart)/1000)
nd=getday(dc)
lowt=-50+treenum
hight=55-treenum
self.date=nd
text1 = font2.render("日 期:"+nd,True,(0,0,0))
screen.blit(text1,(90,250))
people=round(12+3/50*treenum,2)
text2 = font2.render("总人口数:"+str(people)+"亿人",True,(0,0,0))
screen.blit(text2,(90,300))
text3 = font2.render("绿化面积:"+str(treenum)+"万亩",True,(0,0,0))
screen.blit(text3,(90,350))
text4 = font2.render("大气含氧:"+str(round(treenum/2,1))+"%",True,(0,0,0))
screen.blit(text4,(90,400))
text5 = font2.render("有害物质:"+str(50-treenum)+"drec",True,(0,0,0))
screen.blit(text5,(90,450))
text6 = font2.render("降水指数:"+str(treenum*2)+"spi",True,(0,0,0))
screen.blit(text6,(90,500))
text7 = font2.render("最低温度:"+str(lowt)+"°C",True,(0,0,0))
screen.blit(text7,(90,550))
text8 = font2.render("最高温度:"+str(hight)+"°C",True,(0,0,0))
screen.blit(text8,(90,600))
text9 = font2.render("实时温度:"+str(self.temp)+"°C",True,(0,0,0))
screen.blit(text9,(90,650))
class Circle(pygame.sprite.Sprite):
def __init__(self,pos,color):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((1000,1000))
self.image.set_colorkey((1,2,3))
self.image.fill((1, 2, 3))
pygame.draw.circle(self.image,pygame.Color(color),(500,500),500)
self.rect = self.image.get_rect(center=pos)
self.radius=333 #碰撞半径
def draw(self,aSurface):
aSurface.blit(self.image,self.rect)
class UFO(pygame.sprite.Sprite):
def __init__(self,pos,filename):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load('ufo.png')
#pygame.draw.circle(self.image,pygame.Color((255,0,0)),(150,150),150)
self.rect = self.image.get_rect(center=pos) #rect是圆形图片外边界,将image移到指定位置
self.radius=150 #圆的半径
def draw(self,aSurface):
aSurface.blit(self.image,self.rect) #从Sprite派生类不放入Group,类实例显示需调用自定义draw
planetone=PLANET()
planettwo=PLANET()
planetthree=PLANET()
planetfour=PLANET()
planetfive=PLANET()
planetsix=PLANET()
ufo=UFO((1380,558),'ufo.png')
circleRed=Circle((1380,558),'red')
def complete():
alarm=pygame.image.load('alert.png')
screen.blit(alarm,(500,400))
text1 = font.render("祝贺圆满完成绿色星球改造任务!",True,(0,0,0))
screen.blit(text1,(630,550))
pygame.display.update()
pygame.time.delay(2000)
def alarm():
alarm=pygame.image.load('alert.png')
screen.blit(alarm,(500,400))
text1 = font2.render("系统检测到,未来一周后飞羽星即将遭遇暴雨天气,",True,(0,0,0))
screen.blit(text1,(650,500))
text2 = font2.render("请飞羽星居民做好防范!",True,(0,0,0))
screen.blit(text2,(650,555))
button1 = Button('发送警报',WHITE, 750, 650)
button1.display()
button2 = Button('解除警报',WHITE, 1100, 650)
button2.display()
pygame.display.update()
mark=1
while mark:
for event in pygame.event.get():
print(pygame.mouse.get_pressed())
if pygame.mouse.get_pressed()[0]:
if button1.check_click(pygame.mouse.get_pos()):
screen.blit(alarm,(500,400))
text1 = font.render("警报已发送",True,(0,0,0))
screen.blit(text1,(800,550))
pygame.display.update()
pygame.time.delay(1000)
mark=0
if button2.check_click(pygame.mouse.get_pos()):
screen.blit(alarm,(500,400))
text1 = font.render("警报已解除",True,(0,0,0))
screen.blit(text1,(800,550))
pygame.display.update()
pygame.time.delay(1000)
mark=0
pygame.display.update()
print('break')
def title():
loading=pygame.image.load('zhu01.png')
title=pygame.image.load('zhu02.png')
screen.blit(loading,(0,0))
pygame.display.update()
t3=pygame.time.wait(3000)
screen.blit(title,(0,0))
pygame.display.update()
pygame.mixer.music.play()
def intro():
intro1=pygame.image.load('zhu03.png')
intro2=pygame.image.load('zhu04.png')
intro3=pygame.image.load('zhu05.png')
intro4=pygame.image.load('zhu06.png')
intro5=pygame.image.load('zhu07.png')
intro6=pygame.image.load('zhu08.png')
pic_num=0
while True:
if pic_num>6:
break
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key==27:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
pic_num+=1
if pic_num==1:
screen.blit(intro1,(0,0))
elif pic_num==2:
screen.blit(intro2,(0,0))
elif pic_num==3:
screen.blit(intro3,(0,0))
elif pic_num==4:
screen.blit(intro4,(0,0))
elif pic_num==5:
screen.blit(intro5,(0,0))
elif pic_num==6:
screen.blit(intro6,(0,0))
pygame.display.flip()
def game(num):
pygame.time.set_timer(SHOWTEXT, 1000)
pygame.time.set_timer(ALARM, 80000)
button_return = Button('返回星图',BLACK, 580, 980)
planet1=pygame.image.load('1.png')
planet2=pygame.image.load('2.png')
planet3=pygame.image.load('3.png')
planet4=pygame.image.load('4.png')
planet5=pygame.image.load('5.png')
planet6=pygame.image.load('6.png')
tree=pygame.image.load('tree.png')
treebig=pygame.transform.scale(tree,(200,200))
if num==1:
planetnow=planet1
planetclass=planetone
elif num==2:
planetnow=planet2
planetclass=planettwo
elif num==3:
planetnow=planet3
planetclass=planetthree
elif num==4:
planetnow=planet4
planetclass=planetfour
elif num==5:
planetnow=planet5
planetclass=planetfive
elif num==6:
planetnow=planet6
planetclass=planetsix
md=3 #每次移动距离
while 1:
button_return.display()
screen.blit(planetnow,(0,0))
if button_return.check_click(pygame.mouse.get_pos()):
button_return = Button('返回星图',RED, 580, 980)
else:
button_return = Button('返回星图',BLACK, 580, 980)
button_return.display()
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_RIGHT]:
ufo.rect.x+=md
if not pygame.sprite.collide_circle(circleRed,ufo):
ufo.rect.x-=md
elif key_pressed[pygame.K_LEFT]:
ufo.rect.x-=md
if not pygame.sprite.collide_circle(circleRed,ufo):
ufo.rect.x+=md
if key_pressed[pygame.K_UP]:
ufo.rect.y-=md
if not pygame.sprite.collide_circle(circleRed,ufo):
ufo.rect.y+=md
if key_pressed[pygame.K_DOWN]:
ufo.rect.y+=md
if not pygame.sprite.collide_circle(circleRed,ufo):
ufo.rect.y-=md
dc=int((pygame.time.get_ticks()-timestart)/1000)
if dc==15:
alarm()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
raise SystemExit
elif pygame.mouse.get_pressed()[0]:
if button_return.check_click(pygame.mouse.get_pos()):
select()
elif event.type == pygame.KEYDOWN:
if event.key==27:
pygame.quit()
sys.exit()
elif event.key==pygame.K_SPACE:
planetclass.tree_list.append((ufo.rect.x+150,ufo.rect.y+150))
planetclass.tree_time.append(pygame.time.get_ticks())
while 1:
img=pygame.image.load('tree.png')
width=img.get_width()
height=img.get_height()
pygame.display.update()
for i in range(0,10):
screen.blit(planetnow,(0,0))
button_return.display()
planetclass.draw_text()
if len(planetclass.tree_list)!=0:
for index,xy in enumerate(planetclass.tree_list):
tj=pygame.time.get_ticks()
te=planetclass.tree_time[index]
if (tj-te)>5000:
screen.blit(treebig,xy)
else:
screen.blit(tree,xy)
chart=pygame.image.load('chart.jpg')
screen.blit(chart,(70,680))
new_img=pygame.transform.scale(img,(width*(2-i/10),height*(2-i/10)))
screen.blit(new_img,(ufo.rect.x+80,ufo.rect.y+80))
pygame.display.update()
pygame.time.delay(30)
break
if len(planetclass.tree_list)==50:
complete()
elif event.type == SHOWTEXT:
treenum=len(planetclass.tree_list)
lowt=-50+treenum
hight=55-treenum
temp=round(random.uniform(lowt,hight),2)
planetclass.temp=temp
planetclass.temp_list.append(temp)
dd=str(planetclass.date)
f=dd.split("-")
planetclass.date_list.append(f[2])
draw_plt(planetclass.temp_list,planetclass.date_list)
elif event.type==ALARM:
alarm()
if len(planetclass.tree_list)!=0:
for index,xy in enumerate(planetclass.tree_list):
tj=pygame.time.get_ticks()
te=planetclass.tree_time[index]
if (tj-te)>5000:
screen.blit(treebig,xy)
else:
screen.blit(tree,xy)
#circleRed.draw(screen) #test planet coll
ufo.draw(screen)
planetclass.draw_text()
chart=pygame.image.load('chart.jpg')
screen.blit(chart,(70,680))
pygame.display.update()
def select():
global timestart
select=pygame.image.load('zhu09.png')
screen.blit(select,(0,0))
pygame.display.flip()
button1 = Button('开始改造',WHITE, 170, 800)
button2 = Button('开始改造',WHITE, 500, 800)
button3 = Button('开始改造',WHITE, 790, 800)
button4 = Button('开始改造',WHITE, 1075, 800)
button5 = Button('开始改造',WHITE, 1340, 800)
button6 = Button('开始改造',WHITE, 1620, 800)
button1.display()
button2.display()
button3.display()
button4.display()
button5.display()
button6.display()
pygame.display.update()
while 1:
if button1.check_click(pygame.mouse.get_pos()):
button1 = Button('开始改造',RED, 170,800)
else:
button1 = Button('开始改造',WHITE, 170, 800)
if button2.check_click(pygame.mouse.get_pos()):
button2 = Button('开始改造',RED, 500,800)
else:
button2 = Button('开始改造',WHITE, 500, 800)
if button3.check_click(pygame.mouse.get_pos()):
button3 = Button('开始改造',RED, 790,800)
else:
button3 = Button('开始改造',WHITE, 790, 800)
if button4.check_click(pygame.mouse.get_pos()):
button4 = Button('开始改造',RED, 1075,800)
else:
button4 = Button('开始改造',WHITE, 1075, 800)
if button5.check_click(pygame.mouse.get_pos()):
button5 = Button('开始改造',RED, 1340,800)
else:
button5 = Button('开始改造',WHITE, 1340, 800)
if button6.check_click(pygame.mouse.get_pos()):
button6 = Button('开始改造',RED, 1620,800)
else:
button6 = Button('开始改造',WHITE, 1620, 800)
button1.display()
button2.display()
button3.display()
button4.display()
button5.display()
button6.display()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
raise SystemExit
elif pygame.mouse.get_pressed()[0]:
if button1.check_click(pygame.mouse.get_pos()):
game(1)
if button2.check_click(pygame.mouse.get_pos()):
game(2)
if button3.check_click(pygame.mouse.get_pos()):
game(3)
if button4.check_click(pygame.mouse.get_pos()):
game(4)
if button5.check_click(pygame.mouse.get_pos()):
game(5)
if button6.check_click(pygame.mouse.get_pos()):
game(6)
elif event.type == pygame.KEYDOWN:
if event.key==27:
pygame.quit()
sys.exit()
pygame.display.update()
title()
intro()
timestart=pygame.time.get_ticks()
select()
本文分享了一个使用Pygame引擎开发2D游戏的实战经验。通过具体项目,详细介绍了游戏开发过程中遇到的技术难点及解决方法,包括游戏流程控制、素材处理、时间管理、面向对象编程思想的应用等。

被折叠的 条评论
为什么被折叠?



