前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python|一男子竟然用python干这事儿

Python|一男子竟然用python干这事儿

作者头像
算法与编程之美
发布2020-04-01 17:10:18
9280
发布2020-04-01 17:10:18
举报

本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。

1.前言

游戏,大家一定不陌生,那么有没有想过游戏是怎么做出来的呢?作为一个与代码打交道的人,都知道是用一行一行代码堆积出来的。今天,大家就跟小编一起来用代码敲出一款属于自己的游戏吧!

2.准备

今天要做的是一款类似于打乒乓球的小游戏,要做这款游戏必须要有一定python基础,当然只要用心,小白也是可以学会的。

小编将通过以下几个步骤来做这款游戏:

(1)配置环境

(2)设置背景

(3)绘制玩家

(4)方向控制

(5)添加乒乓球

(6)边界判断以及接球检测

(7)分数设置

3.游戏制作

1.配置环境。

首先安装python环境。详情见python官网。

(https://www.python.org/)

这款游戏用到的只有一个工具就是python的“小海龟”——turtle,这是python的内置库。只需要调用就行。这里将turtle调用为t,方便后续使用。

import turtle as t

2.设置背景。

设置背景之前,先想一想背景需要有什么特征。自然是要有宽和高、还有标题、颜色。这里就需要用到turtle的函数,具体看代码。

game = t.Screen()  #绘制游戏框

game.title('八里公路打乒乓')

game.bgcolor('black')

game.setup(800,600)  #宽和高

3.绘制玩家。

同样,绘制玩家时,也需要知道玩家的特征。就是大小、颜色、形状、还有位置。这里需要注意的是turtle的坐标系是怎样的。它同pygame(python的游戏库)不一样的是,它的画布的正中央为坐标原点,所以玩家的位置就要根据玩家大小和游戏窗口大小来计算得出。还有由于玩家是可以移动的,所以其坐标就不能写死,就用两个变量x,y来表示。详见代码。

p1 = t.Turtle()

p1.ht()   #隐藏画笔的标识

p1.up()  #提起画笔,防止移动时留下痕迹

p1.color('yellow')

p1.speed(5)  #移动速度

p1.shape('square')  #玩家形状

p1.shapesize(5,1)    #大小长宽为5:1

p1.goto(-350,0)

p1.st()

p1_score = 0  #玩家1的得分,后续会用

def p1_up():    #移动的方法,后面可以直接调用

    y = p1.ycor()

    y += 20

    p1.sety(y)

def p1_down():

    y = p1.ycor()

    y -= 20

    p1.sety(y)

同理,再绘制出玩家2.这里先看一下效果;

图1玩家绘制效果

4.方向控制。

要控制方向,就需要程序知道键盘动作,所以turtle中有一个listen()函数,可以知道键盘上的动作,具体的哪个按键控制什么动作,都是可以自己设置的。

game.listen()

game.onkey(p1_up,'s')    #移动方向对应按键的设置

game.onkey(p1_down,'x')  #对应的移动在绘制玩家代码中,调用移动方法。

game.onkey(p2_up,'Up')

game.onkey(p2_down,'Down')

注意:在游戏时,只有英文输入法键盘才能控制。

5.添加乒乓球。

添加方法和添加玩家是一样的,不同的是其形状为圆形,位置也要注意,既然是双人游戏,为了公平起见,选择在窗口中心坐标原点出发球。一样要注意坐标不能写死了,也用两个变量表示。还有乒乓球是自己动的,所以还需要给它一个移动“规则”,也就是dx,和dy,这样就是沿着一条斜线移动的。

pp = t.Turtle()

pp.up()

pp.color('white')

pp.speed(0)

pp.shape('circle')

pp.st()

pp.dx = 3

pp.dy = 3

pp.setx(pp.xcor()+pp.dx)  #位置移动

pp.sety(pp.ycor()+pp.dy)

6.边界判断以及接球检测。上述步骤都是比较容易的,没有什么逻辑关系,关键在于对turtle的用法掌握。而这一步骤就需要比较强的编程思维以及一定数学能力了。由于玩家是可以自己移动的,所以就不用管玩家的界限。对于乒乓球而言,它首先是从原点往右上方移动,最先会撞到上方的边界,根据物理的光学反射原理,可以得出球撞到上边界时会以它的入射角度反方向移动,放到坐标系上来看,就是横坐标不变,被反弹回来后其纵坐标变为相反数,所以只需要将乒乓球的移动规则的dy乘上-1就可以了。同理,下边界也是一样的道理。至于坐标的范围就需要自己在纸上画一画了。

pp.setx(pp.xcor()+pp.dx)   #位置移动

pp.sety(pp.ycor()+pp.dy)

if pp.ycor() > 290 or pp.ycor() < -290:  #上下边界范围

   pp.dy *= -1

判断了上下边界,然后再判断左右边界,跟上下边界判断方法一样,不同的是球左右出界后不会反弹。而是回到原点重新开始。

if pp.xcor()>380:  #右边界范围

    pp.goto(0,0)

    p1_score += 1   #球在哪一边出界了,它的对手就加以分。

    score()

if pp.xcor()<-380:   #左边界范围

    pp.goto(0,0)

    p2_score += 1

    score()

再来看接球检测,如果球的坐标与球拍的坐标距离在一定的范围内了,就要让球反弹,dy不变,dx乘上-1。为了防止球在球拍上的粘连情况,让球反弹时适当往球拍外移动一点,这里选择将球的横坐标改变为339或-339.

if pp.ycor()<p2.ycor()+50 and pp.ycor()>p2.ycor()-50 and pp.xcor()>340:

    pp.dx *= -1

pp.setx(339)

if pp.ycor()<p1.ycor()+50 and pp.ycor()>p1.ycor()-50 and pp.xcor()<-340:

    pp.dx *= -1

    pp.setx(-339)

7.分数设置。可以直接用turtle的write()函数,然后再自己设置字的颜色,大小,位置。

def score():

    pen.clear()  #防止叠加

    pen.write('八里公路:%d VS 大魔王:%d' % (p1_score,p2_score),align='center',font=('Arial',20,'bold'))

score()

特别注意的是,由于turtle的工作原理是一遍一遍的画,所以需要定义一个主循环,让需要的一直出现在窗口中。还要防止文字叠加,所以每一画的时候,都要清空画笔,然后update更新。

#判断是否退出

running = True

def stop_loop():

    global running

    running = False

#注册退出事件

root = game.getcanvas().winfo_toplevel()

root.protocol('WM_DELETE_WINDOW',stop_loop)

while running:

    game.update()

上面的几个看不懂的东西,只需要记住就行了,它的目的是让电脑知道叉掉窗口是要退出游戏的意思,这样才退出时不会报错。

4.综合代码

经过以上所有步骤,这个游戏就算是做好了,来看一下完整代码吧。

import turtle as t

#设置背景

game = t.Screen()  #绘制游戏框

game.title('八里公路打乒乓')

game.bgcolor('black')

game.setup(800,600)  #宽和高

game.tracer()

#玩家1

p1 = t.Turtle()

p1.ht()   #隐藏画笔的标识

p1.up()  #提起画笔,防止移动时留下痕迹

p1.color('yellow')

p1.speed(5)  #移动速度

p1.shape('square')  #玩家形状

p1.shapesize(5,1)    #大小长宽为5:1

p1.goto(-350,0)

p1.st()

p1_score = 0  #玩家1的得分,后续会用

def p1_up():   #玩家1的坐标,移动时使用,这里是向上

    y = p1.ycor()

    y += 20   #移动步长

    p1.sety(y)

def p1_down():   #对应的移动在绘制玩家代码中,调用移动方法。

    y = p1.ycor()

    y -= 20

    p1.sety(y)

#玩家2

p2 = t.Turtle()

p2.ht()

p2.up()

p2.color('red')

p2.speed(5)

p2.shape('square')

p2.shapesize(5,1)

p2.goto(350,0)

p2.st()

p2_score = 0

def p2_up():

    y = p2.ycor()

    y += 20

    p2.sety(y)

def p2_down():

    y = p2.ycor()

    y -= 20

    p2.sety(y)

#添加乒乓

pp = t.Turtle()

pp.up()

pp.color('white')

pp.speed(0)

pp.shape('circle')

pp.st()

pp.dx = 3

pp.dy = 3

#添加分数

pen = t.Turtle()

pen.ht()

pen.color('white')

pen.up()

pen.goto(0,250)

pen.down()

def score():

    pen.clear()  #防止叠加

    pen.write('八里公路:%d VS 大魔王:%d' % (p1_score,p2_score),align='center',font=('Arial',20,'bold'))

score()

pen1 = t.Turtle()

pen1.ht()

pen1.up()

pen1.color('white')

pen1.goto(0,220)

pen1.write('左:s(上),x(下);右:方向键控制上下',align='center',font=('Arial',15,'bold'))

#玩家移动

game.listen()

game.onkey(p1_up,'s')   #移动方向对应按键的设置

game.onkey(p1_down,'x')  #对应的移动在绘制玩家代码中,调用移动方法。

game.onkey(p2_up,'Up')

game.onkey(p2_down,'Down')

#判断是否退出

running = True

def stop_loop():

    global running

    running = False

#注册退出事件

root = game.getcanvas().winfo_toplevel()

root.protocol('WM_DELETE_WINDOW',stop_loop)

#乒乓移动

while running:

    game.update()

    pp.setx(pp.xcor()+pp.dx)   #位置移动

    pp.sety(pp.ycor()+pp.dy)

    if pp.ycor() > 290 or pp.ycor() < -290:

        pp.dy *= -1

    #接球

    if pp.ycor()<p2.ycor()+50 and pp.ycor()>p2.ycor()-50 and pp.xcor()>340:

        pp.dx *= -1

        pp.setx(339)

    if pp.ycor()<p1.ycor()+50 and pp.ycor()>p1.ycor()-50 and pp.xcor()<-340:

        pp.dx *= -1

        pp.setx(-339)

    #球出界

    if pp.xcor()>380:  #右边界范围

        pp.goto(0,0)

        p1_score += 1

        score()

    if pp.xcor()<-380:   #左边界范围

        pp.goto(0,0)

        p2_score += 1

        score()

然后再看以下运行效果。

图2 最终效果

5.总结

做完这个简单的游戏后,不知道大家对写代码有了什么新的看法?

当然做游戏不是主要目的,只是通过做游戏来感受以下编程带来的乐趣,毕竟可视化后是要比代码有趣多了。而且,大家也看到了,仅仅是这样一个简单的游戏,也是需要不少功夫的,所以,在编游戏的同时也能提高编程思维,以及解决问题的方法步骤。那么,你是不是也想跟小编一起做做小游戏呢?

END

主 编 | 王文星

责 编 | 江来洪

where2go 团队

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法与编程之美 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档