贰个玩耍能够省略的分为多个部分

python小白尝试写游戏..

学了点pygame不驾驭那什么练手好,先拿贪吃蛇开刀吧.

多少个游戏可以大概的分为三个部分:

  • 数据(变量)
  • 管理数据(函数,方法)

设计变量

率先预想下,画面的那个部分需求仓库储存在变量里

图片 1

方方面面画面上只会有矩形,而且这一个矩形井然有条,大小相当于,原来多个矩形需求多少个变量表示地点,这里,只需求四个变量(行数,列数)就会代表方块的职责

蛇头,食品能够用二元元组表示,蛇身的多寡不明确,只好用含有数个元组的列表表示

别的设定窗口大小800×600,各样方块都以50×50

import pygame
import sys

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("贪吃蛇")

food = (4, 5)
body = [(1, 1),(1,2)]
head = (1, 3)

BLOCK = 0, 0, 0
GREEN = 0, 255, 0
RED = 255, 0, 0
BLUE = 0, 0, 255
WHITE = 255, 255, 255

while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

变量设定好了,游戏早就做到了概况上( ̄▽ ̄)~*

下一步

变量到画面

pygame.draw.rect()是依靠矩形四元数组绘制图像的,那就写个函数”对接”下本身的二元坐标

此地就成数学的主题素材了…

def new_draw_rect(zb, color,screen):
    pygame.draw.rect(screen,color,((zb[1]-1)*50+1,(zb[0]-1)*50+1,48,48))

鉴于50×50时周围方块们会”粘”在联合,方块向里收一下成48×48        ↑

制图图形,

...
while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    screen.fill(WHITE)
    new_draw_rect(food, RED, screen)
    for i in body:
        new_draw_rect(i, BLUE, screen)
    new_draw_rect(head, GREEN, screen)

    pygame.display.update()

 由静到动

 四个难点:

1.怎么时候动

2.怎么动

难题1,曾几何时动,这里有七个思路,

  • 区间固准时期(1秒),动二遍
  • 按二遍键动三回,无操作必然时间(1秒)后,重复最后一次操作

看起来第生机勃勃种方案 简单 不错

首先,先用pygame的clock类限定帧率(100帧),以方便计时

与此同偶然候,参预新变量times,times每便加1,超越一百就”动一动”

加入新变量direction,表示蛇头朝向,衔接键盘操作和”怎么动”

 PS:程序截止在此以前,很难领会要用多少变量

import pygame
import sys

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("贪吃蛇")

fclock = pygame.time.Clock()


food = (4, 5)
body = [(1, 1)]
head = (1, 2)
times = 0
direction = 'right'

BLOCK = 0, 0, 0
GREEN = 0, 255, 0
RED = 255, 0, 0
BLUE = 0, 0, 255
WHITE = 255, 255, 255

def new_draw_rect(zb, color,screen):
    pygame.draw.rect(screen,color,((zb[1]-1)*50+1,(zb[0]-1)*50+1,48,48))
    pass


while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                direction = "up"
            elif event.key == pygame.K_LEFT:
                direction = "left"
            elif event.key == pygame.K_DOWN:
                direction = "down"
            elif event.key == pygame.K_RIGHT:
                direction = "right"
    if times >= 100:
        pass#动一动
        times = 0
    else:
        times += 1

    screen.fill(WHITE)
    new_draw_rect(food, RED, screen)
    for i in body:
        new_draw_rect(i, BLUE, screen)
    new_draw_rect(head, GREEN, screen)

    fclock.tick(100)
    pygame.display.update()

 

 蛇头的活动规律 : 向左近的格子移动,上下左右现实那么些格子由键盘显著

这就写个新函数去变通蛇头的新岗位

def get_front(head,direction):
    x, y = head
    if direction == "up":
        return x-1, y
    elif direction == "left":
        return x, y-1
    elif direction == "down":
        return x+1, y
    elif direction == "right":
        return x, y+1

然后

head = get_front(head,direction)

唯独蛇蛇贰只扎墙里怎么做…….

您的密友【front : 不时记下蛇头前方的岗位】已上线

您的知心人【alive : 记录存活消息】已上线

PS:front能够不是全局变量

def ask_alive(front,body):
    x, y = front
    if x < 0 or x > 12 or y < 0 or y >16 :
        return False
    if front in body:
        return False
    return True

下一场那样用

front = get_front(head,direction)
alive = ask_alive(front,body)
if alive:
  head = front

人话 :先看看蛇头前边是还是不是有危殆,有危急就死了 , 不动啦

其余alive得加到前边的if里面当限定规范,死了就无法乱动啊~

 

蛇身动的规律 : 近头端跟头走,尾端也随之走–向程序靠拢–>>用过的head参加body,相同的时间删去body最老的成员

此处可以观望body必需有序,可变.python里面就用列表了

如若接纳list的append方法,head加在body的末尾,那么body[0]就能够是”最老的分子”就得使用pop(0)删去

PS. body.append(head)得写在head=front前面,在head更新前加进body

    if times >= 100 and alive:
        front = get_front(head,direction)
        alive = ask_alive(front,body)
        if alive:
            body.append(head)
            head = front
            body.pop(0)
        times = 0
    else:
        times += 1

 食物的移动规律:被吃掉后,随飞机地方置再出新 –向程序围拢–>>
当head== food为真时 food随机筛选二个蛇之外的地点现身

def new_food(head,body):
    while 1:
        x = random.randint(1, 12)
        y = random.randint(1, 16)
        if (x, y) != head and (x, y) not in body:
            return x, y

 

那边存在三个隐式BUG,若是蛇充满了每个角落,那那正是死循环
………..然后整整程序卡在这里间….

本子1 : 小编选用没看见,不会有何人能吃到”全屏”的(´⊙ω⊙`)  
 –来自开垦者的懈怠

本子2 【笔者的选项】: 修了那几个BUG

def new_food(head,body):
    i = 0
    while i < 100:
        x = random.randint(1, 12)
        y = random.randint(1, 16)
        if (x, y) != head and (x, y) not in body:
            return (x, y), True
        i += 1
    else:
        return (0, 0), False

food, alive = new_food()

 

 九拾伍回时机 不然就死( ̄へ ̄)     –来自开垦者的恶意

别的,蛇吃了食品将要长意气风发格====>>蛇头前进后生可畏格,蛇尾不动,蛇就就此长了意气风发格====>>当head
= food 为真时body.pop(0)不用实施

        if alive:
            body.append(head)
            head = front
            if food == head:
                food = new_food(head, body)
            else:
                body.pop(0)

 

得了撒花

细节优化

1,

什么样?游戏甘休了?

黑个屏,提醒下

您的死党【back_color】已上线

back_color意气风发开端等于WHITE , alive为假时成为BLOCK

标题栏产生”游戏结束”

    if times >= 100 and alive:
        front = get_front(head, direction)
        alive = ask_alive(front, body)
        if alive:
            body.append(head)
            head = front
            if food == head:
                food, alive = new_food(head, body)
            else:
                body.pop(0)
        else:
            back_color = BLOCK
            pygame.display.set_caption("游戏结束")
        times = 0
    else:
        times += 1

 

 

 

2,

图片 1

如果大器晚成开头按了弹指间left……

恭贺你收获手艺【撞脖子自寻短见】

如故那就

你的死党【old_direction】已上线

old_direction = "right"

def direction_yes_no(direction,old_direction):
    d = {"up": "down", "down": "up", "left": "right", "right": "left"}
    if d[direction] == old_direction:
        return old_direction
    return direction

 

PS : 字典替代if-elif结构省心省时

然后 

  if times >= 100 and alive:
        direction = direction_yes_no(direction, old_direction)
        old_direction = direction
        front = get_front(head, direction)
        alive = ask_alive(front, body)

 

人话 :
增添二个变量记录上一回有效的输入,多少个方向关系不科学时,以老变量为准–向人走近–>>向右跑时,不许向左!!!

Q : direction也得以在按钮事件管理时间限定制呀,举个例子

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                direction = "up"
                   """改为"""
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if direction != "down"
                    direction = "up"

 

A:在乎识这一个法子的BUG早先,小编也是如此想的

大概地点的例子

图片 1

直接按left行不通,right–XX–>left

先按down,快捷再按left ,,right –pass–>> down –pass–>> left

恭贺您拿走工夫【绕过开垦者防护,高水准撞脖子自杀】

3,

Q : 笔者要中断!!!

A : 好有趣游戏,不要动不动就搁浅

你的知音【pause】已上线

逻辑值,P键控制

pause = False

            elif event.key == pygame.K_p:
                pause = not pause    

if times >= 100 and alive and (not pause):
    ....

 

 

下边笔者发一下总体的代码,代码蕴含上边的优化

↓↓↓↓

甘休撒花

import pygame
import sys
import random

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("贪吃蛇")

fclock = pygame.time.Clock()


food = (4, 5)
body = [(1, 1)]
head = (1, 2)

times = 0
direction = "right"
old_direction = "right"
alive = True
pause = False

BLOCK = 0, 0, 0
GREEN = 0, 255, 0
RED = 255, 0, 0
BLUE = 0, 0, 255
WHITE = 255, 255, 255
back_color = WHITE


def new_draw_rect(zb, color,screen):
    pygame.draw.rect(screen,color,((zb[1]-1)*50+1,(zb[0]-1)*50+1,48,48))


def get_front(head, direction):
    x, y = head
    if direction == "up":
        return x-1, y
    elif direction == "left":
        return x, y-1
    elif direction == "down":
        return x+1, y
    elif direction == "right":
        return x, y+1


def ask_alive(front, body):
    x, y = front
    if x < 0 or x > 12 or y < 0 or y >16 :
        return False
    if front in body:
        return False
    return True


def new_food(head, body):
    i = 0
    while i < 100:
        x = random.randint(1, 12)
        y = random.randint(1, 16)
        if (x, y) != head and (x, y) not in body:
            return (x, y), True
        i += 1
    else:
        return (0, 0), False


def direction_yes_no(direction, old_direction):
    d = {"up": "down", "down": "up", "left": "right", "right": "left"}
    if d[direction] == old_direction:
        return old_direction
    return direction

#food = new_food(head,body)

while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                direction = "up"
            elif event.key == pygame.K_LEFT:
                direction = "left"
            elif event.key == pygame.K_DOWN:
                direction = "down"
            elif event.key == pygame.K_RIGHT:
                direction = "right"
            elif event.key == pygame.K_p:
                pause = not pause
    if times >= 100 and alive and (not pause):
        direction = direction_yes_no(direction, old_direction)
        old_direction = direction
        front = get_front(head, direction)
        alive = ask_alive(front, body)
        if alive:
            body.append(head)
            head = front
            if food == head:
                food, alive = new_food(head, body)
            else:
                body.pop(0)
        else:
            back_color = BLOCK
            pygame.display.set_caption("游戏结束")
        times = 0
    else:
        times += 1

    screen.fill(back_color)
    new_draw_rect(food, RED, screen)
    for i in body:
        new_draw_rect(i, BLUE, screen)
    new_draw_rect(head, GREEN, screen)

    fclock.tick(100)
    pygame.display.update()

 

 

↑↑↑↑

↑↑↑↑

↑↑↑↑

4,

Q : 游戏甘休或许暂停后因为times >= 100 and alive and (not
pause)始终为假

times += 1 一贯运维,,,,会不会不太妥善

A :
又不会溢出,,,,,,,,撤废暂停时蛇能便捷跑起来要是time==100那难题就大了,,万幸当初留了些余地写成
>=  

(~ ̄▽ ̄)~ 

5,

Q : 蛇跑的太慢作者想加速

A : 上边的times>=100的100随意改一下就能够

0->100动一动   变成    0->80 动一动

依然动前边的数

0->100动一动   变成    20->100动一动

可能将它设置成变量让它随蛇的长短变化而转变

6,

打字太累,,

direction这里能够使用0,1,2,3

代替 up left down right

键盘事件和get_front()得用同生机勃勃套词

7,

Q : 第三个food之处是长久的,无法”动”吗?

A : 因为小编是先定义变量,再定义函数

food = new_food(head,body)

就得写在概念函数前边,作者不忍心让它三个变量孤单,,,,怕你看不到(写了但注释掉了)

动手术

前方说过

标题1,何时动,这里有多少个思路,

  • 间距固依时期(1秒),动一回
  • 按三次键动二回,无操作必然时间(1秒)后,重复最终一回操作

看起来第风流洒脱种方案  style=”text-decoration: line-through”>轻巧 不错

当下自己感觉第三种方案很难,,,

写了那么些博客后实力大增ᕦ( ᴼ ڡ ᴼ )ᕤ

近些日子本人即便了

第叁个措施,

拍卖按钮事件后times = 100 ,例

    if event.key == pygame.K_UP:
        direction = "up"
        times = 100
    elif event.key == pygame.K_LEFT:
        direction = "left"
        times = 100  

 

while循环当轮就能够动一动

潜伏操作 : 在0.01s内按下多少个键,第一个按的不会”生效”

pygame : 小编得跑完事件列表的各类元素

那是假的第二方案!!!

第1个主意,

把”动一动”的上上下下代码,打包成函数恐怕直接写在开关管理的前边

正是地方times = 100之处 例

    if event.key == pygame.K_UP:
        direction = "up"
        '动一动'
    elif event.key == pygame.K_LEFT:
        direction = "left"
        '动一动'

 

牢牢记住主要的一点times =
0也算”动一动”的内容,第二方案里,开关后计时须要清零!!!

    if times >= 100 and alive and (not pause):
        direction = direction_yes_no(direction, old_direction)
        old_direction = direction
        front = get_front(head, direction)
        alive = ask_alive(front, body)
        if alive:
            body.append(head)
            head = front
            if food == head:
                food, alive = new_food(head, body)
            else:
                body.pop(0)
        else:
            back_color = BLOCK
            pygame.display.set_caption("游戏结束")
        times = 0
    else:
        times += 1

 

为了幸免”诈尸”

“动一动”前还得抬高if alive and (not pause):

times没须求加

我就懒得管了(╥╯^╰╥)那篇随笔写了太短时间,今后早就看不懂当初的代码了

Q :
不知晓您是否记念自个儿,优化2正是本人问的…..是如此的,作者对自个儿的办法还不死心….”出手术”改第二方案后能用吗?

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                direction = "up"
                   """改为"""
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if direction != "down"
                    direction = "up"

 

A : 对于第黄金年代主意完结的第二方案依旧会有小病魔

while循环当轮就会动一动

隐身操作 : 在0.01s内按下三个键,第三个按的不会”生效”

pygame : 笔者得跑完事件列表的各种元素

在0.01s内,按下五个键,就能够一直以来触发【秘籍: 撞脖子自寻短见】

其次办法完毕的相应没问题…….

 完毕撒花✿✿ヽ(°▽°)ノ✿

 

Q :
笔者想在加宽荧屏在左侧展现一下时间分数之类的信息,你还会有哪些”交待”吗?

A :
在pygame展现字体比较有难度….小编必须要祝你程序不出BUG…别的点(800,0)到点(800,600)别忘了画到线,提示游戏的使用者”边界”仍然存在的,让游戏的使用者摔键盘动怒就不好了

 

Q : 笔者正是对你的颜色搭配有理念,颜色微微扎眼….

A :
笔者又不是雕塑,,,,,,,,,,,,颜色搭配的标题,应该,,,,,,,,,应该能够原谅,,,,,,,,,,

 

Q : 游戏太没挑衅性,加点障碍物呗~~

A : walls
会在ask_alive()和new_food()用到,加个if的主题材料,,,,其它绘制显示器这里多加个for,,,,,

自个儿就懒得管了(╥╯^╰╥)那篇小说写了太长期,以往早已看不懂当初的代码了

告竣撒花✿✿ヽ(°▽°)ノ✿

此番真没了..✿✿ヽ(°▽°)ノ✿

如有疏漏,迎接补充

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website