我被活活的逼成了pygame小白

本文分享了一个使用Pygame引擎开发2D游戏的实战经验。通过具体项目,详细介绍了游戏开发过程中遇到的技术难点及解决方法,包括游戏流程控制、素材处理、时间管理、面向对象编程思想的应用等。

前天闲来无事,刚好群里有人问谁会做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()




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值