菜单导航

资源分享
Python小游戏源码
资源分享

Python小游戏源码

NoiseNoise
2021-08-01

一、接金币

 
import os
import cfg
import sys
import pygame
import random
from modules import *


'''游戏初始化'''
def initGame():

初始化pygame, 设置展示窗口

pygame.init()
screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption('catch coins —— ')

加载必要的游戏素材

game_images = {}
for key, value in cfg.IMAGE_PATHS.items():
if isinstance(value, list):
images = []
for item in value: images.append(pygame.image.load(item))
game_images[key] = images
else:
game_images[key] = pygame.image.load(value)
game_sounds = {}
for key, value in cfg.AUDIO_PATHS.items():
if key == 'bgm': continue
game_sounds[key] = pygame.mixer.Sound(value)

返回初始化数据

return screen, game_images, game_sounds

'''主函数'''
def main():

初始化

screen, game_images, game_sounds = initGame()

播放背景音乐

pygame.mixer.music.load(cfg.AUDIO_PATHS['bgm'])
pygame.mixer.music.play(-1, 0.0)

字体加载

font = pygame.font.Font(cfg.FONT_PATH, 40)

定义hero

hero = Hero(game_images['hero'], position=(375, 520))

定义食物组

food_sprites_group = pygame.sprite.Group()
generate_food_freq = random.randint(10, 20)
generate_food_count = 0

当前分数/历史最高分

score = 0
highest_score = 0 if not os.path.exists(cfg.HIGHEST_SCORE_RECORD_FILEPATH) else int(open(cfg.HIGHEST_SCORE_RECORD_FILEPATH).read())

游戏主循环

clock = pygame.time.Clock()
while True:

--填充背景

screen.fill(0)
screen.blit(game_images['background'], (0, 0))

--倒计时信息

countdown_text = 'Count down: ' + str((90000 - pygame.time.get_ticks()) // 60000) + ":" + str((90000 - pygame.time.get_ticks()) // 1000 % 60).zfill(2)
countdown_text = font.render(countdown_text, True, (0, 0, 0))
countdown_rect = countdown_text.get_rect()
countdown_rect.topright = [cfg.SCREENSIZE[0]-30, 5]
screen.blit(countdown_text, countdown_rect)

--按键检测

for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_a] or key_pressed[pygame.K_LEFT]:
hero.move(cfg.SCREENSIZE, 'left')
if key_pressed[pygame.K_d] or key_pressed[pygame.K_RIGHT]:
hero.move(cfg.SCREENSIZE, 'right')

--随机生成食物

generate_food_count += 1
if generate_food_count > generate_food_freq:
generate_food_freq = random.randint(10, 20)
generate_food_count = 0
food = Food(game_images, random.choice(['gold',] * 10 + ['apple']), cfg.SCREENSIZE)
food_sprites_group.add(food)

--更新食物

for food in food_sprites_group:
if food.update(): food_sprites_group.remove(food)

--碰撞检测

for food in food_sprites_group:
if pygame.sprite.collide_mask(food, hero):
game_sounds['get'].play()
food_sprites_group.remove(food)
score += food.score
if score > highest_score: highest_score = score

--画hero

hero.draw(screen)

--画食物

food_sprites_group.draw(screen)

--显示得分

score_text = f'Score: {score}, Highest: {highest_score}'
score_text = font.render(score_text, True, (0, 0, 0))
score_rect = score_text.get_rect()
score_rect.topleft = [5, 5]
screen.blit(score_text, score_rect)

--判断游戏是否结束

if pygame.time.get_ticks() >= 90000:
break

--更新屏幕

pygame.display.flip()
clock.tick(cfg.FPS)

游戏结束, 记录最高分并显示游戏结束画面

fp = open(cfg.HIGHEST_SCORE_RECORD_FILEPATH, 'w')
fp.write(str(highest_score))
fp.close()
return showEndGameInterface(screen, cfg, score, highest_score)

'''run'''
if name == 'main':
while main():
pass

二、滑雪

 
import sys
import cfg
import pygame
import random


'''滑雪者类'''
class SkierClass(pygame.sprite.Sprite):
def init(self):
pygame.sprite.Sprite.init(self)

滑雪者的朝向(-2到2)

self.direction = 0
self.imagepaths = cfg.SKIER_IMAGE_PATHS[:-1]
self.image = pygame.image.load(self.imagepaths[self.direction])
self.rect = self.image.get_rect()
self.rect.center = [320, 100]
self.speed = [self.direction, 6-abs(self.direction)*2]
'''改变滑雪者的朝向. 负数为向左,正数为向右,0为向前'''
def turn(self, num):
self.direction += num
self.direction = max(-2, self.direction)
self.direction = min(2, self.direction)
center = self.rect.center
self.image = pygame.image.load(self.imagepaths[self.direction])
self.rect = self.image.get_rect()
self.rect.center = center
self.speed = [self.direction, 6-abs(self.direction)*2]
return self.speed
'''移动滑雪者'''
def move(self):
self.rect.centerx += self.speed[0]
self.rect.centerx = max(20, self.rect.centerx)
self.rect.centerx = min(620, self.rect.centerx)
'''设置为摔倒状态'''
def setFall(self):
self.image = pygame.image.load(cfg.SKIER_IMAGE_PATHS[-1])
'''设置为站立状态'''
def setForward(self):
self.direction = 0
self.image = pygame.image.load(self.imagepaths[self.direction])

'''
Function:
障碍物类
Input:
img_path: 障碍物图片路径
location: 障碍物位置
attribute: 障碍物类别属性
'''
class ObstacleClass(pygame.sprite.Sprite):
def init(self, img_path, location, attribute):
pygame.sprite.Sprite.init(self)
self.img_path = img_path
self.image = pygame.image.load(self.img_path)
self.location = location
self.rect = self.image.get_rect()
self.rect.center = self.location
self.attribute = attribute
self.passed = False
'''移动'''
def move(self, num):
self.rect.centery = self.location[1] - num

'''创建障碍物'''
def createObstacles(s, e, num=10):
obstacles = pygame.sprite.Group()
locations = []
for i in range(num):
row = random.randint(s, e)
col = random.randint(0, 9)
location = [col64+20, row64+20]
if location not in locations:
locations.append(location)
attribute = random.choice(list(cfg.OBSTACLE_PATHS.keys()))
img_path = cfg.OBSTACLE_PATHS[attribute]
obstacle = ObstacleClass(img_path, location, attribute)
obstacles.add(obstacle)
return obstacles

'''合并障碍物'''
def AddObstacles(obstacles0, obstacles1):
obstacles = pygame.sprite.Group()
for obstacle in obstacles0:
obstacles.add(obstacle)
for obstacle in obstacles1:
obstacles.add(obstacle)
return obstacles

'''显示游戏开始界面'''
def ShowStartInterface(screen, screensize):
screen.fill((255, 255, 255))
tfont = pygame.font.Font(cfg.FONTPATH, screensize[0]//5)
cfont = pygame.font.Font(cfg.FONTPATH, screensize[0]//20)
title = tfont.render(u'滑雪游戏', True, (255, 0, 0))
content = cfont.render(u'按任意键开始游戏', True, (0, 0, 255))
trect = title.get_rect()
trect.midtop = (screensize[0]/2, screensize[1]/5)
crect = content.get_rect()
crect.midtop = (screensize[0]/2, screensize[1]/2)
screen.blit(title, trect)
screen.blit(content, crect)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
return
pygame.display.update()

'''显示分数'''
def showScore(screen, score, pos=(10, 10)):
font = pygame.font.Font(cfg.FONTPATH, 30)
score_text = font.render("Score: %s" % score, True, (0, 0, 0))
screen.blit(score_text, pos)

'''更新当前帧的游戏画面'''
def updateFrame(screen, obstacles, skier, score):
screen.fill((255, 255, 255))
obstacles.draw(screen)
screen.blit(skier.image, skier.rect)
showScore(screen, score)
pygame.display.update()

'''主程序'''
def main():

游戏初始化

pygame.init()
pygame.mixer.init()
pygame.mixer.music.load(cfg.BGMPATH)
pygame.mixer.music.set_volume(0.4)
pygame.mixer.music.play(-1)

设置屏幕

screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption('滑雪游戏 —— 九歌')

游戏开始界面

ShowStartInterface(screen, cfg.SCREENSIZE)

实例化游戏精灵

--滑雪者

skier = SkierClass()

--创建障碍物

obstacles0 = createObstacles(20, 29)
obstacles1 = createObstacles(10, 19)
obstaclesflag = 0
obstacles = AddObstacles(obstacles0, obstacles1)

游戏clock

clock = pygame.time.Clock()

记录滑雪的距离

distance = 0

记录当前的分数

score = 0

记录当前的速度

speed = [0, 6]

游戏主循环

while True:

--事件捕获

for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
speed = skier.turn(-1)
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
speed = skier.turn(1)

--更新当前游戏帧的数据

skier.move()
distance += speed[1]
if distance >= 640 and obstaclesflag == 0:
obstaclesflag = 1
obstacles0 = createObstacles(20, 29)
obstacles = AddObstacles(obstacles0, obstacles1)
if distance >= 1280 and obstaclesflag == 1:
obstaclesflag = 0
distance -= 1280
for obstacle in obstacles0:
obstacle.location[1] = obstacle.location[1] - 1280
obstacles1 = createObstacles(10, 19)
obstacles = AddObstacles(obstacles0, obstacles1)
for obstacle in obstacles:
obstacle.move(distance)

--碰撞检测

hitted_obstacles = pygame.sprite.spritecollide(skier, obstacles, False)
if hitted_obstacles:
if hitted_obstacles[0].attribute == "tree" and not hitted_obstacles[0].passed:
score -= 50
skier.setFall()
updateFrame(screen, obstacles, skier, score)
pygame.time.delay(1000)
skier.setForward()
speed = [0, 6]
hitted_obstacles[0].passed = True
elif hitted_obstacles[0].attribute == "flag" and not hitted_obstacles[0].passed:
score += 10
obstacles.remove(hitted_obstacles[0])

--更新屏幕

updateFrame(screen, obstacles, skier, score)
clock.tick(cfg.FPS)

'''run'''
if name == 'main':
main()

三、乒乓球

 
import sys
import cfg
import pygame
from modules import *


'''定义按钮'''
def Button(screen, position, text, button_size=(200, 50)):
left, top = position
bwidth, bheight = button_size
pygame.draw.line(screen, (150, 150, 150), (left, top), (left+bwidth, top), 5)
pygame.draw.line(screen, (150, 150, 150), (left, top-2), (left, top+bheight), 5)
pygame.draw.line(screen, (50, 50, 50), (left, top+bheight), (left+bwidth, top+bheight), 5)
pygame.draw.line(screen, (50, 50, 50), (left+bwidth, top+bheight), (left+bwidth, top), 5)
pygame.draw.rect(screen, (100, 100, 100), (left, top, bwidth, bheight))
font = pygame.font.Font(cfg.FONTPATH, 30)
text_render = font.render(text, 1, (255, 235, 205))
return screen.blit(text_render, (left+50, top+10))

'''
Function:
开始界面
Input:
--screen: 游戏界面
Return:
--game_mode: 1(单人模式)/2(双人模式)
'''
def startInterface(screen):
clock = pygame.time.Clock()
while True:
screen.fill((41, 36, 33))
button_1 = Button(screen, (150, 175), '1 Player')
button_2 = Button(screen, (150, 275), '2 Player')
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if button_1.collidepoint(pygame.mouse.get_pos()):
return 1
elif button_2.collidepoint(pygame.mouse.get_pos()):
return 2
clock.tick(10)
pygame.display.update()

'''结束界面'''
def endInterface(screen, score_left, score_right):
clock = pygame.time.Clock()
font1 = pygame.font.Font(cfg.FONTPATH, 30)
font2 = pygame.font.Font(cfg.FONTPATH, 20)
msg = 'Player on left won!' if score_left > score_right else 'Player on right won!'
texts = [font1.render(msg, True, cfg.WHITE),
font2.render('Press ESCAPE to quit.', True, cfg.WHITE),
font2.render('Press ENTER to continue or play again.', True, cfg.WHITE)]
positions = [[120, 200], [155, 270], [80, 300]]
while True:
screen.fill((41, 36, 33))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
return
elif event.key == pygame.K_ESCAPE:
sys.exit()
pygame.quit()
for text, pos in zip(texts, positions):
screen.blit(text, pos)
clock.tick(10)
pygame.display.update()

'''运行游戏Demo'''
def runDemo(screen):

加载游戏素材

hit_sound = pygame.mixer.Sound(cfg.HITSOUNDPATH)
goal_sound = pygame.mixer.Sound(cfg.GOALSOUNDPATH)
pygame.mixer.music.load(cfg.BGMPATH)
pygame.mixer.music.play(-1, 0.0)
font = pygame.font.Font(cfg.FONTPATH, 50)

开始界面

game_mode = startInterface(screen)

游戏主循环

--左边球拍(ws控制, 仅双人模式时可控制)

score_left = 0
racket_left = Racket(cfg.RACKETPICPATH, 'LEFT', cfg)

--右边球拍(↑↓控制)

score_right = 0
racket_right = Racket(cfg.RACKETPICPATH, 'RIGHT', cfg)

--球

ball = Ball(cfg.BALLPICPATH, cfg)
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit(-1)
screen.fill((41, 36, 33))

玩家操作

pressed_keys = pygame.key.get_pressed()
if pressed_keys[pygame.K_UP]:
racket_right.move('UP')
elif pressed_keys[pygame.K_DOWN]:
racket_right.move('DOWN')
if game_mode == 2:
if pressed_keys[pygame.K_w]:
racket_left.move('UP')
elif pressed_keys[pygame.K_s]:
racket_left.move('DOWN')
else:
racket_left.automove(ball)

球运动

scores = ball.move(ball, racket_left, racket_right, hit_sound, goal_sound)
score_left += scores[0]
score_right += scores[1]

显示

--分隔线

pygame.draw.rect(screen, cfg.WHITE, (247, 0, 6, 500))

--球

ball.draw(screen)

--拍

racket_left.draw(screen)
racket_right.draw(screen)

--得分

screen.blit(font.render(str(score_left), False, cfg.WHITE), (150, 10))
screen.blit(font.render(str(score_right), False, cfg.WHITE), (300, 10))
if score_left == 11 or score_right == 11:
return score_left, score_right
clock.tick(100)
pygame.display.update()

'''主函数'''
def main():

初始化

pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((cfg.WIDTH, cfg.HEIGHT))
pygame.display.set_caption('pingpong —— 九歌')

开始游戏

while True:
score_left, score_right = runDemo(screen)
endInterface(screen, score_left, score_right)

'''run'''
if name == 'main':
main()

四、俄罗斯方块

 
import os
import sys
import random
from modules import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


'''定义俄罗斯方块游戏类'''
class TetrisGame(QMainWindow):
def init(self, parent=None):
super(TetrisGame, self).init(parent)

是否暂停ing

self.is_paused = False

是否开始ing

self.is_started = False
self.initUI()
'''界面初始化'''
def initUI(self):

icon

self.setWindowIcon(QIcon(os.path.join(os.getcwd(), 'resources/icon.jpg')))

块大小

self.grid_size = 22

游戏帧率

self.fps = 200
self.timer = QBasicTimer()

焦点

self.setFocusPolicy(Qt.StrongFocus)

水平布局

layout_horizontal = QHBoxLayout()
self.inner_board = InnerBoard()
self.external_board = ExternalBoard(self, self.grid_size, self.inner_board)
layout_horizontal.addWidget(self.external_board)
self.side_panel = SidePanel(self, self.grid_size, self.inner_board)
layout_horizontal.addWidget(self.side_panel)
self.status_bar = self.statusBar()
self.external_board.score_signal[str].connect(self.status_bar.showMessage)
self.start()
self.center()
self.setWindowTitle('Tetris —— 九歌')
self.show()
self.setFixedSize(self.external_board.width() + self.side_panel.width(), self.side_panel.height() + self.status_bar.height())
'''游戏界面移动到屏幕中间'''
def center(self):
screen = QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2)
'''更新界面'''
def updateWindow(self):
self.external_board.updateData()
self.side_panel.updateData()
self.update()
'''开始'''
def start(self):
if self.is_started:
return
self.is_started = True
self.inner_board.createNewTetris()
self.timer.start(self.fps, self)
'''暂停/不暂停'''
def pause(self):
if not self.is_started:
return
self.is_paused = not self.is_paused
if self.is_paused:
self.timer.stop()
self.external_board.score_signal.emit('Paused')
else:
self.timer.start(self.fps, self)
self.updateWindow()
'''计时器事件'''
def timerEvent(self, event):
if event.timerId() == self.timer.timerId():
removed_lines = self.inner_board.moveDown()
self.external_board.score += removed_lines
self.updateWindow()
else:
super(TetrisGame, self).timerEvent(event)
'''按键事件'''
def keyPressEvent(self, event):
if not self.is_started or self.inner_board.current_tetris == tetrisShape().shape_empty:
super(TetrisGame, self).keyPressEvent(event)
return
key = event.key()

P键暂停

if key == Qt.Key_P:
self.pause()
return
if self.is_paused:
return

向左

elif key == Qt.Key_Left:
self.inner_board.moveLeft()

向右

elif key == Qt.Key_Right:
self.inner_board.moveRight()

旋转

elif key == Qt.Key_Up:
self.inner_board.rotateAnticlockwise()

快速坠落

elif key == Qt.Key_Space:
self.external_board.score += self.inner_board.dropDown()
else:
super(TetrisGame, self).keyPressEvent(event)
self.updateWindow()

'''run'''
if name == 'main':
app = QApplication([])
tetris = TetrisGame()
sys.exit(app.exec_())

五、消消乐

 
import os
import sys
import cfg
import pygame
from modules import *


'''游戏主程序'''
def main():
pygame.init()
screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption('Gemgem —— 九歌')

加载背景音乐

pygame.mixer.init()
pygame.mixer.music.load(os.path.join(cfg.ROOTDIR, "resources/audios/bg.mp3"))
pygame.mixer.music.set_volume(0.6)
pygame.mixer.music.play(-1)

加载音效

sounds = {}
sounds['mismatch'] = pygame.mixer.Sound(os.path.join(cfg.ROOTDIR, 'resources/audios/badswap.wav'))
sounds['match'] = []
for i in range(6):
sounds['match'].append(pygame.mixer.Sound(os.path.join(cfg.ROOTDIR, 'resources/audios/match%s.wav' % i)))

加载字体

font = pygame.font.Font(os.path.join(cfg.ROOTDIR, 'resources/font/font.TTF'), 25)

图片加载

gem_imgs = []
for i in range(1, 8):
gem_imgs.append(os.path.join(cfg.ROOTDIR, 'resources/images/gem%s.png' % i))

主循环

game = gemGame(screen, sounds, font, gem_imgs, cfg)
while True:
score = game.start()
flag = False

一轮游戏结束后玩家选择重玩或者退出

while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == pygame.KEYUP and event.key == pygame.K_r:
flag = True
if flag:
break
screen.fill((135, 206, 235))
text0 = 'Final score: %s' % score
text1 = 'Press <R> to restart the game.'
text2 = 'Press <Esc> to quit the game.'
y = 150
for idx, text in enumerate([text0, text1, text2]):
text_render = font.render(text, 1, (85, 65, 0))
rect = text_render.get_rect()
if idx == 0:
rect.left, rect.top = (212, y)
elif idx == 1:
rect.left, rect.top = (122.5, y)
else:
rect.left, rect.top = (126.5, y)
y += 100
screen.blit(text_render, rect)
pygame.display.update()
game.reset()

'''run'''
if name == 'main':
main()

转载出处:https://juejin.cn/post/6990604164501864455

 
版权声明

本文为「Noise」原创内容或编译整理;除特别说明外,文中图片并非个人手绘,可能来源于网络、AI 生成、截图等,后期使用 PhotoMator / Procreate 进行处理,仅用于学习与交流。如涉及版权或来源标注不全,请联系处理。未经授权,禁止用于商业用途,禁止抹除水印。转载请注明出处与链接并保留本声明。

...

评论 (0)

评论功能加载中...
Noise

Noise

执迷不悟

推荐阅读

Belin Doc-一键完成高质量文档翻译
AIGC

Belin Doc-一键完成高质量文档翻译

Noise | 2025-08-10

Belin Doc 是一款由 AI 驱动的免费、无限制 文档翻译工具。无需注册,没有限制。

截止发文,该产品属于新产品,未看到上架定价,未登录时可每日使用1000次,但任务有排队

官网:https://belindoc.com

功能

	文档翻译:支持多种格式的文档翻译,
544
eechat-跨平台本地部署LLM工具,支持mcp接入
AIGC

eechat-跨平台本地部署LLM工具,支持mcp接入

Noise | 2025-07-25

eechat 是一款开源免费的国产 AI 应用,支持 Windows、macOS 和 Linux,集成了聊天、多模态指令执行(MCP)、知识库问答(RAG)、语音识别(ASR)、语音合成(TTS)等功能模块。

	开箱即用,无需代码基础,适合非技术背景用户。
	免费开源,国产的免费
895
跨平台云盘挂载本地客户端-OpenList Desktop
资源分享

跨平台云盘挂载本地客户端-OpenList Desktop

Noise | 2025-07-19

OpenList Desktop是一个为 OpenList (Alist) 和 Rclone 设计的跨平台桌面客户端。它提供了一个现代化且用户友好的图形界面,帮助您轻松管理 Alist 服务和 Rclone 云盘挂载,无需记忆和输入繁琐的命令行指令。

开源地址:https://gith

1374