PONG - 100行代码写一个弹球游戏

简介: 游戏引擎用的是 Python 的一个游戏库:pgzero。它是对 pygame 的一个封装,让你不需要写多余的套路代码,只要配置游戏的内容逻辑即可。

大家好,欢迎来到 Crossin的编程教室 !


今天跟大家讲一讲:如何做游戏


游戏的主题是弹球游戏《PONG》,它是史上第一款街机游戏。因此选它作为我这个游戏开发系列的第一期主题。


游戏引擎用的是 Python 的一个游戏库:pgzero。它是对 pygame 的一个封装,让你不需要写多余的套路代码,只要配置游戏的内容逻辑即可。


我们这个游戏用它来写,一共只需要100行代码。


首先需要安装 python 环境。这一步没搞定的同学,可以参考我们 python 入门教程:python666.cn,上面有详细图文介绍。


然后需要安装 pgzero 库,可以命令行下通过 pip 命令安装:


pip install pgzero


安装完,运行一句


pgzrun.go()


我们的游戏世界之门就已经打开了。



现在上面还是混沌初开,一片漆黑。



设定一个矩形的左上角坐标和长宽,在游戏的绘制函数 draw 中用指定颜色填充,我们就得到了一个矩形。


pad_1 = Rect((20, 20), (10, 100))
def draw():
    screen.clear()
    screen.draw.filled_rect(pad_1, 'white')



适当调整一下,就得到了一块游戏中用来挡球的板。



在游戏的更新函数中增加判断,当键盘上的“上”、“下”按键被按下时,修改挡板的y坐标,就可以在游戏中控制挡板的移动了。


PAD_SPEED = 10
def update(dt):
    if keyboard.up:
        pad_1.y -= PAD_SPEED
    elif keyboard.down:
        pad_1.y += PAD_SPEED


这样就已经完成 PONG 游戏中的玩家操控角色:一块可上下移动的挡板。而现在我们用到的代码仅仅10行。


有的小伙伴可能注意到了,这里有两个函数,一个叫 draw,它是负责游戏中的画面绘制,另一个叫 update,它负责游戏中的逻辑更新。


我们经常听到说游戏运行时速度是每秒30帧、60帧之类,或者叫做 FPS(Frames Per Second)。draw 和 update 就是在游戏的“一帧”画面中所要做的事情。你的计算机或者游戏主机的性能越高,每一帧所花费的计算时间就越少,游戏帧数就可以更高,游戏体验也就更流畅。


创建一个叫做 Ball 的类型,属性值包括位置和速度。然后,在绘图函数中以小球的位置为圆心画一个圆,在更新函数中按照匀速直线运动位移公式,也就是 位移=速度x时间,计算出小球下一帧的位置。如此就实现了一个会运动的小球。


class Ball():
    def __init__(self):
        self.pos = [300, 200]
        self.speed = [1, 1]        
    def update(self, dt):
        for i in range(2):
            self.pos[i] += self.speed[i] * dt
ball = Ball()
def draw():
    screen.clear()
    screen.draw.filled_rect(pad_1, 'white')
    screen.draw.filled_circle(ball.pos, BALL_RADIUS, 'white')


再设置一下边界条件,让小球到达屏幕边缘时可以改变对应的速度方向,碰到上下边缘就将y速度分量乘以-1,超出左右边缘则位置重新设置回屏幕中心。


class Ball():
    ...      
    def update(self, dt):
        for i in range(2):
            self.pos[i] += self.speed[i]
        if self.pos[1] < 0 or self.pos[1] > HEIGHT:
            self.speed[1] *= -1
        if self.pos[0] < 0 or self.pos[0] > WIDTH:
            self.reset()


有了板,有了球,接下来就是让他们之间产生关联。


在更新函数中做一个碰撞检测:如果板子的矩形与球的圆心产生了交集,就让球反弹回去。


def update(dt):
    ...
    ball.update(dt)
    if pad_1.collidepoint(ball.pos) and ball.speed[0] < 0:
        ball.speed[0] *= -1


到这一步,游戏的核心物理规则就已经定义完毕。


按照同样的方法,在屏幕的右侧创建第二块板,通过另外的按键进行控制。然后,当小球超出左右边界时,分别给对面一方得分。


class Ball():
    ...      
    def dead(self, side):
        scores[side] += 1
        self.reset()


这样,一个最最简单的,双人版弹球游戏就完成了。


当然,如果你找不到另一个人陪你一起玩,也可以让自己的左手跟右手玩。


或者,给一侧板增加一点自动追踪的代码:让板的位置随着球的位置移动。这也算是一个游戏AI了。


def auto_move_pad(dt):
    if ball.pos[0] > WIDTH / 2 and ball.speed[0] > 0:
        if pad_2.y + pad_2.height * 0.25 > ball.pos[1]:
            pad_2.y -= PAD_SPEED * dt
            if pad_2.top < 0:
                pad_2.top = 0
        elif pad_2.y + pad_2.height * 0.75 < ball.pos[1]:
            pad_2.y += PAD_SPEED * dt
            if pad_2.bottom > HEIGHT:
                pad_2.bottom = HEIGHT


至此,一个具备完整核心玩法的弹球游戏 PONG 已经完成了。加上空格也不到100行代码。特别适合编程新手刚刚接触游戏开发的小伙伴进行练习。


不过,我还给游戏增加了一点点细节,感兴趣的小伙伴可点击文章开头的视频进行观看。喜欢的话欢迎点赞和转发!



之后我还会来尝试更多的游戏类型,更多的玩法。争取完成最初立下的FLAG:实现100个游戏如果你想看某类游戏或者某个游戏的实现,或者对某个实现细节有疑问,也可以留言中告诉我,我会优先考虑。

感谢转发点赞的各位~

相关文章
|
6月前
daimayuan 代码源大富翁游戏
daimayuan 代码源大富翁游戏
45 0
|
存储 程序员 Python
Python版飞机大战游戏的设计(一)-----敌机出场(2)
Python版飞机大战游戏的设计(一)-----敌机出场
|
开发者
你应该试着独自做个游戏
对于大部分从事游戏开发行业的人,其实并没有机会能够完整的去掌控一个游戏制作的全过程。开发的只负责开发工作,美术的只负责美术工作,大概只有策划能够有机会从整体上了解一个游戏,可能在很多公司中,对于策划也分为很多种,如果只是其中的一种策划,也是没有机会的,唯一一个能够从始至终掌控一个游戏的大概叫做总策划或者叫产品经理。
92 0
|
Python
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏03之重力及碰撞检测
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏03之重力及碰撞检测
182 0
|
Python
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏06之死亡后游戏重新开始
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏06之死亡后游戏重新开始
182 0
|
Python 容器
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏05之滚动屏幕
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏05之滚动屏幕
184 0
|
Python
python及pygame雷霆战机游戏项目实战11 玩家多条命
python及pygame雷霆战机游戏项目实战11 玩家多条命
116 0
|
Python
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏04之跳跃
通过游戏学Python系列之小兔要上天---手把手教你使用Pygame开发平台跳跃类游戏04之跳跃
151 0