文档章节

pygame写的多食物面向对象贪吃蛇

z
 zbaigao
发布于 2017/05/17 00:13
字数 683
阅读 122
收藏 0

pygame的贪吃蛇,一次投递多个食物,默认画布15*15,一次投递20个食物,食物之间、食物与蛇之间不会重叠。当方块总数 - 蛇身长度 - 食物个数 < 20时,判断玩家胜利。有生之年终于可以看到贪吃蛇的结局了!

本版本的贪吃蛇Snake、Food和World均独立于具体库,稍作修改可成为命令行版本的贪吃蛇,也可迁移到其他引擎中。

# -*- coding: utf-8 -*-
"""
Created on Tue May 16 07:24:28 2017

@author: zbg
"""
import pygame
from pygame.locals import *

from random import randint, choice, shuffle

class Map(dict):
    def __init__(self, w, h):
        dict.__init__(self)
        self.w = w
        self.h = h
        self.clear()
        
    def __str__(self):
        s = ''
        for j in range(self.h):
            for i in range(self.w):
                s += self[(i, j)]
            s += '\n'
        return s
    
    def clear(self):
        for i in range(self.w):
            for j in range(self.h):
                self[(i, j)] ='.'
            
class Food(object):
    def __init__(self, world, n = 1):
        self.n = n #一次产生n个食物
        self.m = world.m
        self.world = world
        self.w = self.m.w
        self.h = self.m.h
        self.locations = {}#用字典是为了吃食物时方便删除
        
    def generate(self):#由外部world调用,维持n个食物     
        space = []#除开蛇以外的地方的坐标
        for i in range(self.w):
            for j in range(self.h):
                if (i, j) not in self.world.snake.body:
                    space.append((i, j))
        shuffle(space)
        while len(self.locations) < self.n:
            self.locations[space[-1]] = 1 #后面的值1并没有意义。
            del space[-1]
    
    def draw(self):
        for l in self.locations:
            self.m[l] = 'o'
        
class Snake(object):
    '''
    蛇做一些简单的移动、计算和绘制
    改变移动方向交给外部的World来处理
    '''
    def __init__(self, world):
        self.world = world
        self.m = world.m
        self.h = self.m.h
        self.w = self.m.w
        self.direction = "left" #
        self.state = 'alive' # 'alive' or 'dead'
        
        cw, ch = self.w / 2, self.h / 2
        self.body = [(cw, ch), (cw + 1, ch), (cw + 2, ch)]
        
    def draw(self):
        for b in self.body:
            self.m[b] = 'x'
    
    def newhead(self):    
        headw, headh = self.body[0]
        newheadw, newheadh = headw, headh
        if self.direction == "left":
            newheadw = headw - 1
        elif self.direction == "right":
            newheadw = headw + 1
        elif self.direction == "up":
            newheadh = headh - 1
        elif self.direction == "down":
            newheadh = headh + 1
        return newheadw, newheadh    
    
    def move(self):
        x, y = self.newhead()
        if len(self.body) + self.world.food.n + 20 > self.w * self.h:
            print "fine, you win!!"
        elif x == -1 or y == -1 or x == self.w or y == self.h:
            print "error, dead"
        elif (x, y) in self.body:
            print "error, dead"
        elif (x, y) in self.world.food.locations:
            self.body = [self.newhead()] + self.body[:]
            del world.food.locations[(x, y)]
        else:
            self.body = [self.newhead()] + self.body[0: -1]
        
    def changedirection(self, direction):
        self.direction = direction

class World(object):
    def __init__(self, w, h):
        self.m = Map(w, h)
        self.snake = Snake(self)
        self.food = Food(self, 20)
        self.w, self.h = w, h
        
    def run(self):
        self.food.generate()
        self.m.clear()
        self.snake.move()
        self.food.draw()
        self.snake.draw()
        
def show(screen, m):
    for i in range(m.w):
        for j in range(m.h):
            if m[(i, j)] == 'x':
                r = pygame.Rect(i * unit, j * unit, unit, unit)
                pygame.draw.rect(screen,(136,0,21),r,0)
            elif m[(i, j)] == 'o':
                r = pygame.Rect(i * unit, j * unit, unit, unit)
                pygame.draw.rect(screen,(0,174,21),r,0)

h = 15
w = 15
unit = 30
SCREEN_SIZE =  (w * unit, h * unit)  
DIRECTION = {pygame.K_UP: 'up', pygame.K_DOWN: "down", pygame.K_LEFT: "left", pygame.K_RIGHT:"right"}       
world = World(15,15)
clock = pygame.time.Clock()

pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit(0)
        if event.type == pygame.KEYDOWN:
            if event.key in DIRECTION:
                direction = DIRECTION[event.key]
                if direction in ['up', 'down'] and world.snake.direction in ['up', 'down']:
                    pass
                elif direction in ['left', 'right'] and world.snake.direction in ['left', 'right']:
                    pass
                else:
                    world.snake.changedirection(direction)
            
    screen.fill((255,255,255))
    world.run()
    show(screen, world.m)
    pygame.display.update()
    print world.m
    clock.tick(3)

 

© 著作权归作者所有

z
粉丝 6
博文 23
码字总数 15075
作品 0
杭州
私信 提问
完全用链表实现的贪吃蛇

1.链表设计 同事突然说想实现一个贪吃蛇,这使我想起了几年前实现的一个很糟糕的贪吃蛇程序,代码可以在《 一个java写的贪吃蛇程序》里面找到。如今,突然想再实现一个贪吃蛇,不过这次绝对不...

晨曦之光
2012/04/10
276
0
经典游戏开发:C++实现贪吃蛇游戏

贪吃蛇设计思路: 由于是第一次尝试小游戏,主要是了解游戏开发流程、设计思想,借助前人的成果进行修改和尝试,修改调通运行起来,对于自己来说也是进了很大一步呀! 进入主题,贪吃蛇设计思...

邦戈栗子
2018/12/15
0
0
【C/C++】10分钟教你用C++写一个贪吃蛇附带AI功能(附源代码详解和下载)

C++编写贪吃蛇小游戏快速入门 刚学完C++。一时兴起,就花几天时间手动做了个贪吃蛇,后来觉得不过瘾,于是又加入了AI功能。希望大家Enjoy It. 效果图示 AI模式演示 整体规划+原理 大体上可以...

短短的路走走停停
2018/07/29
0
0
原生javascript制作贪吃蛇小游戏

HTML部分 //js开始

LONG—
2018/12/22
0
0
在 Linux 终端中玩贪吃蛇

有了这个 20 世纪 70 年代的经典重制游戏,Python 将不再是你在 Linux 终端能发现的唯一的“蛇”。 欢迎回到 Linux 命令行玩具日历。如果这是你第一次访问该系列,你可能会问什么是命令行玩具...

作者: Jason Baker
01/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JavaConfig版

中心思想:去xml配置文件。 在Spirng Boot和Spring Cloud中,大量使用了注解与JavaConfig。 xml文件 对应的Java类 spring.xml SpringConfig.java spring-mvc.xml SpringMvcConfig.java web.x...

流小文
40分钟前
4
0
Go 定时器内部实现原理剖析

前言 前面我们介绍了一次性定时器Timer和周期性定时器Ticker,这两种定时器内部实现机制相同。创建定时器的协程并不负责计时,而是把任务交给系统协程,系统协程统一处理所有的定时器。 本节...

恋恋美食
45分钟前
0
0
分布式协调神器 ZooKeeper 之整体概述

ZooKeeper 最早起源于雅虎研究院的一个研究小组。当时,雅虎内部很多大型系统基本都需要依赖一个类似的系统来进行分布式协调,但是这些系统往往都存在分布式单点问题。所以,雅虎的开发人员就...

别打我会飞
46分钟前
1
0
Linux learn(三)

6. Linux文件与目录管理(续上一篇) 查看文件类型 file file 文件名 例如: 文件搜索 which($PATH查询执行档) 结构: which [-a] command 选项参数: -a: 将所有PATH目录中可以找到的指令均列...

lazy~
49分钟前
1
0
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

//二叉搜索树条件左子树<根<右子树 //后序遍历说明最后一个元素是该二叉树的根节点 //1 找到该树的左子树 //2 判断右子树是否都大于根的值 //3 同样操作,该根的左右子树是否成立 public cla...

南桥北木
52分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部