标签:direct ber vector ini click pow clear raw and
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Treasure Hunter
In this game, you will play as a treasure hunter to find a mysterious treasure.
In order to find the treasure, you need to defeat a great number of monsters with
time limitation.
Created by Group ShowMaker
"""
import os
import pygame
import random
import numpy
#Initialise Screen
pygame.init()
pygame.mixer.init()
pygame.display.init()
pygame.font.init()
pygame.display.set_caption(‘Treasure Hunter‘)
FPS = 13
width = 960
height = 540
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
dt = clock.tick(FPS) / 1000 #the time interval of two images in the animation
# assets folder
img_dir = ‘assets/pictures‘
music_dir = ‘assets/music‘
# sound effects
shooting_sound = pygame.mixer.Sound(os.path.join(music_dir, ‘shoot.wav‘))
boss_bgm = os.path.join(music_dir, ‘boss_bgm.wav‘)
regular_bgm = os.path.join(music_dir, ‘regular_bgm.wav‘)
die_sound = pygame.mixer.Sound(os.path.join(music_dir, ‘enemy_die.wav‘))
boss_entry = pygame.mixer.Sound(os.path.join(music_dir, ‘boss_entry.wav‘))
boss_die = pygame.mixer.Sound(os.path.join(music_dir, ‘boss_die.wav‘))
level_up = pygame.mixer.Sound(os.path.join(music_dir, ‘level_up.wav‘))
open_chest = pygame.mixer.Sound(os.path.join(music_dir, ‘open_chest.wav‘))
time_limit=pygame.mixer.Sound(os.path.join(music_dir, ‘time_limit.wav‘))
#game background images
background = pygame.image.load(os.path.join(img_dir, ‘bg1.png‘))
background2 = pygame.image.load(os.path.join(img_dir, ‘bg2.jpg‘))
background3 = pygame.image.load(os.path.join(img_dir, ‘bg1.png‘))
background4 = pygame.image.load(os.path.join(img_dir, ‘bg3.jpg‘))
#menu related images
menu_image1 = pygame.image.load(os.path.join(img_dir, ‘main1.jpg‘))
menu_image2 = pygame.image.load(os.path.join(img_dir, ‘main2.jpg‘))
button_quit = pygame.image.load(os.path.join(img_dir, ‘button_quit2.png‘))
button_start = pygame.image.load(os.path.join(img_dir, ‘button_start2.png‘))
button_normal = pygame.image.load(os.path.join(img_dir, ‘normal.png‘))
button_difficult = pygame.image.load(os.path.join(img_dir, ‘difficult.png‘))
die_image = pygame.image.load(os.path.join(img_dir, ‘died.jpg‘))
final1 = pygame.image.load(os.path.join(img_dir, ‘congrats.jpg‘))
bginfo = pygame.image.load(os.path.join(img_dir, ‘bginfo.jpg‘))
#hero images
heroimages = [pygame.image.load(os.path.join(img_dir, ‘h1.png‘)),
pygame.image.load(os.path.join(img_dir, ‘h2.png‘)),
pygame.image.load(os.path.join(img_dir, ‘h3.png‘)),
pygame.image.load(os.path.join(img_dir, ‘h4.png‘)),
pygame.image.load(os.path.join(img_dir, ‘h5.png‘))]
#enemy images
e1images = [pygame.image.load(os.path.join(img_dir, ‘boss01_1.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss01_2.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss01_3.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss01_4.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss01_5.png‘))]
e2images = [pygame.image.load(os.path.join(img_dir, ‘boss05_1.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss05_2.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss05_3.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss05_4.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss05_5.png‘))]
e3images = [pygame.image.load(os.path.join(img_dir, ‘boss02_1.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss02_2.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss02_3.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss02_4.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss02_5.png‘))]
bossimages = [pygame.image.load(os.path.join(img_dir, ‘boss08_1.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss08_2.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss08_3.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss08_4.png‘)),
pygame.image.load(os.path.join(img_dir, ‘boss08_5.png‘))]
#bullet images
bull1 = pygame.image.load(os.path.join(img_dir, ‘bullet1.png‘))
bull2 = pygame.image.load(os.path.join(img_dir, ‘bullet2.png‘))
#props
warning_img = pygame.image.load(os.path.join(img_dir, ‘warning.png‘))
chest = pygame.image.load(os.path.join(img_dir, ‘chest.png‘))
book = pygame.image.load(os.path.join(img_dir, ‘book.png‘))
weapon = pygame.image.load(os.path.join(img_dir, ‘weapon.png‘))
gatei1 = pygame.image.load(os.path.join(img_dir, ‘gate_1.png‘))
heart = pygame.image.load(os.path.join(img_dir, ‘heart.png‘))
def main_menu():
"""
Generate three screens:
first screen: Start or quit the game
Second screen: Instruction and Difficulty selection
Third screen: Background Story (Press Enter to enter the game)
"""
global mode, screen
screen.blit(menu_image1,(0, 0))
clock.tick(FPS)
pygame.mixer.music.load(regular_bgm)
pygame.mixer.music.play(-1)
menu_layer = 1
while True:
#Mouse detection method
buttons = pygame.mouse.get_pressed()
x1, y1 = pygame.mouse.get_pos()
#Start screen
if menu_layer == 1:
screen.blit(button_start, (370, 300))
screen.blit(button_quit, (370, 400))
if 370 <= x1 <= 610 and 300 <= y1 <= 385: #Hit button start
if buttons[0]:
menu_layer = 2
elif 370 <= x1 <= 610 and 400 <= y1 <= 490: #Hit button quit
if buttons[0]:
os._exit(0)
pygame.display.update()
#Select Difficulty Level
elif menu_layer == 2:
screen.blit(menu_image2, (0, 0))
screen.blit(button_normal, (550, 70))
screen.blit(button_difficult, (550, 200))
if 620 <= x1 <= 830 and 110 <= y1 <= 210: #click button normal
if buttons[0]:
mode = ‘normal‘
menu_layer = 3
elif 620 <= x1 <= 830 and 230 <= y1 <= 330: #click button difficult
if buttons[0]:
mode = ‘difficult‘
menu_layer = 3
pygame.display.update()
#Backgroud story
elif menu_layer == 3:
screen.blit(bginfo, (0, 0))
if pygame.key.get_pressed()[pygame.K_RETURN]:
break
pygame.display.update()
#Quit method
for event in pygame.event.get():
if event.type == pygame.QUIT:
os._exit(0)
pygame.mixer.music.stop()
def draw_hero_health(hp):
"""
Draw several hearts on the top left corner of the screen to represent the hp of hero
"""
for i in range(int(hp) + 1):
if i > 0:
screen.blit(heart, (35*i, 10))
def draw_boss_health(health):
"""
Draw a health bar on the top right corner of the screen
"""
if health > 0: #the coordinates of the health bar
WIDTH = 100
HEIGHT = 20
space = 20
pygame.draw.rect(screen, pygame.Color("green"), pygame.Rect(width-WIDTH-space, space, WIDTH + 4, HEIGHT))
pygame.draw.rect(screen, pygame.Color("red"), pygame.Rect(width-WIDTH-space + 2, space+2, WIDTH/boss_health*health, HEIGHT-4))
def gen_enemy(num):
"""
Generate given number of mob and add to sprite group all_sprites
"""
for i in range(num):
mob_element = Mob()
all_sprites.add(mob_element)
mobs.add(mob_element)
def ticktock(limit,ticks,font):
"""
show the time before hero die, display at the top of the screen
"""
text = font.render("Time Remaining " + str((limit-ticks)//60000) + ":" +
str((limit-ticks)//1000%60).zfill(2), True, (0,255,0))
Rect = text.get_rect()
Rect = (300, 10) #position of the time display
screen.blit(text,Rect)
class animated_sprite(pygame.sprite.Sprite):
"""
parent class of all animated objects, take a list of images and automaticlly generate a list of
mirrored images.
use current_time and animation_time to achieve looping images inside the list
"""
def __init__(self, images): # Call the parent class (Sprite) constructor
super().__init__()
self.images = images
self.animation_time = 0.01
self.current_time = 0 #keep track of time
self.index = 0 #used to keep track of which image is in use
self.image = images[self.index] #current image of the animation
self.images_right = self.images #images face right in default
self.images_left = [] #turn the image to face left and store in a list
for image in images:
self.images_left.append(pygame.transform.flip(image, True, False))
class Hero(animated_sprite):
"""
The object player will control, hero is an animated object with ability to
move and shoot
Attributes:
update: use WASD to move the character on the screen, two lists of left and right images
will be automatically switched
shoot: use key arrows to fire a bullet, maximum speen is one bullet per 0.8 second
"""
def __init__(self, position, images, speed = 18, shoot_delay = 800):
super().__init__(images)
size = (39, 37) # The size of the images
self.health = hero_health
self.rect = pygame.Rect(position, size)
self.velocity = pygame.math.Vector2(0, 0)
self.shoot_delay = shoot_delay
self.last_shot = pygame.time.get_ticks()
self.bull_image = bull1
self.speed = speed
def update(self, dt):
#Move
if pygame.key.get_pressed()[pygame.K_a] and self.rect.center[0] > boundaryx[0] - 120:
self.velocity.x = -self.speed
elif pygame.key.get_pressed()[pygame.K_d] and self.rect.center[0] < boundaryx[1]:
self.velocity.x = self.speed
else:
self.velocity.x = 0
if pygame.key.get_pressed()[pygame.K_s] and self.rect.center[1] <boundaryy[1]:
self.velocity.y = self.speed
elif pygame.key.get_pressed()[pygame.K_w] and self.rect.center[1] > boundaryy[0]:
self.velocity.y = -self.speed
else:
self.velocity.y = 0
#Shoot
if pygame.key.get_pressed()[pygame.K_UP]:
self.shoot(1)
elif pygame.key.get_pressed()[pygame.K_DOWN]:
self.shoot(2)
elif pygame.key.get_pressed()[pygame.K_LEFT]:
self.shoot(3)
elif pygame.key.get_pressed()[pygame.K_RIGHT]:
self.shoot(4)
#Update frame
if self.velocity.x > 0: # Use the right images if sprite is moving right.
self.images = self.images_right
elif self.velocity.x < 0:
self.images = self.images_left
#Looping the images in the list
self.current_time += dt
if self.current_time >= self.animation_time and self.velocity != (0,0):
self.current_time = 0
self.index = (self.index + 1) % len(self.images)
self.image = self.images[self.index]
else:
self.image = self.images[3]
self.rect.move_ip(*self.velocity)
def shoot(self,dir):
now = pygame.time.get_ticks()
if now - self.last_shot > self.shoot_delay: #set the shoot frequate of bullet
self.last_shot = now
shooting_sound.play()
bullet = Bullet(self.rect.center[0],self.rect.center[1],self.bull_image,dir) #create new bullet
all_sprites.add(bullet)
bullets.add(bullet)
class Mob(animated_sprite):
"""
the class of regular enemy, move towards the hero if close enough, otherwise will wander around
attributes:
update: animation method (automatically switch left and right images) and move method.
"""
def __init__(self, size = (40,40)):
self.images = random.choice([e1images, e2images, e3images])
super().__init__(self.images)
self.rect = pygame.Rect((0,0),size)
self.image = self.images[self.index]
self.rect.centerx = random.randrange(boundaryx[0],boundaryx[1])
self.rect.centery = random.randrange(boundaryy[0],boundaryy[1])
self.speedy = 8
self.speedx = 8
self.speed = 8
def update(self, dt):
distanceX = hero.rect.center[0] - self.rect.centerx
distanceY = hero.rect.center[1] - self.rect.centery
distance = numpy.sqrt(pow(distanceX,2) + pow(distanceY,2))
# if enemies are too far away from the hero, they will just wander around
if distance > 400:
self.rect.centerx += self.speedx
self.rect.centery += self.speedy
if self.speedx > 0: # Use the right images if sprite is moving right.
self.images = self.images_right
elif self.speedx < 0:
self.images = self.images_left
# if enemies is close enough to the hero, they will go towards him
else:
self.rect.centerx += int(self.speed * distanceX /(distance+0.001))
self.rect.centery += int(self.speed * distanceY /(distance+0.001))
if distanceX > 0:
self.images = self.images_right
else:
self.images = self.images_left
# if touch the boundary
if self.rect.centerx < boundaryx[0] or self.rect.centerx > boundaryx[1]:
self.speedx = -self.speedx
if self.rect.centery < boundaryy[0] or self.rect.centery > boundaryy[1]:
self.speedy = -self.speedy
#Update frame
self.current_time += dt
if self.current_time >= self.animation_time:
self.current_time = 0
self.index = (self.index + 1) % len(self.images)
self.image = self.images[self.index]
class Boss(animated_sprite):
"""
The boss will move towards hero, and have a much bigger size than mobs
Attributes:
update: animation and move method
"""
def __init__(self, images, health, speed, position = (600, 270)):
super().__init__(images)
size = (50,100)
self.rect = pygame.Rect(position,size)
self.health = health
self.speed = speed
def update(self, dt):
distanceX = hero.rect.center[0] - self.rect.centerx
distanceY = hero.rect.center[1] - self.rect.centery
distance = numpy.sqrt(pow(distanceX,2) + pow(distanceY,2))
self.rect.centerx += int(self.speed * distanceX /(distance+0.001))
self.rect.centery += int(self.speed * distanceY /(distance+0.001))
#Update frame
if distanceX > 0:
self.images = self.images_right
else:
self.images = self.images_left
self.current_time += dt
if self.current_time >= self.animation_time:
self.current_time = 0
self.index = (self.index + 1) % len(self.images)
self.image = self.images[self.index]
class Bullet(pygame.sprite.Sprite):
"""
after the hero fire, bullet will fly toward the direction set by the arrow key
Attributes:
update: move method
"""
def __init__(self, x, y, pic, dir):
pygame.sprite.Sprite.__init__(self)
self.image = pic #Initialise the image of bullet
self.speed = 40 #the speed of bullet
self.rect = self.image.get_rect()
#Initialise the direction and original position of bullet
if dir == 1: #up
self.vel = (0, -1)
self.rect.centerx = x
self.rect.bottom = y
elif dir == 2: #down
self.vel = (0, 1)
self.rect.centerx = x
self.rect.top = y
elif dir == 3: #left
self.vel = (-1, 0)
self.rect.centery = y
self.rect.right = x
elif dir == 4: #right
self.vel = (1,0)
self.rect.centery = y
self.rect.left = x
def update(self,dt): #Update the position of bullet
self.rect.move_ip(int(self.speed * self.vel[0]), int(self.speed * self.vel[1]))
class gate(pygame.sprite.Sprite):
"""
sprite used to represent teleport gate (sprite adopted for collision detection)
"""
def __init__(self, pic, x, y):
super().__init__()
self.image = pic
self.rect = self.image.get_rect()
self.x = x
self.y = y
def update(self, dt):
self.rect.centerx = self.x
self.rect.bottom = self.y
class treasure(pygame.sprite.Sprite):
"""
sprite used to represent weapon upgrade and chest that will generate props
"""
def __init__(self,pic,x,y):
super().__init__()
self.image = pic
self.rect = self.image.get_rect()
self.rect.centerx = x #position of the props
self.rect.centery = y
tickfont = pygame.font.Font(None, 40)
boundaryx = (170,920)
boundaryy = (170,510)
mode = ‘normal‘
diesound_play = False
while True:
level = 1
main_menu()
if mode == ‘normal‘:
hero_health = 5
boss_health = 5
#the number of enemy in each level
l1_enemy = random.randint(4,6)
l2_enemy = random.randint(5,8)
l3_enemy = random.randint(1,3)
elif mode == ‘difficult‘:
hero_health = 3
boss_health = 10
l1_enemy = random.randint(5,8)
l2_enemy = random.randint(8,12)
l3_enemy = random.randint(3,6)
#load sprites
gate1 = gate(gatei1, 454, 180)
gate2 = gate(gatei1, 674, 180)
gate3 = gate(gatei1, 450, 180)
fake_gate = gate(gatei1, 10, 300)
hero = Hero((100, 300), heroimages)
all_sprites = pygame.sprite.Group(hero)
bullets = pygame.sprite.Group()
mobs = pygame.sprite.Group()
boss1 = Boss(bossimages, boss_health, 10)
chest1= treasure(chest,600,260)
chest2 = treasure(weapon,random.randrange(boundaryx[0],boundaryx[1]),random.randrange(boundaryy[0],boundaryy[1]))
# game start
background_i = background
gen_enemy(l1_enemy)
pygame.mixer.music.play(-1)
# time limit conditions
timelimit = (l1_enemy + l2_enemy + l3_enemy + boss1.health + 10) * 2000 #set time limit(millisecond) in the battle levels
clock_limit = pygame.time.Clock()
ticks = 0
timewarning = 5 # set the play times of time warning music
while True:
#Quit method
for event in pygame.event.get():
if event.type == pygame.QUIT:
os._exit(0)
#Game Loop
clock.tick(FPS)
all_sprites.update(dt)
screen.blit(background_i, (0, 0))
draw_hero_health(str(hero.health))
all_sprites.draw(screen)
#Display time remaining
if level < 4 and hero.health != 0: #count down
clock_limit.tick()
ticks += clock_limit.get_time()
ticktock(timelimit, ticks, tickfont) #update the time left
if timewarning > 0 and (timelimit-ticks)/(timewarning*1000) <= 1:
time_limit.play()
timewarning -= 1
if ticks >= timelimit: #hero die if exceed the time limit
hero.health = 0
#if a bullet hits an enemy
if len(pygame.sprite.groupcollide(mobs, bullets, True, True)) != 0:
die_sound.play()
#if hero get hit by an enemy
if len(pygame.sprite.spritecollide(hero, mobs, True)) != 0:
die_sound.play()
hero.health -= 1
#if hero died, play sound
if hero.health <= 0 and not diesound_play:
boss_entry.play()
boss_entry.play()
diesound_play = True
#restart the game
if hero.health <= 0 and diesound_play:
all_sprites.empty()
screen.blit(die_image, (0, 0))
level = 1
pygame.mixer.music.stop()
if pygame.key.get_pressed()[pygame.K_RETURN]:
diesound_play = False
break
#First level
if len(mobs.sprites()) < 1 and level == 1:#clear the first level
all_sprites.add(gate1)
if pygame.sprite.collide_rect(hero, gate1):#teleport to next level
bullets.empty()
background_i = background2
all_sprites.add(fake_gate)
hero.rect.center = (10, 280)
gate1.rect.centerx = 18000
gate1.kill()
gen_enemy(l2_enemy)
level = 2
#Level 2, opportunity to upgrade weapon after clear the stage
if len(mobs.sprites()) < 1 and level == 2:
fake_gate.kill()
all_sprites.add(gate2)
screen.blit(warning_img, (285, 230))
pygame.mixer.music.stop()
all_sprites.add(chest2)
if pygame.sprite.collide_rect(hero, chest2):
screen.blit(warning_img, (285, 230))
hero.bull_image = bull2
level_up.play()
chest2.kill()
level=2.2
elif pygame.sprite.collide_rect(hero, gate2):
level = 2.2
#Teleport to Boss scene, set background pic and music
if level == 2.2:
screen.blit(warning_img, (285, 230))
if pygame.sprite.collide_rect(hero, gate2):
chest2.kill()
gate2.kill()
bullets.empty()
background_i = background3
hero.rect.center = (10, 280)
all_sprites.add(boss1)
all_sprites.add(fake_gate)
gen_enemy(l3_enemy)
boss_entry.play()
pygame.mixer.music.load(boss_bgm)
pygame.mixer.music.play(-1)
level = 3
#Level 3, boss scene
if level == 3:
draw_boss_health(boss1.health)
if pygame.sprite.collide_rect(hero, boss1):
hero.health = 0
if len(pygame.sprite.spritecollide(boss1, bullets, True)) != 0:
boss1.health -= 1
boss_entry.play()
if boss1.health <= 0:
boss1.kill()
all_sprites.remove(mobs, bullets)
mobs.empty()
fake_gate.kill()
boss_die.play()
boss_die.play()
boss_die.play()
level = 3.1
#Teleport to next level
if level == 3.1:
all_sprites.add(gate3)
if pygame.sprite.collide_rect(hero, gate3):
gate3.kill()
background_i = background4
hero.rect.center = (40,280)
level = 4
#Level 4, Treasure Cave
if level == 4:
all_sprites.add(chest1)
if pygame.sprite.collide_rect(hero,chest1):
open_chest.play()
chest1.kill()
level = 5
pygame.time.delay(500)
#Level 5, final scene of the game
if level == 5:
screen.blit(final1,(0,0))
if pygame.key.get_pressed()[pygame.K_RETURN]:
pygame.mixer.music.stop()
break
pygame.display.update()
标签:direct ber vector ini click pow clear raw and
原文地址:https://www.cnblogs.com/Stephanie-boke/p/12444208.html