|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
import pygame
import sys
import traceback
from pygame.locals import *
from random import *
pygame.init()
pygame.mixer.init()
class Ball(pygame.sprite.Sprite):
#定义基类的碰撞类型
crashtype=1
def __init__(self,grayball_image,greenball_image,position,speed,bg_size,target,control=False):
pygame.sprite.Sprite.__init__(self)
self.grayball_image=pygame.image.load(grayball_image).convert_alpha()
self.greenball_image=pygame.image.load(greenball_image).convert_alpha()
self.rect=self.grayball_image.get_rect()
self.rect.left,self.rect.top=position
#控制速度方向
self.side=[choice([-1,1]),choice([-1,1])]
self.speed=speed
self.width,self.height=bg_size
self.target=target
self.radius=self.rect.width/2
self.control=control
self.collide=False
def move(self):
if self.control:
self.rect=self.rect.move(self.speed)
else:
self.rect=self.rect.move((self.speed[0]*self.side[0],\
self.speed[1]*self.side[1]))
if Ball.crashtype==1:
#碰撞返回
if self.rect.left<=0:
self.speed[0]=-self.speed[0]
self.rect.left=0
elif self.rect.right>=self.width:
self.speed[0]=-self.speed[0]
self.rect.right=self.width
elif self.rect.top<=0 :
self.speed[1]=-self.speed[1]
self.rect.top=0
elif self.rect.bottom>=self.height:
self.speed[1]=-self.speed[1]
self.rect.bottom=self.height
elif Ball.crashtype==2:
#碰撞穿越
if self.rect.right<=0 :
self.rect.left=self.width
elif self.rect.left>=self.width:
self.rect.right=0
if self.rect.bottom<=0 :
self.rect.top=self.height
elif self.rect.top>=self.height:
self.rect.bottom=0
def crash(self):
self.side=[-self.side[0],-self.side[1]]
self.collide=True
def check(self,motion):
if self.target<motion<self.target+5:
return True
else:
return False
#避免当小球不可控的时候刚好速度为0的状态
def zerospeed(self):
if self.speed==[0,0]:
self.speed=[randint(-5,5),randint(-5,5)]
class Glass():
def __init__(self,glass_image,bg_size):
self.glass_image=pygame.image.load(glass_image).convert_alpha()
self.glass_rect=self.glass_image.get_rect()
self.glass_rect.center=bg_size[0]//2,bg_size[1]-self.glass_rect.height//2
class Hand():
def __init__(self,hand_image,bg_size,glass_size):
self.hand_image=pygame.image.load(hand_image).convert()
self.hand_image.set_colorkey((255,255,255))#把白色区域变成透明
self.hand_rect=self.hand_image.get_rect()
self.hand_rect.center=bg_size[0]//2,bg_size[1]-glass_size[1]//2
self.width=bg_size[0],glass_size[0]
self.height=bg_size[1],glass_size[1]
self.control=False
def bianjie(self,center_position):
if center_position[0]+self.hand_rect.width/2>(self.width[0]+self.width[1])/2:
self.hand_rect.right=(self.width[0]+self.width[1])//2
elif center_position[0]-self.hand_rect.width/2<(self.width[0]-self.width[1])/2:
self.hand_rect.left=(self.width[0]-self.width[1])//2
if center_position[1]+self.hand_rect.height/2>self.height[0]:
self.hand_rect.bottom=self.height[0]
elif center_position[1]-self.hand_rect.height/2<(self.height[0]-self.height[1]):
self.hand_rect.top=(self.height[0]-self.height[1])
def bianjie(glass_rect,position):
if glass_rect.left<position[0]<glass_rect.right and\
glass_rect.top<position[1]<glass_rect.bottom:
count=1
else:
count=0
return count
def main():
pygame.init()
pygame.mixer.init()
grayball_image='gray_ball.png'
greenball_image='green_ball.png'
bg_image='background.png'
glass_image='glass.png'
hand_image='hand.png'
running =True
bg_size=width,height=1024,681
screen=pygame.display.set_mode(bg_size)
pygame.display.set_caption('play the ball,press "p" to change crashtype,press "b" to quit the game')
glass=Glass(glass_image,bg_size)
glass_size=glass.glass_rect.width,glass.glass_rect.height
hole=[(117,119,199,201),(225,227,390,392),(503,505,320,322),(698,700,192,194),(906,908,419,421)]
hand=Hand(hand_image,bg_size,glass_size)
background=pygame.image.load(bg_image).convert_alpha()
#定义碰撞类型
flag=1
#存放精灵对象
balls=[]
#存放精灵
group=pygame.sprite.Group()
#添加背景音乐
pygame.mixer.music.load('bg_music.ogg')
pygame.mixer.music.play()
#添加音效
loser_sound=pygame.mixer.Sound('loser.wav')
laugh_sound=pygame.mixer.Sound('laugh.wav')
winner_sound=pygame.mixer.Sound('winner.wav')
hole_sound=pygame.mixer.Sound('hole.wav')
#音乐播放完时游戏结束
GAMEOVER=USEREVENT#把GAMEOVER定义为一个用户事件
pygame.mixer.music.set_endevent(GAMEOVER)
#标记鼠标左键动作
select=0
#标记鼠标相对glass的位置
count=0
#生成精灵
for i in range(5):
position=randint(0,width-100),randint(0,height-100)
speed=[randint(1,5),randint(1,5)]
ball=Ball(grayball_image,greenball_image,position,speed,bg_size,5*(i+1))
while pygame.sprite.spritecollide(ball,group,False,pygame.sprite.collide_circle):
ball.rect.left,ball.rect.top=randint(0,width-100),randint(0,height-100)
balls.append(ball)
group.add(ball)
clock=pygame.time.Clock()
#记录每秒鼠标事件数量
motion=0
#设置自定义事件,计时器,每1000毫秒触发一次MYTIMER
MYTIMER=USEREVENT +1
pygame.time.set_timer(MYTIMER,1000)
#设置按键的重复事件
pygame.key.set_repeat(100,100)
while running:#用来控制程序结束,只设置True则只有点退出程序的时候才能quit
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()#在idle运行的时候保证能退出
sys.exit()
elif event.type==GAMEOVER:
loser_sound.play()
pygame.time.delay(2000)
laugh_sound.play()
pygame.quit()
running=False
elif event.type==MYTIMER:
if select:
if motion:
for each in group:
if each.check(motion):
each.speed=[0,0]
each.control=True
#else:#这里不能要,不然一旦下个事件开始球又会变回原样
#each.control=False
motion=0#判断完是否控制球后清零
#记录鼠标事件
elif event.type==MOUSEMOTION:
motion+=1
elif event.type==KEYDOWN:
if event.key==K_p:
if flag==1:
Ball.crashtype=2
flag=2
elif flag==2:
Ball.crashtype=1
flag=1
if event.key==K_w:
for each in group:
if each.control:
each.speed[1]-=1
if event.key==K_s:
for each in group:
if each.control:
each.speed[1]+=1
if event.key==K_a:
for each in group:
if each.control:
each.speed[0]-=1
if event.key==K_d:
for each in group:
if each.control:
each.speed[0]+=1
if event.key==K_SPACE:
for each in group:
if each.control:
for i in hole:
if i[0]<=each.rect.left<=i[1] and \
i[2]<=each.rect.top<=i[3]:
hole_sound.play()
each.speed=[0,0]
group.remove(each)
#保证进度的球在其他球的最下面,最先画的最下面
temp=balls.pop(balls.index(each))
balls.insert(0,temp)
hole.remove(i)
if not hole:
pygame.mixer.music.stop()#此时音乐结束发送了事件,通过delay的方法执行完后面才真正结束
winner_sound.play()
pygame.time.delay(3000)
laugh_sound.play()
pygame.time.delay(3000)
if event.key==K_b:
pygame.quit()
elif event.type==MOUSEBUTTONDOWN:
#只有鼠标在glass里面才有响应
count=bianjie(glass.glass_rect,pygame.mouse.get_pos())
if count:
if event.button==1:
select=1
elif event.type==MOUSEBUTTONUP:
select=0
#判断鼠标位置在glass里面就不可见
mouse_center=pygame.mouse.get_pos()
if glass.glass_rect.left<mouse_center[0]<glass.glass_rect.right and\
glass.glass_rect.top<mouse_center[1]<glass.glass_rect.bottom:
visible=False
else:
visible=True
if select:
hand.hand_rect.center=pygame.mouse.get_pos()
hand.bianjie(hand.hand_rect.center)
else:
visible=True
pygame.mouse.set_visible(visible)
screen.blit(background,(0,0))
screen.blit(glass.glass_image,glass.glass_rect)
screen.blit(hand.hand_image,hand.hand_rect)
for each in balls:
each.move()
if each.collide:#避免同向运动球碰撞抖动
each.speed=[randint(1,10),randint(1,10)]
each.collide=False
if each.control:
#控制的时候画绿色小球
screen.blit(each.greenball_image,each.rect)
else:
each.zerospeed()
screen.blit(each.grayball_image,each.rect)
for each in group:
group.remove(each)
if pygame.sprite.spritecollide(each,group,False,pygame.sprite.collide_circle):
each.crash()
each.control=False
group.add(each)
pygame.display.flip()
clock.tick(30)
if __name__=='__main__':
try:
main()
except SystemExit:
pass
except:
traceback.print_exc()
pygame.quit()
input()
运行后按b退出游戏,或者游戏正常结束都会报异常
Traceback (most recent call last):
File "F:\学习笔记\程序\pygame\0-pygame-sprite-f1.py", line 325, in <module>
main()
File "F:\学习笔记\程序\pygame\0-pygame-sprite-f1.py", line 281, in main
mouse_center=pygame.mouse.get_pos()
pygame.error: video system not initialized
在每个pygame.quit()后面加上 最后变成 try:
main()
except Exception:
traceback.print_exc()
pygame.quit()
input()
emm,都解决啦,尴尬
|
|