forked from InfoProjekt/game
		
	
		
			
				
	
	
		
			555 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			555 lines
		
	
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import pygame as pg
 | |
| from classes import *
 | |
| from main import *
 | |
| import random
 | |
| 
 | |
| vec = pg.math.Vector2
 | |
| fps = 60
 | |
| 
 | |
| 
 | |
| pg.font.init()
 | |
| fonts = {
 | |
|     'medieval': 'medieval.ttf',
 | |
|     'minecraft': 'Minecraft Evenings.otf',
 | |
|     '3dpixel': '3D-Pixel.ttf',
 | |
|     '8bit': '8bitlim.ttf',
 | |
|     '8bito': '8blimro.ttf',
 | |
|     'arcade': 'ARCADECLASSIC.ttf',
 | |
|     'modern_game': 'astron boy video.otf',
 | |
|     'modern': 'astron boy.otf',
 | |
|     'wonder': 'Beyond Wonderland.ttf',
 | |
|     'curved': 'Digitag.ttf',
 | |
|     'simple': 'DisposableDroidBB.ttf',
 | |
|     'rounded': 'dpcomic.ttf',
 | |
|     'playfull': 'Endalian Script.ttf',
 | |
|     'blocky': 'FREAKSOFNATURE.ttf',
 | |
|     'catchy': 'Future TimeSplitters.otf',
 | |
|     'simple_wide': 'Halo3.ttf',
 | |
|     'simple_fat': 'INVASION2000.ttf',
 | |
|     'very_gamy': 'ka1.ttf',
 | |
|     'simple_round': 'Karma Suture.otf',
 | |
|     'mono': 'manaspc.ttf',
 | |
|     'damaged': 'Merchant Copy.ttf',
 | |
|     'big_natural': 'MorialCitadel.TTF',
 | |
|     'spacy': 'nasalization-rg.otf',
 | |
|     'sci-fi': 'neuropol.otf',
 | |
|     'hollow_big_edge': 'papercut.ttf',
 | |
|     'space_shuttle': 'pdark.ttf',
 | |
|     'thin': 'PixelFJVerdana12pt.ttf',
 | |
|     'random': 'Seattle Avenue.ttf',
 | |
|     'pixel': 'yoster.ttf'
 | |
| }
 | |
| 
 | |
| class Objects():
 | |
|     def __init__(self, name, ms, sprite, x, y) -> None:
 | |
|         self.name = name
 | |
|         self.speed = ms
 | |
|         with open(f'art/images/{sprite}') as i:
 | |
|             self.sprite = pg.transform.scale2x(pg.image.load(i)) 
 | |
|         self.x = x
 | |
|         self.y = y
 | |
|         self.hidden = False
 | |
|         self.rect = pg.Rect(self.x, self.y, self.sprite.get_width(), self.sprite.get_height())
 | |
|     
 | |
|     def draw(self, screen):
 | |
|         if self.hidden:
 | |
|             return
 | |
|         self.rect.x, self.rect.y = self.x, self.y
 | |
|         screen.blit(self.sprite, self.rect)
 | |
|         pg.draw.rect(screen, '#ef0120', self.rect,  2)
 | |
| 
 | |
| class NPC(Objects):
 | |
|     def __init__(self, name, ms, sprite, convo_scene, x, y) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y)
 | |
|         self.talking = False
 | |
|         self.hidden = False
 | |
|         self.conversation = Convo(self, convo_scene)
 | |
|         self.lastUpdate = pg.time.get_ticks()
 | |
|     
 | |
|     def talk(self, objects):
 | |
|         self.talking = True
 | |
|         objects[0][0].talking = True
 | |
|     
 | |
|     def draw(self, screen):
 | |
|         super().draw(screen)
 | |
|         if self.talking:
 | |
|             self.conversation.draw(screen)
 | |
|     
 | |
|     def update(self, keys, objects):
 | |
|         if self.name == 'oldlady':
 | |
|             if self.conversation.convo_scene==0 and 'rat' in objects[0][0].killed and objects[1]==[]:
 | |
|                 self.conversation.convo_scene=1
 | |
|         if self.lastUpdate + 200 < pg.time.get_ticks():
 | |
|             if self.talking:
 | |
|                 self.conversation.update(keys, objects)
 | |
|                 self.lastUpdate = pg.time.get_ticks()
 | |
|             else:
 | |
|                 touches = pg.sprite.spritecollideany(self, objects[0])
 | |
|                 if touches is not None and keys[pg.K_f] and isinstance(touches, MainCharacter):
 | |
|                     self.talk(objects) 
 | |
|                     self.lastUpdate = pg.time.get_ticks()
 | |
| 
 | |
| 
 | |
| class Convo(Label):
 | |
|     def __init__(self, npc, convo_scene, text='', x = 140, y = 600, width = 1000, height = 100, font='simple', font_size = 20) -> None:
 | |
|         super().__init__(x, y, width, height, text, font, font_size)
 | |
|         self.convo_act=0
 | |
|         self.npc = npc
 | |
|         self.convo_scene = convo_scene
 | |
|         self.convos = [
 | |
|             ['oldlady', 0, ['There are so many rats here.', 'I wish someone would to something against that.','An experienced fighter could kill them.', 'For them it only takes a mouseclick.']],
 | |
|             ['oldlady', 1, ['Oh, did you kill all the rats?', 'You must be the chosen one!', 'It would be nice if you would go and talk to the village elder.']],
 | |
|             ['elder', 0, ['Who are you?', 'You want to help us?', 'We have a serious problem with monsters.', 'One day they appeared out of nowhere and started attacking.', 'When you jump into the portal over there,', 'You will be send to a place with monsters.', 'PLEASE help us!']],
 | |
|             ['elder', 1, ['Who are you?', 'You want to help us?', 'We have a serious problem with monsters.', 'One day they appeared out of nowhere and started attacking.', 'When you jump into the portal over there,', 'You will be send to a place with monsters.', 'PLEASE help us!']]
 | |
|         ]
 | |
| 
 | |
|     def draw(self, screen):
 | |
|         self.text = self.findConversation()[2][self.convo_act]
 | |
|         super().draw(screen)
 | |
| 
 | |
| 
 | |
|     def findConversation(self):
 | |
|         for convo in self.convos:
 | |
|             if convo[0] == self.npc.name and convo[1] == self.convo_scene:
 | |
|                 return convo
 | |
|         return ['ERROR']
 | |
| 
 | |
|     def update(self, keys, objects):
 | |
|         if keys[pg.K_f]:
 | |
|             convo = self.findConversation()
 | |
|             if self.convo_act+1 < len(convo[2]):
 | |
|                 self.text = convo[2][self.convo_act]
 | |
|                 self.convo_act += 1
 | |
|             else:
 | |
|                 if convo[0] == 'oldlady':
 | |
|                     if convo[1] == 0:
 | |
|                         for i in range(0,5):
 | |
|                             objects[1].append(Rat('rat', random.randint(150,250), 800, 400+i*20, 1, 1, 1, 100, 25))
 | |
|                     elif convo[1] == 1:
 | |
|                         objects[0][0].level.level = 5
 | |
|                         while 'rat' in objects[0][0].killed: objects[0][0].killed.remove('rat')
 | |
|                 if convo[0] == 'elder':
 | |
|                     if convo[1] == 0:
 | |
|                         objects[4].append(Obstacle('portal', 'interactable', 'art/images/background/portal.png', False, 700, 300))
 | |
|                         self.convo_scene += 1
 | |
|                 self.convo_act = 0
 | |
|                 self.npc.talking = False
 | |
|                 objects[0][0].talking = False
 | |
| 
 | |
| 
 | |
| class Fighter(Objects):
 | |
|     def __init__(self, name, ms, sprite, x, y, health, damage, level, asp, atr) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y)
 | |
|         self.health = health
 | |
|         self.damage = damage
 | |
|         self.level = level
 | |
|         self.attack_speed = asp
 | |
|         self.attack_range = atr
 | |
|         self.lastHurt = pg.time.get_ticks()
 | |
|         self.lastAttack = pg.time.get_ticks()
 | |
|         self.hurtCooldown = 0
 | |
| 
 | |
| 
 | |
| class MainCharacter(Fighter):
 | |
|     def __init__(self, name, ms, sprite, x, y, health, damage, level, asp, atr, killed =[]) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, health, damage, level, asp, atr)
 | |
|         self.book = Book(0, 0, [], None, None)
 | |
|         self.talking = False
 | |
|         self.level = Level(1000, 38, 150, 40, level, f'will to live: {level}%', 'simple', 20, )
 | |
|         self.health = Hearts(health, sprite=['fullheart.png', 'fullheart.png', 'fullheart.png', 'fullheart.png', 'fullheart.png'], x=900, y= 50, hurtCooldown=self.hurtCooldown)
 | |
|         self.thinks = Thinks(self.x+20, self.y-50, 150, 100, 'brr I\'m freezing')
 | |
|         self.freezing = True
 | |
|         self.killed = killed #amount of mobs that were killed
 | |
| 
 | |
|     def draw(self, screen):
 | |
|         if self.hidden:
 | |
|             return
 | |
|         self.rect.x, self.rect.y = self.x, self.y
 | |
|         screen.blit(self.sprite, self.rect)
 | |
|         self.health.draw(screen)
 | |
|         self.level.draw(screen)
 | |
|         self.book.draw(screen)
 | |
|         pg.draw.rect(screen, '#e900fa', self.rect, 2)
 | |
|         if self.thinks.hidden == False:
 | |
|             self.thinks.draw(screen, self.x+20, self.y-100)
 | |
| 
 | |
|     def hurt(self, damage, objects):
 | |
|         if not self.talking:
 | |
|             self.health.hurt(damage)
 | |
|     
 | |
|     def obstacle_interaction(self, objects):
 | |
|         touches = pg.sprite.spritecollideany(self, objects[4])
 | |
|         if touches is not None:
 | |
|             if touches.name == 'fireplace':
 | |
|                 self.freezing = False
 | |
|             elif touches.name == 'portal' and self.level.level != 1:
 | |
|                 return 'play'
 | |
|             elif touches.name == 'house' and self.level.level != 1:
 | |
|                 self.x = 500
 | |
|                 self.y = 400
 | |
|                 return 'house'
 | |
|             elif 'wall' in touches.name:
 | |
|                 return 'wall'
 | |
|         else:
 | |
|              return True
 | |
|     
 | |
|     def walk(self, keys, objects):
 | |
|         moveto = vec(0, 0)
 | |
|         if keys[pg.K_w] or keys[pg.K_UP]:
 | |
|             moveto += vec(0, -1)
 | |
|         if keys[pg.K_a] or keys[pg.K_LEFT]:
 | |
|             moveto += vec(-1, 0)
 | |
|         if keys[pg.K_s] or keys[pg.K_DOWN]:
 | |
|             moveto += vec(0, 1)
 | |
|         if keys[pg.K_d] or keys[pg.K_RIGHT]:
 | |
|             moveto += vec(1, 0)
 | |
|         if not moveto == vec(0, 0):
 | |
|             moveto.scale_to_length(self.speed)
 | |
| 
 | |
|         self.x += moveto[0] / fps
 | |
|         self.y += moveto[1] / fps 
 | |
|         touches = pg.sprite.spritecollideany(self, objects[2] + objects[4])
 | |
|         if touches is not None and not isinstance(touches, Weapons):
 | |
|             if isinstance(touches, Obstacle):
 | |
|                 if not touches.collision:
 | |
|                     # print(touches.name)
 | |
|                     return
 | |
|                 if touches.type == 'wall':
 | |
|                     if touches.name == 'wall_l':
 | |
|                         self.x += (2 + (self.x - touches.rect.x))
 | |
|                     elif touches.name == 'wall_r':
 | |
|                         self.x -= (2 + self.rect.width - (touches.rect.x - self.x))
 | |
|                     if touches.name == 'wall_t':
 | |
|                         self.y += (2 + (self.y - touches.rect.y))
 | |
|                     elif touches.name == 'wall_b':
 | |
|                         self.y -= (2 + self.rect.height - (touches.rect.y - self.y))
 | |
|                     return
 | |
|             elif isinstance(touches, NPC):
 | |
|                 return
 | |
| 
 | |
|             if self.x <= touches.rect.x: self.x -= (self.rect.width - (touches.rect.x - self.x))
 | |
|             elif self.x > touches.rect.x: self.x += (self.rect.width - (self.x - touches.rect.x - touches.rect.width * 0.66))
 | |
|             #if self.y <= touches.y: pass
 | |
|             #elif self.y > touches.y: pass
 | |
|             #self.x -= moveto[0] * 2 / fps
 | |
|             #self.y -= moveto[1] * 2 / fps
 | |
| 
 | |
|         """
 | |
|         if self.x <= 32:
 | |
|             self.x = 33
 | |
|         elif self.x >= objects[3][0].width - 32:
 | |
|             self.x = objects[3][0].width - 32 - self.rect.width + 1
 | |
|         if self.y <= 32:
 | |
|             self.y = 33
 | |
|         elif self.y >= objects[3][0].height - 32:
 | |
|             self.y = objects[3][0].height - 32 - self.rect.height + 1
 | |
|         """
 | |
|     
 | |
|     def attack(self, obj, mouse):
 | |
|         if self.lastAttack + self.attack_speed * 1000 < pg.time.get_ticks():
 | |
|             moveto = mouse - vec(self.x, self.y)
 | |
|             if self.book.current_sp == 'fireball':
 | |
|                 weapon = Fireball('fb1', 100, self.x, self.y, moveto, 5)
 | |
|             elif self.book.current_sp == 'windslash':
 | |
|                 weapon = Windslash('ws1', 100, self.x, self.y, moveto, 10)
 | |
|             else:
 | |
|                 weapon = Punch('punch', 100, self.x, self.y, moveto, 1, Mobs, life_ticks=500)
 | |
|             obj[3].append(weapon)
 | |
|             self.lastAttack = pg.time.get_ticks()
 | |
| 
 | |
|     def update(self, keys, mouse, objects):
 | |
|         if not self.talking:
 | |
|             self.walk(keys, objects)
 | |
|             if pg.mouse.get_pressed()[0]:
 | |
|                 self.attack(objects, vec(mouse))
 | |
|         self.thinks.update(objects, self)
 | |
|         if self.health.health <= 0:
 | |
|             return 'village'
 | |
|         else:
 | |
|             return self.obstacle_interaction(objects)
 | |
| 
 | |
| class Hearts():
 | |
|     def __init__(self, health, sprite, x, y, hurtCooldown) -> None:
 | |
|         self.x = x
 | |
|         self.y = y
 | |
|         self.health = health
 | |
|         self.lastHurt = pg.time.get_ticks()
 | |
|         self.hurtCooldown = hurtCooldown
 | |
|         self.hidden = False
 | |
|         self.sprite=[]
 | |
|         for parts in sprite:
 | |
|             with open(f'art/images/main_attributes/{parts}') as i:
 | |
|                 self.sprite.append(pg.image.load(i))
 | |
|         self.rect = []
 | |
|         for each in self.sprite:
 | |
|             self.rect.append(pg.Rect(self.x, self.y, each.get_width(), each.get_height()))
 | |
|         
 | |
|     def hurt(self,damage):
 | |
|         if self.lastHurt + self.hurtCooldown < pg.time.get_ticks():
 | |
|             self.health -= damage
 | |
|             self.lastHurt = pg.time.get_ticks()
 | |
|             self.update()
 | |
| 
 | |
|     def draw(self, screen):
 | |
|         if self.hidden:
 | |
|             return
 | |
|         for i in range(0, 5):
 | |
|             self.rect[i].x, self.rect[i].y = self.x + i * 20, self.y
 | |
|             screen.blit(self.sprite[i], self.rect[i])
 | |
|     
 | |
|     def update(self):
 | |
|         sprite = []
 | |
|         for i in range(0, 5):
 | |
|             if self.health >= 4 + 4 * i:
 | |
|                 sprite.append('fullheart.png')
 | |
|             elif self.health == 3 + 4 * i:
 | |
|                 sprite.append('dreiviertelheart.png')
 | |
|             elif self.health >= 2 + 4 * i:
 | |
|                 sprite.append('halfheart.png')
 | |
|             elif self.health >= 1 + 4 * i:
 | |
|                 sprite.append('viertelheart.png')
 | |
|             elif self.health <= 4 * i:
 | |
|                 sprite.append('noheart.png')  
 | |
|         self.sprite = []
 | |
|         for parts in sprite:
 | |
|             with open(f'art/images/main_attributes/{parts}') as i:
 | |
|                 self.sprite.append(pg.image.load(i))
 | |
| 
 | |
| 
 | |
| class Level(Label):
 | |
|     def __init__(self, x, y, width, height, level, text, font='simple', font_size=20, font_color='#1e90ff', sprite='label.png') -> None:
 | |
|         super().__init__(x, y, width, height, text, font, font_size, font_color, sprite)
 | |
|         self.level = level
 | |
|     def draw(self, screen):
 | |
|         self.text = f'will to live: {self.level}%'
 | |
|         super().draw(screen)
 | |
| 
 | |
| class Thinks(Label):
 | |
|     def __init__(self, x, y, width, height, text, font='simple', font_size=15, font_color='#000000', sprite='thinks.png') -> None:
 | |
|         super().__init__(x, y, width, height, text, font, font_size, font_color, sprite)
 | |
|         self.scene = 0
 | |
| 
 | |
|     def draw(self, screen, x, y):
 | |
|         if self.hidden:
 | |
|             return
 | |
|         self.x = x
 | |
|         self.y = y
 | |
|         super().draw(screen)
 | |
|     
 | |
|     def update(self, objects, main):
 | |
|         if not self.hidden:
 | |
|             if self.scene == 0 and not main.freezing:
 | |
|                 self.scene = 1
 | |
|                 self.hidden = True
 | |
|             elif self.scene == 1 and main.talking:
 | |
|                 self.scene = 2
 | |
|                 self.hidden = True
 | |
|         if self.scene == 1:
 | |
|             touches = pg.sprite.spritecollideany(main, objects[2])
 | |
|             if touches is not None and isinstance(touches, NPC):
 | |
|                 self.text = 'I should press \"f\"'
 | |
|                 self.hidden = False
 | |
|             else:
 | |
|                 self.hidden = False
 | |
|                 self.text = 'the lady over there'
 | |
| 
 | |
| class Book():
 | |
|     def __init__(self, x, y, spells, current_spell, current_shield) -> None:
 | |
|         with open(f'art/images/main_attributes/book.png') as i:
 | |
|             self.sprite = pg.image.load(i)
 | |
|             self.sprite = pg.transform.scale(self.sprite, (1280, 720))
 | |
|         self.x = x
 | |
|         self.y = y
 | |
|         self.hidden = False
 | |
|         self.rect = pg.Rect(self.x, self.y, self.sprite.get_width(), self.sprite.get_height())
 | |
|         self.sp_list = spells
 | |
|         self.current_sp = current_spell
 | |
|         self.text_left = ["Dear User, ", "in case you fell on the ground too hard,", "here is a quick reminder:", 
 | |
|                             "You are a homeless person. One cold day","you went to the library to warm up yourself.", 
 | |
|                             "There you got bored and found and opened me.", "This lead to you being thrown into this world.", 
 | |
|                             "But you can find a way out of here again."] 
 | |
|         self.text_right = ["This book will help you to survive.", "You can open and close me when pressing e.",
 | |
|                            "Click on a picture to choose your spell.",
 | |
|                            "Talk to fairies to unlock new spells!"]
 | |
|         self.buttons=[]
 | |
|         self.buttons_y = 400
 | |
|         self.buttons_x = 800
 | |
| 
 | |
|     
 | |
|     def draw(self, screen):
 | |
|         if self.hidden:
 | |
|             return
 | |
|         self.rect.x, self.rect.y = self.x, self.y
 | |
|         screen.blit(self.sprite, self.rect)
 | |
|         text_left_y = 100
 | |
|         text_right_y = 100
 | |
|         for text in self.text_left:
 | |
|             label = Label(100, text_left_y, 500, 50, text, font_color='#000000', sprite='empty.png')
 | |
|             label.draw(screen)
 | |
|             text_left_y += 50
 | |
|         for text in self.text_right:
 | |
|             label = Label(680, text_right_y, 500, 50, text, font_color='#000000', sprite='empty.png')
 | |
|             label.draw(screen)
 | |
|             text_right_y += 50
 | |
|         for button in self.buttons:
 | |
|             button.update(screen)
 | |
|     
 | |
|     def addspell(self, spell):
 | |
|         if spell not in self.sp_list:
 | |
|             self.sp_list.append(spell)
 | |
|             self.current_sp = spell
 | |
|             self.buttons.append(Button(self.buttons_x, self.buttons_y, 58, 50, f'{spell}_icon.png', 'medieval', 23, attributes=[spell], onclickFunction=self.update_spell))
 | |
|             self.buttons_y += 100
 | |
| 
 | |
|     def update_spell(self, spell):
 | |
|         self.current_sp = spell
 | |
| 
 | |
|     def update(self):
 | |
|         pass
 | |
| 
 | |
| class Mobs(Fighter):
 | |
|     def __init__(self, name, ms, sprite, x, y, health, damage, level, asp, atr, drops) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, health, damage, level, asp, atr)
 | |
|         self.drops = drops * (self.level / 2)
 | |
|     
 | |
|     def chase(self, obj):
 | |
|         x = obj[0][0].x
 | |
|         y = obj[0][0].y
 | |
|         moveto = vec(x, y) - vec(self.x, self.y)
 | |
|         if not (moveto).length() <= self.attack_range:
 | |
|             moveto.scale_to_length(self.speed)
 | |
|             self.x += moveto[0] / fps
 | |
|             self.y += moveto[1] / fps
 | |
|             touches = pg.sprite.spritecollideany(self, obj[4])
 | |
|             if touches is not None and not isinstance(touches, Weapons):
 | |
|                 if isinstance(touches, Obstacle):
 | |
|                     if not touches.collision:
 | |
|                         return
 | |
|                     if touches.type == 'wall':
 | |
|                         if touches.name == 'wall_l':
 | |
|                             self.x += (2 + (self.x - touches.rect.x))
 | |
|                         elif touches.name == 'wall_r':
 | |
|                             self.x -= (2 + self.rect.width - (touches.rect.x - self.x))
 | |
|                         if touches.name == 'wall_t':
 | |
|                             self.y += (2 + (self.y - touches.rect.y))
 | |
|                         elif touches.name == 'wall_b':
 | |
|                             self.y -= (2 + self.rect.height - (touches.rect.y - self.y))
 | |
| 
 | |
|                     if self.x <= touches.rect.x: self.x -= (self.rect.width - (touches.rect.x - self.x))
 | |
|                     elif self.x > touches.rect.x: self.x += (self.rect.width - (self.x - touches.rect.x - touches.rect.width * 0.66))
 | |
|         else:
 | |
|             self.attack(moveto, obj)
 | |
|     
 | |
|     
 | |
|     def hurt(self, damage, objects):
 | |
|         self.health -= damage
 | |
|         if self.health <= 0:
 | |
|             objects[0][0].killed.append(self.name)
 | |
|             self.hidden = True
 | |
|             objects[1].remove(self)
 | |
|     
 | |
|     
 | |
|     def update(self, obj):
 | |
|         self.chase(obj)
 | |
| 
 | |
| 
 | |
| class Skeleton(Mobs):
 | |
|     def __init__(self, name, ms, x, y, health, damage, level, asp, atr, sprite = 'people/skeleton.png', drops=0) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, health, damage, level, asp, atr, drops)
 | |
|     
 | |
|     def attack(self, moveto, obj):
 | |
|         if self.lastAttack + self.attack_speed * 1000 < pg.time.get_ticks():
 | |
|             obj[3].append(Arrow("arrow", 200, self.x, self.y, moveto, self.damage))
 | |
|             self.lastAttack = pg.time.get_ticks()
 | |
|     
 | |
| 
 | |
| class Zombie(Mobs):
 | |
|     def __init__(self, name, ms, x, y, health, damage, level, asp, atr, sprite='people/zombie.png', drops=0) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, health, damage, level, asp, atr, drops)
 | |
|     
 | |
|     
 | |
|     def attack(self, moveto, obj):
 | |
|         if self.lastAttack + self.attack_speed * 1000 < pg.time.get_ticks():
 | |
|             obj[3].append(Punch('punch', 100, self.x, self.y, moveto, self.damage, MainCharacter))
 | |
|             self.lastAttack = pg.time.get_ticks()
 | |
| 
 | |
| class Rat(Mobs):
 | |
|     def __init__(self, name, ms, x, y, health, damage, level, asp, atr, sprite='people/rat.png', drops=0) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, health, damage, level, asp, atr, drops)
 | |
|     
 | |
|     
 | |
|     def attack(self, moveto, obj):
 | |
|         if self.lastAttack + self.attack_speed * 1000 < pg.time.get_ticks():
 | |
|             obj[3].append(Punch('punch', 100, self.x, self.y, moveto, self.damage, MainCharacter))
 | |
|             self.lastAttack = pg.time.get_ticks()
 | |
| 
 | |
| class Weapons(Objects):
 | |
|     def __init__(self, name, ms, sprite, x, y, moveto, damage, life_ticks) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y)
 | |
|         self.moveto = moveto
 | |
|         self.damage = damage
 | |
|         self.life_ticks= life_ticks
 | |
|         self.spawn_tick = pg.time.get_ticks()
 | |
|         pos = vec(1,0)
 | |
|         angle = pos.angle_to(moveto)
 | |
|         
 | |
|         self.sprite = pg.transform.rotate(self.sprite, -angle)
 | |
|     
 | |
|     def die(self, objects, kills):
 | |
|         touches = pg.sprite.spritecollideany(self, objects[0] + objects[1])
 | |
|         if touches is not None and isinstance(touches, kills):
 | |
|             touches.hurt(self.damage, objects)
 | |
|             self.hidden = True
 | |
|             if self in objects[3]:
 | |
|                 objects[3].remove(self)
 | |
|             
 | |
|     def move(self, objects):
 | |
|         self.moveto.scale_to_length(self.speed)
 | |
|         self.x += self.moveto[0] / fps
 | |
|         self.y += self.moveto[1] / fps
 | |
|         if pg.time.get_ticks() - self.spawn_tick > self.life_ticks:
 | |
|             self.hidden = True
 | |
|             objects[3].remove(self)
 | |
| 
 | |
| class Spells(Weapons):
 | |
|     def __init__(self, name, ms, sprite, x, y, moveto, damage, life_ticks) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, moveto, damage, life_ticks)
 | |
| 
 | |
| class Fireball(Spells):
 | |
|     def __init__(self, name, ms, x, y, moveto, damage, sprite = 'weapons/fireball.png', life_ticks=5000) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, moveto, damage, life_ticks)
 | |
|     
 | |
|     def update(self, objects):
 | |
|         self.move(objects)
 | |
|         self.die(objects, Mobs)
 | |
| 
 | |
| class Windslash(Spells):
 | |
|     def __init__(self, name, ms, x, y, moveto, damage, sprite = 'weapons/windslash.png', life_ticks=1000) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, moveto, damage, life_ticks)
 | |
|     
 | |
|     def update(self, objects):
 | |
|         self.move(objects)
 | |
|         self.die(objects, Mobs)
 | |
|     
 | |
|     def move(self, objects):
 | |
|         super().move(objects)
 | |
|         self.moveto = self.moveto.rotate(5)
 | |
| 
 | |
| 
 | |
| class Arrow(Weapons):
 | |
|     def __init__(self, name, ms, x, y, moveto, damage, sprite = 'weapons/arrow.png', life_ticks=5000) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, moveto, damage, life_ticks)
 | |
|     
 | |
|     def update(self, objects):
 | |
|         self.move(objects)
 | |
|         self.die(objects, MainCharacter)
 | |
| 
 | |
| 
 | |
| class Punch(Weapons):
 | |
|     def __init__(self, name, ms, x, y, moveto, damage, kills, sprite = 'weapons/empty.png', life_ticks=100) -> None:
 | |
|         super().__init__(name, ms, sprite, x, y, moveto, damage, life_ticks)
 | |
|         self.kills = kills
 | |
|     
 | |
|     def update(self, objects):
 | |
|         self.move(objects)
 | |
|         self.die(objects, self.kills)
 |