优秀作品

# 例程1:贪吃蛇游戏源码

gui = GUI("fine")

gui.HideConsoleWindow()

time = TIME()

math = MATH()


GAME_WIDTH  = 640

GAME_HEIGHT = 480


# 初始化方向

global direction = "right"          # 初始运动方向向右

global Snake


# 自定义类

class SNAKE(object)                # object 不能省略,object表示是基类,可以继承

{

    snake = []

    food  = []

    def draw(self,gui)       # draw方法是刷新界面,参数1是类对象本身,参数2是窗口ID

    {

        packageList = []     # 先创建一个空的指令包

        # 首先刷新游戏背景

        drawlist = ["CanvasPutImage","background",0,0]     # 重画背景指令

        packageList.append(drawlist)                       # 把指令打包

        # 刷新食物

        listfood = self.food       # 获取食物属性。listfood[0],listfood[1]是食物位置,listfood[2]是食物图片昵称

        drawlist = ["PutImage",listfood[2],listfood[0],listfood[1],32,32] 

        packageList.append(drawlist)

        # 刷新蛇

        listsnake = self.snake     # 获取设身体属性 

        for i in listsnake

        {

            # i[0]~i[1]是蛇的部件的位置,i[2]是蛇的部位昵称,i[3]是蛇的运动方向

            drawlist = ["PutImage",i[2],i[0],i[1],16,16]     # 循环获取蛇身的每一段位置

            packageList.append(drawlist)                     # 打包

        }

        gui.DrawPackage(packageList)                     # 一次性发出多个绘画指令

    }

}



# 移动蛇

def move_snake(Snake)    # 参数是个全局变量,是蛇对象

{

    delt_x = 0

    delt_y = 0

    

    snake_list = Snake.snake     # 取出蛇身体是个双重列表:[[x0,y0,"Head","方向"],[x1,y1,"Body","方向"],……]

    Snake_Head = snake_list[0]   # 蛇头列表

    head_x = Snake_Head[0]       # 蛇头x位置    

    head_y = Snake_Head[1]       # 蛇头y位置


    if direction == "right"

    {

        delt_x = 16     # 一次移动8个像素

    }

    elif direction == "left"

    {

       delt_x =  - 16

    }

    elif direction == "up"

    {

        delt_y = - 16

    }

    elif direction == "down"

    {

        delt_y =  16

    }


    # 边界检测

    head_x = head_x + delt_x     #

    head_y = head_y + delt_y     #

    if head_x < 0 or head_x >= GAME_WIDTH or head_y < 0 or head_y >= GAME_HEIGHT  

    {

        return False

    }

    

    # 将当前蛇头一节用蛇身节替换

    Snake_Head.replace(2,"Body")              # Snake_Head的第二项是皮肤,给蛇头换皮肤

    snake_list.replace(0,Snake_Head)          # 组合换装后的蛇,蛇头已经被蛇身替换

    

    head = [head_x,head_y,"Head",direction]   # 构造新的蛇头

    snake_list.insert(0,head)                 # 给蛇增加一个蛇头(不论是否吃到食物,先增加一个节蛇身)


    # 获取当前食物位置

    food_list = Snake.food

    food_x = food_list[0]

    food_y = food_list[1]


    # 判断是否吃到食物

    if (head_x > food_x-20 and head_x < food_x+20) and (head_y > food_y-20 and  head_y < food_y+20 )   

    {   

        # 如果吃到食物,蛇身维持新的状态,同时,重新随机放置食物

        food_x = math.rand(32,GAME_WIDTH-32)-8

        food_y = math.rand(32,GAME_HEIGHT-32)-8

        food_list = [food_x,food_y,"Food"]       # 参数1~2是位置,参数3食物

    }

    else  # 没有吃到食物,恢复蛇身体,并前进一步

    {

        x = snake_list.pop()                 # 先抛弃掉最后一节

        length = len(snake_list)             # 计算当前蛇身长度

        temp_list = snake_list[length-2]     # 取出蛇身倒数第二节 temp_list = [xn-2,yn-2,"Body","方向"]

        temp_list.replace(2,"Tail1")         # 将倒数第二节的图形换掉 temp_list = [xn-2,yn-2,"Tail1","方向"]

        temp_list = snake_list[length-1]     # 取出蛇身倒数第二节 temp_list = [xn-1,yn-1,"Body","方向"]

        temp_list.replace(2,"Tail0")         # 将倒数第二节的图形换掉 temp_list = [xn-1,yn-1,"Tail0","方向"]

        # 这样做始终保持尾部是小图形

    }

    # 由于类属性发生了变化,生成新的贪吃蛇类对象

    Snake = SNAKE(snake_list,food_list)      # 根据更新后的数据,生成新的贪吃蛇的类对象

    return True

}


# 定义初始化函数

def init()

{

    # 初始化,食物随机位置

    food_x = math.rand(32,GAME_WIDTH-32)-4     # 食物坐标

    food_y = math.rand(32,GAME_HEIGHT-32)-4    # 食物坐标

    food_list = [food_x,food_y,"Food"]         # 食物列表:参数1~2是位置,参数3食物图片名称

    # 初始化蛇体,只有三节

    snake_list0 = [3*16,5*16,"Head" ,"right"]            # 参数1~2是位置,参数3是体态,惨数4是方向

    snake_list1 = [2*16,5*16,"Tail1","right"]

    snake_list2 = [1*16,5*16,"Tail0","right"]

    snake_list = [snake_list0,snake_list1,snake_list2]   # snake_list是双重列表,是蛇身体,包含三节。


    # 生成初始化类对象

    Snake = SNAKE(snake_list,food_list)   # 生成贪吃蛇的类对象

}




# 创建游戏窗口

title       = "贪吃蛇游戏"                          # 窗口标题

size        = [10,3,82.3,38]                        # 窗口尺寸

# 四个方向控制按钮

button_up    = ["上", "button", 13, 32, 10, 1]

button_down  = ["下", "button", 28, 32, 10, 1]

button_left  = ["左", "button", 43, 32, 10, 1]

button_right = ["右", "button", 58, 32, 10, 1]


list = [title,size,button_up,button_down,button_left,button_right]    # 打包窗口元素

gui.Fine(list)                                                  # 创建Fine窗口,并返回资源ID

# 加载游戏资源

loadList = []     # 创建一个空的列表,用于打包绘图指令


drawlist = ["LoadImage","D:\\fine\\fin\\snake\\background.bmp","background"]     # 加载背景图片

loadList.append(drawlist)                                                        # 添加到指令包


drawlist = ["LoadImage","D:\\fine\\fin\\snake\\food.bmp","Food"]                 # 加载食物图片

loadList.append(drawlist)


drawlist = ["LoadImage","D:\\fine\\fin\\snake\\snakeBody.bmp","Body"]            # 加载身体图片

loadList.append(drawlist)


drawlist = ["LoadImage","D:\\fine\\fin\\snake\\snakeHead.bmp","Head"]            # 加载头图片

loadList.append(drawlist)


drawlist = ["LoadImage","D:\\fine\\fin\\snake\\snakeTail1.bmp","Tail1"]          # 加载尾部大图片

loadList.append(drawlist)


drawlist = ["LoadImage","D:\\fine\\fin\\snake\\snakeTail0.bmp","Tail0"]          # 加载尾部小图片

loadList.append(drawlist)


gui.DrawPackage(loadList)        # 一次性加载所有资源


buttonenable = 0    # 按钮enable

speed = 30          # 初始速度

init()              # 初始化SNAKE

count = 0


while gui.FineClosed() != -1          # 检查窗口关闭消息

{

    PowerDown(3)  

    if gui.FineReady() == 0   # 有按键按下

    {

        x = gui.FineRead()

        button_action = x[0]

        if button_action == "button-0"    # 上

        {

            direction = "up"

        }

        elif button_action == "button-1"  # 下

        {

            direction = "down"

        }

        elif button_action == "button-2"  # 左

        {

            direction = "left"

        }

        elif button_action == "button-3"  # 右

        {

            direction = "right"

        }  

        buttonenable = 0     # 禁止按键,避免多次按键

    }    


    count = count + 1                       # 节能设置

    if(count < speed) {continue}

    count = 0

    if not move_snake(Snake)             # 按既定方向移动一位,如果越界game over,没有越界继续

    {

        box = GUI("box")

        box.MessageBox("游戏结束!是否继续?","确定|取消")

        while box.MessageBoxClosed() != -1 {PowerDown(3)}

        select  = box.MessageBoxRead()

        if select != 0

        {

             gui.CloseFine()             # 关闭窗口,退出程序

        }

        else                              # 如果按了确定键

        {

            init()                        # 初始化

            count = 0

            continue                     # 跳转到while循环起点

        }

    }

    

    if len(Snake.snake) > 14             # 如果蛇身体长大到超过10节,认为可以通关了。

    {

        box = GUI("box")

        box.MessageBox("恭喜你顺利通关!再来一局?","确定|取消")

        while box.MessageBoxClosed() != -1 {PowerDown(3)}

        x  = box.MessageBoxRead()

        if x == 0                          # 如果选择继续玩,则逐渐提高速度

        {

            speed = speed - 2             # 速度逐渐变快

            if speed < 26

            {

                speed = 26                # 限制最快速度

            }

            init()                         # 初始化

            count = 0

            continue                      # 重启游戏

        }

        else                              # 如果选择取消、或直接关闭MessageBox窗口,则退出程序

        {

            gui.CloseFine()             # 关闭窗口,退出程序

        }

    }

    Snake.draw(gui)                        # 自定义类方法,绘图

}

0