pygame制作第一天
截个图
首先还是黑屏哈。后面找时间慢慢做地图跟其他角色,还有攻击方式等。
这里先做了一个"炫酷"的雨云召唤技能。
人物可以移动,g键召唤持续10秒的跟随目标的雨云。角色会被雨滴攻击。
思路很重要,不然数据传递就乱了。
雨滴是单个的,与其他元素无关(除了要传入攻击目标)。
云里面生成雨滴对象的集合,雨滴的x范围在与的[x,x+cloud.width]内
云需要跟随目标(这里暂定是玩家自己)需要定义其x,y的速度,以及方向。
人物我做了个基类charactor,玩家player继承基类。未雨绸缪哈
python
class Charactor(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def attack(self):
pass
def update(self, keys):
pass
def draw_damage(self, damage, window):
pass
def draw(self, delta, window):
pass
python
import pygame
from cloud import Cloud
from settings import *
from charactor import Charactor
class Player(Charactor):
def __init__(self):
super().__init__()
self.hp = 100
self.x_speed = person_x_speed
self.y_speed = person_y_speed
self.facing = {
'right': True,
"left": False,
'up': False,
'down': False
}
self.pre_facing = 'right'
self.peron_down_walk_images = peron_down_walk_images
self.peron_up_walk_images = peron_up_walk_images
self.peron_right_walk_images = peron_right_walk_images
self.peron_left_walk_images = peron_left_walk_images
self.image_index = 0
self.image = peron_down_walk_images[self.image_index]
self.width = peron_down_walk_images[self.image_index].get_width()
self.height = peron_down_walk_images[self.image_index].get_height()
self.hit_by_raindrop = 0
self.font = pygame.font.Font(None, 36)
self.get_damage = 0 # 受到伤害
self.get_damage_text = None # 受到伤害文本
self.time_counter = 0 # 计时器
self.skills = {
'g': {'status': False,
'cloud': Cloud(self.x, self.y - 200),
'exist_time': 10,
}
}
def update(self, keys):
if keys[pygame.K_a]:
self.x -= self.x_speed
self.facing['right'], self.facing['left'], self.facing['up'], self.facing[
'down'] = False, True, False, False
if keys[pygame.K_d]:
self.x += self.x_speed
self.facing['right'], self.facing['left'], self.facing['up'], self.facing[
'down'] = True, False, False, False
if keys[pygame.K_w]:
self.y -= self.y_speed
self.facing['right'], self.facing['left'], self.facing['up'], self.facing[
'down'] = False, False, True, False
if keys[pygame.K_s]:
self.y += self.y_speed
self.facing['right'], self.facing['left'], self.facing['up'], self.facing[
'down'] = False, False, False, True
if keys[pygame.K_g]:
if not self.skills['g']['status']:
self.skills['g']['status'] = True
def skill_cloud(self, delta, window):
if self.time_counter >= self.skills['g']['exist_time']:
self.skills['g']['status'] = False
self.time_counter = 0
if self.skills['g']['status']:
self.skills['g']['cloud'].rained_objects = [self]
self.skills['g']['cloud'].update(delta, self)
self.skills['g']['cloud'].draw(window)
else:
self.skills['g']['cloud'] = Cloud(self.x, self.y - 200)
def damaged(self, damage):
font = pygame.font.Font(None, 24)
text1 = font.render(f"-{damage}", True, (255, 0, 0))
self.get_damage = damage
self.get_damage_text = text1
def draw(self, delta, window):
self.time_counter += delta
self.skill_cloud(delta, window)
for k, v in self.facing.items():
if v and self.pre_facing != k:
self.pre_facing = k
self.image_index = 0
if v and self.pre_facing == k:
self.image_index = self.image_index + int(delta * FPS) if self.image_index < 6 else 0
self.image = peron_down_walk_images[self.image_index]
self.width = peron_down_walk_images[self.image_index].get_width()
self.height = peron_down_walk_images[self.image_index].get_height()
if self.facing['right']:
images = self.peron_right_walk_images
elif self.facing['left']:
images = self.peron_left_walk_images
elif self.facing['up']:
images = self.peron_up_walk_images
else:
images = self.peron_down_walk_images
window.blit(images[self.image_index], (self.x, self.y))
pygame.draw.rect(window, (0, 0, 255), (0, 0, 40, 30))
text1 = self.font.render(str(self.hp), True, (255, 0, 0))
window.blit(text1, (screen_width - 100, 5))
if self.get_damage:
window.blit(self.get_damage_text, (self.x, self.y - 30))
self.get_damage = 0
python
import random
import pygame
from settings import *
class Rain(pygame.sprite.Sprite):
def __init__(self, x, y, rained_objects):
super().__init__()
self.width = random.randint(0, 3)
self.length = random.randint(8, 15)
self.image = pygame.Surface([self.width, self.length])
self.image.fill((244, 244, 255))
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.rained_objects = rained_objects
self.drop_speed = random.randint(rain_drop_speed[0], rain_drop_speed[1]) # 下落速度随机范围
self.gravity = drop_gravity # 加速度
def check_collision(self, item):
return True if (item.x < self.rect.x < item.x + item.width
and item.y < self.rect.y < item.y + item.height) else False
def update(self):
self.drop_speed = self.drop_speed * (1 + self.gravity)
self.rect.y += int(self.drop_speed)
if self.rect.y > screen_height:
self.kill()
damage = int(10 * ((self.width * self.length) / 10))
for item in self.rained_objects:
if self.check_collision(item):
item.hit_by_raindrop += 1
item.hp -= damage
item.damaged(damage)
self.kill()
python
import random
import pygame
from settings import *
from rain import Rain
class Cloud:
def __init__(self, x, y):
self.x = x
self.y = y
self.image = pygame.image.load(cloud_image_path).convert_alpha()
self.width = self.image.get_width()
self.height = self.image.get_height()
self.x_speed = cloud_x_speed
self.y_speed = cloud_y_speed
self.move_right = True
self.move_down = True
self.delta = 0
self.raining = True
self.raindrops = pygame.sprite.Group()
self.rain_counts = rain_counts
self.rained_objects = []
self.raining_time = 0
self.total_raining_time = 10
self.target_distance = 100
def update(self, delta, target):
self.raining_time += delta
self.x = self.x + self.x_speed if self.move_right else self.x - self.x_speed
self.y = self.y + self.y_speed if self.move_down else self.y - self.y_speed
if self.x + self.width <= target.x: self.move_right = True
if self.x >= target.x + target.width: self.move_right = False
if self.y + self.height < target.y - self.target_distance:
self.move_down, self.y_speed = True, cloud_y_speed
elif self.y + self.height > target.y - self.target_distance:
self.move_down, self.y_speed = False, cloud_y_speed
else:
self.y_speed = 0
def rain(self, window):
rain_range = [i for i in range(self.x, self.x + self.width)]
if len(self.raindrops) <= self.rain_counts and self.raining:
x = random.choice(rain_range)
y = self.y + self.height
new_raindrop = Rain(x, y, self.rained_objects)
self.raindrops.add(new_raindrop)
self.raindrops.update()
self.raindrops.draw(window)
def draw(self, window):
window.blit(self.image, (self.x, self.y))
self.rain(window)
if self.raining_time >= self.total_raining_time:
self.raining = False
python
import random
import pygame
screen_width = 1280
screen_height = 720
FPS = 60
cloud_image_path = "data/cloud.png"
cloud_x_speed = 2
cloud_y_speed = 1
person_x_speed = 5
person_y_speed = 3
rain_counts = 5
rain_drop_speed = [3, 8]
rain_drop_interval = 0.1
drop_gravity = 0.005
peron_down_walk_images = []
for i in range(0, 7):
img = pygame.image.load("data/catgame/walk/down_walk_%d.png" % i)
peron_down_walk_images.append(img)
peron_up_walk_images = []
for i in range(0, 7):
img = pygame.image.load("data/catgame/walk/up_walk_%d.png" % i)
peron_up_walk_images.append(img)
peron_left_walk_images = []
for i in range(0, 7):
img = pygame.image.load("data/catgame/walk/left_walk_%d.png" % i)
peron_left_walk_images.append(img)
peron_right_walk_images = []
for i in range(0, 7):
img = pygame.image.load("data/catgame/walk/right_walk_%d.png" % i)
peron_right_walk_images.append(img)
ground_path = "data/ground1.png"
ground_rows = 4
ground_columns = 8