You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
12 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# coding: utf-8
# 滑雪小游戏
import sys
import pygame
import random
from pygame.locals import *
# 滑雪者类
class SkierClass(pygame.sprite.Sprite):
def __init__(self): import pygame, sys, random
skier_images = ["skier_down.png", "skier_right1.png", "skier_right2.png",
"skier_left2.png", "skier_left1.png"]
class SkierClass(pygame.sprite.Sprite): # 创建滑雪者
def __init__(self):
pygame.sprite.Sprite.__init__(self) # 基类的init方法
self.image = pygame.image.load("skier_crash.png") # 这个是滑雪者的美照。
self.rect = self.image.get_rect() # 用于获得Image的矩形大小
self.rect.center = [320, 100] # 指定矩形的中心位置
self.angle = 0
def turn(self, direction): # 滑雪者 转向函数 其中的direction参数是指定滑雪者移动的方向和程度点击两次右键比一次右键滑动的幅度要大一会自己试着运行一下试试。
self.angle = self.angle + direction # 滑雪者当前的移动速度
if self.angle < -2: self.angle = -2 # 用于将滑雪者的移动方式固定到这五个方式当中
if self.angle > 2: self.angle = 2
center = self.rect.center
self.image = pygame.image.load(skier_images[self.angle]) # 这个时候滑雪者应该有的姿态图片。
self.rect = self.image.get_rect()
self.rect.center = center
speed = [self.angle, 6 - abs(self.angle) * 2] # 滑雪者的速度。
return speed
def move(self, speed): # 滑雪者左右移动
self.rect.centerx = self.rect.centerx + speed[0] # 滑雪者所在位置
if self.rect.centerx < 20: self.rect.centerx = 20 # 滑雪者所在位置不应该超过的最大最小值。
if self.rect.centerx > 620: self.rect.centerx = 620
class ObstacleClass(pygame.sprite.Sprite): # 创建树和小旗
def __init__(self, image_file, location, type):
pygame.sprite.Sprite.__init__(self)
self.image_file = image_file # image_file可能是树或者小旗
self.image = pygame.image.load(image_file) # 载入当前的图片
self.location = location
self.rect = self.image.get_rect()
self.rect.center = location
self.type = type
self.passed = False
def scroll(self, terrainPos): # 场景上滚,造成下滑假象。
self.rect.centery = self.location[1] - terrainPos
def create_map(start, end): # 创建一个窗口,包含随机的树和小旗
obstacles = pygame.sprite.Group() # 创建独立运动的组织
locations = []
gates = pygame.sprite.Group()
for i in range(10):
row = random.randint(start, end) # 获得随机数在 start-end之间
col = random.randint(0, 9)
location = [col * 64 + 20, row * 64 + 20] # 确定所在位置
if not (location in locations): # 如果上面定义的物体不在已经确定属性(位置等参数)的物体里面。
locations.append(location)
type = random.choice(["tree", "flag"]) # 随机选择是树还是小旗
if type == "tree":
img = "skier_tree.png" # 选择相应的图片
elif type == "flag":
img = "skier_flag.png"
obstacle = ObstacleClass(img, location, type) # 将上面的形成的物体添加到游戏
obstacles.add(obstacle)
return obstacles
def animate(): # 如果发生移动就重新绘制屏幕
screen.fill([255, 255, 255]) # 指定背景颜色 RGB
pygame.display.update(obstacles.draw(screen))
screen.blit(skier.image, skier.rect) # 用于绘制位图 在屏幕的skier.rect位置绘制skier.image
screen.blit(score_text, [10, 10])
pygame.display.flip()
def updateObstacleGroup(map0, map1): # 切换到场景的下一屏
obstacles = pygame.sprite.Group()
for ob in map0: obstacles.add(ob)
for ob in map1: obstacles.add(ob)
return obstacles
pygame.init() # 初始化pygame的所有模块
def Show_Start_Interface(Demo, width, height,con1,con2):
Demo.fill((255, 255, 255))
tfont = pygame.font.Font('./font.ttf', 100)
cfont = pygame.font.Font('./font.ttf',50 )
title = tfont.render(con1, True, (255, 0, 0))
content = cfont.render(con2, True, (0, 0, 255))
trect = title.get_rect()
trect.midtop = (width / 2, height / 10)
crect = content.get_rect()
crect.midtop = (width / 3, height / 2.2)
Demo.blit(title, trect)
Demo.blit(content, crect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
return
Demo = pygame.display.set_mode((900, 900))
Show_Start_Interface(Demo, 900, 900,"滑雪游戏",'按任意键开始')
screen = pygame.display.set_mode([900, 900]) # 用于初始化窗口,其中的参数就是分辨率
clock = pygame.time.Clock() # 载入监听时间的模块 clock在下面还可以看到 clock.tick等方法
skier = SkierClass() # 初始化SkierClass对象
speed = [0, 6]
map_position = 0
points = 0
map0 = create_map(20, 29)
map1 = create_map(10, 19)
activeMap = 0
obstacles = updateObstacleGroup(map0, map1)
font = pygame.font.Font(None, 50)
while True:
clock.tick(100) # 每秒更新30次图形 ---这就是帧率。
for event in pygame.event.get(): # 检查按键或者窗口是否关闭
if event.type == pygame.QUIT: sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
speed = skier.turn(-1)
elif event.key == pygame.K_RIGHT:
speed = skier.turn(1)
skier.move(speed) # 移动滑雪者
map_position += speed[1] # 滚动场景
if map_position >= 640 and activeMap == 0: # 从场景的一个窗口切换到下一个窗口
activeMap = 1
map0 = create_map(20, 29)
obstacles = updateObstacleGroup(map0, map1)
if map_position >= 1280 and activeMap == 1:
activeMap = 0
for ob in map0:
ob.location[1] = ob.location[1] - 1280
map_position = map_position - 1280
map1 = create_map(10, 19)
obstacles = updateObstacleGroup(map0, map1)
for obstacle in obstacles:
obstacle.scroll(map_position)
hit = pygame.sprite.spritecollide( skier,obstacles, False) # 检查是否碰到树或者小旗。
if hit:
if hit[0].type == "tree" and not hit[0].passed:
points = points - 10
skier.image = pygame.image.load("skier_crash.png")
animate()
pygame.time.delay(400)
skier.image = pygame.image.load("skier_down.png")
skier.angle = 0
speed = [0, 6]
hit[0].passed = True
if points<0:
Show_Start_Interface(Demo, 900, 900,"游戏结束",'按任意键重新开始')
points=0
elif hit[0].type == "flag" and not hit[0].passed:
points += 10
obstacles.remove(hit[0])
# 显示得分
score_text = font.render("Score: " + str(points), 1, (0, 0, 0))
animate()
pygame.sprite.Sprite.__init__(self)
# 滑雪者的朝向(-2到2)
self.direction = 0
self.imgs = ["skier_crash.png", "skier_right1.png", "skier_right2.png", "skier_left2.png", "skier_left1.png"]
self.person = pygame.image.load(self.imgs[self.direction])
self.rect = self.person.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.person = pygame.image.load(self.imgs[self.direction])
self.rect = self.person.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)
# 障碍物类
# 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 create_obstacles(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 = [col * 64 + 20, row * 64 + 20]
if location not in locations: locations.append(location)
attribute = random.choice(["tree", "flag"])
img_path = './images/tree.png' if attribute == "tree" else './images/flag.png'
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 main():
'''
初始化
'''
pygame.init()
# 屏幕
screen = pygame.display.set_mode([900, 900])
# 主频
clock = pygame.time.Clock()
# 滑雪者
skier = SkierClass()
# 记录滑雪的距离
distance = 0
# 创建障碍物
obstacles0 = create_obstacles(20, 29)
obstacles1 = create_obstacles(10, 19)
obstaclesflag = 0
obstacles = AddObstacles(obstacles0, obstacles1)
# 分数
font = pygame.font.Font(None, 50)
score = 0
score_text = font.render("Score: " + str(score), 1, (0, 0, 0))
# 速度
speed = [0, 6]
Show_Start_Interface(screen, 640, 640)
'''
主循环
'''
# 更新屏幕
def update():
screen.fill([255, 255, 255])
pygame.display.update(obstacles.draw(screen))
screen.blit(skier.person, skier.rect)
screen.blit(score_text, [10, 10])
pygame.display.flip()
while True:
for event in pygame.event.get():
if event.type == 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 = create_obstacles(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 = create_obstacles(10, 19)
obstacles = AddObstacles(obstacles0, obstacles1)
# 用于碰撞检测
for obstacle in obstacles:
obstacle.move(distance)
# 碰撞检测
is_hit = pygame.sprite.spritecollide(skier, obstacles, False)
if is_hit:
if is_hit[0].attribute == "tree" and not is_hit[0].passed: score -= 50
skier.person = pygame.image.load("./images/skier_fall.png")
update()
# 摔倒后暂停一会再站起来
pygame.time.delay(1000)
skier.person = pygame.image.load("./images/skier_forward.png")
skier.direction = 0
speed = [0, 6]
is_hit[0].passed = True
if is_hit[0].attribute == "flag" and not is_hit[0].passed:
score += 10
obstacles.remove(is_hit[0])
score_text = font.render("Score: " + str(score), 1, (0, 0, 0))
update()
clock.tick(40)
if __name__ == '__main__':
print(" ")