IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    贪吃蛇

    imouse发表于 2011-02-25 21:34:39
    love 0
    看了www.pygame.org,感觉挺好玩的,看看pygame的手册,参考其它贪吃蛇写法,产生如下代码:
    有注释,有详细代码,有真相!贪吃蛇 - imouse - imouse的博客
    #!/usr/bin/python
    #-*-coding:utf8-*-

    #
    import pygame
    import random
    import os

    main_dir = os.path.split(os.path.abspath(__file__))[0]
    print main_dir

    # 屏幕大小
    SCREENSIZE = (640,480)
    SCREENRECT = pygame.Rect(0, 0, SCREENSIZE[0], SCREENSIZE[1])
    CAPTION = "first Snake"


    # 帧
    FPS = 30

    # 起始蛇长
    START_SEGMENT = 5

    #起始地点
    START_POS = (20,20)

    # 移动速率
    MOVE_RATE = 2
    MOVE_THRESHOLD = 5

    #蛇头,食物大小
    FOODSIZE = (12,12)
    SNAKE_HEAD_SIZE = (12,12)
    SNAKE_SEG_SIZE = (12,12)

    # 障碍物宽度
    BLOCK_WIDE = 5

    # food, snanke_segment只能在这范围内产生
    SCREEN_SEGMENT = ((SCREENSIZE[0]) / SNAKE_SEG_SIZE[0] -1, (SCREENSIZE[1]) / \
    SNAKE_SEG_SIZE[1] - 1)


    #颜色
    BACKGROUND_COLOR = (255, 255, 255)
    FOOD_COLOR = (0, 0, 0)
    SNAKE_HEAD_COLOR = (0, 255, 0)
    SNAKE_SEG_COLOR = (0, 0, 255)
    BLOCK_COLOR = (255, 0, 0)
    #GAME OVER
    GAME_OVER_COLOR = (255, 0, 0)

    #方向
    #关键地方
    moveRight = 1
    moveLeft = 2
    moveUp = 3
    moveDown = 4

    MOVE_VECTOR = {moveLeft : (-1, 0),
    moveRight: (1, 0),
    moveUp : (0, -1),
    moveDown : (0, 1)
    }

    MOVE_VECTOR_PIXS = {moveLeft : (-SNAKE_SEG_SIZE[0], 0),
    moveRight: (SNAKE_SEG_SIZE[0], 0),
    moveUp : (0, -SNAKE_SEG_SIZE[1]),
    moveDown : (0, SNAKE_SEG_SIZE[1])
    }

    #分数
    SCORE = 0

    # 蛇身
    class Snake_Segment(pygame.sprite.Sprite):
    def __init__(self, spos, segment_groups, color = SNAKE_SEG_COLOR):
    pygame.sprite.Sprite.__init__(self)
    # 创建方块
    self.image = pygame.Surface(SNAKE_SEG_SIZE).convert()
    self.image.fill(color)

    # 初始位置
    self.spos = spos
    # 设置image在初始位置出现
    self.rect = self.image.get_rect()
    self.rect.topleft = (spos[0] * SNAKE_SEG_SIZE[0], spos[1] * SNAKE_SEG_SIZE[1])

    # 蛇身属于一个或多个组,做碰撞检测
    self.segment_groups = segment_groups
    for group in segment_groups:
    group.add(self)

    # 紧跟到一个蛇身
    self.behind_segment = None

    # 初始化相左移动
    self.movedir = moveLeft

    def add_segment(self):
    """在当前后面增加一个新的蛇身,蛇长长"""
    seg = self
    # 循环到尾部增加
    while True:
    if seg.behind_segment == None:
    x = seg.spos[0]
    y = seg.spos[1]
    if seg.movedir == moveLeft:
    x += 1 # 如果当前方向相左移动,则需要向右边加一个,其它方向类似
    elif seg.movedir == moveRight:
    x -= 1
    elif seg.movedir == moveUp:
    y += 1
    elif seg.movedir == moveDown:
    y -= 1
    seg.behind_segment = Snake_Segment((x, y), seg.segment_groups)
    seg.behind_segment.movedir = seg.movedir
    break
    else:
    seg = seg.behind_segment #向后查找

    def update(self):
    """移动的动作在头部中"""
    pass

    def move(self):
    """根据方向移动到不同位置上"""
    #self.spos = (self.spos[0] + MOVE_VECTOR[self.movedir][0], self.spos[0] + MOVE_VECTOR[self.movedir][1])
    x = self.spos[0] + MOVE_VECTOR[self.movedir][0]
    y = self.spos[1] + MOVE_VECTOR[self.movedir][1]

    if x < 0:
    x = SCREEN_SEGMENT[0]
    elif y < 0:
    y = SCREEN_SEGMENT[1]
    elif x > SCREEN_SEGMENT[0]:
    x = 0
    elif y > SCREEN_SEGMENT[1]:
    y = 0

    self.spos = (x, y)
    self.rect.topleft = (x * SNAKE_SEG_SIZE[0], y * SNAKE_SEG_SIZE[1])
    # 同时移动后面的蛇身
    if self.behind_segment != None:
    self.behind_segment.move()
    self.behind_segment.movedir = self.movedir

    class Snake_Head(Snake_Segment):
    """蛇头, 主要属性是方向"""
    def __init__(self, spos, movedir, segment_groups):
    Snake_Segment.__init__(self, spos, segment_groups, color = SNAKE_HEAD_COLOR)
    self.movedir = movedir
    self.movecount = 0

    def update(self):
    self.movecount += MOVE_RATE
    if self.movecount > MOVE_THRESHOLD:
    self.move()
    self.movecount = 0

    class Food(pygame.sprite.Sprite):
    def __init__(self, takeupgroup):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.Surface(FOODSIZE).convert()
    self.image.fill((250,250,250))

    # 两个food不能出现在同一个或相交的位置
    self.rect = self.image.get_rect()
    while True:
    self.rect.topleft = (random.randint(0,SCREEN_SEGMENT[0]) * SNAKE_SEG_SIZE[0],\
    random.randint(0,SCREEN_SEGMENT[1]) * SNAKE_SEG_SIZE[1])
    for sprt in takeupgroup:
    if self.rect.colliderect(sprt):
    continue #随机生成的与前一个位置相交,则继续生成位置
    break

    class Block(pygame.sprite.Sprite):
    def __init__(self, rect):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.Surface((rect[2], rect[3])).convert()
    self.image.fill(BLOCK_COLOR)
    self.rect = self.image.get_rect()
    self.rect.topleft = (rect[0], rect[1])


    class Score(pygame.sprite.Sprite):
    def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.font = pygame.font.Font(None, 20)
    self.font.set_italic(1)
    self.color = pygame.Color('white')
    self.lastscore = -1
    self.update()
    self.rect = self.image.get_rect().move(10,450)
    def update(self):
    if SCORE != self.lastscore:
    self.lastscore = SCORE
    msg = "Score: %d" % SCORE
    self.image = self.font.render(msg, 0, self.color)

    class ResourceLoad:
    def __init__(self):
    self.datapath = os.path.join(main_dir,'data')

    def load_image(self,file):
    "加载图片"
    try:
    self.file = os.path.join(self.datapath, file)
    surface = pygame.image.load(self.file)
    except pygame.error:
    raise SystemExit('Could not load image "%s" %s' %(self.file,\
    pygame.get_error))
    return surface.convert()

    def load_images(self, *files):
    imgs = []
    for file in files:
    imgs.append(load_image(file))
    return imgs

    # 默认声音类
    class dummysound:
    def play(self):pass
    def load_sound(file):
    if not pygame.mixer: return dummysound()
    self.file = os.path.join(self.datapath, file)
    try:
    sound = pygame.mixer.Sound(self.file)
    return sound
    except pygame.error:
    print 'Warning, unable to load , %s' % self.file
    return dummysound()


    def main():
    # initialize everything
    pygame.init()
    screen = pygame.display.set_mode(SCREENSIZE)
    pygame.display.set_caption('Snake')
    pygame.mouse.set_visible(0)

    # background
    #background = pygame.Surface(screen.get_size())
    #background = background.convert()
    #background.fill((0,0,0))
    # 加载图片,代替黑屏背景
    res = ResourceLoad()
    background = res.load_image('background2.jpg')

    # display the background
    screen.blit(background, (0,0))
    pygame.display.flip()

    # prepare Snake
    clock = pygame.time.Clock()

    # groups
    snakegroup = pygame.sprite.Group()
    snakeheadgroup = pygame.sprite.Group()
    foodgroup = pygame.sprite.Group()
    takeupgroup = pygame.sprite.Group()
    blockgroup = pygame.sprite.Group()
    allsprites = pygame.sprite.RenderUpdates()

    # 创建一条蛇
    snake = Snake_Head(START_POS, moveRight, [snakegroup, allsprites, takeupgroup])
    snakeheadgroup.add(snake)
    for i in range(START_SEGMENT):
    snake.add_segment()

    #创建障碍物
    #blocktop = Block((0, 0, SCREENSIZE[0], BLOCK_WIDE))
    #blockgroup.add(blocktop)
    #blockleft = Block((0, 0, BLOCK_WIDE, SCREENSIZE[1]))
    #blockgroup.add(blockleft)
    #blockright = Block((SCREENSIZE[0]-BLOCK_WIDE, 0, BLOCK_WIDE, SCREENSIZE[1]))
    #blockgroup.add(blockright)
    #blockbottom = Block((0, SCREENSIZE[1]-BLOCK_WIDE, SCREENSIZE[0], BLOCK_WIDE))
    #blockgroup.add(blockbottom)
    #for block in blockgroup:
    # allsprites.add(block)

    global socre
    if pygame.font:
    allsprites.add(Score())
    global SCORE

    curfood = None

    # 初始化方向
    movedir = snake.movedir
    donotmovedir = moveRight

    lose = False
    quit = False
    while not quit:
    clock.tick(FPS)
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    print "exit, good bye!"
    quit = True
    return
    keystate = pygame.key.get_pressed()

    # 相左不能向右,反之亦然,
    # 向上不能向下, 反之亦然
    curMovdir = snake.movedir
    if keystate[pygame.K_RIGHT] == 1:
    movedir = moveRight
    donotmovedir = moveLeft
    elif keystate[pygame.K_LEFT] == 1:
    movedir = moveLeft
    donotmovedir = moveRight
    elif keystate[pygame.K_UP] == 1:
    movedir = moveUp
    donotmovedir = moveDown
    elif keystate[pygame.K_DOWN] == 1:
    movedir = moveDown
    donotmovedir = moveUp
    if not curMovdir == donotmovedir:
    snake.movedir = movedir

    allsprites.clear(screen, background)

    allsprites.update()

    # 产生一个食物,以后会一次产生一个或多个食物
    if curfood == None:
    curfood = Food(takeupgroup)
    foodgroup.add(curfood)
    takeupgroup.add(curfood)
    allsprites.add(curfood)

    # 检测碰撞
    # snake -> snake
    col = pygame.sprite.groupcollide(snakeheadgroup, snakegroup,\
    False,False)
    for head in col:
    for tail in col[head]:
    if not tail is snake:
    print "snake crash"
    quit = True
    lose = True


    # snake -> food
    col = pygame.sprite.groupcollide(snakeheadgroup, foodgroup,\
    False,True)
    for head in col:
    for tail in col[head]:
    curfood = None
    snake.add_segment()
    SCORE += 1

    # snake -> block
    #col = pygame.sprite.groupcollide(snakeheadgroup,blockgroup,\
    # True, False)
    #for head in col:
    # for block in col[head]:
    # quit = True
    # lose = True

    # 重绘制所有元素
    screen.blit(background,(0,0))
    allsprites.draw(screen)
    pygame.display.flip()

    if lose == True:
    f = pygame.font.Font(None, 100)
    failmsg = f.render('Game Over', True, GAME_OVER_COLOR)
    failmsgrect = failmsg.get_rect()
    failmsgrect.center = SCREENRECT.center
    screen.blit(failmsg, failmsgrect)
    pygame.display.flip()
    pygame.time.wait(2000)



    pygame.quit()

    if __name__ == '__main__': main()



沪ICP备19023445号-2号
友情链接