Pygame简单入门教程(绘制Rect、控制移动、碰撞检测、Github项目源代码)

Pygame简明教程

引言:本教程中的源码已上传个人Github: GItHub链接
视频教程推荐:YouTube教程–有点过于简单了
官方文档推荐:虽然写的一般,但还是推荐!

Navigator~

  • Pygame简明教程
  • 安装pygame
    • 一、代码框架
    • 二、案件输入
    • 三、绘制方块
      • 3.1 绘制
      • 3.2 移动
    • 四、碰撞
      • 4.1 检测方法
      • 5.2 敌人和碰撞
        • 5.2.1 敌人or朋友?
        • 5.2.2 测试碰撞

安装pygame

cmd中安装即可

pip3 install pygame

一、代码框架

main.py

import sysimport pygame
pygame.init()   # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200   # 窗口宽度,高度
FPS = 60    # 帧率
running = True  # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率if __name__ == "__main__":while running:for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = Falsepygame.quit()sys.exit()# 退出游戏辣!

运行结果
在这里插入图片描述

二、案件输入

需要修改的代码:


if __name__ == "__main__":while running:for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = False############ 获取输入 ##################keys = pygame.key.get_pressed()if keys[pygame.K_DOWN]:print("你按下了 \/ 哦!")if keys[pygame.K_UP]:print("你按下了 /\ 哦!")if keys[pygame.K_LEFT]:print("你按下了 < 哦!")if keys[pygame.K_RIGHT]:print("你按下了 > 哦!")######################################pygame.quit()sys.exit()# 退出游戏辣!

修改结束,完整代码如下:

main.py

import sysimport pygame
pygame.init()   # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200   # 窗口宽度,高度
FPS = 60    # 帧率
running = True  # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率if __name__ == "__main__":while running:for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = False############ 获取输入 ##################keys = pygame.key.get_pressed()if keys[pygame.K_DOWN]:print("你按下了 \/ 哦!")if keys[pygame.K_UP]:print("你按下了 /\ 哦!")if keys[pygame.K_LEFT]:print("你按下了 < 哦!")if keys[pygame.K_RIGHT]:print("你按下了 > 哦!")######################################pygame.quit()sys.exit()# 退出游戏辣!

三、绘制方块

3.1 绘制

我们使用该方法来进行绘制方块对象:

pygame.draw.rect(screen, self.color, self.hit_box)  # 更新绘制

下文会出现碰撞箱,是为了便于使用后文中定义的碰撞检测方法。

定义Player类:


class Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue")   # 颜色def update(self):self.hit_box = (self.x, self.y, self.width, self.height)    # 更新碰撞箱位置pygame.draw.rect(screen, self.color, self.hit_box)  # 更新绘制################### 创建一个方块对象
player = Player()
###################

main.py

import sysimport pygame
pygame.init()   # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200   # 窗口宽度,高度
FPS = 60    # 帧率
running = True  # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率class Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue")   # 颜色def update(self):self.hit_box = (self.x, self.y, self.width, self.height)    # 更新碰撞箱位置pygame.draw.rect(screen, self.color, self.hit_box)  # 更新绘制################### 创建一个方块对象
player = Player()
###################if __name__ == "__main__":while running:screen.fill(pygame.Color("White"))for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = False############ 获取输入 ##################keys = pygame.key.get_pressed()if keys[pygame.K_DOWN]:print("你按下了 \/ 哦!")if keys[pygame.K_UP]:print("你按下了 /\ 哦!")if keys[pygame.K_LEFT]:print("你按下了 < 哦!")if keys[pygame.K_RIGHT]:print("你按下了 > 哦!")######################################player.update()pygame.display.update()pygame.quit()sys.exit()# 退出游戏辣!

3.2 移动

我们可以再加点猛料,让player可以动起来:

Player类中作如下修改:

class Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue")   # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef update(self):self.hit_box = (self.x, self.y, self.width, self.height)    # 更新碰撞箱位置pygame.draw.rect(screen, self.color, self.hit_box)  # 更新绘制

按键部分也进行修改:

############ 获取输入 ##################keys = pygame.key.get_pressed()if keys[pygame.K_DOWN]:player.down()if keys[pygame.K_UP]:player.up()if keys[pygame.K_LEFT]:player.left()if keys[pygame.K_RIGHT]:player.right()######################################

完整代码如下:

main.py

import sysimport pygame
pygame.init()   # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200   # 窗口宽度,高度
FPS = 60    # 帧率
running = True  # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率class Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue")   # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef update(self):self.hit_box = (self.x, self.y, self.width, self.height)    # 更新碰撞箱位置pygame.draw.rect(screen, self.color, self.hit_box)  # 更新绘制################### 创建一个方块对象
player = Player()
###################if __name__ == "__main__":while running:screen.fill(pygame.Color("White"))for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = False############ 获取输入 ##################keys = pygame.key.get_pressed()if keys[pygame.K_DOWN]:player.down()if keys[pygame.K_UP]:player.up()if keys[pygame.K_LEFT]:player.left()if keys[pygame.K_RIGHT]:player.right()######################################player.update()pygame.display.update()pygame.quit()sys.exit()# 退出游戏辣!

由于动态不便于演示,这里省略。

四、碰撞

4.1 检测方法

pygame中对于碰撞检测的实现手段还是挺多的,可以使用Sprite精灵来统一管理,也可以自己手搓。
这里写后者~

检测两个矩形是否重叠即可判断是否碰撞,只要检测其中一个矩形的四个顶点是否在另一个矩形内部即可。

为了表示四个点,抽象出一个顶点类:

Point

class Point(object):def __init__(self, x, y):self.x = xself.y = y

这里定一个一个CollisionController类来统一检测所有碰撞

CollisionController


class CollisionController():def RectCollide(hitbox1, hitbox2):'''检测四个点是否在另一个矩形体内即可box1 = (x, y, width, height)0  1   2     3:param hitbox1::param hitbox2::return:'''p1 = Point(hitbox1[0], hitbox1[1])p2 = Point(hitbox1[0] + hitbox1[2], hitbox1[1])p3 = Point(hitbox1[0], hitbox1[1] + hitbox1[3])p4 = Point(hitbox1[0] + hitbox1[2], hitbox1[1] + hitbox1[3])points = [p1, p2, p3, p4]for p in points:if (p.x >= hitbox2[0]and p.x <= hitbox2[0] + hitbox2[2]and p.y >= hitbox2[1]and p.y <= hitbox2[1] + hitbox2[3]):return Truereturn False

需要检测的时候直接调用CollisionController.RectCollide()即可,参数中传入两个矩形碰撞箱。
下文将教你写一个敌人来运用这个函数。

5.2 敌人和碰撞

5.2.1 敌人or朋友?

定义一个敌人:

class Enemy(Player):pass

哈哈哈,直接继承玩家类就行了,多好!人生苦短我用Python, 懒得复写我用继承,游戏开发不能没有面向对象!!

别忘记生成对象,并且在主函数中加入更新的方法:

main.py

import sysimport pygame
pygame.init()   # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200   # 窗口宽度,高度
FPS = 60    # 帧率
running = True  # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率class Point(object):def __init__(self, x, y):self.x = xself.y = y
class CollisionController():def RectCollide(hitbox1, hitbox2):'''检测四个点是否在另一个矩形体内即可box1 = (x, y, width, height)0  1   2     3:param hitbox1::param hitbox2::return:'''p1 = Point(hitbox1[0], hitbox1[1])p2 = Point(hitbox1[0] + hitbox1[2], hitbox1[1])p3 = Point(hitbox1[0], hitbox1[1] + hitbox1[3])p4 = Point(hitbox1[0] + hitbox1[2], hitbox1[1] + hitbox1[3])points = [p1, p2, p3, p4]for p in points:if (p.x >= hitbox2[0]and p.x <= hitbox2[0] + hitbox2[2]and p.y >= hitbox2[1]and p.y <= hitbox2[1] + hitbox2[3]):return Truereturn Falseclass Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue")   # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef update(self):self.hit_box = (self.x, self.y, self.width, self.height)    # 更新碰撞箱位置pygame.draw.rect(screen, self.color, self.hit_box)  # 更新绘制
class Enemy(Player):pass################### 创建一个方块对象
player = Player()
enemy = Enemy()
###################if __name__ == "__main__":while running:screen.fill(pygame.Color("White"))  # 填充一个背景色for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = False############ 获取输入 ##################keys = pygame.key.get_pressed()if keys[pygame.K_DOWN]:player.down()if keys[pygame.K_UP]:player.up()if keys[pygame.K_LEFT]:player.left()if keys[pygame.K_RIGHT]:player.right()####################################### ****************** 更新对象 *******************enemy.update()player.update()# ****************** ------ *******************pygame.display.update() # 更新画面pygame.quit()sys.exit()# 退出游戏辣!

运行发现多了一个小伙伴~在这里插入图片描述

5.2.2 测试碰撞
import sysimport pygame
pygame.init()   # 初始化pygame模块
WIDTH, HEIGHT = 800, 1200   # 窗口宽度,高度
FPS = 60    # 帧率
running = True  # 游戏运行状态
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 设置窗口,screen为窗口对象
pygame.display.set_caption("怀念高中第一次接触Pygame的那个暑假!") # 设置窗口标题
clock = pygame.time.Clock() # 统一游戏帧率class Point(object):def __init__(self, x, y):self.x = xself.y = yclass Player(object):def __init__(self):self.x = WIDTH // 2self.y = HEIGHT // 2self.width = 100self.height = 200self.hit_box = (self.x, self.y, self.width, self.height)self.color = pygame.Color("Blue")   # 颜色self.velocity = 10def left(self):self.x -= self.velocitydef right(self):self.x += self.velocitydef up(self):self.y -= self.velocitydef down(self):self.y += self.velocitydef update(self):self.hit_box = (self.x, self.y, self.width, self.height)    # 更新碰撞箱位置pygame.draw.rect(screen, self.color, self.hit_box)  # 更新绘制
class Enemy(Player):passclass CollisionController():def RectCollide(hitbox1, hitbox2):'''检测四个点是否在另一个矩形体内即可box1 = (x, y, width, height)0  1   2     3:param hitbox1::param hitbox2::return:'''p1 = Point(hitbox1[0], hitbox1[1])p2 = Point(hitbox1[0] + hitbox1[2], hitbox1[1])p3 = Point(hitbox1[0], hitbox1[1] + hitbox1[3])p4 = Point(hitbox1[0] + hitbox1[2], hitbox1[1] + hitbox1[3])points = [p1, p2, p3, p4]for p in points:if (p.x >= hitbox2[0]and p.x <= hitbox2[0] + hitbox2[2]and p.y >= hitbox2[1]and p.y <= hitbox2[1] + hitbox2[3]):return Truereturn False# def obj_collided(self, object1, object2):#     if self.RectCollide(object1.hit_box, object2.hit_box):#         return True#     else:#         return False################### 创建一个方块对象
player = Player()
enemy = Enemy()
###################if __name__ == "__main__":while running:screen.fill(pygame.Color("White"))  # 填充一个背景色for event in pygame.event.get():if event.type == pygame.QUIT: # 检测是否点击右上角窗口小xrunning = False############ 获取输入 ##################keys = pygame.key.get_pressed()if keys[pygame.K_DOWN]:player.down()if keys[pygame.K_UP]:player.up()if keys[pygame.K_LEFT]:player.left()if keys[pygame.K_RIGHT]:player.right()####################################### $$$$$$$$$$$$$$$ 碰撞检测 $$$$$$$$$$$$$$$$$$$if CollisionController.RectCollide(player.hit_box, enemy.hit_box):print("哎呀,创了一下咧!")# $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$# ****************** 更新对象 *******************enemy.update()player.update()# ****************** ------ *******************pygame.display.update() # 更新画面pygame.quit()sys.exit()# 退出游戏辣!

可以看到,现在每次撞一下都会被聪明的计算机给发现。在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/9051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

五一开始内卷前端,如何迅速的一个月内找到工作!

写在前面 五一过了代表新的一年不知不觉过了半年了&#xff0c;各位工作找到怎么样&#xff0c;有没有在工作中遇到解决不了的问题&#xff0c;这些问题后面怎么处理了呢&#xff1f; hello大家好&#xff0c;我又又又来了&#xff0c;今天纯干货&#xff0c;上班的朋友适当摸…

Linux下的I2C通信

I2C通信: 一.硬件初识: IIC(inter-intergrated-Circu):内部集成总线 四线通讯:SCL,SDA,GND,VCC,串行,半双工 I2C 总线是同步,串行,半双工通信总线。 I2C 总线由时钟线 SDA 和 SCL 两根信号线构成。并且都有上拉电阻。确保总线空闲状态为高电平。 I2C 总线支持多…

ElasticSearch 与 OpenSearch:拉开性能差距

Elasticsearch 与 OpenSearch&#xff1a;扩大性能差距 对于任何依赖快速、准确搜索数据的组织来说&#xff0c;强大、快速且高效的搜索引擎是至关重要的元素。对于开发人员和架构师来说&#xff0c;选择正确的搜索平台可以极大地影响您的组织提供快速且相关结果的能力。在我们…

揭秘抖音快速涨10000粉的方法:巨量千川投流让你轻松快速增粉

抖音已经成为了当今社交平台的热门之一&#xff0c;而如何快速涨粉已经成为了很多人关注的焦点。本文将揭秘一种高效的方式——巨量千川投流&#xff0c;通过官方真实流量和真实粉丝&#xff0c;每天快速涨关注&#xff0c;实现快速增粉1000~10万。 巨量千川投流是一种专业的抖…

必读干货!国内验证签发的SSL证书六大优势

JoySSL官网 注册码230918 国内验证签发的SSL证书&#xff0c;作为网络安全基础设施的重要组成部分&#xff0c;对于维护互联网数据安全、保障用户隐私、提升网站信誉度具有不可小觑的作用。特别是在当前数字化转型加速、数据合规要求日益严格的背景下&#xff0c;选择国内验证签…

路由的基本使用

目录 一、VueRouter介绍 二、VueRouter的使用 三、注意 一、VueRouter介绍 VueRouter是Vue官方的一个路由插件&#xff0c;是一个第三方包。 作用&#xff1a;修改地址栏路径时&#xff0c;切换显示匹配的组件 官网:Vue Router (vuejs.org) 二、VueRouter的使用 注意&am…

Vue 3.3 编译宏 vue3.3新增了一些语法糖和宏,包括泛型组件、defineSlots、defineEmits、defineOptions

Vue 3.3新增了一些语法糖和宏&#xff0c;包括泛型组件、defineSlots、defineEmits、defineOptions defineProps 父组件传参 <template><Child name"my"></Child> </template> <script setup lang"ts"> import Child fro…

Linux学习笔记4---点亮LED灯(汇编裸机)

本系统学习利用的是正点原子的阿尔法mini开发板&#xff0c;本系列的学习笔记也是按照正点原子的教程进行学习&#xff0c;但并不是利用虚拟机进行开发&#xff0c;而是使用Windows下的子系统WSL进行学习。 因为 Cortex-A 芯片一上电 SP 指针还没初始化&#xff0c;C 环境还没准…

【C++】零钱兑换的始端---柠檬水找零

欢迎来CILMY23的博客 本篇主题为 零钱兑换的始端---柠檬水找零 个人主页&#xff1a;CILMY23-CSDN博客 个人专栏系列&#xff1a; Python | C | C语言 | 数据结构与算法 感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言&#xff1a; 柠檬水找…

嘴尚绝卤味:传承经典,缔造美食新风尚

卤味&#xff0c;作为中国传统美食的代表之一&#xff0c;历经千年的传承与发展&#xff0c;早已成为无数食客餐桌上的宠儿。而在这个美食盛行的时代&#xff0c;嘴尚绝卤味凭借其独特的口感和精湛的工艺&#xff0c;成为卤味市场中的佼佼者&#xff0c;引领着卤味文化的新潮流…

图数据库 之 Neo4j 与 AI 大模型的结合绘制知识图谱

引言 随着信息时代的到来&#xff0c;海量的文本数据成为了我们获取知识的重要来源。然而&#xff0c;如何从这些文本数据中提取出有用的信息&#xff0c;并将其以可视化的方式展示出来&#xff0c;一直是一个具有挑战性的问题。近年来&#xff0c;随着人工智能技术的发展&…

MyBatis认识

一、定义 MyBatis是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;Plain Old Java O…

【热门话题】ElementUI 快速入门指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 ElementUI 快速入门指南环境准备安装 ElementUI创建 Vue 项目安装 ElementUI 基…

SpringBoot之远程调用的三大方式

为什么要使用远程调用&#xff1f; SpringBoot不仅继承了Spring框架原有的优秀特性&#xff0c;而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。在Spring-Boot项目开发中&#xff0c;存在着本模块的代码需要访问外面模块接口&#xff0c;或外部url链接的需求…

Golang 开发实战day13 - Reciver Functions

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 Golang 开发实战day13 - 接收…

第42天:WEB攻防-PHP应用MYSQL架构SQL注入跨库查询文件读写权限操作

第四十二天 一、PHP-MYSQL-SQL注入-常规查询 1.PHP-MYSQL-Web组成架构 MySQL(统一管理) ​ root&#xff08;自带默认&#xff09; ​ 网站A testA ​ 网站B testB MySQL(一对一管理) ​ testA用户 ​ 网站A testA ​ testB用户 ​ 网站B testB access无数据库用户 m…

三勾软件 / 三勾点餐系统门店系统,java+springboot+vue3

项目介绍 三勾点餐系统基于javaspringbootelement-plusuniapp打造的面向开发的小程序商城&#xff0c;方便二次开发或直接使用&#xff0c;可发布到多端&#xff0c;包括微信小程序、微信公众号、QQ小程序、支付宝小程序、字节跳动小程序、百度小程序、android端、ios端。 在…

LVS 负载均衡部署 NAT模式

一、环境准备 配置环境&#xff1a; 负载调度器&#xff1a;配置双网卡 内网&#xff1a;172.168.1.11(ens33) 外网卡&#xff1a;12.0.0.1(ens37)二台WEB服务器集群池&#xff1a;172.168.1.12、172.168.1.13 一台NFS共享服务器&#xff1a;172.168.1.14客户端&#xff…

Android的NDK开发中Cmake报缺少对应的x86的so文件

需要实现一个串口操作的命令。 供应商提供了2个so文件。 分别是 armeabi-v7a 和 arm64-v8a 添加到对应的cpp下。 在CMakeLists.txt里添加so文件 # 添加预编译的库 add_library(libxxx SHARED IMPORTED)# 设置库的路径 set_target_properties(libxxx PROPERTIES IMPORTED_…

springboot和html学院教务管理系统

端口号根据你实际运行程序的端口号来 访问地址&#xff1a;localhost:8080 学生 : student1 123456 管理员&#xff1a;admin 123456 老师&#xff1a;2020001 123456 sys_user 表是账号和密码