def __init__(self, x, y): self.pos = Vector(x, y) self.vel = Vector(0, 0) self.w = 20 self.h = 40 self.speed = 5 self.jump_ready = True self.jump_pow = 70 self.max_stamina = 15 self.stamina = self.max_stamina self.rect = pygame.Rect(self.pos.x, self.pos.y, self.w, self.h) self.images = [ pygame.transform.scale(pygame.image.load('data/player/player_idle.png'), (self.w, self.h)), pygame.transform.scale(pygame.image.load('data/player/player_walk.png'), (self.w, self.h)) ] self.counter = 0 self.to_change = 5 self.spaw_bullet_at = Vector(0, 0)
def __calculate_right_points(middle, right, offset): right_end_up = middle + Vector(offset.x, -(right.width * WIDTH_MULTIPLIER) // 2) right_start_up = right_end_up + Vector(right.length * LENGTH_MULTIPLIER, 0) right_start_down = right_end_up + Vector(0, right.width * WIDTH_MULTIPLIER) right_end_down = right_start_up + Vector(0, right.width * WIDTH_MULTIPLIER) return RoadPointsGroup(PointsPair(right_start_down, right_end_down), PointsPair(right_start_up, right_end_up))
def __calculate_left_points(middle, left, offset): left_start_up = middle - Vector(offset.x, (left.width * WIDTH_MULTIPLIER) // 2) left_end_up = left_start_up + Vector(-left.length * LENGTH_MULTIPLIER, 0) left_start_down = left_end_up + Vector(0, left.width * WIDTH_MULTIPLIER) left_end_down = left_start_up + Vector(0, left.width * WIDTH_MULTIPLIER) return RoadPointsGroup(PointsPair(left_start_up, left_end_up), PointsPair(left_start_down, left_end_down))
def __calculate_top_points(middle, top, offset): top_end_left = middle - Vector( (top.width * WIDTH_MULTIPLIER) // 2, offset.y) top_start_left = top_end_left - Vector(0, top.length * LENGTH_MULTIPLIER) top_end_right = top_start_left + Vector(top.width * WIDTH_MULTIPLIER, 0) top_start_right = top_end_right + Vector(0, top.length * LENGTH_MULTIPLIER) return RoadPointsGroup(PointsPair(top_start_right, top_end_right), PointsPair(top_start_left, top_end_left))
def __calculate_down_points(middle, down, offset): down_start_left = middle + Vector(-(down.width * WIDTH_MULTIPLIER) // 2, offset.y) down_end_left = down_start_left + Vector(0, down.length * LENGTH_MULTIPLIER) down_start_right = down_end_left + Vector(down.width * WIDTH_MULTIPLIER, 0) down_end_right = down_start_right - Vector(0, down.length * LENGTH_MULTIPLIER) return RoadPointsGroup(PointsPair(down_start_left, down_end_left), PointsPair(down_start_right, down_end_right))
def vectorise_data(raw): """Converts a list of [x,y,z] data to Vector(x,y,z)""" temp = [] for vert in raw: temp.append(Vector(vert[0], vert[1], vert[2])) return temp
def create_map_painter(intersection, roads): """ Map painter initializer :param intersection: Intersection data, such as road lengths :type intersection: Intersection :param roads: Road definitions top,left,right,bottom :type roads: dict[str,RoadSizeVector] """ __offset = MaxOffset( int( max(roads["top"].width * WIDTH_MULTIPLIER, roads["bottom"].width * WIDTH_MULTIPLIER) / 2), int( max(roads["left"].width * WIDTH_MULTIPLIER, roads["right"].width * WIDTH_MULTIPLIER) / 2)) __middle = Vector( CONST_OFFSET + roads["left"].length * LENGTH_MULTIPLIER + __offset.y, CONST_OFFSET + roads["top"].length * LENGTH_MULTIPLIER + __offset.x) points = calculate_points(__middle, roads, __offset) # type: PointsQuadruple _vector_calculator = _MapVectorsCalculator( points) # type: _MapVectorsCalculator return MapPainter(points.left.outside.start, intersection, _vector_calculator, points)
class Game: player_offset = Vector(WALLSIZE // 2, WALLSIZE // 2) + Vector(*MAZEOFFSET) def __init__(self): self.maze = Maze(30, 30) def start(self): self.maze.init() generator = Maze.randomize(self.maze) Maze.randomize_exits(self.maze) try: while next(generator): pass except StopIteration: pass self.player_position = Vector(self.maze.entrance, 0) def process_event(self,event): if event.type == pygame.KEYDOWN: if event.key == pygame.K_r: self.start() return True if event.key in moves: self.move_player(moves[event.key]) return True return False def display(self, screen): self.maze.display(screen) pos = Vector(WALLSIZE * self.player_position.X, WALLSIZE * self.player_position.Y) + Game.player_offset pygame.draw.circle(screen, RED, tuple(pos), WALLSIZE // 3) def move_player(self, direction): if self.maze.board[self.player_position.X][self.player_position.Y].locked[direction]: return move = (0, 0) if direction == Direction.Right and self.player_position.X < self.maze.length: move = (1, 0) if direction == Direction.Left and self.player_position.X > 0: move = (-1, 0) if direction == Direction.Down and self.player_position.Y < self.maze.height: move = (0, 1) if direction == Direction.Up and self.player_position.Y > 0: move = (0, -1) self.player_position += Vector(*move)
def __init__(self, x, y, px, py): self.pos = Vector(x, y) self.speed = 10 self.size = 5 dx = px - x dy = py - y self.vel = Vector(dx, dy) self.vel.normalise() self.vel.mult(self.speed) self.is_live = True self.lethal = False self.to_die = False self.ttl = 100 self.till_lethal = self.ttl - 20 self.rect = pygame.Rect(self.pos.x, self.pos.y, self.size, self.size)
def start(self): self.maze.init() generator = Maze.randomize(self.maze) Maze.randomize_exits(self.maze) try: while next(generator): pass except StopIteration: pass self.player_position = Vector(self.maze.entrance, 0)
def reset_vars(): global fire_rate, max_fire_rate, bullets global enemies, wave bullets = [] max_fire_rate = 5 fire_rate = max_fire_rate enemies = [DotEnemy()] wave = 1 player.pos = Vector(50, envir.ground - 60)
def move_to_player(self, player_pos, enemies): dx = player_pos.x - self.pos.x dy = player_pos.y - self.pos.y vel = Vector(dx, dy) vel.normalise() vel.mult(self.speed) for enemy in enemies: if (d := sqrt((enemy.pos.x - self.pos.x)**2 + (enemy.pos.y - self.pos.y)**2)) > 0 and d < 50: diff = enemy.pos - self.pos diff.normalise() vel.sub(diff)
def move_player(self, direction): if self.maze.board[self.player_position.X][self.player_position.Y].locked[direction]: return move = (0, 0) if direction == Direction.Right and self.player_position.X < self.maze.length: move = (1, 0) if direction == Direction.Left and self.player_position.X > 0: move = (-1, 0) if direction == Direction.Down and self.player_position.Y < self.maze.height: move = (0, 1) if direction == Direction.Up and self.player_position.Y > 0: move = (0, -1) self.player_position += Vector(*move)
def show(self, screen, mouse_pos): if self.counter >= 2: self.counter = 0 target = mouse_pos - self.pos target.normalise() target.mult(25) target.add(self.pos) screen.blit(self.images[self.counter], (int(self.pos.x), int(self.pos.y))) pygame.draw.line(screen, [255, 255, 255], (int(self.pos.x + self.w/2), int(self.pos.y + self.h/4)), (int(target.x + self.w/2), int(target.y + self.h/4)), 5) pygame.draw.circle(screen, [255, 255, 255], (int(target.x + self.w/2), int(target.y + self.h/4)), 4) self.spaw_bullet_at = Vector(int(target.x + self.w/2), int(target.y + self.h/4)) self.to_change -= 1
def __init__(self): x = randint(0, envir.size[0]) y = randint(0, 300) self.pos = Vector(x, y) self.w = 20 self.h = 20 self.speed = 5 self.is_live = True self.lethal = True self.rect = pygame.Rect(x, y, self.w, self.h) self.health = 3 self.image = pygame.transform.scale( pygame.image.load('data/enemies/enemy.png'), (self.w, self.h))
def p_list(self,p): '''list : '(' itemlist ')' ''' p[0] = self.condenseAllPreFixLists(p[2]) if not self.noVectorOrTensor and ( len(p[2])==3 or len(p[2])==9 or len(p[2])==6): isVector=True for i in p[2]: try: float(i) except: isVector=False if isVector: if len(p[2])==3: p[0]=Vector(*p[2]) elif len(p[2])==9: p[0]=Tensor(*p[2]) else: p[0]=SymmTensor(*p[2])
def dist(elem): avrg = Vector(0, 0, 0) for vert in elem: avrg.add(vert) avrg.div(len(elem)) averages.append(avrg) if depth_test: return ((0 - avrg.x)**2 + (0 - avrg.y)**2 + (-1000 - avrg.z)**2) else: return 0
def test_negation(a, b): assert -Vector(a, b) == Vector(-a, -b)
def p_vector(self,p): '''vector : '(' number number number ')' ''' if self.noVectorOrTensor: p[0]=p[2:5] else: p[0]=Vector(*p[2:5])
class Player(): def __init__(self, x, y): self.pos = Vector(x, y) self.vel = Vector(0, 0) self.w = 20 self.h = 40 self.speed = 5 self.jump_ready = True self.jump_pow = 70 self.max_stamina = 15 self.stamina = self.max_stamina self.rect = pygame.Rect(self.pos.x, self.pos.y, self.w, self.h) self.images = [ pygame.transform.scale(pygame.image.load('data/player/player_idle.png'), (self.w, self.h)), pygame.transform.scale(pygame.image.load('data/player/player_walk.png'), (self.w, self.h)) ] self.counter = 0 self.to_change = 5 self.spaw_bullet_at = Vector(0, 0) def show(self, screen, mouse_pos): if self.counter >= 2: self.counter = 0 target = mouse_pos - self.pos target.normalise() target.mult(25) target.add(self.pos) screen.blit(self.images[self.counter], (int(self.pos.x), int(self.pos.y))) pygame.draw.line(screen, [255, 255, 255], (int(self.pos.x + self.w/2), int(self.pos.y + self.h/4)), (int(target.x + self.w/2), int(target.y + self.h/4)), 5) pygame.draw.circle(screen, [255, 255, 255], (int(target.x + self.w/2), int(target.y + self.h/4)), 4) self.spaw_bullet_at = Vector(int(target.x + self.w/2), int(target.y + self.h/4)) self.to_change -= 1 def update(self, key, enemies): self.rect = pygame.Rect(self.pos.x, self.pos.y, self.w, self.h) for enemy in enemies: if self.rect.colliderect(enemy.rect) and enemy.lethal : return True # region movement change = False if key[K_a] : self.vel.x -= self.speed; change = True if key[K_d] : self.vel.x += self.speed; change = True if key[K_SPACE] and self.jump_ready: self.vel.y -= self.jump_pow self.jump_ready = False change = True if change and self.to_change <= 0: self.counter += 1 self.to_change = 5 self.pos.add(self.vel) #endregion # region ground cases if self.pos.y + self.h < envir.ground: self.vel.y += envir.gravity else: self.pos.y = envir.ground - self.h self.jump_ready = True self.stamina = self.max_stamina #endregion # region wall cases # left if self.pos.x >= envir.size[0] - self.w: self.pos.x = envir.size[0] - self.w if self.stamina <= 0: self.vel.y *= 0.6 else: self.vel.y = 0 self.stamina -= 1 if key[K_a] and not key[K_d]: self.jump_ready = True # right if self.pos.x <= 0: self.pos.x = 0 if self.stamina <= 0: self.vel.y *= 0.6 else: self.vel.y = 0 self.stamina -= 1 if key[K_d] and not key[K_a]: self.jump_ready = True #endregion # region top case if self.pos.y <= 0: self.pos.y = 0 if self.vel.y < 0: self.vel.y *= -1 #endregion self.vel.mult(0.8)
class Bullet(): def __init__(self, x, y, px, py): self.pos = Vector(x, y) self.speed = 10 self.size = 5 dx = px - x dy = py - y self.vel = Vector(dx, dy) self.vel.normalise() self.vel.mult(self.speed) self.is_live = True self.lethal = False self.to_die = False self.ttl = 100 self.till_lethal = self.ttl - 20 self.rect = pygame.Rect(self.pos.x, self.pos.y, self.size, self.size) def show(self, screen): if self.lethal: c = colors.bullet else: c = colors.non_lethal pygame.draw.circle(screen, c, (int(self.pos.x), int(self.pos.y)), self.size) def update(self): self.pos.add(self.vel) self.rect = pygame.Rect(self.pos.x, self.pos.y, self.size, self.size) self.ttl -= 1 if self.ttl < self.till_lethal: self.lethal = True if self.pos.x >= envir.size[0]: self.pos.x = envir.size[0] self.vel.x *= -1 if self.to_die: self.is_live = False if self.pos.x <= 0: self.pos.x = 0 self.vel.x *= -1 if self.to_die: self.is_live = False if self.pos.y >= envir.ground: self.pos.y = envir.ground self.vel.y *= -1 if self.to_die: self.is_live = False if self.pos.y <= 0: self.pos.y = 0 self.vel.y *= -1 if self.to_die: self.is_live = False if self.ttl <= 0: self.to_die = True
def test_substraction(a, b, c, d): assert Vector(a, b) - Vector(c, d) == Vector(a - c, b - d)
def test_sum(a, b, c, d): assert Vector(a, b) + Vector(c, d) == Vector(a + c, b + d)
def game(screen): # region import globals and setup controlls global fire_rate, max_fire_rate, bullets global enemies, wave pygame.mouse.set_visible(False) key = pygame.key.get_pressed() mouse_pos = pygame.mouse.get_pos() mouse_pos = Vector(mouse_pos[0], mouse_pos[1]) mouse_pressed = pygame.mouse.get_pressed() screen.fill(colors.black) #endregion # region player controlls if player.update(key, enemies + bullets) == True: reset_vars() screen.fill(colors.white) pygame.display.update() return 'gameover' player.show(screen, mouse_pos) #endregion # region bullet controlls if mouse_pressed == (1, 0, 0) and fire_rate == max_fire_rate: bullets.append( Bullet(player.spaw_bullet_at.x, player.spaw_bullet_at.y, mouse_pos.x, mouse_pos.y)) fire_rate = 0 if fire_rate < max_fire_rate: fire_rate += 1 temp = [] for bullet in bullets: if bullet.is_live: bullet.update() bullet.show(screen) temp.append(bullet) bullets = temp #endregion # region enemy controlls temp = [] for enemy in enemies: if enemy.is_live: enemy.update(player.pos, bullets, enemies) enemy.show(screen) temp.append(enemy) enemies = temp if len(enemies) == 0: wave += 1 for _ in range(wave): enemies.append(DotEnemy()) #endregion # region screen controlls pygame.draw.rect(screen, colors.brown, (0, envir.ground, envir.size[0], 50)) screen.blit(mouse, (mouse_pos.x - 5, mouse_pos.y - 5)) #endregion return 'game'
def display(self, screen): self.maze.display(screen) pos = Vector(WALLSIZE * self.player_position.X, WALLSIZE * self.player_position.Y) + Game.player_offset pygame.draw.circle(screen, RED, tuple(pos), WALLSIZE // 3)
def test_copy(a, b): p1 = Vector(a, b) p2 = p1.copy() assert not (p1 is p2) assert p1 == p2
import random import pygame from data_structures import Vector from consts import * from direction import Direction downVector = Vector(0, WALLSIZE) rightVector = Vector(WALLSIZE, 0) class Tile: B = rightVector C = rightVector + downVector D = downVector def __init__(self): self.left = None self.right = None self.up = None self.down = None self.clear_walls() self.visited = False def unlock(self, direction): self.locked[direction] = False def draw(self, vector, surface): if self.locked[Direction.Up]: pygame.draw.line(surface, BLACK, tuple(vector), tuple(vector + Tile.B)) if self.locked[Direction.Right]:
def test_multiply(a, b): p1 = Vector(a[0], a[1]) p2 = p1 * b assert p2.x == a[0] * b assert p2.y == a[1] * b
def test_bad_multiply(): tmp = Vector(1, 1) for i in ["", 1.0, Vector(1, 1)]: with pytest.raises(ValueError) as excinfo: tmp * i assert "int" in str(excinfo.value).lower()
def left_movement_vector(x_delta, y_delta): """Calculates left movement vector""" point = _MapVectorsCalculator.down_movement_vector(y_delta, x_delta) return Vector(-point.x, point.y)