pygame过河搭桥画笔小游戏

"""pygame过河搭桥画笔小游戏,这是pygame多关卡创意画笔类小游戏,这个程序增加Pen类,当鼠标按下移动时,画一条线给小球搭桥.
   画的时间长短有限制,每关画的次数限制为3次,
   并且按左键画绿色,按右键画黑色。
   操作方法:按左右方向箭头操作小球,碰到红色死亡。
   下一个版本是增加各种道具,藏在红色之中,通过画黑线可以进入等等。
"""
__author__ = "李兴球"
__date__ = "2019年1月"
import math
import pygame
from glob import glob
from pygame.locals import *

def insert_point(a,b,step):
    """在两点之间线性插入坐标点,a:起点坐标,b:终点坐标,step:步长"""
    points = []
    x1,y1 = a       # 起点
    x2,y2 = b       # 终点
    dy = y2 - y1
    dx = x2 - x1
    angle = math.atan2(dy,dx)
    distance = int(math.sqrt(dx*dx+dy*dy))
    for d in range(1,distance,step):
        dx = d * math.cos(angle)
        dy = d * math.sin(angle)
        p = int(a[0] + dx),int(a[1] + dy)
        points.append(p)
    return points

class Pen():
    def __init__(self,ball):
        self.ball = ball                     # 笔可以访问球,以便访问球的属性方法等。
        self.screen = ball.screen 
        self.color = GREEN                   # 初始颜色为绿色
        self.thickness = 30                  # 笔触大小,实际上是画圆时的半径
        self.draw_times  = [ 3 for i in range(len(self.ball.backgrounds))] # 每关画的次数为3
        
    def alt_color(self,color):         
        self.color = color
        
    def paint(self,previous_point,mouse_pos,):
        """在ball.background上画圆点"""  
        
        dx = mouse_pos[0] - previous_point[0]   # 鼠标指针x和前一个点的x距离
        dy = mouse_pos[1] - previous_point[1]   # 鼠标指针y和前一个点的y距离
        distance = math.sqrt(dx*dx + dy*dy)   
         
        pygame.draw.circle(self.ball.background, self.color, mouse_pos, self.thickness)

        if distance>=4:      # 如果距离大于等于4,则线性插入画点,不插会有断点
            points = insert_point(previous_point,mouse_pos,1)             
            for p in points:                 
                pygame.draw.circle(self.ball.background, self.color, p, self.thickness)             
            
           
class Ball:
    def __init__(self,radius,color,position,screen,backgrounds):
        self.radius = radius
        self.screen = screen
        self.backgrounds = backgrounds                     # 所有的关卡对象
        self.level = 0                                     # 开始关卡
        self.background = self.backgrounds[self.level]     # 当前背景(关卡)
        self.level_amounts = len(backgrounds)              # 关卡数量
        self.screen_width = self.screen.get_width()        # 屏幕宽度 
        self.screen_height = self.screen.get_height()      # 屏幕高度
        self.image = pygame.Surface((radius*2,radius*2))   # 新建正方形面对象
        self.image.set_colorkey(BLACK)                     # 不渲染颜色为黑色
        pygame.draw.circle(self.image,color,(radius,radius),radius) # 在面上画圆
        self.rect = self.image.get_rect()                  # 得到矩形对象 
        self.start_position = position # 记录起始坐标点
        self.rect.center = position
        self.dx = 0                    # x速度
        self.dy = 0                    # y速度
        self.acc = 0.2                 # 加速度
        self.outer_ring_points = []    # 实时记录圆形边缘8个点的坐落标,用于像素检测
        self.bumped_green = False      # 是否碰到绿色
        self.bumped_red = False        # 是否碰到红色,碰到了就死
        
    def keypressed_check(self):
        keys = pygame.key.get_pressed()# 得到按键布尔值表
        
        if keys[K_DOWN] and not self.bumped_green:
            self.dy += 1
        if keys[K_LEFT] and  self.bumped_green:
            self.dx = -2
            self.dy = -2       
            
        if keys[K_RIGHT] and  self.bumped_green:
            self.dx = 2
            self.dy = -2
             
    def update(self):
        self.rect.move_ip(self.dx,self.dy)
        self.mission_check()                 # 过关检测
        self.get_outer_ring_point_list()
        self.check_bumped_pixel()            # 像素检测
        if self.bumped_green:
            self.dx = 0
            self.dy = -1
        else:
            self.dy = self.dy + self.acc    # 加速下降
    def mission_check(self):
        """过关检测,判断坐标"""
        if self.level < self.level_amounts-1 :
          if  self.rect.right > self.screen_width : # 右x坐标大于屏幕最右
              self.level = self.level + 1
              self.background = self.backgrounds[self.level]
              self.rect.left = 0
        else:
            if self.rect.right>=self.screen_width:self.dx = -self.dx

        if  self.level > 0:
           if self.rect.left <  0 :                 # 左x坐标小于屏幕最左
              self.level = self.level - 1
              self.background = self.backgrounds[self.level]
              self.rect.right = self.screen_width
        else:
            if self.rect.left<=0:self.dx = -self.dx
        
                    
    def get_outer_ring_point_list(self):
        """得到圆形边缘坐标点,用于像素检测"""
        xo,yo = self.rect.center 
        self.outer_ring_points = []
        for angle in range(0,360,45):  # 最多8个检测点
            x = xo + self.radius * math.cos(math.radians(angle))
            y = yo + self.radius * math.sin(math.radians(angle))
            if x <= 0 or x >= self.screen_width:continue
            if y <= 0 or y >= self.screen_height:continue
            self.outer_ring_points.append((int(x),int(y)))
        #print(self.outer_ring_points,self.dx,self.dy)
    def check_bumped_pixel(self):
        """像素检测,取最多8个点,对背景图进行像素值检测。"""
        if self.outer_ring_points==[]:
            self.bumped_green = False
            self.bumped_red = False
            return 
        for point in self.outer_ring_points:
            pixel = self.background.get_at(point) # 每个点在背景上的像素值
            if pixel == GREEN :         # 绿色 
                self.bumped_green = True
            else:
                self.bumped_green = False               
            if pixel == RED:            # 红色
                self.bumped_red = True
                self.rect.center = self.start_position            
                self.bumped_red = False
                self.dx = 0
                self.dy = 0
                #print("碰红色")
                break
            if self.bumped_red or self.bumped_green:break 
            
    def draw(self):
        self.screen.blit(self.image,self.rect)

if __name__ == "__main__":

    RED = (255,0,0,255)
    GREEN = (0,255,0,255)
    BLUE = (0,0,255,255)
    BLACK = (0,0,0,255)    
    MAGENTA  = (255,0,255,255)
    
    game_title = "过河搭桥_作者:李兴球_www.scratch8.net"
    width,height = 800,600
    
    pygame.init()
    screen = pygame.display.set_mode((width,height))
    pygame.display.set_caption(game_title)
    backgrounds = [pygame.image.load(image) for image in glob("backgrounds/*.png")]

    start_position =  (50,height//2-250)
    ball = Ball(10,MAGENTA,start_position,screen,backgrounds)
    clock = pygame.time.Clock()
    running = True
    
    start_draw = 0                            # 鼠标左键按下标志
    pen = Pen(ball)                           # 新建画笔
本文隐藏内容 登陆 后才可以浏览