Python-炸弹人【附完整源码】

news2025/1/11 20:40:22

炸弹人

炸弹人是童年的一款经典电子游戏,玩家控制一个类似"炸弹人"的角色,这个角色可以放置炸弹,并在指定的时间内引爆它们消灭敌人以达到目标,此游戏共设有两节关卡,代码如下:

运行效果:方向键控制上下左右, 点击空格键丢炸弹
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一:主程序:

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

'''游戏主程序'''
def main(cfg):
    # 初始化
    pygame.init()
    pygame.mixer.init()
    pygame.mixer.music.load(cfg.BGMPATH)
    pygame.mixer.music.play(-1, 0.0)
    screen = pygame.display.set_mode(cfg.SCREENSIZE)
    pygame.display.set_caption('炸弹人')
    # 开始界面
    Interface(screen, cfg, mode='game_start')
    # 游戏主循环
    font = pygame.font.SysFont('Consolas', 15)
    for gamemap_path in cfg.GAMEMAPPATHS:
        # -地图
        map_parser = mapParser(gamemap_path, bg_paths=cfg.BACKGROUNDPATHS, wall_paths=cfg.WALLPATHS, blocksize=cfg.BLOCKSIZE)
        # -水果
        fruit_sprite_group = pygame.sprite.Group()
        used_spaces = []
        for i in range(5):
            coordinate = map_parser.randomGetSpace(used_spaces)
            used_spaces.append(coordinate)
            fruit_sprite_group.add(Fruit(random.choice(cfg.FRUITPATHS), coordinate=coordinate, blocksize=cfg.BLOCKSIZE))
        # -我方Hero
        coordinate = map_parser.randomGetSpace(used_spaces)
        used_spaces.append(coordinate)
        ourhero = Hero(imagepaths=cfg.HEROZELDAPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='ZELDA')
        # -电脑Hero
        aihero_sprite_group = pygame.sprite.Group()
        coordinate = map_parser.randomGetSpace(used_spaces)
        aihero_sprite_group.add(Hero(imagepaths=cfg.HEROBATMANPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='BATMAN'))
        used_spaces.append(coordinate)
        coordinate = map_parser.randomGetSpace(used_spaces)
        aihero_sprite_group.add(Hero(imagepaths=cfg.HERODKPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='DK'))
        used_spaces.append(coordinate)
        # -炸弹bomb
        bomb_sprite_group = pygame.sprite.Group()
        # -用于判断游戏胜利或者失败的flag
        is_win_flag = False
        # -主循环
        screen = pygame.display.set_mode(map_parser.screen_size)
        clock = pygame.time.Clock()
        while True:
            dt = clock.tick(cfg.FPS)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit(-1)
                # --↑↓←→键控制上下左右, 空格键丢炸弹
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        ourhero.move('up')
                    elif event.key == pygame.K_DOWN:
                        ourhero.move('down')
                    elif event.key == pygame.K_LEFT:
                        ourhero.move('left')
                    elif event.key == pygame.K_RIGHT:
                        ourhero.move('right')
                    elif event.key == pygame.K_SPACE:
                        if ourhero.bomb_cooling_count <= 0:
                            bomb_sprite_group.add(ourhero.generateBomb(imagepath=cfg.BOMBPATH, digitalcolor=cfg.YELLOW, explode_imagepath=cfg.FIREPATH))
            screen.fill(cfg.WHITE)
            # --电脑Hero随机行动
            for hero in aihero_sprite_group:
                action, flag = hero.randomAction(dt)
                if flag and action == 'dropbomb':
                    bomb_sprite_group.add(hero.generateBomb(imagepath=cfg.BOMBPATH, digitalcolor=cfg.YELLOW, explode_imagepath=cfg.FIREPATH))
            # --吃到水果加生命值(只要是Hero, 都能加)
            ourhero.eatFruit(fruit_sprite_group)
            for hero in aihero_sprite_group:
                hero.eatFruit(fruit_sprite_group)
            # --游戏元素都绑定到屏幕上
            map_parser.draw(screen)
            for bomb in bomb_sprite_group:
                if not bomb.is_being:
                    bomb_sprite_group.remove(bomb)
                explode_area = bomb.draw(screen, dt, map_parser)
                if explode_area:
                    # --爆炸火焰范围内的Hero生命值将持续下降
                    if ourhero.coordinate in explode_area:
                        ourhero.health_value -= bomb.harm_value
                    for hero in aihero_sprite_group:
                        if hero.coordinate in explode_area:
                            hero.health_value -= bomb.harm_value
            fruit_sprite_group.draw(screen)
            for hero in aihero_sprite_group:
                hero.draw(screen, dt)
            ourhero.draw(screen, dt)
            # --左上角显示生命值
            pos_x = showText(screen, font, text=ourhero.hero_name+'(our):'+str(ourhero.health_value), color=cfg.YELLOW, position=[5, 5])
            for hero in aihero_sprite_group:
                pos_x, pos_y = pos_x+15, 5
                pos_x = showText(screen, font, text=hero.hero_name+'(ai):'+str(hero.health_value), color=cfg.YELLOW, position=[pos_x, pos_y])
            # --我方玩家生命值小于等于0/电脑方玩家生命值均小于等于0则判断游戏结束
            if ourhero.health_value <= 0:
                is_win_flag = False
                break
            for hero in aihero_sprite_group:
                if hero.health_value <= 0:
                    aihero_sprite_group.remove(hero)
            if len(aihero_sprite_group) == 0:
                is_win_flag = True
                break
            pygame.display.update()
            clock.tick(cfg.FPS)
        if is_win_flag:
            Interface(screen, cfg, mode='game_switch')
        else:
            break
    Interface(screen, cfg, mode='game_end')


'''run'''
if __name__ == '__main__':
    while True:
        main(cfg)

二:配置文件 – cfg.py

import os

'''屏幕大小'''
SCREENSIZE = (640, 480)
'''块大小'''
BLOCKSIZE = 30
'''FPS'''
FPS = 30
'''游戏地图路径'''
GAMEMAPPATHS = [os.path.join(os.getcwd(), path) for path in \
    ['resources/maps/1.map', 'resources/maps/2.map']]
'''墙路径'''
WALLPATHS = [os.path.join(os.getcwd(), path) for path in \
    ['resources/images/misc/wall0.png', 'resources/images/misc/wall1.png', 'resources/images/misc/wall2.png']]
'''英雄路径'''
HERODKPATHS = [os.path.join(os.getcwd(), path) for path in \
    ['resources/images/dk/left.png', 'resources/images/dk/right.png', 'resources/images/dk/up.png', 'resources/images/dk/down.png']]
HEROZELDAPATHS = [os.path.join(os.getcwd(), path) for path in \
    ['resources/images/zelda/left.png', 'resources/images/zelda/right.png', 'resources/images/zelda/up.png', 'resources/images/zelda/down.png']]
HEROBATMANPATHS = [os.path.join(os.getcwd(), path) for path in \
    ['resources/images/batman/left.png', 'resources/images/batman/right.png', 'resources/images/batman/up.png', 'resources/images/batman/down.png']]
'''水果路径'''
FRUITPATHS = [os.path.join(os.getcwd(), path) for path in \
    ['resources/images/misc/banana.png', 'resources/images/misc/cherry.png']]
'''背景路径'''
BACKGROUNDPATHS = [os.path.join(os.getcwd(), path) for path in \
    ['resources/images/misc/bg0.png', 'resources/images/misc/bg1.png', 'resources/images/misc/bg2.png']]
'''爆炸和发射路径'''
BOMBPATH = os.path.join(os.getcwd(), 'resources/images/misc/bomb.png')
FIREPATH = os.path.join(os.getcwd(), 'resources/images/misc/fire.png')
'''背景音乐'''
BGMPATH = os.path.join(os.getcwd(), 'resources/audio/bgm.mp3')
'''一些颜色'''
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

三:素材包 – resources

(1)audio文件:

bgm.mps音乐大家自己去找然后设置就好

(2)images文件:

图片太多了,做不到全部放置,大家根据配置文件自己去弄就好,或者私信我,我单独给大家发

(3)maps文件:

#1.map
xxxxxxxxxxxxx
x00000000000x
x0x0x0x0x0x0x
x00000000000x
x0x0x0x0x0x0x
x00000000000x
x0x0x0x0x0x0x
x00000000000x
x0x0x0x0x0x0x
x00000000000x
xxxxxxxxxxxxx
#2.map
2222222222222222222222222
2wwwww2wwwww2wwwww2wwwww2
2222222222222222222222222
2zz2zz2x1x1x1x1x1x2zz2zz2
2zz2zz2111111111112zz2zz2
2222222x1x1x1x1x1x2222222
2wwwww2111111111112wwwww2
2222222x1x1x1x1x1x2222222
2zz2zz2111111111112zz2zz2
2zz2zz2x1x1x1x1x1x2zz2zz2
2222222222222222222222222
2wwwww2wwwww2wwwww2wwwww2
2222222222222222222222222

四:文件包 – modules

(1)__init__.py

'''初始化'''
from .MAP import mapParser
from .misc import showText, Button, Interface
from .Sprites import Wall, Background, Fruit, Bomb, Hero

(2)MAP.py

import random
from .Sprites import *

'''.map文件解析器'''
class mapParser():
	def __init__(self, mapfilepath, bg_paths, wall_paths, blocksize, **kwargs):
		self.instances_list = self.__parse(mapfilepath)
		self.bg_paths = bg_paths
		self.wall_paths = wall_paths
		self.blocksize = blocksize
		self.height = len(self.instances_list)
		self.width = len(self.instances_list[0])
		self.screen_size = (blocksize * self.width, blocksize * self.height)
	'''地图画到屏幕上'''
	def draw(self, screen):
		for j in range(self.height):
			for i in range(self.width):
				instance = self.instances_list[j][i]
				if instance == 'w':
					elem = Wall(self.wall_paths[0], [i, j], self.blocksize)
				elif instance == 'x':
					elem = Wall(self.wall_paths[1], [i, j], self.blocksize)
				elif instance == 'z':
					elem = Wall(self.wall_paths[2], [i, j], self.blocksize)
				elif instance == '0':
					elem = Background(self.bg_paths[0], [i, j], self.blocksize)
				elif instance == '1':
					elem = Background(self.bg_paths[1], [i, j], self.blocksize)
				elif instance == '2':
					elem = Background(self.bg_paths[2], [i, j], self.blocksize)
				else:
					raise ValueError('instance parse error in mapParser.draw...')
				elem.draw(screen)
	'''随机获取一个空地'''
	def randomGetSpace(self, used_spaces=None):
		while True:
			i = random.randint(0, self.width-1)
			j = random.randint(0, self.height-1)
			coordinate = [i, j]
			if used_spaces and coordinate in used_spaces:
				continue
			instance = self.instances_list[j][i]
			if instance in ['0', '1', '2']:
				break
		return coordinate
	'''根据坐标获取元素类型'''
	def getElemByCoordinate(self, coordinate):
		return self.instances_list[coordinate[1]][coordinate[0]]
	'''解析.map文件'''
	def __parse(self, mapfilepath):
		instances_list = []
		with open(mapfilepath) as f:
			for line in f.readlines():
				instances_line_list = []
				for c in line:
					if c in ['w', 'x', 'z', '0', '1', '2']:
						instances_line_list.append(c)
				instances_list.append(instances_line_list)
		return instances_list

(3)misc.py

import sys
import pygame

'''在屏幕指定位置显示文字'''
def showText(screen, font, text, color, position):
	text_render = font.render(text, True, color)
	rect = text_render.get_rect()
	rect.left, rect.top = position
	screen.blit(text_render, rect)
	return rect.right


'''按钮'''
def Button(screen, position, text, buttoncolor=(120, 120, 120), linecolor=(20, 20, 20), textcolor=(255, 255, 255), bwidth=200, bheight=50):
	left, top = position
	pygame.draw.line(screen, linecolor, (left, top), (left+bwidth, top), 5)
	pygame.draw.line(screen, linecolor, (left, top-2), (left, top+bheight), 5)
	pygame.draw.line(screen, linecolor, (left, top+bheight), (left+bwidth, top+bheight), 5)
	pygame.draw.line(screen, linecolor, (left+bwidth, top+bheight), (left+bwidth, top), 5)
	pygame.draw.rect(screen, buttoncolor, (left, top, bwidth, bheight))
	font = pygame.font.SysFont('Consolas', 30)
	text_render = font.render(text, 1, textcolor)
	rect = text_render.get_rect()
	rect.centerx, rect.centery = left + bwidth / 2, top + bheight / 2
	return screen.blit(text_render, rect)

'''游戏开始/关卡切换/游戏结束界面'''
def Interface(screen, cfg, mode='game_start'):
	pygame.display.set_mode(cfg.SCREENSIZE)
	if mode == 'game_start':
		clock = pygame.time.Clock()
		while True:
			screen.fill((41, 36, 33))
			button_1 = Button(screen, (220, 150), 'START')
			button_2 = Button(screen, (220, 250), 'QUIT')
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					pygame.quit()
					sys.exit(-1)
				elif event.type == pygame.MOUSEBUTTONDOWN:
					if button_1.collidepoint(pygame.mouse.get_pos()):
						return True
					elif button_2.collidepoint(pygame.mouse.get_pos()):
						pygame.quit()
						sys.exit(-1)
			pygame.display.update()
			clock.tick(cfg.FPS)
	elif mode == 'game_switch':
		clock = pygame.time.Clock()
		while True:
			screen.fill((41, 36, 33))
			button_1 = Button(screen, (220, 150), 'NEXT')
			button_2 = Button(screen, (220, 250), 'QUIT')
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					pygame.quit()
					sys.exit(-1)
				elif event.type == pygame.MOUSEBUTTONDOWN:
					if button_1.collidepoint(pygame.mouse.get_pos()):
						return True
					elif button_2.collidepoint(pygame.mouse.get_pos()):
						pygame.quit()
						sys.exit(-1)
			pygame.display.update()
			clock.tick(cfg.FPS)
	elif mode == 'game_end':
		clock = pygame.time.Clock()
		while True:
			screen.fill((41, 36, 33))
			button_1 = Button(screen, (220, 150), 'RESTART')
			button_2 = Button(screen, (220, 250), 'QUIT')
			for event in pygame.event.get():
				if event.type == pygame.QUIT:
					pygame.quit()
					sys.exit(-1)
				elif event.type == pygame.MOUSEBUTTONDOWN:
					if button_1.collidepoint(pygame.mouse.get_pos()):
						return True
					elif button_2.collidepoint(pygame.mouse.get_pos()):
						pygame.quit()
						sys.exit(-1)
			pygame.display.update()
			clock.tick(cfg.FPS)
	else:
		raise ValueError('Interface.mode unsupport %s...' % mode)

(4)Sprites.py

import copy
import random
import pygame

'''墙类'''
class Wall(pygame.sprite.Sprite):
	def __init__(self, imagepath, coordinate, blocksize, **kwargs):
		pygame.sprite.Sprite.__init__(self)
		self.image = pygame.image.load(imagepath)
		self.image = pygame.transform.scale(self.image, (blocksize, blocksize))
		self.rect = self.image.get_rect()
		self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize
		self.coordinate = coordinate
		self.blocksize = blocksize
	'''画到屏幕上'''
	def draw(self, screen):
		screen.blit(self.image, self.rect)
		return True


'''背景类'''
class Background(pygame.sprite.Sprite):
	def __init__(self, imagepath, coordinate, blocksize, **kwargs):
		pygame.sprite.Sprite.__init__(self)
		self.image = pygame.image.load(imagepath)
		self.image = pygame.transform.scale(self.image, (blocksize, blocksize))
		self.rect = self.image.get_rect()
		self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize
		self.coordinate = coordinate
		self.blocksize = blocksize
	'''画到屏幕上'''
	def draw(self, screen):
		screen.blit(self.image, self.rect)
		return True


'''水果类'''
class Fruit(pygame.sprite.Sprite):
	def __init__(self, imagepath, coordinate, blocksize, **kwargs):
		pygame.sprite.Sprite.__init__(self)
		self.kind = imagepath.split('/')[-1].split('.')[0]
		if self.kind == 'banana':
			self.value = 5
		elif self.kind == 'cherry':
			self.value = 10
		else:
			raise ValueError('Unknow fruit %s...' % self.kind)
		self.image = pygame.image.load(imagepath)
		self.image = pygame.transform.scale(self.image, (blocksize, blocksize))
		self.rect = self.image.get_rect()
		self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize
		self.coordinate = coordinate
		self.blocksize = blocksize
	'''画到屏幕上'''
	def draw(self, screen):
		screen.blit(self.image, self.rect)
		return True


'''炸弹类'''
class Bomb(pygame.sprite.Sprite):
	def __init__(self, imagepath, coordinate, blocksize, digitalcolor, explode_imagepath, **kwargs):
		pygame.sprite.Sprite.__init__(self)
		self.image = pygame.image.load(imagepath)
		self.image = pygame.transform.scale(self.image, (blocksize, blocksize))
		self.explode_imagepath = explode_imagepath
		self.rect = self.image.get_rect()
		# 像素位置
		self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize
		# 坐标(元素块为单位长度)
		self.coordinate = coordinate
		self.blocksize = blocksize
		# 爆炸倒计时
		self.explode_millisecond = 6000 * 1 - 1
		self.explode_second = int(self.explode_millisecond / 1000)
		self.start_explode = False
		# 爆炸持续时间
		self.exploding_count = 1000 * 1
		# 炸弹伤害能力
		self.harm_value = 1
		# 该炸弹是否还存在
		self.is_being = True
		self.font = pygame.font.SysFont('Consolas', 20)
		self.digitalcolor = digitalcolor
	'''画到屏幕上'''
	def draw(self, screen, dt, map_parser):
		if not self.start_explode:
			# 爆炸倒计时
			self.explode_millisecond -= dt
			self.explode_second = int(self.explode_millisecond / 1000)
			if self.explode_millisecond < 0:
				self.start_explode = True
			screen.blit(self.image, self.rect)
			text = self.font.render(str(self.explode_second), True, self.digitalcolor)
			rect = text.get_rect(center=(self.rect.centerx-5, self.rect.centery+5))
			screen.blit(text, rect)
			return False
		else:
			# 爆炸持续倒计时
			self.exploding_count -= dt
			if self.exploding_count > 0:
				return self.__explode(screen, map_parser)
			else:
				self.is_being = False
				return False
	'''爆炸效果'''
	def __explode(self, screen, map_parser):
		explode_area = self.__calcExplodeArea(map_parser.instances_list)
		for each in explode_area:
			image = pygame.image.load(self.explode_imagepath)
			image = pygame.transform.scale(image, (self.blocksize, self.blocksize))
			rect = image.get_rect()
			rect.left, rect.top = each[0] * self.blocksize, each[1] * self.blocksize
			screen.blit(image, rect)
		return explode_area
	'''计算爆炸区域'''
	def __calcExplodeArea(self, instances_list):
		explode_area = []
		# 区域计算规则为墙可以阻止爆炸扩散, 且爆炸范围仅在游戏地图范围内
		for ymin in range(self.coordinate[1], self.coordinate[1]-5, -1):
			if ymin < 0 or instances_list[ymin][self.coordinate[0]] in ['w', 'x', 'z']:
				break
			explode_area.append([self.coordinate[0], ymin])
		for ymax in range(self.coordinate[1]+1, self.coordinate[1]+5):
			if ymax >= len(instances_list) or instances_list[ymax][self.coordinate[0]] in ['w', 'x', 'z']:
				break
			explode_area.append([self.coordinate[0], ymax])
		for xmin in range(self.coordinate[0], self.coordinate[0]-5, -1):
			if xmin < 0 or instances_list[self.coordinate[1]][xmin] in ['w', 'x', 'z']:
				break
			explode_area.append([xmin, self.coordinate[1]])
		for xmax in range(self.coordinate[0]+1, self.coordinate[0]+5):
			if xmax >= len(instances_list[0]) or instances_list[self.coordinate[1]][xmax] in ['w', 'x', 'z']:
				break
			explode_area.append([xmax, self.coordinate[1]])
		return explode_area


'''角色类'''
class Hero(pygame.sprite.Sprite):
	def __init__(self, imagepaths, coordinate, blocksize, map_parser, **kwargs):
		pygame.sprite.Sprite.__init__(self)
		self.imagepaths = imagepaths
		self.image = pygame.image.load(imagepaths[-1])
		self.image = pygame.transform.scale(self.image, (blocksize, blocksize))
		self.rect = self.image.get_rect()
		self.rect.left, self.rect.top = coordinate[0] * blocksize, coordinate[1] * blocksize
		self.coordinate = coordinate
		self.blocksize = blocksize
		self.map_parser = map_parser
		self.hero_name = kwargs.get('hero_name')
		# 生命值
		self.health_value = 50
		# 炸弹冷却时间
		self.bomb_cooling_time = 5000
		self.bomb_cooling_count = 0
		# 随机移动冷却时间(仅AI电脑用)
		self.randommove_cooling_time = 100
		self.randommove_cooling_count = 0
	'''角色移动'''
	def move(self, direction):
		self.__updateImage(direction)
		if direction == 'left':
			if self.coordinate[0]-1 < 0 or self.map_parser.getElemByCoordinate([self.coordinate[0]-1, self.coordinate[1]]) in ['w', 'x', 'z']:
				return False
			self.coordinate[0] = self.coordinate[0] - 1
		elif direction == 'right':
			if self.coordinate[0]+1 >= self.map_parser.width or self.map_parser.getElemByCoordinate([self.coordinate[0]+1, self.coordinate[1]]) in ['w', 'x', 'z']:
				return False
			self.coordinate[0] = self.coordinate[0] + 1
		elif direction == 'up':
			if self.coordinate[1]-1 < 0 or self.map_parser.getElemByCoordinate([self.coordinate[0], self.coordinate[1]-1]) in ['w', 'x', 'z']:
				return False
			self.coordinate[1] = self.coordinate[1] - 1
		elif direction == 'down':
			if self.coordinate[1]+1 >= self.map_parser.height or self.map_parser.getElemByCoordinate([self.coordinate[0], self.coordinate[1]+1]) in ['w', 'x', 'z']:
				return False
			self.coordinate[1] = self.coordinate[1] + 1
		else:
			raise ValueError('Unknow direction %s...' % direction)
		self.rect.left, self.rect.top = self.coordinate[0] * self.blocksize, self.coordinate[1] * self.blocksize
		return True
	'''随机行动(AI电脑用)'''
	def randomAction(self, dt):
		# 冷却倒计时
		if self.randommove_cooling_count > 0:
			self.randommove_cooling_count -= dt
		action = random.choice(['left', 'left', 'right', 'right', 'up', 'up', 'down', 'down', 'dropbomb'])
		flag = False
		if action in ['left', 'right', 'up', 'down']:
			if self.randommove_cooling_count <= 0:
				flag = True
				self.move(action)
				self.randommove_cooling_count = self.randommove_cooling_time
		elif action in ['dropbomb']:
			if self.bomb_cooling_count <= 0:
				flag = True
				self.bomb_cooling_count = self.bomb_cooling_time
		return action, flag
	'''生成炸弹'''
	def generateBomb(self, imagepath, digitalcolor, explode_imagepath):
		return Bomb(imagepath=imagepath, coordinate=copy.deepcopy(self.coordinate), blocksize=self.blocksize, digitalcolor=digitalcolor, explode_imagepath=explode_imagepath)
	'''画到屏幕上'''
	def draw(self, screen, dt):
		# 冷却倒计时
		if self.bomb_cooling_count > 0:
			self.bomb_cooling_count -= dt
		screen.blit(self.image, self.rect)
		return True
	'''吃水果'''
	def eatFruit(self, fruit_sprite_group):
		eaten_fruit = pygame.sprite.spritecollide(self, fruit_sprite_group, True, None)
		for fruit in eaten_fruit:
			self.health_value += fruit.value
	'''更新角色朝向'''
	def __updateImage(self, direction):
		directions = ['left', 'right', 'up', 'down']
		idx = directions.index(direction)
		self.image = pygame.image.load(self.imagepaths[idx])
		self.image = pygame.transform.scale(self.image, (self.blocksize, self.blocksize))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1288410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt/C++视频监控拉流显示/各种rtsp/rtmp/http视频流/摄像头采集/视频监控回放/录像存储

一、前言 本视频播放组件陆陆续续写了6年多&#xff0c;一直在持续更新迭代&#xff0c;视频监控行业客户端软件开发首要需求就是拉流显示&#xff0c;比如给定一个rtsp视频流地址&#xff0c;你需要在软件上显示实时画面&#xff0c;其次就是录像保存&#xff0c;再次就是一些…

22、pytest多个参数化的组合

官方实例 # content of test_multi_parametrie.py import pytestpytest.mark.parametrize("x",[0,1]) pytest.mark.parametrize("y",[2,3]) def test_foo(x,y):print("{}-{}".format(x,y))pass解读与实操 要获得多个参数化参数的所有组合&…

vue3里面使用ref和toRef、toRefs

vue3 里面我们经常会使用ref()来接受内部值&#xff0c;返回一个响应式的对象。创建可以使用任何类型的响应式ref。这里对象是响应式的&#xff0c;可以进行更改的&#xff0c;对象有一个value属性&#xff0c;其值就是所传递的原始值。ref() 将传入参数的值包装为一个带 .valu…

【链表Linked List】力扣-83 删除排序链表中的重复元素

目录 题目描述 解题过程 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2]示例 2&#xff1a; 输入&#xff1…

【每日OJ —— 94. 二叉树的中序遍历】

每日OJ —— 94. 二叉树的中序遍历 1.题目&#xff1a;94. 二叉树的中序遍历2.解法2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目&#xff1a;94. 二叉树的中序遍历 2.解法 2.1.算法讲解 1.首先如果在每次每个节点遍历的时候都去为数组开辟空间&#xff0c;这样的效率太低…

android开发市场被抢占,鸿蒙能入行吗?

根据最新的数据&#xff0c;华为Mate60系列在上市第二周就成功占据了国内手机市场的17%份额&#xff0c;排名第二。而机构预测&#xff0c;华为手机在第37周有望超过20%的市场份额&#xff0c;成为国内手机市场的冠军。 一开始&#xff0c;人们对HarmonyOSNEXT持保留态度&…

国产麒麟操作系统部署记录

前提&#xff1a;部署项目首先要安装各种软件&#xff0c;在内网环境下无法在线下载。 思路&#xff1a;首先部署一台能上网的系统&#xff0c;在此系统下只下载包&#xff0c;然后传到另一台内网系统下进行安装&#xff1b; 1、最开始yum未安装&#xff0c;因此需要先安装yu…

PHP短信接口防刷防轰炸多重解决方案三(可正式使用)

短信接口盗刷轰炸&#xff1a;指的是黑客利用非法手段获取短信接口的访问权限&#xff0c;然后使用该接口发送大量垃圾短信给目标用户 短信验证码轰炸解决方案一(验证码类解决)-CSDN博客 短信验证码轰炸解决方案二(防止海外ip、限制ip、限制手机号次数解决)-CSDN博客 PHP短信…

JavaScript 数组方法 reduce() 的用法

一、概述 在JavaScript中&#xff0c;reduce()方法是一个非常实用的数组方法&#xff0c;它接收一个函数作为累加器&#xff08;accumulator&#xff09;&#xff0c;数组中的每个值&#xff08;从左到右&#xff09;开始缩减&#xff0c;最终为一个值。这个方法在处理数组…

数据结构 | 二叉树的各种遍历

数据结构 | 二叉树的各种遍历 文章目录 数据结构 | 二叉树的各种遍历创建节点 && 创建树二叉树的前中后序遍历二叉树节点个数二叉树叶子节点个数二叉树第k层节点个数二叉树查找值为x的节点二叉树求树的高度二叉树的层序遍历判断二叉树是否是完全二叉树 我们本章来实现二…

【C语言】指针与数组的潜在联系

目录 前言 改变固有数组的平面思维 注意&#xff1a; 数组操作与指针等价 指针数组 数组指针 笔试加深理解&#xff1a; 解析&#xff1a; 前言 《C Traps and Pitfalls》(C语言缺陷与陷阱)中有一句著名的见解&#xff1a; “在C语言中&#xff0c;指针与数组这两个概念…

MUC\GD32低功耗模式简介

 前言 低功耗模式在现在的开发中尤为重要&#xff0c;特别是在使用电池的设备中&#xff0c;今天我们就拿GD32来聊一聊低功耗模式&#xff0c;以及他们使用的状态与唤醒方式以及耗电情况。 GD32支持的低功耗模式&#xff1a;  省电模式 MCU支持三种省电模式&#xff0…

SpringBoot3-创建自定义启动器,使用自定义starter启动器

1、创建自定义启动工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.a…

647. Palindromic Substrings 516. Longest Palindromic Subsequence

647. Palindromic Substrings Given a string s, return the number of palindromic substrings 回文子串 in it. A string is a palindrome when it reads the same backward as forward. A substring is a contiguous sequence of characters within the string. nomal: …

Hello World!

一、minist数据集 深度学习编程特有的hello world程序&#xff1a;采用minist数据集完成意向特定深度学习项目 1、minist数据集介绍 MNIST数据集是一个广泛使用的手写数字识别数据集&#xff0c;它包含了许多不同人手写的数字图片。这个数据集被广泛用于研究手写数字识别&…

文件上传漏洞(带实例)

漏洞介绍&#xff1a; 现代互联网的Web应用程序中&#xff0c;上传文件是一种常见的功能&#xff0c;因为它有助于提高业务效率&#xff0c;如企业的OA系统&#xff0c;允许用户上传图片&#xff0c;视频&#xff0c;头像和许多其他类型的文件。然而向用户提供的功能越多&#…

海外服务器和国内服务器有什么样的区别呢

海外服务器和国内服务器有什么样的区别呢&#xff0c;其实呢在外形方面是大同小异&#xff0c;除了外形还有一些其他方面还存在这一些差异。 一&#xff0c;地理位置的差异。 海外服务器——有可能在中国数据中心之外的任何国家地区&#xff0c;例如美国服务器&#xff0c;韩…

深度解析IP应用场景API:提升风险控制与反欺诈能力

前言 在当今数字化时代&#xff0c;网络安全和用户数据保护成为企业日益关注的焦点。IP应用场景API作为一种强大的工具&#xff0c;不仅能够在线调用接口获取IP场景属性&#xff0c;而且具备识别IP真人度的能力&#xff0c;为企业提供了卓越的风险控制和反欺诈业务能力。本文将…

企业如何结合数字化技术实现精益生产

企业要想长远良性发展&#xff0c;就必须不断追求生产效率的极致&#xff0c;才能不断对抗各方各面带来的压力。结合国家大环境趋势&#xff0c;绿色生产已然成为了国家关注的重点&#xff0c;所以老旧耗能的企业生产模式注定会被时代所淘汰。企业只有紧跟国家的发展步伐&#…

Mysql分布式集群部署---MySQL集群Cluster将数据分成多个片段,每个片段存储在不同的服务器上

1.1 目的 部署MysqlCluster集群环境 1.2 MySQL集群Cluster原理 1 数据分片 MySQL集群Cluster将数据分成多个片段&#xff0c;每个片段存储在不同的服务器上。这样可以将数据负载分散到多个服务器上&#xff0c;提高系统的性能和可扩展性。 2. 数据同步 MySQL集群Cluster使…