亲爱的家长朋友:
还记得孩子用C++写的第一个游戏吗?可能是猜数字、井字棋,或者是第31期的智能动物园。现在我要告诉您一个激动人心的消息:用Python开发游戏,比C++简单10倍!
如果说C++游戏开发像用机床加工零件,需要精确到毫米,那么Python游戏开发就像用3D打印机制作模型——设计好,一键打印,快速成型!
答案是:能!而且效果很棒!
Pygame是什么?
# 打开命令行,输入:
pip install pygame
孩子可以这样理解:就像在手机上安装一个新APP,点一下"安装"按钮,等一会儿就能用了。
import pygame
import sys
# 初始化Pygame
pygame.init()
# 创建游戏窗口(800x600像素)
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("我的第一个Python游戏")
# 游戏主循环
running = True
while running:
# 处理事件(如关闭窗口)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 填充背景色(RGB:红色=255, 绿色=0, 蓝色=0)
screen.fill((255, 0, 0)) # 红色背景
# 更新屏幕显示
pygame.display.flip()
# 退出游戏
pygame.quit()
sys.exit()
孩子可以这样理解:
pygame.init():打开游戏机的电源set_mode((800, 600)):设定游戏屏幕大小while running:游戏一直运行,直到玩家退出screen.fill((255, 0, 0)):把屏幕涂成红色pygame.display.flip():把画好的内容显示出来贪吃蛇游戏有三个核心部分:
import pygame
import random
import sys
# 初始化
pygame.init()
# 游戏设置
WIDTH, HEIGHT = 800, 600
GRID_SIZE = 20
GRID_WIDTH = WIDTH // GRID_SIZE
GRID_HEIGHT = HEIGHT // GRID_SIZE
# 颜色定义(RGB)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 120, 255)
classSnake:
"""贪吃蛇类"""
def__init__(self):
self.reset()
defreset(self):
"""重置蛇的状态"""
self.length = 3
self.positions = [(GRID_WIDTH // 2, GRID_HEIGHT // 2)]
self.direction = random.choice([(1, 0), (0, 1)]) # 随机初始方向
self.score = 0
# 初始化蛇身
for i inrange(1, self.length):
x, y = self.positions[0]
dx, dy = self.direction
self.positions.append((x - dx * i, y - dy * i))
defget_head_position(self):
"""获取蛇头位置"""
returnself.positions[0]
defturn(self, point):
"""改变蛇的方向"""
# 防止直接反向(比如不能从向右直接变成向左)
ifself.length > 1and (point[0] * -1, point[1] * -1) == self.direction:
return
self.direction = point
defmove(self):
"""蛇移动一步"""
head = self.get_head_position()
x, y = self.direction
new_head = ((head[0] + x) % GRID_WIDTH, (head[1] + y) % GRID_HEIGHT)
# 检查是否撞到自己
if new_head inself.positions[1:]:
self.reset()
returnFalse
self.positions.insert(0, new_head)
iflen(self.positions) > self.length:
self.positions.pop()
returnTrue
defdraw(self, surface):
"""绘制蛇"""
for i, p inenumerate(self.positions):
# 蛇头用不同颜色
color = BLUE if i == 0else GREEN
rect = pygame.Rect(p[0] * GRID_SIZE, p[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE)
pygame.draw.rect(surface, color, rect)
pygame.draw.rect(surface, BLACK, rect, 1)
defgrow(self):
"""蛇吃到食物后变长"""
self.length += 1
self.score += 10
classFood:
"""食物类"""
def__init__(self):
self.position = (0, 0)
self.randomize_position()
defrandomize_position(self):
"""随机生成食物位置"""
self.position = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))
defdraw(self, surface):
"""绘制食物"""
rect = pygame.Rect(self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE)
pygame.draw.rect(surface, RED, rect)
pygame.draw.rect(surface, BLACK, rect, 1)
defdraw_grid(surface):
"""绘制网格"""
for x inrange(0, WIDTH, GRID_SIZE):
pygame.draw.line(surface, (40, 40, 40), (x, 0), (x, HEIGHT))
for y inrange(0, HEIGHT, GRID_SIZE):
pygame.draw.line(surface, (40, 40, 40), (0, y), (WIDTH, y))
defmain():
"""游戏主函数"""
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Python贪吃蛇")
clock = pygame.time.Clock()
snake = Snake()
food = Food()
font = pygame.font.SysFont('simhei', 25)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
# 键盘控制
if event.key == pygame.K_UP:
snake.turn((0, -1))
elif event.key == pygame.K_DOWN:
snake.turn((0, 1))
elif event.key == pygame.K_LEFT:
snake.turn((-1, 0))
elif event.key == pygame.K_RIGHT:
snake.turn((1, 0))
elif event.key == pygame.K_r:
snake.reset() # 按R键重置游戏
# 蛇移动
ifnot snake.move():
continue
# 检查是否吃到食物
if snake.get_head_position() == food.position:
snake.grow()
food.randomize_position()
# 确保食物不出现在蛇身上
while food.position in snake.positions:
food.randomize_position()
# 绘制
screen.fill(BLACK)
draw_grid(screen)
snake.draw(screen)
food.draw(screen)
# 显示分数
score_text = font.render(f'分数: {snake.score}', True, WHITE)
screen.blit(score_text, (10, 10))
# 显示操作提示
tips_text = font.render('方向键控制移动 | R键重置游戏', True, WHITE)
screen.blit(tips_text, (WIDTH - 350, 10))
pygame.display.flip()
clock.tick(10) # 控制游戏速度
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
孩子可以这样理解:
飞机大战游戏需要:
import pygame
import random
import sys
# 初始化
pygame.init()
# 游戏设置
WIDTH, HEIGHT = 800, 600
FPS = 60
# 颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
BLUE = (50, 150, 255)
GREEN = (50, 255, 100)
classPlayer:
"""玩家飞机类"""
def__init__(self):
self.width = 50
self.height = 40
self.x = WIDTH // 2 - self.width // 2
self.y = HEIGHT - 100
self.speed = 5
self.color = BLUE
self.health = 100
self.score = 0
defmove(self, keys):
"""根据按键移动飞机"""
if keys[pygame.K_LEFT] andself.x > 0:
self.x -= self.speed
if keys[pygame.K_RIGHT] andself.x < WIDTH - self.width:
self.x += self.speed
if keys[pygame.K_UP] andself.y > 0:
self.y -= self.speed
if keys[pygame.K_DOWN] andself.y < HEIGHT - self.height:
self.y += self.speed
defdraw(self, surface):
"""绘制玩家飞机"""
# 飞机主体
pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))
# 飞机头部
pygame.draw.polygon(surface, WHITE, [
(self.x + self.width // 2, self.y - 10),
(self.x + 10, self.y + 10),
(self.x + self.width - 10, self.y + 10)
])
# 飞机机翼
pygame.draw.rect(surface, WHITE, (self.x - 5, self.y + 10, 10, 15))
pygame.draw.rect(surface, WHITE, (self.x + self.width - 5, self.y + 10, 10, 15))
# 显示血量
health_width = int((self.health / 100) * self.width)
pygame.draw.rect(surface, GREEN, (self.x, self.y - 15, health_width, 5))
pygame.draw.rect(surface, RED, (self.x + health_width, self.y - 15, self.width - health_width, 5))
defget_rect(self):
"""获取飞机的碰撞矩形"""
return pygame.Rect(self.x, self.y, self.width, self.height)
classEnemy:
"""敌机类"""
def__init__(self):
self.width = 40
self.height = 40
self.x = random.randint(0, WIDTH - self.width)
self.y = random.randint(-100, -40)
self.speed = random.randint(2, 5)
self.color = RED
self.value = 10# 击落得分
defmove(self):
"""敌机向下移动"""
self.y += self.speed
returnself.y > HEIGHT # 返回是否飞出屏幕
defdraw(self, surface):
"""绘制敌机"""
# 敌机主体
pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))
# 敌机装饰
pygame.draw.circle(surface, WHITE, (self.x + self.width // 2, self.y + self.height // 2), 8)
pygame.draw.rect(surface, BLACK, (self.x + 5, self.y + 15, 30, 10))
defget_rect(self):
"""获取敌机的碰撞矩形"""
return pygame.Rect(self.x, self.y, self.width, self.height)
classBullet:
"""子弹类"""
def__init__(self, x, y):
self.width = 5
self.height = 15
self.x = x
self.y = y
self.speed = 10
self.color = GREEN
defmove(self):
"""子弹向上移动"""
self.y -= self.speed
returnself.y < 0# 返回是否飞出屏幕
defdraw(self, surface):
"""绘制子弹"""
pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))
defget_rect(self):
"""获取子弹的碰撞矩形"""
return pygame.Rect(self.x, self.y, self.width, self.height)
defsimple_plane_game():
"""简化版飞机大战游戏"""
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Python飞机大战")
clock = pygame.time.Clock()
player = Player()
enemies = []
bullets = []
enemy_timer = 0
bullet_timer = 0
font = pygame.font.SysFont('simhei', 24)
running = True
while running:
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 获取按键状态
keys = pygame.key.get_pressed()
# 玩家移动
player.move(keys)
# 自动发射子弹(空格键或自动)
bullet_timer += 1
if bullet_timer >= 10: # 每10帧发射一次
bullets.append(Bullet(player.x + player.width // 2 - 2, player.y))
bullet_timer = 0
# 生成敌机
enemy_timer += 1
if enemy_timer >= 30: # 每30帧生成一个敌机
enemies.append(Enemy())
enemy_timer = 0
# 移动子弹并检查是否飞出屏幕
bullets = [bullet for bullet in bullets ifnot bullet.move()]
# 移动敌机并检查是否飞出屏幕
enemies = [enemy for enemy in enemies ifnot enemy.move()]
# 检测碰撞:子弹 vs 敌机
for bullet in bullets[:]: # 使用副本遍历,因为要删除元素
for enemy in enemies[:]:
if bullet.get_rect().colliderect(enemy.get_rect()):
player.score += enemy.value
if bullet in bullets:
bullets.remove(bullet)
if enemy in enemies:
enemies.remove(enemy)
break
# 检测碰撞:玩家 vs 敌机
for enemy in enemies[:]:
if player.get_rect().colliderect(enemy.get_rect()):
player.health -= 20
enemies.remove(enemy)
if player.health <= 0:
running = False
# 绘制
screen.fill(BLACK)
# 绘制星空背景
for _ inrange(50):
x = random.randint(0, WIDTH)
y = random.randint(0, HEIGHT)
pygame.draw.circle(screen, WHITE, (x, y), 1)
# 绘制游戏对象
player.draw(screen)
for bullet in bullets:
bullet.draw(screen)
for enemy in enemies:
enemy.draw(screen)
# 显示分数和血量
score_text = font.render(f'分数: {player.score}', True, WHITE)
health_text = font.render(f'血量: {player.health}', True, GREEN)
screen.blit(score_text, (10, 10))
screen.blit(health_text, (10, 40))
# 显示操作提示
tips_text = font.render('方向键移动 | 自动射击', True, WHITE)
screen.blit(tips_text, (WIDTH - 200, 10))
pygame.display.flip()
clock.tick(FPS)
# 游戏结束
screen.fill(BLACK)
game_over_font = pygame.font.SysFont('simhei', 48)
game_over_text = game_over_font.render('游戏结束!', True, RED)
score_text = font.render(f'最终分数: {player.score}', True, WHITE)
screen.blit(game_over_text, (WIDTH // 2 - 100, HEIGHT // 2 - 50))
screen.blit(score_text, (WIDTH // 2 - 80, HEIGHT // 2 + 20))
pygame.display.flip()
# 等待3秒后退出
pygame.time.wait(3000)
pygame.quit()
sys.exit()
if __name__ == "__main__":
simple_plane_game()
孩子可以这样理解:
import pygame
import sys
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
classGameObject:
"""游戏对象基类"""
def__init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
defdraw(self, surface):
pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))
defget_rect(self):
return pygame.Rect(self.x, self.y, self.width, self.height)
deftemplate_game():
"""游戏模板,可以在此基础上修改"""
player = GameObject(400, 500, 50, 50, (0, 100, 255))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 控制玩家移动
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 5
if keys[pygame.K_RIGHT]:
player.x += 5
if keys[pygame.K_UP]:
player.y -= 5
if keys[pygame.K_DOWN]:
player.y += 5
# 绘制
screen.fill((0, 0, 0))
player.draw(screen)
# 显示提示
font = pygame.font.SysFont('simhei', 24)
text = font.render('用方向键移动方块 | 这是你的游戏起点!', True, (255, 255, 255))
screen.blit(text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
# 修改这个模板,创建你自己的游戏!
# 可以添加:敌人、子弹、分数、关卡等
| 安装配置 | pip install pygame | ||
| 代码量 | |||
| 开发速度 | |||
| 学习曲线 | |||
| 性能 | |||
| 适合项目 |
A:可以,但需要额外工具:
A:可以,但有限制:
A:建议路线:
A:Pygame适合:
当孩子想做复杂游戏时:
# 1. 初始化
pygame.init()
screen = pygame.display.set_mode((宽度, 高度))
# 2. 游戏循环
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 3. 绘制
screen.fill(颜色)
# 绘制图形...
pygame.display.flip()
# 4. 控制帧率
clock.tick(60) # 60帧/秒
# 5. 退出
pygame.quit()
# 矩形
pygame.draw.rect(屏幕, 颜色, (x, y, 宽, 高))
# 圆形
pygame.draw.circle(屏幕, 颜色, (圆心x, 圆心y), 半径)
# 线条
pygame.draw.line(屏幕, 颜色, (起点x, 起点y), (终点x, 终点y), 宽度)
# 文字
font = pygame.font.SysFont('字体', 大小)
text = font.render('文字内容', True, 颜色)
屏幕.blit(text, (x, y))
# 方法1:矩形碰撞
rect1.colliderect(rect2)
# 方法2:圆形碰撞(计算距离)
distance = ((x1 - x2)**2 + (y1 - y2)**2)**0.5
if distance < 半径1 + 半径2:
print("碰撞了!")
# 方法3:像素级碰撞(更精确但更慢)
# 使用pygame.mask模块
第三十六期:Python数据分析入门——用数据讲故事!
预告内容:
为什么重要:数据分析是21世纪最重要的技能之一!从学习成绩到购物习惯,从天气预测到游戏设计,数据无处不在。学会数据分析,孩子就能从数据中发现规律、做出预测、讲述故事!
亲爱的家长朋友:
当孩子用Python开发出第一个可玩的游戏时,那种成就感是难以言喻的。他们不再只是游戏的消费者,而是成为了创造者。这种身份转变,对孩子的自信心和创造力培养有着深远的影响。
Python游戏开发的美妙之处在于:它让孩子专注于创意和逻辑,而不是繁琐的语法细节。孩子可以很快看到自己的想法变成可互动的现实,这种即时反馈是保持学习动力的关键。
如果您看到孩子沉迷于调试游戏bug,请不要担心——这其实是最高效的学习过程。每一个bug的解决,都是一次逻辑思维和问题解决能力的锻炼。
鼓励孩子把游戏分享给朋友、家人,甚至发布到网上(在您的监督下)。他人的反馈和建议,会让孩子学会接受批评、改进作品,这是非常重要的社会技能。
游戏开发不只是"玩游戏",它是数学(坐标、速度、碰撞)、物理(运动、重力)、艺术(色彩、布局)、文学(故事、对话)的完美结合。孩子在不知不觉中,就在进行跨学科的学习。
让我们下期再见,一起进入Python数据分析的奇妙世界!
如果您觉得这篇文章有帮助,欢迎点赞、转发,让更多家长看到! 有问题想交流?欢迎在评论区留言! 关注我们,一起陪伴孩子走进编程的世界!