您的位置:首页 > 编程语言 > Python开发

python模仿开发贪食蛇小游戏历程

2014-09-03 15:39 399 查看
说起来,对python颇感兴趣的我开始尝试一下用python开发小游戏,正好我在中国大学MOOC上选修了高级语言程序设计(Python)课程 http://www.icourse163.org/course/hit-9003#/info。在课程的最后几章就讲到了python的gui开发,还附上了他们开发的贪食蛇python源码,做得挺好的小游戏,我开始了自己的模仿之路。

我只是一个python菜鸟,很多地方都不熟悉,但是通过阅读课程提供的源码,我慢慢学会python的gui开发,开始认识Tkinter模块。

下面我开始简单说说模仿开发之路:

源码界面:



模仿界面:



MVC模式:

是一个框架模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。

View

• draw_Food()

• draw_Snake()

• show_Score()

Model

• random_Food()

• snake()

• score()

Control

• play()

• iseated()

• isdead()

• move()

• gameover()

• restart()

代码部分:(具体的也不装B了,毕竟不是我自己的劳动成果,说一下我的一点修改收获)

一、文件头

# -*- coding: utf-8 -*-

"""
my SnakeGame
Created on Fri Aug 29 18:49:50 2014
@author lingowei
"""

from Tkinter import *
import random
# -*- coding: utf-8 -*-
是用来指定文件编码为utf-8的

<span style="font-size:14px;">from Tkinter import *
import random</span>
加载Tkinter模块和random模块

提供一个关于tkinker模块所有成员函数的功能介绍书:http://tkinter.unpythonic.net/pydoc/

二、SnakeGame类

def __init__(self): 
        self.step = 10
        self.score_ = -1
        # the snake position
        self.snakeX = [255,245]
        self.snakeY = [255,255]
        
        #to initialize the moving direction
        self.snakeDirection = "right"
        self.snakeMove = [1, 0]
        # to draw the game frame 
        window = Tk()
        window.geometry("800x550+180+160")
        window.maxsize(800,550)
        window.minsize(800,550)
        window.title("贪食蛇")
        
        self.canvas = Canvas(window, bg = "#191919", width = 800, height = 550)
        self.canvas.create_line(0,500,800,500, fill = 'white')
        self.scoretext = self.canvas.create_text(100, 520, text = 'Score: 0', font=("Purisa", 20), fill = 'white')    
        self.canvas.grid(row = 0)   
        self.draw_score()
        self.draw_food()
        self.draw_snake()  
        self.play()
        window.mainloop()
意思:

画布分成若干个长宽为10像素的小格子,

游戏积分初始为-1(至于为什么不是0,这个稍后说)

设置蛇的x,y坐标(列表上有两个数,即初始蛇只有两格长)

设置蛇的初始运动方向"right".

[1,0]代表蛇的x坐标+1,y坐标+0(就是向右走的意思啦)

下面就是显示可视化窗口

<span style="white-space:pre">	</span> window.geometry("800x550+180+160")

#800x550代表了初始化时主窗口的大小,180,160代表了初始化时窗口所在的位置

设置窗口最大最小大小,相等的话就是固定窗口大小(利于贪食蛇的运动区域控制)

设置窗口标题

然后,就是tkinker比较常用的控件:Canvas(画布)

Canvas的成员函数有http://tkinter.unpythonic.net/pydoc/Tkinter.Canvas.html

意义:在window下设置一个背景颜色为"#191919",宽为800,高为550的画布

在画布中创建一条白线

在画布中创建白色文本(Score:0)

执行视图层的• draw_Food()•
draw_Snake()• show_Score()

这里就是为什么初始分数为-1
执行控制层的 play()

window.mainloop()显示窗口

"=== View Part ==="         
    def draw_score(self):
        self.score()
        self.canvas.itemconfig(self.scoretext, text="Score: " + str(self.score_))
       
    def draw_food(self):
        self.canvas.delete('food')
        self.foodx,self.foody=self.random_food()
        self.canvas.create_rectangle(self.foodx - self.step / 2,self.foody - self.step / 2,\
        self.foodx + self.step / 2,self.foody + self.step / 2, fill = 'white', tags='food')
        
    def draw_snake(self):
        self.canvas.delete("snake")
        x,y=self.snake()
        for i in range(len(x)):
           self.canvas.create_rectangle(x[i] - self.step / 2,y[i] - self.step / 2,\
            x[i] + self.step / 2,y[i] + self.step / 2, fill='orange',tags='snake')


画布调整参数函数:itemconfig(canvas中的元素的id, 要修改的元素属性)

python换行:需要用“\”表示转行

tags = "food":画布中的元素标签是food

"=== Model Part ==="
    def random_food(self): 
    # return food position but not in the snake position
        return(random.randrange(5,795,self.step),random.randrange(5,495,self.step))
        
    def snake(self):
    #return x array and y array
    #前一段的位置给下一段
        for i in range(len(self.snakeX)-1,0,-1):
            self.snakeX[i] = self.snakeX[i-1]
            self.snakeY[i] = self.snakeY[i-1]
            
        self.snakeX[0] += self.snakeMove[0] * self.step
        self.snakeY[0] += self.snakeMove[1] * self.step
        return(self.snakeX,self.snakeY)
    
    def score(self):
        self.score_ += 1


"=== Control Part ==="     
    def iseated(self):
    # return true or false
        if self.snakeX[0] == self.foodx and self.snakeY[0] == self.foody:
            return True
        else:
            return False
    
    def isdead(self):
    # 判断头是否撞墙,或是否咬到自身
        if self.snakeX[0] < 5 or self.snakeX[0] > 795 or\
        self.snakeY[0] < 5 or self.snakeY[0] > 495:
            return True
        
        for i in range(1,len(self.snakeX)):
            if self.snakeX[0] == self.snakeX[i] and self.snakeY[0] == self.snakeY[i]:
                return True
        else:
            return False
    
    def move(self,event):
    # 通过键盘控制蛇的运动
    # left:[-1,0],right:[1,0],up:[0,1],down:[0,-1]  
        if event.keycode == 39 and self.snakeDirection != 'left':
            self.snakeMove = [1,0]
            self.snakeDirection = "right"
            
        elif event.keycode == 38 and self.snakeDirection != 'down':
            self.snakeMove = [0,-1]
            self.snakeDirection = "up"
            
        elif event.keycode == 37 and self.snakeDirection != 'right':
            self.snakeMove = [-1,0]
            self.snakeDirection = "left"
            
        elif event.keycode == 40 and self.snakeDirection != 'up':
            self.snakeMove = [0,1]
            self.snakeDirection = "down"
        #如何加速?  
        #else:
        #    print event.keycode
    
    def play(self):
    # main 
        self.canvas.bind('<Key>',self.move)
        self.canvas.focus_set()
        self.updatetime = 115
        
        while True:
            self.update = self.updatetime - self.score_
            if self.isdead():
                self.gameover()
                break
                
            elif self.iseated():
                self.snakeX[0] += self.snakeMove[0] * self.step
                self.snakeY[0] += self.snakeMove[1] * self.step   
                self.snakeX.insert(1,self.foodx)
                self.snakeY.insert(1,self.foody)
                
                self.draw_score()
                self.draw_food()
                self.draw_snake()
                self.canvas.after(100)
                self.canvas.update()
            
            else:
                self.draw_snake() 
                self.canvas.after(self.update)
                self.canvas.update()
                
    def gameover(self):
        # self.canvas.delete("food","snake")
        self.canvas.unbind('<Key>')
        self.canvas.bind("<Key>",self.restart)
        self.canvas.create_text(270,180,text="                   Game Over!\n \
        Press any key to continue",font=("Purisa", 30),tags='text', fill = "white")
        
    def restart(self,event):
        self.canvas.delete('text')
        self.canvas.unbind('<Key>')
        
        self.score_ = -1
        # the snake position
        self.snakeX = [255,245]
        self.snakeY = [255,255]
        
        #to initialize the moving direction
        self.snakeDirection = "right"
        self.snakeMove = [1, 0]

        self.draw_score() 
        self.draw_food()
        self.draw_snake()
        
        self.play()


SnakeGame类已经写完,下面剩下的就是运行:SnakeGame()

写到这里,在我的电脑上是已经可以运行的了,但是,我也想发布给同学玩玩,所以,下面来介绍一下使用py2exe把python文件转化为可执行文件

教程一搜很多,官方的:http://www.py2exe.org/index.cgi/Tutorial 中文版的:http://www.cnblogs.com/jans2002/archive/2006/09/30/519393.html

在这里我就不再说一遍了,我要说的是我遇到的一些转换上的问题——拒绝访问!!!!







这个问题烦恼了我一天,我实在找不出其问题所在,我问学长,学长说没遇到过;问老师,老师说他可行;但我的就是拒绝访问,我纳闷了。

后来,我把问题:

File "D:\Python27\lib\site-packages\py2exe\build_exe.py", line 860, in build_e

xecutable

add_resource(ensure_unicode(exe_path), script_bytes, u"PYTHONSCRIPT", 1, Tru

e)

RuntimeError: EndUpdateResource: 拒绝访问。

一搜,发现原来是杀毒软件在搅蛋,

After two days investigating we found a solution with the help of the IT staff.

The issue arise when py2exe try to modify the executable adding metadata and\or icon.

The root cause? Simple... ANTIVIRUS.

It considers that operation a threat and cause the Access Denied error.

Thank you all!
然后,我把自己的杀毒软件关闭即可。

最后,感谢中国大学MOOChttp://www.icourses.cn/imooc/,stackoverflow网http://stackoverflow.com/questions/21848033/access-denied-using-py2exe等等网站的帮助,我也希望可以用同样的方式帮助他人。

希望这个小小的介绍大神们不要喷,希望初学者可以有些许收获,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: