首先做这个项目之前得清楚需要的材料和这个项目的结构,我自己感觉这个游戏项目的难点就在于钩子摆动的问题,它需要利用到三角函数来实现出来,我利用了pygame.transform.rotate()方法来实现钩字摇摆的问题,用sin和cos的方法来计算出钩字旋转的角度,对于目前的自己来说这就是最难的部分!这个项目我一共写了6个部分完成的,接下来就是代码部分!
项目管理代码
import mining
import pygame
from pygame.locals import *
import time
class A():
def __init__(self):
# pygame初始化 否则找不到字体文件
pygame.init()
def main(screen):
# 创建窗口
# screen = pygame.display.set_mode((1400, 900))
# 创建背景图片
background = pygame.image.load("./material/dabeijing.png")
# 创建玩家人物对象
miner = mining.Miner(screen)
# # 创建管理石头对象
manage_kuang = mining.Manage_kuang(screen)
# 创建钩子对象
crash = mining.Hook(screen)
music = mining.GameSound()
music.playBackgroundMusic()
while True:
# 将背景贴到界面中
screen.blit(background, (0, 0))
# 调用人物的显示功能
miner.display()
# 调用钩子的显示功能
crash.hook_display()
# 调用钩子旋转功能
crash.hook_rotate()
# 钩子检测按键
a = crash.control()
if a:
music.playHookSound()
# 钩子移动功能
crash.move()
# 钩子越界检测
crash.scope()
crash.scope2()
crash.scope3()
# 检测钩子碰撞
crash.pengzhuang(manage_kuang)
# 将钩子和物体一起向回拉
crash.move2()
# 随机石头
manage_kuang.random_fond()
for fond1 in manage_kuang.fonds:
fond1.display()
# fond1.move()
# 显示界面
pygame.display.update()
time.sleep(0.002)
def one():
# 创建窗口
screen = pygame.display.set_mode((1400, 900), 0, 32)
# 创建背景图片
background1 = pygame.image.load("9999.png")
# background = pygame.image.load("./material/dabeijing.png")
while True:
screen.blit(background1, (0, 0))
# a = input()
# if a == "a":
# break
for event in pygame.event.get():
print(event.type)
# print(pygame.K_SPACE)
# 判断是否是点击了退出按钮
if event.type == 12:
print("exit")
exit() # 让整个程序结束,return让 函数结束,break让循环结束
elif event.type == 3:
print(3333333333333333)
return screen
pygame.display.update()
# break
screen = one()
main(screen)
钩子碰撞
from math import sin, cos, pi
import pygame
from pygame.locals import *
import time
class Hook(pygame.sprite.Sprite):
"""钩子类"""
def __init__(self, screen):
pygame.sprite.Sprite.__init__(self)
self.rawimage = pygame.image.load("./material/gouzi3.png") # 原始图片
self.image = self.rawimage # 旋转后的图形,初始值就是原始图
self.rect = self.rawimage.get_rect() # 获取原始图形的矩形.
# self.aaa = pygame.image.load("./material/钩子.png") # 原始图片
self.x = 1400
self.y = 950
self.screen = screen
self.rect.topleft = [self.rect.x, self.rect.y]
# 定义一个变量用来进行使
self.a = True
self.b = False
self.c = False
self.d = False
self.num1 = False
self.num2 = True
self.hook_rotate_flag = True
self.speed = 5
# 转角
self.corner = 0
self.num = 2
self.speed = []
self.v = 10
self.aaa = False
# self.font = pygame.font.SysFont(" ", 40) # 格式, 大小
# 文本, 有没有抗锯齿, 颜色, 背景(可不写)
# self.text_surface = self.font.render("***** ", True, (200, 255, 255))
def hook_display(self):
"""显示功能"""
self.screen.blit(self.image, self.rect)
# self.screen.blit(self.aaa, (700, 0))
# self.screen.blit(self.text_surface, (self.rect.x, self.rect.y))
def hook_rotate(self):
"""旋转功能"""
self.right_rotate()
def detection(self):
"""检测按键功能"""
# 获取事件,比如按键等
for event in pygame.event.get():
# 判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit() # 让整个程序结束,return让函数结束,break让循环结束
def right_rotate(self):
"""旋转"""
if self.a:
if self.corner > -90:
self.corner -= self.num
self.image = pygame.transform.rotate(self.rawimage, self.corner)
self.rect = self.image.get_rect()
self.rect.x = self.x // 2 - self.rect.w // 2
self.rect.y = self.y - 730 - self.rect.h // 2
if self.corner == -90:
self.num = -2
self.corner = -88
if self.corner >= 90:
self.num = 2
self.corner = 88
self.rect.topleft = [self.rect.x, self.rect.y]
self.speed = [-int(self.v * sin(self.corner * pi / 180)), -int(self.v * cos(self.corner * pi / 180))]
def control(self):
"""检测键盘,调用对应的功能"""
# 获取事件,比如按键等
for event in pygame.event.get():
# 判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit() # 让整个程序结束,return让函数结束,break让循环结束
# 判断连续按键,注意下面要使用if,不能使用elif,否则当一起按下2个键的时候,只能处理一个键,另外的那个不处理
key = pygame.key.get_pressed()
# 判断是否要发射子弹
if key[K_SPACE]:
print('space')
self.a = False
self.b = True
return True
def move(self):
# if self.corner > 0:
if self.b:
self.rect.x -= self.speed[0]
self.rect.y -= self.speed[1]
# print(self.rect.y, self.rect.x)
self.rect.topleft = [self.rect.x, self.rect.y]
if self.rect.x < 0:
self.c = True
self.b = False
self.aaa = True
elif self.rect.x > 1330:
self.d = True
self.b = False
self.aaa = True
elif self.rect.y > 810:
self.num1 = True
self.b = False
self.aaa = True
def pengzhuang(self, stones):
"""碰撞检测"""
# 如果放钩子,则碰撞检测
if self.aaa == False:
for stone in stones.fonds:
if pygame.sprite.collide_mask(self, stone):
stone.a = False
self.aaa = True # 表示拉取钩子
self.b = False
# while True:
stone.y = self.rect.y
stone.x = self.rect.x
# if self.move2():
# stone.fonds.remove(stone)
# 如果碰到了一个黄金,则不再继续判断碰撞,意味着每次只获取一个黄金
# return stone
self.obj = stone
# 从列表中删除
stones.fonds.remove(stone)
break
def move2(self):
global stones
if self.aaa is True:
self.rect.x += self.speed[0]
self.rect.y += self.speed[1]
self.rect.topleft = [self.rect.x, self.rect.y]
try:
if self.obj:
self.obj.x += self.speed[0]
self.obj.y += self.speed[1]
self.obj.rect.topleft = [self.obj.x, self.obj.y]
self.obj.screen.blit(self.obj.image, (self.obj.x, self.obj.y))
print("-----黄金正在被拉取中---")
except:
print(123)
# self.rect.x += self.speed[0]
# self.rect.y += self.speed[1]
print(222)
if self.rect.y <= 150:
self.a = True
self.aaa = False # 当已经成功的将黄金拉回来,则修改这个判断,表示下一次的放钩子
self.obj = None
print("------黄金已经被收取成功--------")
# return True
def scope(self):
if self.c:
self.rect.x += self.speed[0]
self.rect.y += self.speed[1]
if self.rect.x >= 650:
self.a = True
self.c = False
def scope2(self):
if self.d:
self.rect.x += self.speed[0]
self.rect.y += self.speed[1]
if self.rect.x <= 650:
self.a = True
self.d = False
def scope3(self):
if self.num1:
self.rect.x += self.speed[0]
self.rect.y += self.speed[1]
if self.rect.y < 120:
self.a = True
self.num1 = False
def main():
clock = pygame.time.Clock()
# 创建窗口
screen = pygame.display.set_mode((1400, 900))
hook = Hook(screen)
# 创建一个对象
# enemy_plane = EnemyPlane2(screen)
background = pygame.image.load("./material/背景.png")
# stars = mineral.Manage_kuang(screen)
while True:
screen.blit(background, (0, 0))
# screen.fill((0, 100, 255))
# 显示钩子
hook.hook_display()
# 检测按键
# hook.detection()
# 旋转功能
hook.hook_rotate()
# 检测按键
hook.control()
# 移动功能
hook.move()
# hook.pengzhuang()
# 越界检测
hook.scope()
hook.scope2()
hook.scope3()
# 调用目标
# enemy_plane.display()
# 显示界面
pygame.display.update()
# time.sleep(0.02)
clock.tick(50)
if __name__ == "__main__":
main()
# pygame.mouse.get_pressed()
分数代码
import mining
import pygame
from pygame.locals import *
import time
class HeroPlane(pygame.sprite.Sprite):
def __init__(self, screen):
# 调用父类初始化方法
# pygame.sprite.Sprite.__init__(self)
super().__init__()
# 窗口
self.screen = screen
# 一个玩家飞机图片
self.image = pygame.image.load('./feiji/feiji.png')
# 飞机矩形区域对象
self.rect = self.image.get_rect()
# 左上角坐标
self.rect.topleft = [512 / 2 - 116 / 2, 600]
def drawText(self, text, x, y, textHeight=30, fontColor=(255, 255, 255), backgroudColor=None):
# 通过字体文件获得字体对象 参数1 字体文件 参数2 字体大小
font_obj = pygame.font.Font('./feiji/baddf.ttf', textHeight)
# 1文字 2是否抗锯齿 3文字颜色 4背景颜色
text_obj = font_obj.render(text, True, fontColor, backgroudColor) # 配置要显示的文字
# 获得要显示的对象的rect
text_rect = text_obj.get_rect()
# 设置显示对象的坐标
text_rect.topleft = (x, y)
# 绘制字 到指定区域 参1是文字对象 参2 矩形对象
self.screen.blit(text_obj, text_rect)
任务图形代码
import pygame
from pygame.locals import *
import time
# import random
class Miner(object):
"""人物类"""
def __init__(self, screen):
# 定义人物的位置
self.x = 600
self.y = 40
# 定义玩家图片
self.image = pygame.image.load("./material/renwu3.png")
# 存储需要显示玩家的对象引用
self.screen = screen
self.speed = 1
self.direction = "right"
self.direction2 = "down"
self.bombed_flag = False
self.rect = self.image.get_rect()
self.rect.topleft = [self.x, self.y]
def display(self):
"""显示玩家"""
self.screen.blit(self.image, (self.x, self.y))
def control(self):
"""检测键盘,调用相对应的功能"""
# 判断是否是点击了退出按钮
for event in pygame.event.get():
if event.type == QUIT:
print("exit")
exit() # 让整个程序结束
def auto_move(self):
"""控制玩家人物的自由移动"""
if self.bombed_flag is False:
if self.direction2 == "down":
self.y += self.speed
if self.y > 60:
self.direction2 = "up"
elif self.direction2 == "up":
self.y -= self.speed
if self.y < 30:
self.direction2 = "down"
self.rect.topleft = [self.x, self.y]
def main():
# 创建界面
screen = pygame.display.set_mode((1400, 900))
# 创建背景图片
background = pygame.image.load("./huang_jin_kuang_gong/Inkedsnipaste20181122_083528_LI.jpg")
# 创建玩家人物对象
miner = Miner(screen)
while True:
# 将背景贴到界面中
screen.blit(background, (0, 0))
# 调用玩家的显示功能
miner.display()
# 调用玩家的键盘检测功能
miner.control()
miner.auto_move()
# 显示界面
pygame.display.update()
time.sleep(0.01)
if __name__ == "__main__":
main()
界面代码
import pygame
from pygame.locals import *
import time
# import random
class A(object):
"""界面类"""
def __init__(self, screen):
self.start = True
self.over = False
self.image1 = pygame.image.load("./黄金矿工/timg.png")
# self.image2 = pygame.image.load("./feiji/gameover2.png")
self.image3 = pygame.image.load("./黄金矿工/beijin.png")
self.screen = screen
self.flag = False
def display(self):
if self.flag is False:
if self.start:
self.screen.blit(self.image1, (0, 0))
else:
self.screen.blit(self.image3, (0, 0))
if self.over:
self.screen.blit(self.image2, (0, 0))
def b(self):
key = pygame.key.get_pressed()
if key[K_SPACE]:
self.over = True
def mouse_info(self):
image = pygame.image.load("./黄金矿工/start.jpg").convert_alpha()
image.blit(image, (0, 0))
again_rect = image.get_rect()
if pygame.mouse.get_pressed()[0]:
# 获取鼠标坐标
pos = pygame.mouse.get_pos()
# 如果用户点击“开始游戏”
if again_rect.left < pos[0] < again_rect.right and again_rect.top < pos[1] < again_rect.bottom:
# 调用main函数,开始游戏
# main()
self.flag = True
def main():
# 初始化游戏
pygame.init()
# 创建一个窗口
screen = pygame.display.set_mode((1400, 900))
a = A(screen)
while True:
# 获取事件,比如按键等
for event in pygame.event.get():
# 判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit()
a.display()
a.mouse_info()
a.b()
# 显示界面
pygame.display.update()
time.sleep(0.01)
if __name__ == '__main__':
main()
矿石代码
import pygame
from pygame.locals import *
import time
import random
class Fond(pygame.sprite.Sprite):
def __init__(self, screen, x, y):
pygame.sprite.Sprite.__init__(self)
# 定义石头默认显示的位置
self.x = x
self.y = y
self.speed = 1 # 敌机移动速度
self.speed2 = 10
# 定义玩家图片
self.image = pygame.image.load("./material/huangjin4.png")
# 存储将来要显示的窗口对象引用
self.screen = screen
self.dic = "right"
self.fenshu = 3000
self.rect = self.image.get_rect()
self.a = True
# 定义一个变量来影响钩子的速度
self.sudu = 1
self.rect.topleft = [self.x, self.y]
def display(self):
"""
显示石头
:return:
"""
self.screen.blit(self.image, (self.x, self.y))
self.rect.topleft = [self.x, self.y]
def move(self):
if self.a:
if self.dic == "left":
# self.y += self.speed
self.x -= self.speed2
if self.x <= 0:
self.dic = "right"
elif self.dic == "right":
self.x += self.speed2
if self.x >= 1200:
self.dic = "left"
self.rect.topleft = [self.x, self.y]
class Mouse(pygame.sprite.Sprite):
def __init__(self, screen, x, y):
pygame.sprite.Sprite.__init__(self)
# 定义玩家默认显示的位置
self.x = x
self.y = y
self.speed = 1 # 敌机移动速度
self.speed2 = 10
# 定义玩家图片
self.image = pygame.image.load("./material/huangjin4.png")
# 存储将来要显示的窗口对象引用
self.screen = screen
self.dic = "left"
self.fenshu = 8000
self.rect = self.image.get_rect()
# 定义一个变量来影响钩子的速度
self.sudu = 1
self.a = True
self.rect.topleft = [self.x, self.y]
def display(self):
"""
显示老鼠
:return:
"""
self.screen.blit(self.image, (self.x, self.y))
self.rect.topleft = [self.x, self.y]
def move(self):
if self.a:
if self.dic == "left":
# self.y += self.speed
self.x -= self.speed2
if self.x <= 0:
self.dic = "right"
elif self.dic == "right":
self.x += self.speed2
if self.x >= 1250:
self.dic = "left"
self.rect.topleft = [self.x, self.y]
class Dog(pygame.sprite.Sprite):
def __init__(self, screen, x, y):
pygame.sprite.Sprite.__init__(self)
# 定义玩家默认显示的位置
self.x = x
self.y = y
self.speed = 1 # 敌机移动速度
self.speed2 = 6
# 定义玩家图片
self.image = pygame.image.load("./material/huangjin4.png")
# 存储将来要显示的窗口对象引用
self.screen = screen
self.dic = "left"
self.fenshu = 30000
self. sudu = 1
self.rect = self.image.get_rect()
self.rect.topleft = [self.x, self.y]
# 定义一个变量来影响钩子的速度
self.sudu = 30
self.a = True
def display(self):
"""
显示狗
:return:
"""
self.screen.blit(self.image, (self.x, self.y))
self.rect.topleft = [self.x, self.y]
def move(self):
if self.a:
if self.dic == "left":
# self.y += self.speed
self.x -= self.speed2
if self.x <= -50:
self.dic = "right"
elif self.dic == "right":
self.x += self.speed2
if self.x >= 1150:
self.dic = "left"
self.rect.topleft = [self.x, self.y]
class Cat(pygame.sprite.Sprite):
def __init__(self, screen, x, y):
pygame.sprite.Sprite.__init__(self)
# 定义玩家默认显示的位置
self.x = x
self.y = y
self.speed = 1 # 敌机移动速度
self.speed2 = 6
# 定义图
self.image = pygame.image.load("./tututu/shitou4.png")
# 存储将来要显示的窗口对象引用
self.screen = screen
self.dic = "left"
self.fenshu = 100000
self.rect = self.image.get_rect()
self.a = True # 定义一个变量来影响钩子的速度
self.sudu = 1
self.rect.topleft = [self.x, self.y]
def display(self):
"""
显示猫
:return:
"""
self.screen.blit(self.image, (self.x, self.y))
self.rect.topleft = [self.x, self.y]
# def move(self):
# if self.a:
# if self.dic == "left":
# # self.y += self.speed
# self.x -= self.speed2
# if self.x <= 0:
# self.dic = "right"
# elif self.dic == "right":
# self.x += self.speed2
# if self.x >= 1000:
# self.dic = "left"
# self.rect.topleft = [self.x, self.y]
class Manage_kuang(object):
"""管理石头类"""
def __init__(self, screen):
self.screen = screen
self.fonds = list() # 存储所有的石头
self.x_list1 = list()
self.x_list2 = list()
self.x_list3 = list()
self.x_list4 = list()
def random_fond(self):
"""随机生成石头"""
x = random.randint(200, 1200)
y = random.randint(400, 500)
if len(self.x_list1) < 1:
fond = Fond(self.screen, x, y)
self.fonds.append(fond)
self.x_list1.append(x)
if len(self.x_list1) < 3 and (x >= self.x_list1[-1]+300 or x <= self.x_list1[-1]-300):
fond = Fond(self.screen, x, y)
self.fonds.append(fond)
self.x_list1.append(x)
self.x_list1.sort()
x1 = random.randint(200, 1200)
y1 = random.randint(300, 700)
if len(self.x_list2) < 1:
mouse = Mouse(self.screen, x1, y1)
self.fonds.append(mouse)
self.x_list2.append(x1)
elif len(self.x_list2) < 3 and (x1 >= self.x_list3[-1]+300 or x1 <= self.x_list3[-1]-300):
mouse = Mouse(self.screen, x1, y1)
self.fonds.append(mouse)
self.x_list2.append(x1)
self.x_list2.sort()
x2 = random.randint(200, 1200)
y2 = random.randint(500, 750)
if len(self.x_list3) < 1:
dog = Dog(self.screen, x2, y2)
self.fonds.append(dog)
self.x_list3.append(x2)
elif len(self.x_list3) < 2 and (x2 >= self.x_list3[0]+300 or x2 <= self.x_list3[0]-300):
dog = Dog(self.screen, x2, y2)
self.fonds.append(dog)
self.x_list3.append(x2)
self.x_list3.sort()
x3 = random.randint(200, 1100)
y3 = random.randint(500, 700)
if len(self.x_list4) < 1:
cat = Cat(self.screen, x3, y3)
self.fonds.append(cat)
self.x_list4.append(x3)
elif len(self.x_list4) < 1 and (x3 >= self.x_list3[-1]+300 or x3 <= self.x_list3[-1]-300):
cat = Cat(self.screen, x3, y3)
self.fonds.append(cat)
self.x_list4.append(x3)
self.x_list4.sort()
def main():
# 创建一个窗口
screen = pygame.display.set_mode((1400, 900))
# 创建一个背景图片
background = pygame.image.load("./material/back.png")
# 创建一个图片,当做飞机
hero_plane = pygame.image.load("./feiji/hero1.png")
# 显示石头
manage_kuang = Manage_kuang(screen)
while True:
# 随机石头
manage_kuang.random_fond()
for fond1 in manage_kuang.fonds:
fond1.display()
fond1.move()
for mouse1 in manage_kuang.mouse:
mouse1.display()
mouse1.move()
for dog1 in manage_kuang.dogs:
dog1.display()
dog1.move()
for cat1 in manage_kuang.cats:
cat1.display()
cat1.move()
# 获取事件,比如按键等
for event in pygame.event.get():
# 判断是否是点击了退出按钮
if event.type == QUIT:
print("exit")
exit() # 让整个程序结束,return让函数结束,break让循环结束
# 判断是否是按下了键
elif event.type == KEYDOWN:
# 检测按键是否是a或者left
if event.key == K_a or event.key == K_LEFT:
print('left')
# 检测按键是否是d或者right
elif event.key == K_d or event.key == K_RIGHT:
print('right')
# 检测按键是否是空格键
elif event.key == K_SPACE:
print('space')
# 显示界面
pygame.display.update()
time.sleep(0.01)
if __name__ == '__main__':
main()
以上就是全部完整的项目代码,目前有一个BUG尚未解决,但是程序能正常运行。