关于pygame:01基本套路篇学习python游戏开发你不能错过这个

申明: 原创不易,未经许可,不得转载 0.前言hello,小伙伴们,我是带你们一起写游戏的猫姐!最近猫姐忙着做 python 编程入门的课程,曾经在抖音上更新了57 集,从 0 开始学习 python 编程的小伙伴,能够在抖音(抖音个人主页)下来看看,相对不会让你们悲观! 好了,咱们明天接着做游戏,明天猫姐给大家带来一款在抖音上很经典的小游戏,游戏中一个小朋友须要把从天而降蘑菇接住,然而只能接住没有毒的蘑菇。如果接住了有毒的蘑菇,游戏就失败了!这款游戏尽管很简略,整个游戏的代码也只有 200 多行,然而却蕴含了python游戏编程里70%的外围知识点,所以只有你读懂了这款游戏的所有代码!你就能够开始开发本人的python小游戏了,比方,像打飞机,打地鼠,这样的小游戏,你必定也是可能写的进去的! 尽管这个游戏很简略,然而为了让小伙伴真的能学会python游戏编程 ,猫姐这里也要分成几个视频一步一步地教大家把这个游戏写进去。 明天这一集,咱们先来学习一下python游戏编程的根本套路,学习完这个套路后,下一集,猫姐将在第一集代码的根底上,实现一个用方向键管制的小方块,成果是这样的。 当然,这个方块最初会变成一个采蘑菇的小朋友!不多说,咱们进入正题吧! 1.python游戏开发的根本套路这一集,猫姐将带大家简略认识一下 pygame,pygame是 python 游戏开发的一个框架,应用这个框架咱们能够用 python 语言疾速开发出各种游戏。所以在写游戏代码前,还是须要理解一下 pygame 的根本工作原理。 2. 意识 pygame 的根本框架首先,咱们新建一个 part1-game.py 的文件,而后关上这个文件开始写代码!咱们将 pygame , locals , sys 这些模块导入进来,不便前面应用。 import pygamefrom pygame.locals import *import sys接下来再通过 pygame 的 init 函数实现游戏的初始化工作,因为咱们应用的游戏框架是 pygame ,在应用前,都须要对其进行一些初始化,大家不必过多的去理解细节,只有晓得这是必须的就能够了,就像咱们吃饭前要洗手,拿筷子一样。 pygame.init()初始化工作实现后,因为咱们的游戏是运行在一个窗口外面,所以这里还要创立一个窗口。咱们先来定义窗口的宽度和高度,创立窗口能够通过pygame.display.set_mode 这个函数来实现,在 set_mode 函数的括号外面,须要传入的是游戏窗口的宽度和高度。这个函数将失去一个返回值,咱们用 screen 这个变量保留这个返回值。 WIDTH = 600HEIGHT = 800screen = pygame.display.set_mode((WIDTH, HEIGHT))当初把程序运行一下,看看成果,单击鼠标右键,抉择Run + part1-game,程序运行起来后,能够看到窗口一闪而过,就隐没了。 为什么窗口会隐没呢?这是因为代码从上到下胜利运行后就胜利退出了,而实在的游戏须要不停地刷新窗口,并将内容显在屏幕上,所以咱们还须要应用while True这个有限循环,这样代码就不会退出了。在while True循环外面,应用pygame.display.update函数来更新屏幕上显示的内容。这里咱们能够看到一个比拟残缺代码了。 ...

April 13, 2022 · 1 min · jiezi

关于pygame:pygame实现成语填空游戏

最近看到很多人玩成语填字游戏,那么先用pygame来做一个吧,花了大半天终于实现了,附下效果图。偷了下懒程序没有拆分,所有程序写在一个文件里,次要代码如下: # -*- coding=utf-8 -*- import sys import random import pygame from pygame.locals import * reload(sys) sys.setdefaultencoding('utf-8') f = open('words.txt') all_idiom = f.readlines() f.close() word_dic = {} for idiom in all_idiom: idiom = idiom.strip().decode('utf-8') for word in idiom: if word not in word_dic: word_dic[word] = [idiom] else: word_dic[word].append(idiom) word_arr = list(word_dic.keys()) header_height = 30 main_space = 20 block_size = 36 block_num=12 bspace = 2 space = 20 width = block_size * block_num + main_space * 2 height = header_height + block_size * block_num + main_space * 2 + (block_size+space) * 3 pygame.init() screen = pygame.display.set_mode((width,height)) screencaption = pygame.display.set_caption(u'成语填空') font = pygame.font.Font(u'syht.otf', int(block_size*0.8)) dray_gray = 50,50,50 white = 255,255,255 #textImage = font.render(u'你好', True, white) class IdiomInfo(object): def __init__(self,idiom): self.idiom = idiom self.dire = 0 self.word_arr = [] class WordInfo(object): def __init__(self, word, i, j): self.i = i self.j = j self.word = word self.is_lock = True self.state = -1 self.hide_index = -1 self.op_hide_index = -1 class Matrix(object): rows = 0 cols = 0 data = [] def __init__(self, rows, cols, data=None): self.rows = rows self.cols = cols if data is None: data = [None for i in range(rows * cols)] self.data = data def set_val(self, x, y, val): self.data[y * self.cols + x] = val def get_val(self, x, y): return self.data[y * self.cols + x] def exist_val_four_around(self, x, y, ignore_set): move_arr = [(-1,0),(1,0),(0,-1),(0,1)] for dx,dy in move_arr: tx = x + dx ty = y + dy if (tx,ty) in ignore_set: continue if tx < 0 or tx >= self.cols or ty <0 or ty >= self.rows: continue if self.data[ty * self.cols + tx]: return True return False def check_new_idiom(matrix, new_idiom, new_dire, word_info): windex = new_idiom.index(word_info.word) cx,cy = word_info.i, word_info.j ignore_set = set([(cx,cy)]) new_idiom_word_arr=[] for i in range(-windex,-windex+len(new_idiom)): if i==0: new_idiom_word_arr.append(word_info) else: tx = cx+i if new_dire == 0 else cx if tx < 0 or tx >= block_num: return None,None ty = cy if new_dire == 0 else cy+i if ty < 0 or ty >= block_num: return None,None if matrix.exist_val_four_around(tx, ty, ignore_set): return None,None old_word_info = matrix.get_val(tx, ty) if old_word_info: return None,None new_word_info = WordInfo(new_idiom[i+windex], tx, ty) new_idiom_word_arr.append(new_word_info) return new_idiom_word_arr,windex def add_idiom_to_matrix(matrix, word_dic, idiom_dic, idiom_num): if idiom_num == 0: return 0 for idiom,idiom_info in idiom_dic.items(): dire = idiom_info.dire new_dire = 1 - dire for word_info in idiom_info.word_arr: word = word_info.word idiom_list = word_dic[word] for new_idiom in idiom_list: if new_idiom in idiom_dic: continue new_idiom_word_arr,windex = check_new_idiom(matrix, new_idiom, new_dire, word_info) if new_idiom_word_arr: new_idiom_info = IdiomInfo(new_idiom) new_idiom_info.dire = new_dire for new_index in range(len(new_idiom_word_arr)): new_word_info = new_idiom_word_arr[new_index] if new_index == windex: new_idiom_info.word_arr.append(word_info) else: matrix.set_val(new_word_info.i, new_word_info.j , new_word_info) new_idiom_info.word_arr.append(new_word_info) idiom_dic[new_idiom] = new_idiom_info return len(new_idiom) -1 + add_idiom_to_matrix(matrix, word_dic, idiom_dic, idiom_num - 1) return 0 def get_idiom_matrix(word_arr, word_dic, idiom_num): cx = 4 cy = 4 matrix = Matrix(block_num, block_num) n = random.randint(0,len(word_arr)-1) word = word_arr[n] idiom = word_dic[word][0] idiom_dic={} idiom_dic[idiom] = IdiomInfo(idiom) wn = len(idiom) last_i = -100 for i in range(len(idiom)): word_info = WordInfo(idiom[i],cx-1+i,cy) matrix.set_val(cx-1+i,cy,word_info) idiom_dic[idiom].word_arr.append(word_info) wn += add_idiom_to_matrix(matrix, word_dic, idiom_dic, idiom_num-1) return matrix, idiom_dic, wn bg_image = pygame.image.load('bg.jpeg') bg_image = pygame.transform.scale(bg_image,(width, height)) bg2_image = pygame.image.load('bg2.jpeg') bg2_image = pygame.transform.scale(bg2_image,(block_size*block_num,block_size*block_num)) block_bg_image = pygame.image.load('tzg.jpg') block_bg_image = pygame.transform.scale(block_bg_image,(block_size-bspace*2,block_size-bspace*2)) def get_hide_arr(matrix, idiom_dic, all_word_num, percent): hide_arr = [] for k,v in idiom_dic.items(): n = random.randint(0, len(v.word_arr)-1) word_info = v.word_arr[n] if word_info.hide_index != -1:continue word = word_info.word info = matrix.get_val(word_info.i,word_info.j) info.word = '' info.hide_index = len(hide_arr) info.is_lock = False hide_arr.append([word_info.i,word_info.j,word,None]) tmp_arr = [] for i in range(block_num): for j in range(block_num): info = matrix.get_val(i,j) if info and info.word: tmp_arr.append((i,j,info.word)) while len(hide_arr) < all_word_num*percent: n = random.randint(0,len(tmp_arr)-1) i,j,word = tmp_arr.pop(n) info = matrix.get_val(i,j) info.word = '' info.hide_index = len(hide_arr) info.is_lock = False hide_arr.append([i,j,word,None]) return hide_arr def get_next_select(matrix, x, y): arr = [] for i in range(block_num): for j in range(block_num): info = matrix.get_val(i, j) if info is not None and len(info.word) == 0: dist = (i-x)*(i-x)+(j-y)*(j-y) if i<x: dist+=0.2 if j<y: dist+=0.4 arr.append((i,j,dist)) if len(arr) == 0: return None arr.sort(cmp=lambda x,y:cmp(x[-1],y[-1])) return (arr[0][0],arr[0][1]) def check_idiom(): for idiom, idiom_info in idiom_dic.items(): tmp_idiom_str = '' word_arr = idiom_info.word_arr for word_info in word_arr: word = word_info.word if len(word) > 0: tmp_idiom_str+=word if len(tmp_idiom_str) == len(idiom): state = 1 if tmp_idiom_str == idiom else 2 else: state = 0 for word_info in word_arr: if word_info.state != 1: word_info.state = state for idiom, idiom_info in idiom_dic.items(): word_arr = idiom_info.word_arr for word_info in word_arr: if word_info.state != 1: return False return True stage = 1 def init(new_stage): idiom_num = (new_stage/5)+3 if new_stage>100: percent = 0.7 else: percent = 0.2+(new_stage*1.0/100)*(0.7-0.2) matrix,idiom_dic,all_word_num = get_idiom_matrix(word_arr, word_dic, idiom_num) hide_arr = get_hide_arr(matrix, idiom_dic, all_word_num, percent) select_rect = hide_arr[0][0],hide_arr[0][1] stage_textImage = pygame.font.Font(u'syht.otf', 30).render(u'第%s关'%new_stage, True, dray_gray) return matrix,idiom_dic,all_word_num,hide_arr,select_rect,stage_textImage matrix,idiom_dic,all_word_num,hide_arr,select_rect,stage_textImage = init(stage) stage_font_width, stage_font_height = stage_textImage.get_size() stage_x = (width - stage_font_width)/2 stage_y = (header_height - stage_font_height)/2+main_space/2 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() if event.type == MOUSEBUTTONDOWN: pressed_array = pygame.mouse.get_pressed() if pressed_array[0]: x, y = pygame.mouse.get_pos() for i in range(block_num): for j in range(block_num): bx = main_space + block_size*i+bspace by = header_height + main_space + block_size*j+bspace if x >= bx and x <= bx+block_size-bspace*2 and y >= by and y<= by+block_size-bspace*2: info = matrix.get_val(i, j) if info and info.state != 1 and info.hide_index >= 0: if info.op_hide_index>=0: hide_arr[info.op_hide_index][-1] = None info.word = '' info.op_hide_index=-1 check_idiom() select_rect = i,j break sx = main_space sy = header_height + main_space+ block_size*block_num +space n = 0 for hi in range(len(hide_arr)): tmp_x = sx + (n%block_num)*block_size tmp_y = sy + (n/block_num)*block_size if hide_arr[hi][-1] is None and x >= tmp_x and x <= tmp_x+block_size-bspace*2 and y >= tmp_y and y<= tmp_y+block_size-bspace*2: info = matrix.get_val(select_rect[0],select_rect[1]) info.word = hide_arr[hi][2] info.op_hide_index = hi info.state = 0 hide_arr[hi][-1] = select_rect new_select_rect = get_next_select(matrix, select_rect[0],select_rect[1]) select_rect = new_select_rect flag = check_idiom() if flag: stage += 1 matrix,idiom_dic,all_word_num,hide_arr,select_rect,stage_textImage = init(stage) break n += 1 screen.blit(bg_image, (0,0)) screen.blit(stage_textImage, (stage_x,stage_y)) panel = screen.subsurface((main_space,header_height+main_space,block_size*block_num,block_size*block_num)) panel.blit(bg2_image, (0,0)) for i in range(block_num): for j in range(block_num): info = matrix.get_val(i,j) if info is not None: bx = block_size*i+bspace by = block_size*j+bspace panel.blit(block_bg_image, (bx,by)) if info.state == 1: textImage = font.render(info.word, True, (30,144,30)) elif info.state == 2: textImage = font.render(info.word, True, (255,0,0)) elif info.is_lock == 1: textImage = font.render(info.word, True, (150,150,150)) else: textImage = font.render(info.word, True, dray_gray) tw, th = textImage.get_size() dx=(block_size-bspace*2-tw)/2 dy=(block_size-bspace*2-th)/2 panel.blit(textImage, (bx+dx,by+dy)) if (i,j) == select_rect: pygame.draw.rect(panel,(255,0,0),(bx,by,block_size-bspace*2,block_size-bspace*2),2) sx = main_space sy = header_height + main_space+ block_size*block_num +space n = 0 for i,j,word,op in hide_arr: screen.blit(block_bg_image, (sx + (n%block_num)*block_size,sy + (n/block_num)*block_size)) if op is None: textImage = font.render(word, True, dray_gray) tw, th = textImage.get_size() dx=(block_size-bspace*2-tw)/2 dy=(block_size-bspace*2-th)/2 screen.blit(textImage, (dx+sx+ (n%block_num)*block_size,dy+sy+ (n/block_num)*block_size)) n+=1 pygame.display.update()代码就这么多了,不过这边用到几个额定的依赖:bg.jpeg 用于做整个界面的背景bg2.jpeg 用于做上半局部的背景tzg.jpg 每个文字的格子的背景words.txt 一个成语的列表文件(每行一条成语),如果换成诗词或者歇后语什么的也是没有问题的syht.otf 一个字体库,用于失常显示中文 ...

July 8, 2021 · 6 min · jiezi

关于pygame:向量使用1pygame编写篮球游戏火柴人运球避开防守跳起投篮向量法处理防守者逼近投篮者前进数据

编写“火柴人运球避开防守跳起投篮”游戏时,未零碎学习pygame,边看边编程,并不知道pygame中有向量。游戏中投篮者凑近篮板投篮,防守者迫近防守,向投篮者方向挪动若干间隔。原计算后退间隔的代码没应用向量,因而逻辑关系较简单,精度差,还破费较多工夫。后发现pygame中有向量,改为向量法实现,可简化编程,进步了精度。程序中篮球从投篮处向篮板后退代码,也可应用向量,但改后和原代码没有劣势,因而未改。向量是解决这类问题罕用的办法,是编写游戏必须把握的常识。 文章中特别强调:对于向量的一个要点是,它们仅示意绝对方向和大小,一个向量的地位是没有意义的。这是指数学意义上的向量。但实际上,在程序中解决的向量是在游戏坐标系中的有向线段,地位还是必要的。能够这样了解,有向线段是指定了地位的向量,因而,向量的许多概念和办法也实用于有向线段。另外,请认真学习向量差的物理意义。Guard类的办法draw(self)中被改写代码如下。请留神是投篮者向量减防守者向量,从而产生从防守者到投篮者的向量,防守者从本人所在位置登程沿向量方向迫近投篮者。这里防守者处是静止的出发点,投篮者处是目的地,为方便使用请记住:出发点到目标点向量,是目的地减出发点。很多游戏要用到这些概念,例如,投篮、踢球和射击等。 vGuard=pygame.math.Vector2(self.x,self.y) #防守者向量,参数是防守者坐标vPlayer=pygame.math.Vector2(self.PlayerX,self.PlayerY) #投篮者向量,参数是投篮者坐标vG_P=vPlayer-vGuard #留神投篮者向量减防守者向量,产生从防守者到投篮者的向量dist=vG_P.length() #防守者到投篮者间隔#vG_P=vG_P.normalize() #可先变单位向量#vG_P=vG_P*5 #向量长度变为5vG_P.scale_to_length(5) #也可间接将向量长度变为5,这是防守者向投篮者方向1帧后退间隔if dist>200: #如距投篮者>200,返回初始点 self.x,self.y=400,300elif self.PlayerFrameNum<4: #如投篮者未投篮,迫近投篮者 self.x+=int(vG_P.x) #防守者挪动 self.y+=int(vG_P.y)残缺程序如下。所需图形和原来程序雷同。 import pygameimport mathimport randomimport osclass Ball(): #篮球类 def __init__(self,screen): #screen是游戏主窗体,Surface类实例 self.screen=screen b=pygame.image.load('b.png').convert_alpha() #失去篮球图形 r=b.get_rect() self.p=pygame.transform.scale(b,(r.width//2,r.height//2)) #放大图形 self.x,self.y,self.xi,self.yi=0,0,0,0#(x,y)篮球坐标,(xi,yi)是篮球两个地位间增量 self.frameNum=9 #篮球帧编号(1-8),=9,篮球不可见 self.mark=0 #此次投篮中否,=0不中,=1中 self.score=0 #投篮投中次数(得分) def draw(self): #主程序调用,实现篮球动画 if self.frameNum==9: #篮球帧编号=9,篮球不可见 return if self.frameNum==1: #第1帧计算必要数据,下句坐标(self.x,self.y)是球运行终点 dx,dy=(400-self.x),(40-self.y) #坐标(400,530)点是球碰到篮板上的点 self.xi=dx//6 #篮球从起始点到篮板每帧沿x轴后退的增量 self.yi=dy//6 #篮球从起始点到篮板每帧沿y轴后退的增量 dist=math.sqrt((dx**2)+(dy**2)) #投篮点间隔篮板间隔 n=int(dist//100) #除数越小,总投中率越低 if random.randint(1,n+1)==1: #随机数为1投中,n+1防止dist<100为0 self.mark=1 #投中标记为1 else: self.mark=0 #投不中为0 if self.frameNum>=1 and self.frameNum<6: #从第1帧到第5帧,球按此法后退 self.x+=self.xi #篮球每帧沿x轴减少1个增量值 self.y+=self.yi #篮球每帧沿y轴减少1个增量值 self.frameNum+=1 elif self.frameNum==6: #此帧球将碰到篮板,要精确管制碰到篮板的落点 self.x=400 #球碰到篮板的x坐标 self.frameNum+=1 if self.mark==1: #投中,篮球落点y轴方向凑近篮筐 self.y=90 else: #投不中,篮球落点y轴方向离篮筐较远 self.y=70 else: #篮球着落的两个点,即第7,8帧 if self.mark==0: #球未投中,球除着落,还沿x轴方向挪动,球从篮筐两侧落下 if self.xi>=0: #如球从左到右,最初两帧,球沿x轴方向持续从左向右挪动 self.x+=30 else: self.x-=30 #否则最初两帧,球沿x轴方向持续从右向左挪动 self.y+=25 #如投中x坐标不变,即球间接着落穿过篮筐 self.frameNum+=1 self.screen.blit(self.p, (self.x, self.y)) #在屏幕指定地位绘制篮球 if self.frameNum==9 and self.mark==1: #球所有动作实现,判断得分是否加1 self.score+=1class Guard(): #防守者类 def __init__(self,screen): ##screen是游戏主窗体,Surface类实例 self.screen=screen self.images=[] for n in range(2): #将2帧图像保留到列表中 p = pygame.image.load(str(n+16)+'.png').convert_alpha()#文件名为16.png,17.png r=p.get_rect() p = pygame.transform.scale(p, (r.width//6, r.height//6)) #调整图像的大小 self.images.append(p) self.frameNum=0 #帧编号,0-1 self.x,self.y=400,300 #防守运动员在窗体的初始坐标 self.PlayerX,self.PlayerY=0,0 #此时投篮手坐标 self.PlayerFrameNum=0 #此时投篮手帧号 self.rect=None#调用blit绘制图形,返回rect记录图形在screen坐标和图形宽和高,用来检测碰撞 def draw(self): #主程序调用,实现防守者动画 p=self.images[self.frameNum] #取出以后帧图形 if self.PlayerX-self.x<0: #面向投篮手 p=pygame.transform.flip(p,True,False) vGuard=pygame.math.Vector2(self.x,self.y) #防守者向量,参数是防守者坐标 vPlayer=pygame.math.Vector2(self.PlayerX,self.PlayerY) #投篮者向量,参数是投篮者坐标 vG_P=vPlayer-vGuard #留神投篮者向量减防守者向量,产生从防守者到投篮者的向量 dist=vG_P.length() #防守者到投篮者间隔 #vG_P=vG_P.normalize() #可先变单位向量 #vG_P=vG_P*5 #向量长度变为5 vG_P.scale_to_length(5) #也可间接将向量长度变为5,这是防守者向投篮者方向1帧后退间隔 if dist>200: #如距投篮者>200,返回初始点 self.x,self.y=400,300 elif self.PlayerFrameNum<4: #如投篮者未投篮,迫近投篮者,如投篮者投篮,防守者地位不变 self.x+=int(vG_P.x) #防守者挪动 self.y+=int(vG_P.y) #下句返回rect用来检测碰撞,其属性x,y是图形在游戏窗口坐标,width,hight是图形宽和高 self.rect=self.screen.blit(p,(self.x,self.y)) #在屏幕指定地位绘制防守者 self.frameNum+=1 if self.frameNum==2: self.frameNum=0class Player(): #投篮手类 def __init__(self,screen): #screen是游戏主窗体,Surface类实例 self.screen=screen self.images=[] for n in range(16): #将16帧图像(包含运球和跳投图像)保留到列表中 p = pygame.image.load(str(n)+'.png').convert_alpha()#文件名为1.png,2.png... r=p.get_rect() p = pygame.transform.scale(p, (r.width//6, r.height//6)) #调整图像的大小 self.images.append(p) self.frameNum=0 #帧编号,运球为0到3,跳投为4到15 self.x,self.y=0,0 #图像在窗体的坐标 self.mouseX,self.mouseY=0,0 #此时鼠标坐标值 self.jumpUpOrDown=-10 #按空格键后投篮手向上跳,初始值为正数。到最高点后着落,为负数 self.rect=None#调用blit绘制图形,返回rect记录图形在screen坐标和图形宽和高,用来检测碰撞 def dribble(self): #运球动画 p=self.images[self.frameNum] if self.mouseX-self.x<0: #面向鼠标 p=pygame.transform.flip(p,True,False) self.x,self.y=self.mouseX,self.mouseY #投篮手坐标=鼠标坐标 if self.x<1: #管制投篮手必须在篮球场中 self.x=1 if self.x+90>width: self.x=width-90 if self.y<230: self.y=230 if self.y+120>height: self.y=height-120 self.rect=self.screen.blit(p,(self.x,self.y)) #在指定地位绘制图形,返回rect self.frameNum+=1 if self.frameNum==4: self.frameNum=0 def jumpShot(self): #跳投动画 p=self.images[self.frameNum] if self.x>width/2: #面向篮板 p=pygame.transform.flip(p,True,False) self.screen.blit(p, (self.x, self.y)) #跳投初始地位是运球转跳投时地位 self.y+=self.jumpUpOrDown #当前先向上(y值缩小),到最高点后降落 self.frameNum+=1 if self.frameNum==9: #开始着落,着落值为正 self.jumpUpOrDown=10 if self.frameNum==16: #=16,跳起投篮完结,转运球 self.frameNum=0 self.jumpUpOrDown=-10pygame.init()os.environ['SDL_VIDEO_WINDOW_POS']="%d,%d"%(200,40) #游戏窗口距左侧和顶部点数为200,40size = width, height = 800,600 #创立游戏窗口大小screen = pygame.display.set_mode(size) pygame.display.set_caption("投手运球和跳投") #设置窗口题目bg_img = pygame.image.load("篮球场1.png").convert() #背景篮球场图像fclock = pygame.time.Clock() #创立管制频率的clockfps = 4 #定义刷新频率player=Player(screen) #投篮手类实例ball=Ball(screen) #篮球类实例guard=Guard(screen) #防守者类实例font1 = pygame.font.SysFont('宋体', 50, True) #创立字体gameOver=False #该次游戏是否完结,初始不完结running = True #程序是否完结,初始运行while running: for event in pygame.event.get(): if event.type == pygame.QUIT: #解决退出事件 running = False #程序完结 if event.type == pygame.MOUSEMOTION: #鼠标挪动事件 player.mouseX,player.mouseY=event.pos #将鼠标地位传递给投篮手用于运球 if event.type == pygame.KEYUP: #按键后抬起事件,防止长按键不抬起 if event.key == pygame.K_SPACE: #按空格键后抬起 if player.frameNum<4: #如在运球状态,转投篮状态 player.frameNum=4 #已在投篮状态不解决 if event.key == pygame.K_r and gameOver==True: #按r键后抬起,重玩游戏 gameOver=False ball.score=0 screen.blit(bg_img, (0, 0)) #绘制篮球场背景 surface1=font1.render('score:'+str(ball.score),True,[255,0,0]) #不能显示中文 screen.blit(surface1, (20, 20)) #显示进球数(得分) if gameOver==True: #如果该次游戏完结,后边程序不再执行 fclock.tick(fps) #fps是每秒多少帧,减去程序运行工夫,为实现fps,还需延迟时间 continue if player.frameNum>=4: #如果投篮手帧号>=4,投篮手正在跳投 player.jumpShot() if player.frameNum==8: #第8帧跳起手中无球,篮球要呈现并开始向篮板静止 ball.frameNum=1 #球向篮板静止第1帧 ball.x=player.x #球向篮板静止的起始地位 ball.y=player.y else: #如果投篮手帧号<4,投篮手正在运球 player.dribble() ball.draw() #篮球动画 guard.PlayerX,guard.PlayerY=player.x,player.y #将投篮手地位传递给防守者 guard.PlayerFrameNum=player.frameNum #将投篮手帧号传递给防守者 guard.draw() #防守运动员动画 if player.frameNum<4: #仅在投篮手运球时,判断和防守者是否产生碰撞 if player.rect.colliderect(guard.rect): #检测投篮者和防守者是否产生碰撞 gameOver=True #产生碰撞,游戏完结 surface2=font1.render('if play again,press key r',True,[255,0,0]) screen.blit(surface2, (20, 100)) #显示如持续玩,按r键 pygame.display.flip() #刷新游戏场景 fclock.tick(fps) #fps是每秒多少帧,减去程序运行工夫,为实现fps,还需延迟时间pygame.quit()

June 30, 2021 · 2 min · jiezi

关于pygame:pygame游戏实例入门

开发环境pycharm+anconda3;第三方库: pygame;(从题目看这句略显多余) 第三方库装置办法一:间接在pycharm外面装置。files->seting->project->python Interpreter在左侧界面的最左侧边栏下面有个加号,点击后在弹出页面搜寻须要的第三方库,而后间接装置。办法二:pip装置。因为用的是anconda所以须要在终端外面将目录切换至anconda3/Scripts后再装置。命令:pip installs pygame工作介绍本工作是开发一个猴子接香蕉的小游戏,通过键盘管制猴子静止,接住随机掉落的香蕉。读者须要自行筹备背景图片,猴子图片,香蕉图片三张,当然,如果不喜爱猴子或香蕉也能够抉择其它物品的图片作为素材。大略实现思路咱们须要编写两个类:猴子类,和香蕉类两个类都须要有图片门路,静止速度,初始地位等属性。还须要有让他们静止的办法。其中,香蕉只须要编写从上至下静止,猴子类须要让猴子能够在上下左右不同方向静止。主函数外面须要用键盘来管制猴子静止,随机生成香蕉从上到下静止,并且检测猴子是否碰到香蕉 具体实现流程游戏背景界面首先是做一个游戏的背景界面,这外面须要引入背景图片,并且实现手动开关游戏界面。 主函数: import pygameimport sysdef main(): pygame.init()#初始化pygame size = width, height = 450, 560#界面尺寸 screen = pygame.display.set_mode(size)#设置界面尺寸 bg = pygame.image.load('background.jpg')#加载背景图片 pygame.display.set_caption("游戏")#设置题目 while True: #检测事件产生 for event in pygame.event.get(): if event.type == pygame.QUIT:#产生的事件类型为敞开时 sys.exit() #退出 screen.blit(bg, bg.get_rect()) #显示图片 pygame.display.update() #更新 pygame.time.Clock().tick(60) #设置游戏频率为60if __name__ == '__main__': main()猴子类猴子类编写界面的坐标是左上角为(0,0),猴子的起始地位为右下角,所以坐标是(界面宽度-猴子宽度,界面高度-猴子高度) class Monkey(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) position = 400, 510 self.speed = [0, 0] self.img = pygame.image.load('monkey.png') self.rect = self.img.get_rect() self.rect.center = position self.image = self.img def move_left(self): self.speed = [-5, 0] if self.rect.left < 0: self.rect.left = 0 else: self.rect = self.rect.move(self.speed) def move_right(self): self.speed = [5, 0] if self.rect.right > 450: self.rect.right = 450 else: self.rect = self.rect.move(self.speed) def move_up(self): self.speed = [0, -5] if self.rect.top < 0: self.rect.top = 0 else: self.rect = self.rect.move(self.speed) def move_down(self): self.speed = [0, 5] if self.rect.bottom > 560: self.rect.bottom = 560 else: self.rect = self.rect.move(self.speed)猴子类运行猴子类运行时须要依据键盘所按下的键来判断猴子静止状态,须要在后面加一句 from pygame.locals import ...

June 28, 2021 · 3 min · jiezi

关于pygame:Pygame欢乐打地鼠游戏unit01-项目初始化

打地鼠游戏:0.游戏界面1.根本套路 import pygameimport syspygame.init()screen = pygame.display.set_mode((500,500))while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()2.设置题目和图标 pygame.display.set_caption('打地鼠')iconImg = pygame.image.load('./images/a.png')pygame.display.set_icon(iconImg)3.加载背景图 bgImg = pygame.image.load('./images/背景.png')screen.blit(bgImg, (0,0))pygame.display.update()4.设置游戏画面帧率 colok = pygame.time.Clock()clock.tick(60)5.封装draw() / eventListen()函数 def draw(): screen.blit(bgImg, (0, 0))def eventListen(): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()残缺代码 import pygameimport syspygame.init()screen = pygame.display.set_mode((500,500))pygame.display.set_caption('打地鼠')iconImg = pygame.image.load('./images/a.png')pygame.display.set_icon(iconImg)#加载背景图片bgImg = pygame.image.load('./images/背景.png')def draw(): screen.blit(bgImg, (0, 0))def eventListen(): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()while True: pygame.time.Clock().tick(60) eventListen() draw() pygame.display.update()

June 28, 2021 · 1 min · jiezi

关于pygame:pygame编写篮球游戏火柴人运球避开防守跳起投篮

网上有很多篮球类游戏,这里应用pygame编写了一个。游戏中有一个投篮手,一个防守者。投篮手运球避开防守,跳起投篮,投中得一分。投篮手离篮筐越近,投篮准确率越高,但离篮筐越近,越可能碰到防守者,如碰到,游戏完结。下边是游戏的效果图。游戏背景是篮球场,如上图。有3个角色,投篮手、防守者和篮球各1个,别离用类来定义。角色动画造型采纳火柴人,这是因为火柴人造型容易找到,即便本人画一个也不难。惋惜自己画图能力太差,只能从一段视频中一帧一帧抠出造型。所有图形背景都要设置为通明。3个角色所有图形如下:投篮手运球有4个彩色造型,帧号0-3,当按空格键将启动跳投,将帧号批改为4,跳投有12个彩色造型,帧号4-15,所有造型用来实现投篮手运球和跳投动画。在前1篇博文“篮球游戏中的运球_用列表保留每帧图片”中,能够看到在每秒4帧图形状况下,4个造型就能够实现运球动画,留神球也是造型的一部分。但在每秒4帧图形状况下,跳投动画仅用4帧图形是不可能的,试了一下,每秒4帧,感觉要用12帧图形,即跳投从起跳到再落下需用12*\0.25秒=3秒工夫,才有称心的动画成果。跳投的12个图形有有点对付事,但还是能看到动画成果的,如把12个图形认真画一下,可能成果更好。留神,跳投的第4、5和6帧中图形是有篮球的,后边帧无篮球,在适当时候(本例在第8帧),篮球角色将呈现在投篮者上方,以此为终点向篮板静止,在第13帧碰到篮板,第14和15帧球向下静止,如投中,间接掉到蓝中,如未投中,从侧方向下掉。篮球只有一个图形。首先要解决的问题是那种状况投篮能中,那种状况投篮不中。网上投篮游戏投中规定形形色色。本游戏规则是:间隔篮筐越远投篮越不准,在某一点投篮,那次投中,那次投不中无规律,或者说是随机的,但投中概率是定值。设从投篮点到篮筐间隔为L,令n=(L//100)取整数,应用随机数发生器产生1到n+1之间随机整数。规定随机数为1,投中,其它随机整数投不中。如点到篮筐架间隔Y<100,n=0,投中率为100%;如200>L>99,n=1,投中率为50%;如300>L>199,n=2,投中率为33%,等等。防守者只有2个黄色造型,仿佛少了点,在本例勉强够用。当防守者和投篮手间隔大于200,防守者退到防守初始地位。小于200,而且投篮手正在运球,防守者迫近防守,即防守者面向投篮手挪动若干间隔(应为整数),如碰到投篮手,游戏完结。所谓面向,即防守者沿防守者和投篮手连线挪动。这样,这个连线L,以及防守者和投篮手两点沿x、y轴的差值dx和dy组成一个直角三角形。如防守者每帧沿x轴挪动dx1,沿y轴挪动dy1,只有dx1/dy1=dx/dy,就保障防守者面向投篮手挪动。可令dy1=7,则dx1=7dx/dy。但dy为0,要产生被0除谬误。为防止此种状况,可先判断dx和dy大小,如dx<dy,采纳上式,否则,dx1=7,dy1=7dy/dx。留神dx和dy是不可能同时为0的,因同时为0前,投篮手和防守者就会靠近,产生碰撞,导致游戏完结。这样做,不同方向挪动的间隔可能不同,上例中,最大值为两直角边都为7,间隔为9.899,只能取整数为:9,如较小直角边为0,则间隔为7。另外,沿x、y轴增量都只能是整数,因而方向也有误差。以下是游戏全副程序,做了具体注解,应该较容易读懂程序。程度无限,未免有考虑不周之处,欢送批评指正。仅拷贝源程序不能正确运行,须要制作投篮手和防守者全副造型,球造型,背景篮球场,放到源程序所在文件夹中。将把源程序和所有图像打包上传,有须要的读者可下载。玩网络游戏时,因为投篮者随鼠标挪动,在关上程序或重玩游戏时,必须把鼠标移到程序窗口外边界,防止程序一开始就和防守者产生碰撞,导致游戏完结。 import pygameimport mathimport randomimport osclass Ball(): #篮球类 def __init__(self,screen): #screen是游戏主窗体,Surface类实例 self.screen=screen b=pygame.image.load('b.png').convert_alpha() #失去篮球图形 r=b.get_rect() self.p=pygame.transform.scale(b,(r.width//2,r.height//2)) #放大图形 self.x,self.y,self.xi,self.yi=0,0,0,0#(x,y)篮球坐标,(xi,yi)是篮球两个地位间增量 self.frameNum=9 #篮球帧编号(1-8),=9,篮球不可见 self.mark=0 #此次投篮中否,=0不中,=1中 self.score=0 #投篮投中次数(得分) def draw(self): #主程序调用,实现篮球动画 if self.frameNum==9: #篮球帧编号=9,篮球不可见 return if self.frameNum==1: #第1帧计算必要数据,下句坐标(self.x,self.y)是球运行终点 dx,dy=(400-self.x),(40-self.y) #坐标(400,530)点是球碰到篮板上的点 self.xi=dx//6 #篮球从起始点到篮板每帧沿x轴后退的增量 self.yi=dy//6 #篮球从起始点到篮板每帧沿y轴后退的增量 dist=math.sqrt((dx**2)+(dy**2)) #投篮点间隔篮板间隔 n=int(dist//100) #除数越小,总投中率越低 if random.randint(1,n+1)==1: #随机数为1投中,n+1防止dist<100为0 self.mark=1 #投中标记为1 else: self.mark=0 #投不中为0 if self.frameNum>=1 and self.frameNum<6: #从第1帧到第5帧,球按此法后退 self.x+=self.xi #篮球每帧沿x轴减少1个增量值 self.y+=self.yi #篮球每帧沿y轴减少1个增量值 self.frameNum+=1 elif self.frameNum==6: #此帧球将碰到篮板,要精确管制碰到篮板的落点 self.x=400 #球碰到篮板的x坐标 self.frameNum+=1 if self.mark==1: #投中,篮球落点y轴方向凑近篮筐 self.y=90 else: #投不中,篮球落点y轴方向离篮筐较远 self.y=70 else: #篮球着落的两个点,即第7,8帧 if self.mark==0: #球未投中,球除着落,还沿x轴方向挪动,球从篮筐两侧落下 if self.xi>=0: #如球从左到右,最初两帧,球沿x轴方向持续从左向右挪动 self.x+=30 else: self.x-=30 #否则最初两帧,球沿x轴方向持续从右向左挪动 self.y+=25 #如投中x坐标不变,即球间接着落穿过篮筐 self.frameNum+=1 self.screen.blit(self.p, (self.x, self.y)) #在屏幕指定地位绘制篮球 if self.frameNum==9 and self.mark==1: #球所有动作实现,判断得分是否加1 self.score+=1class Guard(): #防守者类 def __init__(self,screen): ##screen是游戏主窗体,Surface类实例 self.screen=screen self.images=[] for n in range(2): #将2帧图像保留到列表中 p = pygame.image.load(str(n+16)+'.png').convert_alpha()#文件名为16.png,17.png r=p.get_rect() p = pygame.transform.scale(p, (r.width//6, r.height//6)) #调整图像的大小 self.images.append(p) self.frameNum=0 #帧编号,0-1 self.x,self.y=400,300 #防守运动员在窗体的初始坐标 self.PlayerX,self.PlayerY=0,0 #此时投篮手坐标 self.PlayerFrameNum=0 #此时投篮手帧号 self.rect=None#调用blit绘制图形,返回rect记录图形在screen坐标和图形宽和高,用来检测碰撞 def draw(self): #主程序调用,实现防守者动画 p=self.images[self.frameNum] #取出以后帧图形 if self.PlayerX-self.x<0: #面向投篮手 p=pygame.transform.flip(p,True,False) dx,dy=self.PlayerX-self.x,self.PlayerY-self.y #防守者和投篮手两点沿x、y轴的差值dx和dy dist=math.sqrt((dx**2)+(dy**2)) #计算投篮手和防守者间隔 dx1,dy1=0,0 #防守者每帧沿x轴挪动dx1,沿y轴挪动dy1 if dist>200: #如距投篮者>200,返回初始点 self.x,self.y=400,300 elif self.PlayerFrameNum<4: #如投篮者未投篮,迫近投篮者,如投篮者投篮,防守者地位不变 if abs(dx)<abs(dy): #保障abs(dy)不为0,使下句dx/dy肯定不会被0除 d=abs(dx/dy) dy1=7 #如矩形长边为7, dx1=int((dy1*d)//1) #dx1可能是:0,1,2,3,4,5,6,7 else: #保障abs(dx)不为0,使下句dy/dx肯定不会被0除 d=abs(dy/dx) dx1=7 #如矩形长边为7, dy1=int((dx1*d)//1) #dy1可能是:0,1,2,3,4,5,6,7 if dx<0: #失去dx的正负号 dx1=-dx1 if dy<0: #失去dy的正负号 dy1=-dy1 self.x+=dx1 #防守者挪动 self.y+=dy1#下句返回rect用来检测碰撞,其属性x,y是图形在游戏窗口坐标,width,hight是图形宽和高 self.rect=self.screen.blit(p,(self.x,self.y)) #在屏幕指定地位绘制防守者 self.frameNum+=1 if self.frameNum==2: self.frameNum=0class Player(): #投篮手类 def __init__(self,screen): #screen是游戏主窗体,Surface类实例 self.screen=screen self.images=[] for n in range(16): #将16帧图像(包含运球和跳投图像)保留到列表中 p = pygame.image.load(str(n)+'.png').convert_alpha()#文件名为1.png,2.png... r=p.get_rect() p = pygame.transform.scale(p, (r.width//6, r.height//6)) #调整图像的大小 self.images.append(p) self.frameNum=0 #帧编号,运球为0到3,跳投为4到15 self.x,self.y=0,0 #图像在窗体的坐标 self.mouseX,self.mouseY=0,0 #此时鼠标坐标值 self.jumpUpOrDown=-10 #按空格键后投篮手向上跳,初始值为正数。到最高点后着落,为负数 self.rect=None#调用blit绘制图形,返回rect记录图形在screen坐标和图形宽和高,用来检测碰撞 def dribble(self): #运球动画 p=self.images[self.frameNum] if self.mouseX-self.x<0: #面向鼠标 p=pygame.transform.flip(p,True,False) self.x,self.y=self.mouseX,self.mouseY #投篮手坐标=鼠标坐标 if self.x<1: #管制投篮手必须在篮球场中 self.x=1 if self.x+90>width: self.x=width-90 if self.y<230: self.y=230 if self.y+120>height: self.y=height-120 self.rect=self.screen.blit(p,(self.x,self.y)) #在指定地位绘制图形,返回rect self.frameNum+=1 if self.frameNum==4: self.frameNum=0 def jumpShot(self): #跳投动画 p=self.images[self.frameNum] if self.x>width/2: #面向篮板 p=pygame.transform.flip(p,True,False) self.screen.blit(p, (self.x, self.y)) #跳投初始地位是运球转跳投时地位 self.y+=self.jumpUpOrDown #当前先向上(y值缩小),到最高点后降落 self.frameNum+=1 if self.frameNum==9: #开始着落,着落值为正 self.jumpUpOrDown=10 if self.frameNum==16: #=16,跳起投篮完结,转运球 self.frameNum=0 self.jumpUpOrDown=-10pygame.init()os.environ['SDL_VIDEO_WINDOW_POS']="%d,%d"%(200,40) #游戏窗口距左侧和顶部点数为200,40size = width, height = 800,600 #创立游戏窗口大小screen = pygame.display.set_mode(size) pygame.display.set_caption("投手运球和跳投") #设置窗口题目bg_img = pygame.image.load("篮球场1.png").convert() #背景篮球场图像fclock = pygame.time.Clock() #创立管制频率的clockfps = 4 #定义刷新频率player=Player(screen) #投篮手类实例ball=Ball(screen) #篮球类实例guard=Guard(screen) #防守者类实例font1 = pygame.font.SysFont('宋体', 50, True) #创立字体gameOver=False #该次游戏是否完结,初始不完结running = True #程序是否完结,初始运行while running: for event in pygame.event.get(): if event.type == pygame.QUIT: #解决退出事件 running = False #程序完结 if event.type == pygame.MOUSEMOTION: #鼠标挪动事件 player.mouseX,player.mouseY=event.pos #将鼠标地位传递给投篮手用于运球 if event.type == pygame.KEYUP: #按键后抬起事件,防止长按键不抬起 if event.key == pygame.K_SPACE: #按空格键后抬起 if player.frameNum<4: #如在运球状态,转投篮状态 player.frameNum=4 #已在投篮状态不解决 if event.key == pygame.K_r and gameOver==True: #按r键后抬起,重玩游戏 gameOver=False ball.score=0 screen.blit(bg_img, (0, 0)) #绘制篮球场背景 surface1=font1.render('score:'+str(ball.score),True,[255,0,0]) #不能显示中文 screen.blit(surface1, (20, 20)) #显示进球数(得分) if gameOver==True: #如果该次游戏完结,后边程序不再执行 fclock.tick(fps) #fps是每秒多少帧,减去程序运行工夫,为实现fps,还需延迟时间 continue if player.frameNum>=4: #如果投篮手帧号>=4,投篮手正在跳投 player.jumpShot() if player.frameNum==8: #第8帧跳起手中无球,篮球要呈现并开始向篮板静止 ball.frameNum=1 #球向篮板静止第1帧 ball.x=player.x #球向篮板静止的起始地位 ball.y=player.y else: #如果投篮手帧号<4,投篮手正在运球 player.dribble() ball.draw() #篮球动画 guard.PlayerX,guard.PlayerY=player.x,player.y #将投篮手地位传递给防守者 guard.PlayerFrameNum=player.frameNum #将投篮手帧号传递给防守者 guard.draw() #防守运动员动画 if player.frameNum<4: #仅在投篮手运球时,判断和防守者是否产生碰撞 if player.rect.colliderect(guard.rect): #检测投篮者和防守者是否产生碰撞 gameOver=True #产生碰撞,游戏完结 surface2=font1.render('if play again,press key r',True,[255,0,0]) screen.blit(surface2, (20, 100)) #显示如持续玩,按r键 pygame.display.flip() #刷新游戏场景 fclock.tick(fps) #fps是每秒多少帧,减去程序运行工夫,为实现fps,还需延迟时间pygame.quit()

June 18, 2021 · 2 min · jiezi

python开发植物大战僵尸游戏

开发思路1.引入需要的模块,配置图片路径,设置界面宽高背景颜色,创建游戏主入口。#1引入需要的模块import pygameimport random#1配置图片地址IMAGE_PATH = 'imgs/'#1设置页面宽高scrrr_width=800scrrr_height =560#1创建控制游戏结束的状态GAMEOVER = False#1主程序class MainGame(): #1加载游戏窗口 def init_window(self): #1调用显示模块的初始化 pygame.display.init() #1创建窗口 MainGame.window = pygame.display.set_mode([scrrr_width,scrrr_height]) # #1开始游戏 def start_game(self): #1初始化窗口 self.init_window() #1只要游戏没结束,就一直循环 while not GAMEOVER: #1渲染白色背景 MainGame.window.fill((255, 255, 255)) #1实时更新 pygame.display.update()#1启动主程序if __name__ == '__main__': game = MainGame() game.start_game() 2.文本绘制,创建要动态改变的属性,渲染的位置#2 创建关数,得分,剩余分数,钱数shaoguan = 1score = 0remnant_score = 100money = 200#2 文本绘制def draw_text(self, content, size, color): pygame.font.init() font = pygame.font.SysFont('kaiti', size) text = font.render(content, True, color) return text#2 加载帮助提示def load_help_text(self): text1 = self.draw_text('1.按左键创建向日葵 2.按右键创建豌豆射手', 26, (255, 0, 0)) MainGame.window.blit(text1, (5, 5))#2 渲染的文字和坐标位置 MainGame.window.blit(self.draw_text('当前钱数$: {}'.format(MainGame.money), 26, (255, 0, 0)), (500, 40)) MainGame.window.blit(self.draw_text( '当前关数{},得分{},距离下关还差{}分'.format(MainGame.shaoguan, MainGame.score, MainGame.remnant_score), 26, (255, 0, 0)), (5, 40)) self.load_help_text()3.创建地图类,初始化地图和坐标#3 创建地图类class Map(): #3 存储两张不同颜色的图片名称 map_names_list = [IMAGE_PATH + 'map1.png', IMAGE_PATH + 'map2.png'] #3 初始化地图 def __init__(self, x, y, img_index): self.image = pygame.image.load(Map.map_names_list[img_index]) self.position = (x, y) # 是否能够种植 self.can_grow = True #3 加载地图 def load_map(self): MainGame.window.blit(self.image,self.position) #3 存储所有地图坐标点 map_points_list = [] #3 存储所有的地图块 map_list = [] #3 初始化坐标点 def init_plant_points(self): for y in range(1, 7): points = [] for x in range(10): point = (x, y) points.append(point) MainGame.map_points_list.append(points) print("MainGame.map_points_list", MainGame.map_points_list) #3 初始化地图 def init_map(self): for points in MainGame.map_points_list: temp_map_list = list() for point in points: # map = None if (point[0] + point[1]) % 2 == 0: map = Map(point[0] * 80, point[1] * 80, 0) else: map = Map(point[0] * 80, point[1] * 80, 1) # 将地图块加入到窗口中 temp_map_list.append(map) print("temp_map_list", temp_map_list) MainGame.map_list.append(temp_map_list) print("MainGame.map_list", MainGame.map_list) #3 将地图加载到窗口中 def load_map(self): for temp_map_list in MainGame.map_list: for map in temp_map_list: map.load_map() #3 初始化坐标和地图 self.init_plant_points() self.init_map() #3 需要反复加载地图 self.load_map() 4.创建植物类,图片加载报错处理,加载植物方法#4 图片加载报错处理LOG = '文件:{}中的方法:{}出错'.format(__file__,__name__)#4 植物类class Plant(pygame.sprite.Sprite): def __init__(self): super(Plant, self).__init__() self.live=True # 加载图片 def load_image(self): if hasattr(self, 'image') and hasattr(self, 'rect'): MainGame.window.blit(self.image, self.rect) else: print(LOG) #4 存储所有植物的列表plants_list = []5.创建向日葵类#5 向日葵类class Sunflower(Plant): def __init__(self,x,y): super(Sunflower, self).__init__() self.image = pygame.image.load('imgs/sunflower.png') self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.price = 50 self.hp = 100 #5 时间计数器 self.time_count = 0 #5 功能:生成阳光(生产钱) def produce_money(self): self.time_count += 1 if self.time_count == 25: MainGame.money += 5 self.time_count = 0 #5 向日葵加入到窗口中 def display_sunflower(self): MainGame.window.blit(self.image,self.rect) 6.创建豌豆射手类 #6 豌豆射手类class PeaShooter(Plant): def __init__(self,x,y): super(PeaShooter, self).__init__() # self.image 为一个 surface self.image = pygame.image.load('imgs/peashooter.png') self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.price = 50 self.hp = 200 #6 发射计数器 self.shot_count = 0 #6 增加射击方法 def shot(self): #6 记录是否应该射击 should_fire = False for zombie in MainGame.zombie_list: if zombie.rect.y == self.rect.y and zombie.rect.x < 800 and zombie.rect.x > self.rect.x: should_fire = True #6 如果活着 if self.live and should_fire: self.shot_count += 1 # 计数器到25发射一次 if self.shot_count == 25: #6 基于当前豌豆射手的位置,创建子弹 peabullet = PeaBullet(self) #6 将子弹存储到子弹列表中 MainGame.peabullet_list.append(peabullet) self.shot_count = 0 #6 将豌豆射手加入到窗口中的方法 def display_peashooter(self): MainGame.window.blit(self.image,self.rect) #6 增加豌豆射手发射处理 def load_plants(self): for plant in MainGame.plants_list: #6 优化加载植物的处理逻辑 if plant.live: if isinstance(plant, Sunflower): plant.display_sunflower() plant.produce_money() elif isinstance(plant, PeaShooter): plant.display_peashooter() plant.shot() else: MainGame.plants_list.remove(plant) #6 调用加载植物的方法 self.load_plants() 7.创建子弹类#7 豌豆子弹类class PeaBullet(pygame.sprite.Sprite): def __init__(self,peashooter): self.live = True self.image = pygame.image.load('imgs/peabullet.png') self.damage = 50 self.speed = 10 self.rect = self.image.get_rect() self.rect.x = peashooter.rect.x + 60 self.rect.y = peashooter.rect.y + 15 def move_bullet(self): #7 在屏幕范围内,实现往右移动 if self.rect.x < scrrr_width: self.rect.x += self.speed else: self.live = False #7 新增,子弹与僵尸的碰撞 def hit_zombie(self): for zombie in MainGame.zombie_list: if pygame.sprite.collide_rect(self,zombie): #打中僵尸之后,修改子弹的状态, self.live = False #僵尸掉血 zombie.hp -= self.damage if zombie.hp <= 0: zombie.live = False self.nextLevel() #7闯关方法 def nextLevel(self): MainGame.score += 20 MainGame.remnant_score -=20 for i in range(1,100): if MainGame.score==100*i and MainGame.remnant_score==0: MainGame.remnant_score=100*i MainGame.shaoguan+=1 MainGame.produce_zombie+=50 def display_peabullet(self): MainGame.window.blit(self.image,self.rect) #7 存储所有豌豆子弹的列表 peabullet_list = [] #7 加载所有子弹的方法def load_peabullets(self): for b in MainGame.peabullet_list: if b.live: b.display_peabullet() b.move_bullet() #7 调用子弹是否打中僵尸的方法 b.hit_zombie() else: MainGame.peabullet_list.remove(b) #7 调用加载所有子弹的方法 self.load_peabullets() 8.事件处理#8事件处理def deal_events(self): #8 获取所有事件 eventList = pygame.event.get() #8 遍历事件列表,判断 for e in eventList: if e.type == pygame.QUIT: self.gameOver() elif e.type == pygame.MOUSEBUTTONDOWN: # print('按下鼠标按键') print(e.pos) # print(e.button)#左键1 按下滚轮2 上转滚轮为4 下转滚轮为5 右键 3 x = e.pos[0] // 80 y = e.pos[1] // 80 print(x, y) map = MainGame.map_list[y - 1][x] print(map.position) #8 增加创建时候的地图装填判断以及金钱判断 if e.button == 1: if map.can_grow and MainGame.money >= 50: sunflower = Sunflower(map.position[0], map.position[1]) MainGame.plants_list.append(sunflower) print('当前植物列表长度:{}'.format(len(MainGame.plants_list))) map.can_grow = False MainGame.money -= 50 elif e.button == 3: if map.can_grow and MainGame.money >= 50: peashooter = PeaShooter(map.position[0], map.position[1]) MainGame.plants_list.append(peashooter) print('当前植物列表长度:{}'.format(len(MainGame.plants_list))) map.can_grow = False MainGame.money -= 50 #8 调用事件处理的方法 self.deal_events() 9.创建僵尸类#9 僵尸类class Zombie(pygame.sprite.Sprite): def __init__(self,x,y): super(Zombie, self).__init__() self.image = pygame.image.load('imgs/zombie.png') self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y self.hp = 1000 self.damage = 2 self.speed = 1 self.live = True self.stop = False #9 僵尸的移动 def move_zombie(self): if self.live and not self.stop: self.rect.x -= self.speed if self.rect.x < -80: #8 调用游戏结束方法 MainGame().gameOver() #9 判断僵尸是否碰撞到植物,如果碰撞,调用攻击植物的方法 def hit_plant(self): for plant in MainGame.plants_list: if pygame.sprite.collide_rect(self,plant): #8 僵尸移动状态的修改 self.stop = True self.eat_plant(plant) #9 僵尸攻击植物 def eat_plant(self,plant): #9 植物生命值减少 plant.hp -= self.damage #9 植物死亡后的状态修改,以及地图状态的修改 if plant.hp <= 0: a = plant.rect.y // 80 - 1 b = plant.rect.x // 80 map = MainGame.map_list[a][b] map.can_grow = True plant.live = False #8 修改僵尸的移动状态 self.stop = False #9 将僵尸加载到地图中 def display_zombie(self): MainGame.window.blit(self.image,self.rect) #9 新增存储所有僵尸的列表 zombie_list = [] count_zombie = 0 produce_zombie = 100 #9 新增初始化僵尸的方法 def init_zombies(self): for i in range(1, 7): dis = random.randint(1, 5) * 200 zombie = Zombie(800 + dis, i * 80) MainGame.zombie_list.append(zombie) #9将所有僵尸加载到地图中 def load_zombies(self): for zombie in MainGame.zombie_list: if zombie.live: zombie.display_zombie() zombie.move_zombie() # v2.0 调用是否碰撞到植物的方法 zombie.hit_plant() else: MainGame.zombie_list.remove(zombie) #9 调用初始化僵尸的方法 self.init_zombies() #9 调用展示僵尸的方法 self.load_zombies() #9 计数器增长,每数到100,调用初始化僵尸的方法 MainGame.count_zombie += 1 if MainGame.count_zombie == MainGame.produce_zombie: self.init_zombies() MainGame.count_zombie = 0 #9 pygame自己的休眠 pygame.time.wait(10) 10.游戏结束方法#10 程序结束方法def gameOver(self): MainGame.window.blit(self.draw_text('游戏结束', 50, (255, 0, 0)), (300, 200)) pygame.time.wait(400) global GAMEOVER GAMEOVER = True11.完整项目地址:https://github.com/371854496/... 觉得还OK的话,点下Star,作者不易,thank you! ...

June 8, 2019 · 5 min · jiezi

pygame.error: font not initialized的解决及init()到底干了什么

环境Python3.6.8pygame1.9.4贴上报错源码:import pygamemy_font = pygame.font.SysFont(‘arial’, 16)my_font = pygame.font.Font(‘my_font.ttf’, 16)报错内容:Traceback (most recent call last): File “C:\Users\HaoziHuang\Desktop\pygame\4\4.py”, line 6, in <module> my_font = pygame.font.SysFont(‘arial’, 16) File “D:\rjyj\Python\python3.6.8\lib\site-packages\pygame\sysfont.py”, line 320, in SysFont return constructor(fontname, size, set_bold, set_italic) File “D:\rjyj\Python\python3.6.8\lib\site-packages\pygame\sysfont.py”, line 243, in font_constructor font = pygame.font.Font(fontpath, size)pygame.error: font not initialized不管先执行哪一个字体语句都会报错, 当发生此错误时这时我们该检查程序开始部分是否缺少pygame的初始化语句pygame.init()而我们想问了, pygame.init()到底初始化个啥呀???这个问题问得好!以下内容转载自:简明现代魔法, 感谢大佬的分享你究竟有(init)几个好(子)妹(模)妹(块)?当我们在init()的时候,我们在干什么init 这个单词在我们用python进行面向对象开发的时候是跑不了的。理解python的__init__()其实就是和这里的init()作用差不多。做的工作都是__初始化__.至于他在干什么,我的解释是这样的:我们已经知道python有一个特殊的“工具包(模块)”叫pygame了。在我们要动手用它完成我们的想法之前,电脑这个强迫症需要我们检查一遍,这个工具包是否完整,能否正常给我们提供帮助。而这个检查的动作,就是pygame.init()那么init()实际上检查了哪些东西呢?这个其实也不难实验。直接在shell里面,我执行了这个函数:>>> import pygame>>> pygame.init()(6, 0)不明所以的,他给了我一个元组(6,0),我也很不理解,这个6和0分别代表什么意思。所以查阅了pygame的官方文档initialize all imported pygame modulesinit() -> (numpass, numfail)Initialize all imported pygame modules. No exceptions will be raised if a module fails, but the total number if successful and failed inits will be returned as a tuple. You can always initialize individual modules manually, but pygame.init() is a convenient way to get everything started. The init() functions for individual modules will raise exceptions when they fail.You may want to initialize the different modules separately to speed up your program or to not use things your game does not.It is safe to call this init() more than once: repeated calls will have no effect. This is true even if you have pygame.quit() all the modules.初始化所有导入的pygame模块。如果模块失败,则不会引发异常,但如果成功且失败的总数将作为元组返回。您可以随时手动初始化单个模块,但pygame.init()初始化所有导入的pygame模块是一种方便的方法来启动所有内容。各个模块的init()函数会在失败时引发异常。您可能希望单独初始化不同的模块以加速您的程序或不使用您的游戏没有的东西。不止一次调用此init()是安全的:重复调用将不起作用。即使你有pygame.quit()所有模块也是如此。关于init()的一个意外的实验我以前从来没有深究过pygame.init()这个函数究竟init了哪些模块,仅仅在实践的过程中知道,音频播放和创建文字字体的时候,如果没有init就会报错。今天我在安装我的新的电脑环境的时候,因为不知道电脑的型号,所以并没有特意去搜索和安装电脑对应的驱动。结果在安装完python之后,安装pygame(wheel也要安装)之后,运行常规的测试函数pygame.init()返回的数字是(5,1)排除问题的方法就是把已知可以init()的子模块都先运行掉。经过排查,发现pygame无法调用声卡驱动。剩下的事情就好办很多了,重新安装一下声卡驱动,重启之后就可以正常init了。但是在这个过程中,我可以得出比以前更加接近实际的一个结论:pygame.init()在做的,其实就是检查,电脑上一些需要的硬件调用接口、基础功能是否有问题。如果有,他会在程序运行之前就反馈给你,方便你进行排查和规避。说了这么多,它到底init了哪些子模块>>> import pygame>>> pygame.init()(6, 0)>>> pygame.display.init()>>> pygame.font.init()>>> pygame.joystick.init()>>> pygame.mixer.init()>>> pygame.scrap.init()Traceback (most recent call last): File “<stdin>”, line 1, in <module>pygame.error: No display mode is set>>> pygame.freetype.init()Traceback (most recent call last): File “<stdin>”, line 1, in <module>AttributeError: module ‘pygame’ has no attribute ‘freetype’>>> pygame.midi.init()Traceback (most recent call last): File “<stdin>”, line 1, in <module>AttributeError: module ‘pygame’ has no attribute ‘midi’>>> pygame.cdrom.init()我把pygame官网上面的doc里介绍的所有带有init的子模块都运行了一遍。其中midi和freetype这两个模块已经没有了(吐槽一下官方的文档吧,都没了还放着嘛)。scrap初始化失败是因为没有窗口。这样的话,其实已经有5个模块是被初始化了。但是scrap在没有窗口的情况下会报错,到底算不算一个init。还需要后面再仔细看看文档和源码吧。That’s all!再次感谢这位大佬的分享! ...

February 17, 2019 · 2 min · jiezi