This commit is contained in:
Luthics 2023-07-07 15:33:48 +08:00
parent 20042416f6
commit fa0f8a1a4f
11 changed files with 505 additions and 59 deletions

BIN
assets/Minecraft.ttf Normal file

Binary file not shown.

BIN
assets/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
assets/enemy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

46
day2/Shield.py Normal file
View File

@ -0,0 +1,46 @@
import pygame
import math
class Shield(pygame.sprite.Sprite):
def __init__(self, player):
super().__init__()
self.player = player
self.radius = 16
self.arc_angle = 90
self.start_angle = 0
self.shield_image = pygame.Surface(
(self.radius*2, self.radius*2), pygame.SRCALPHA)
self.color = (0, 255, 0)
self.update_shield_image()
def update_shield_image(self):
self.shield_image.fill((0, 0, 0, 0)) # 透明背景
pygame.draw.arc(self.shield_image, self.color, self.shield_image.get_rect(), math.radians(
self.start_angle), math.radians(self.start_angle + self.arc_angle), self.radius)
def generate(self):
self.player_group = pygame.sprite.Group()
self.player_group.add(self.player)
# 根据玩家的位置和护盾角度调整护盾的位置和角度
self.rect = self.shield_image.get_rect(center=self.player.rect.center)
self.rect.x -= self.radius
self.rect.y -= self.radius
self.rotate_shield()
def rotate_shield(self):
rotated_image = pygame.transform.rotate(
self.shield_image, self.player.toword_angle)
self.image = pygame.Surface(rotated_image.get_size(), pygame.SRCALPHA)
self.image.blit(rotated_image, (0, 0))
self.mask = pygame.mask.from_surface(self.image)
def damage(self):
self.arc_angle -= 90
self.start_angle += 90
if self.arc_angle <= 0:
self.kill()
else:
self.update_shield_image()
self.rotate_shield()

Binary file not shown.

458
day2/main.py Normal file
View File

@ -0,0 +1,458 @@
# coding = utf-8
import pygame
import sys
import math
import random
from pygame.sprite import Sprite
from pygame.sprite import Group
from Shield import Shield
class Map:
def __init__(self, width, height, tile_size=40):
self.width = width
self.height = height
self.tile_size = tile_size
self.tiles = []
self.circle = [0, 0, 0, 0]
self.circle_r = 200
def render(self, screen):
colors = {
0: (242, 234, 211), # 浅色
1: (255, 0, 0), # 红色
2: (0, 0, 255) # 蓝色
}
for y in range(self.height):
for x in range(self.width):
tile_type = self.tiles[y][x]
tile_color = colors.get(tile_type, (255, 255, 255)) # 默认为白色
rect = pygame.Rect(x * self.tile_size, y *
self.tile_size, self.tile_size, self.tile_size)
pygame.draw.rect(screen, tile_color, rect)
# 画圆
# 如果全部为1
if self.circle[0] == 1 and self.circle[1] == 1 and self.circle[2] == 1 and self.circle[3] == 1:
pygame.draw.circle(screen, (0, 255, 0), (400, 300), self.circle_r)
else:
for i in range(4):
if self.circle[i] == 1:
# 从 90*i 开始画,画 90 度
pygame.draw.arc(screen, (255, 255, 255), (400 - self.circle_r, 300 - self.circle_r, self.circle_r * 2, self.circle_r * 2),
math.radians(90 * i), math.radians(90 * (i + 1)), 4)
# 画两个边
pygame.draw.line(screen, (255, 255, 255), (400, 300), (400 + self.circle_r * math.cos(math.radians(90 * i)),
300 - self.circle_r * math.sin(math.radians(90 * i))), 4)
pygame.draw.line(screen, (255, 255, 255), (400, 300), (400 + self.circle_r * math.cos(math.radians(90 * (i + 1))),
300 - self.circle_r * math.sin(math.radians(90 * (i + 1)))), 4)
def generate_map(self):
# 先生成一个空的二维数组
self.tiles = []
for y in range(self.height):
row = []
for x in range(self.width):
row.append(random.randint(-1, 1))
self.tiles.append(row)
for y in range(self.height):
for x in range(self.width):
self.tiles[y][x] = self.map_func(x, y)
def map_func(self, x, y):
neighbors_weights = [
self.get_tile_weight(x-1, y),
self.get_tile_weight(x+1, y),
self.get_tile_weight(x, y-1),
self.get_tile_weight(x, y+1)
]
weight_sum = sum(neighbors_weights)/4 + random.uniform(-0.3, 0.3)
tile_type = 0 # 默认为绿色
# 最外面一圈默认为红色
if x == 0 or y == 0 or x == self.width - 1 or y == self.height - 1:
tile_type = 1
# 每隔4个格子随机出现一个蓝色格子
elif random.random() < 0.01:
tile_type = 2
return tile_type
def get_tile_weight(self, x, y):
if x < 0 or y < 0 or x >= self.width or y >= self.height:
return 0 # 超出地图边界默认权重为0
return self.tiles[y][x]
class Bullet(pygame.sprite.Sprite):
def __init__(self, position, direction, color, owner, speed=8):
super().__init__()
# 使用SRCALPHA色彩格式创建Surface对象
self.image = pygame.Surface((16, 16), pygame.SRCALPHA)
self.image.fill(color)
# pygame.draw.line(self.image, (255, 255, 255), (0, 15), (32, 15), 4)
# pygame.draw.line(self.image, (255, 255, 255), (15, 0), (15, 32), 4)
self.rect = self.image.get_rect()
self.rect.center = position
self.direction = direction
self.speed = speed
self.owner = owner
self.collision_rect = pygame.Rect(
self.rect.x, self.rect.y, self.rect.width, self.rect.height)
def update(self):
dx = math.cos(math.radians(self.direction)) * self.speed
dy = -math.sin(math.radians(self.direction)) * self.speed
self.rect.x += dx
self.rect.y += dy
self.collision_rect.x = self.rect.x
self.collision_rect.y = self.rect.y
class Mysprite(Sprite):
def __init__(self, id, bot=False):
super().__init__()
if(bot):
self.mast_image = pygame.image.load('./assets/enemy.png')
else :
self.mast_image = pygame.image.load('./assets/cat.png') # 读取图像
self.original_image = self.mast_image.copy()
self.rect = self.mast_image.get_rect(height=32, width=32) # 获取图像矩形参数
self.frame_rect = self.rect.copy() # 声明框架参数
self.rect.x, self.rect.y = 400, 300
# self.frame_rect.width /= 1
# self.frame_rect.height /= 4
self.id = id
self.frame = 0
self.last_frame = (self.rect.height // self.frame_rect.height) - 1
self.old_frame = 1
self.last_time = 0
self.speed = 4
self.direction = 1
self.toword_angle = 0
self.hp = 10
self.move_directions = []
self.collision_rect = pygame.Rect(
self.rect.x, self.rect.y, self.rect.width, self.rect.height)
self.last_use_time = 0
self.click_move = False
self.click_move_x = 0
self.click_move_y = 0
self.bot = bot
self.cool_down = 500
self.hurt_time = 0
def update(self, current_time, rate=100):
if current_time >= self.last_time + rate:
self.frame += 1
if self.frame > self.last_frame:
self.frame = 0
self.last_time = current_time
if self.bot:
self.bot_update()
current_time = pygame.time.get_ticks()
if current_time - self.hurt_time < 100:
overlay = pygame.Surface(self.image.get_size())
overlay.fill((255, 0, 0, 25))
self.image.blit(overlay, (0, 0),
special_flags=pygame.BLEND_MULT)
else:
self.image = self.original_image.copy()
if self.old_frame != self.frame:
self.frame_rect.x = (self.frame // 4) * self.frame_rect.width
self.frame_rect.y = (self.frame % 4) * self.frame_rect.height
self.old_frame = self.frame
if self.direction == 1:
self.frame_rect.y = 0 # 向上
elif self.direction == 2:
self.frame_rect.y = self.frame_rect.height # 向下
elif self.direction == 3:
self.frame_rect.y = self.frame_rect.height * 2 # 向左
elif self.direction == 4:
self.frame_rect.y = self.frame_rect.height * 3 # 向右
self.updatemove()
self.image = self.mast_image.subsurface(self.frame_rect) # 这里就是在生成子表面
self.collision_rect.x = self.rect.x
self.collision_rect.y = self.rect.y
def attack(self):
# 发射子弹
# 随机生成一个颜色
color = (random.randint(0, 255), random.randint(
0, 255), random.randint(0, 255))
bullet = Bullet(self.rect.center, self.toword_angle, color, self)
bullet_group.add(bullet)
def bot_update(self):
# bot 的更新逻辑
# 随机移动
if random.random() < 0.05:
self.startmove(random.choice(['left', 'right', 'up', 'down']))
if random.random() < 0.1:
self.stopmove(random.choice(['left', 'right', 'up', 'down']))
if random.random() < 0.01:
self.attack()
if random.random() < 0.01:
self.flash()
def be_hit(self, attacker=None):
self.hp -= 1
self.hurt_time = pygame.time.get_ticks()
if self.hp <= 0:
if(attacker != None):
if(attacker.bot == False):
attacker.hp += 10
attacker.cool_down = max(0, attacker.cool_down - 25)
self.kill()
def updatemove(self):
dx = 0
dy = 0
if(self.click_move):
# 判断是否到达目标点
if(abs(self.rect.centerx - self.click_move_x) < 3 and abs(self.rect.centery - self.click_move_y) < 3):
self.click_move = False
else:
self.move(self.click_move_x - self.rect.centerx,
self.click_move_y - self.rect.centery)
return
if 'left' in self.move_directions:
dx -= 1
if 'right' in self.move_directions:
dx += 1
if 'up' in self.move_directions:
dy -= 1
if 'down' in self.move_directions:
dy += 1
self.move(dx, dy)
# 三角函数
def clickmove(self, x, y):
self.click_move = True
self.click_move_x = x
self.click_move_y = y
def move(self, dx, dy):
if dx != 0 or dy != 0:
angle = math.atan2(-dy, dx)
self.rect.x += self.speed * math.cos(angle)
if(self.rect.x < 0):
self.rect.x = 0
elif(self.rect.x + self.rect.width > 800):
self.rect.x = 800 - self.rect.width
self.rect.y -= self.speed * math.sin(angle)
if(self.rect.y < 0):
self.rect.y = 0
elif(self.rect.y + self.rect.height > 600):
self.rect.y = 600 - self.rect.height
# 判断是否和其他玩家碰撞
for player in group.sprites():
if player.id != self.id:
if self.collision_rect.colliderect(player.collision_rect):
self.rect.x -= self.speed * math.cos(angle)
self.rect.y += self.speed * math.sin(angle)
self.resetmove()
break
for enemy in enemy_group.sprites():
if self.collision_rect.colliderect(enemy.collision_rect):
self.rect.x -= self.speed * math.cos(angle)
self.rect.y += self.speed * math.sin(angle)
self.resetmove()
break
self.toword_angle = math.degrees(angle)
if(dy < 0):
self.direction = 4
elif(dy > 0):
self.direction = 1
if(dx < 0):
self.direction = 2
elif(dx > 0):
self.direction = 3
def resetmove(self):
self.move_directions = []
def startmove(self, direction):
self.click_move = False
self.move_directions.append(direction)
def stopmove(self, direction):
if direction in self.move_directions:
self.move_directions.remove(direction)
def flash(self):
if pygame.time.get_ticks() - self.last_use_time < self.cool_down:
return
self.last_use_time = pygame.time.get_ticks()
for i in range(4):
color = (random.randint(0, 255), random.randint(
0, 255), random.randint(0, 255))
bullet = Bullet(self.rect.center,
self.toword_angle + i * 30 - 45, color, self, 16)
bullet_group.add(bullet)
pygame.init()
font = pygame.font.Font("./assets/MineCraft.ttf", 24)
screen = pygame.display.set_mode((800, 600))
color = (255, 255, 255)
tick = pygame.time.Clock() # 第一行初始化了一个Clock对象
player1 = Mysprite(1)
player2 = Mysprite(2)
group = Group()
bullet_group = Group()
shields = pygame.sprite.Group()
shield1 = Shield(player1)
shield2 = Shield(player2)
shields.add(shield1)
shields.add(shield2)
group.add(player1)
group.add(player2)
player1.rect.center = (200, 300)
player2.rect.center = (600, 300)
enemy_group = pygame.sprite.Group()
enemy_timer_interval = 5000
enemy_timer_event = pygame.USEREVENT + 1
pygame.time.set_timer(enemy_timer_event, enemy_timer_interval)
map_tile_size = 8
map_width = screen.get_width() // map_tile_size
map_height = screen.get_height() // map_tile_size
map_obj = Map(map_width, map_height, map_tile_size)
map_obj.generate_map()
while True:
tick.tick(60) # 给tick方法加上的参数就成为了游戏绘制的最大帧率
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN: # 键盘事件
if player1 in group:
if event.key == pygame.K_a:
player1.startmove('left')
elif event.key == pygame.K_d:
player1.startmove('right')
elif event.key == pygame.K_w:
player1.startmove('up')
elif event.key == pygame.K_s:
player1.startmove('down')
elif event.key == pygame.K_v:
player1.attack()
elif event.key == pygame.K_b:
player1.flash()
if player2 in group:
if event.key == pygame.K_LEFT:
player2.startmove('left')
elif event.key == pygame.K_RIGHT:
player2.startmove('right')
elif event.key == pygame.K_UP:
player2.startmove('up')
elif event.key == pygame.K_DOWN:
player2.startmove('down')
elif event.key == pygame.K_COMMA:
player2.attack()
elif event.key == pygame.K_PERIOD:
player2.flash()
elif event.key == pygame.K_1:
map_obj.circle[0] = 1 - map_obj.circle[0]
elif event.key == pygame.K_2:
map_obj.circle[1] = 1 - map_obj.circle[1]
elif event.key == pygame.K_3:
map_obj.circle[2] = 1 - map_obj.circle[2]
elif event.key == pygame.K_4:
map_obj.circle[3] = 1 - map_obj.circle[3]
elif event.type == pygame.KEYUP:
if player1 in group:
if event.key == pygame.K_a:
player1.stopmove('left')
elif event.key == pygame.K_d:
player1.stopmove('right')
elif event.key == pygame.K_w:
player1.stopmove('up')
elif event.key == pygame.K_s:
player1.stopmove('down')
if player2 in group:
if event.key == pygame.K_LEFT:
player2.stopmove('left')
elif event.key == pygame.K_RIGHT:
player2.stopmove('right')
elif event.key == pygame.K_UP:
player2.stopmove('up')
elif event.key == pygame.K_DOWN:
player2.stopmove('down')
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
player1.clickmove(event.pos[0], event.pos[1])
elif event.button == 3:
player2.clickmove(event.pos[0], event.pos[1])
if event.type == enemy_timer_event:
enemy = Mysprite(len(enemy_group.sprites()) + 3, True)
enemy.rect.center = (random.randint(0, 800),
random.randint(0, 600))
enemy_group.add(enemy)
screen.fill(color)
ticks = pygame.time.get_ticks()
map_obj.render(screen)
group.update(ticks)
bullet_group.update()
enemy_group.update(ticks)
# shields.update()
group.draw(screen)
bullet_group.draw(screen)
enemy_group.draw(screen)
# shields.draw(screen)
if player1 in group:
if player1.hp > 0:
# 左上角血量显示
player1_hp_text = font.render(
"HP " + str(player1.hp), True, (0, 0, 0))
screen.blit(player1_hp_text, (10, 10))
# 下面是技能冷却时间显示,显示一个条形,总宽度 100px
if pygame.time.get_ticks() - player1.last_use_time < 500:
pygame.draw.rect(screen, (255, 255, 0), (10, 30, 100, 10))
# 从左向右
pygame.draw.rect(screen, (0, 128, 255), (10, 30, (pygame.time.get_ticks() -
player1.last_use_time) / 5, 10))
else:
pygame.draw.rect(screen, (0, 128, 255), (10, 30, 100, 10))
if player2 in group:
if player2.hp > 0:
# 右上角血量显示
player2_hp_text = font.render(
"HP " + str(player2.hp), True, (0, 0, 0))
hp_text_width = player2_hp_text.get_width()
screen.blit(player2_hp_text,
(screen.get_width() - hp_text_width - 10, 10))
# 下面是技能冷却时间显示,显示一个条形,总宽度 100px
if pygame.time.get_ticks() - player2.last_use_time < 500:
pygame.draw.rect(screen, (255, 255, 0),
(screen.get_width() - 110, 30, 100, 10))
# 从右向左
pygame.draw.rect(screen, (0, 128, 255), (screen.get_width() - 110 + 100 - (pygame.time.get_ticks() -
player2.last_use_time) / 5, 30, (pygame.time.get_ticks() - player2.last_use_time) / 5, 10))
else:
pygame.draw.rect(screen, (0, 128, 255),
(screen.get_width() - 110, 30, 100, 10))
for bullet in bullet_group.sprites():
for player in group.sprites():
if bullet.collision_rect.colliderect(player.collision_rect) and bullet.owner.id != player.id:
player.be_hit()
bullet.kill()
for enemy in enemy_group.sprites():
if bullet.collision_rect.colliderect(enemy.collision_rect) and bullet.owner.bot != True:
enemy.be_hit(bullet.owner)
bullet.kill()
pygame.display.update()
pygame.event.pump()

BIN
day2/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

BIN
day2/sprite.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1 @@
OWN

0
day4/main.py Normal file
View File

59
main.py
View File

@ -1,59 +0,0 @@
import pygame
# 初始化pygame
pygame.init()
# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
# 设置窗口大小和标题
size = (700, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Pygame光波")
# 循环标志
done = False
# 时钟对象
clock = pygame.time.Clock()
# 圆心位置列表和半径列表
circles = []
# 游戏循环
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
# 当左键被按下时,将圆心位置和半径保存到列表中
circle_pos = event.pos
circle_radius = 1
circles.append((circle_pos, circle_radius))
# 填充背景色
screen.fill(BLACK)
# 遍历圆心位置列表,绘制每一个光波
for pos, radius in circles:
pygame.draw.circle(screen, YELLOW, pos, radius, 5)
radius += 5
# 如果圆的半径已经大于一定值,从列表中删除该光波
if radius > 200:
circles.remove((pos, radius))
# 更新圆的半径
else:
circles[circles.index((pos, radius))] = (pos, radius)
# 更新屏幕
pygame.display.flip()
# 控制帧率
clock.tick(60)
# 退出游戏
pygame.quit()