forked from reddit-pygame/snowboard-challenge
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcourse.py
More file actions
85 lines (76 loc) · 3.69 KB
/
Copy pathcourse.py
File metadata and controls
85 lines (76 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import pygame as pg
import prepare
from obstacles import Tree, RightGate, LeftGate, Jump, Rock
from obstacles import GreenSign, BlueSign, BlackSign, Pylon
from chairlift import ChairLift
class Course(object):
def __init__(self, course_info):
self.map_name = course_info["map_name"]
self.map_size = course_info["map_size"]
self.map_rect = pg.Rect((0, 0), self.map_size)
self.view_rect = prepare.SCREEN_RECT.copy()
self.class_map = {"tree": Tree,
"rightgate": RightGate,
"leftgate": LeftGate,
"jump": Jump,
"rock": Rock,
"greensign": GreenSign,
"bluesign": BlueSign,
"blacksign": BlackSign,
"pylon": Pylon
}
self.chairlift = ChairLift(self.map_size)
self.obstacles = pg.sprite.Group()
self.gates = pg.sprite.Group()
self.load_from_info(course_info)
self.make_sections()
def make_sections(self, split_num=1000):
"""Divide the obstacles into different sections to avoid unnecessary collision checks."""
self.obstacles.add(self.chairlift.pylons.sprites())
num = max(1, int(len(self.obstacles) / split_num))
section_length = int(self.map_size[1] / num)
self.sections = {}
for y in range(0, self.map_size[1], section_length):
rect_info = (0, y, self.map_size[0], section_length)
rect = pg.Rect(rect_info)
self.sections[rect_info] = pg.sprite.Group([x for x in self.obstacles if rect.collidepoint(x.rect.midbottom)])
def get_section_sprites(self):
"""Return sprites from sections that collide with self.view_rect."""
visible = set()
for rect_info in self.sections:
if pg.Rect(rect_info).colliderect(self.view_rect):
visible.update(self.sections[rect_info])
return visible
def load_from_info(self, course_info):
"""Instantiate course objects from course_info, a dict loaded from JSON."""
for item in course_info["obstacles"]:
klass = self.class_map[item[0].lower()]
midbottom = item[1]
obstacle = klass(midbottom, self.obstacles)
if "gate" in item[0].lower():
self.gates.add(obstacle)
def reset(self):
"""Get course ready for player to take another run down the slope."""
for gate in self.gates:
gate.reset()
def update(self, dt, boarder):
self.chairlift.update(dt)
self.view_rect.center = boarder.rect.center
self.view_rect.clamp_ip(self.map_rect)
self.gates.update(boarder)
self.collidables = {x for x in self.get_section_sprites() if x.rect.colliderect(self.view_rect)}
for collidable in (c for c in self.collidables if c.collider.colliderect(boarder.collider)):
collidable.collide_with_boarder(boarder)
if boarder.collider.colliderect(self.chairlift.bottom_lifthut.rect):
boarder.reset((self.map_rect.centerx, 50))
self.reset()
def draw(self, surface, boarder=None):
offset = -self.view_rect.left, -self.view_rect.top
if boarder:
self.collidables.add(boarder)
onscreen = self.collidables
else:
onscreen = {x for x in self.get_section_sprites() if x.rect.colliderect(self.view_rect)}
for obstacle in sorted(onscreen, key=lambda x: x.collider.bottom):
obstacle.draw(surface, offset)
self.chairlift.draw(surface, offset)