Adds an obstacle system
This commit is contained in:
68
Throot.py
Normal file
68
Throot.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import time
|
||||||
|
import thumby
|
||||||
|
import math
|
||||||
|
|
||||||
|
import Games.Throot.map
|
||||||
|
import Games.Throot.sprites
|
||||||
|
from Games.Throot.artrepository import OBSTACLES
|
||||||
|
|
||||||
|
from random import randrange
|
||||||
|
|
||||||
|
import thumby
|
||||||
|
|
||||||
|
from Games.Throot.map import ObstacleSlice, OBSTACLE_SLICES
|
||||||
|
from Games.Throot.sprites import update_entities
|
||||||
|
|
||||||
|
class GameLoop:
|
||||||
|
def __init__(self):
|
||||||
|
self.current_depth = 0
|
||||||
|
self.diving_velocity = 10
|
||||||
|
self.diving_accel = 0
|
||||||
|
self.current_obstacle_slice = OBSTACLE_SLICES[0]
|
||||||
|
self.entities = set()
|
||||||
|
|
||||||
|
def get_obstacle_slice(self):
|
||||||
|
return OBSTACLE_SLICES[randrange(0, len(OBSTACLE_SLICES))]
|
||||||
|
|
||||||
|
def update(self, tpf):
|
||||||
|
"""
|
||||||
|
Executes one tick of the game
|
||||||
|
"""
|
||||||
|
prev_depth = self.current_depth
|
||||||
|
self.diving_velocity += self.diving_accel * tpf
|
||||||
|
self.current_depth += self.diving_velocity * tpf
|
||||||
|
|
||||||
|
if self.current_depth % ObstacleSlice.height < prev_depth % ObstacleSlice.height:
|
||||||
|
self.current_obstacle_slice = self.get_obstacle_slice()
|
||||||
|
|
||||||
|
# Generate new entities as needed
|
||||||
|
self.entities |= update_entities(self.current_obstacle_slice, self.current_depth, prev_depth)
|
||||||
|
|
||||||
|
# Updates the entities
|
||||||
|
to_remove = set()
|
||||||
|
for entity in self.entities:
|
||||||
|
if not entity.update(tpf, self.current_depth, prev_depth):
|
||||||
|
to_remove.add(entity)
|
||||||
|
self.entities -= to_remove
|
||||||
|
|
||||||
|
thumby.display.fill(0)
|
||||||
|
# Draw the entities
|
||||||
|
for entity in self.entities:
|
||||||
|
entity.render(tpf, self.current_depth, prev_depth)
|
||||||
|
thumby.display.update()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Set the FPS (without this call, the default fps is 30)
|
||||||
|
thumby.display.setFPS(60)
|
||||||
|
|
||||||
|
print("Starting game loop")
|
||||||
|
loop = GameLoop()
|
||||||
|
|
||||||
|
prev_time = 0
|
||||||
|
while True:
|
||||||
|
t0 = time.ticks_ms()
|
||||||
|
tps = (t0 - prev_time) / 1000
|
||||||
|
loop.update(tps)
|
||||||
|
prev_time = t0
|
||||||
|
|
||||||
|
main()
|
||||||
19
map.py
19
map.py
@@ -1,4 +1,4 @@
|
|||||||
from typing import List, Tuple
|
import thumby
|
||||||
|
|
||||||
class ObstacleSlice:
|
class ObstacleSlice:
|
||||||
"""
|
"""
|
||||||
@@ -7,11 +7,11 @@ class ObstacleSlice:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
How many units an obstacle slice is
|
How many units an obstacle slice is high
|
||||||
"""
|
"""
|
||||||
height=20
|
height=max(80, thumby.display.height * 2)
|
||||||
|
|
||||||
def __init__(self, obstacle_map: List[Tuple[int]], difficulty: int):
|
def __init__(self, obstacle_map, difficulty: int):
|
||||||
"""
|
"""
|
||||||
Creates an obstacle slice
|
Creates an obstacle slice
|
||||||
|
|
||||||
@@ -24,3 +24,14 @@ class ObstacleSlice:
|
|||||||
"""
|
"""
|
||||||
self.obstacle_map = obstacle_map
|
self.obstacle_map = obstacle_map
|
||||||
self.difficulty = difficulty
|
self.difficulty = difficulty
|
||||||
|
|
||||||
|
OBSTACLE_SLICES = [
|
||||||
|
ObstacleSlice(
|
||||||
|
[
|
||||||
|
(10, 0, 0, 0, 0),
|
||||||
|
(53, 30, 1, 0, 0),
|
||||||
|
(5, 45, 0, 0, 0)
|
||||||
|
],
|
||||||
|
0
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|||||||
36
sprites.py
36
sprites.py
@@ -1,11 +1,9 @@
|
|||||||
from typing import List, Tuple
|
|
||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
import thumby
|
import thumby
|
||||||
|
|
||||||
import images
|
from Games.Throot.map import ObstacleSlice
|
||||||
|
from Games.Throot.artrepository import OBSTACLES
|
||||||
from map import ObstacleSlice
|
|
||||||
|
|
||||||
class Entity:
|
class Entity:
|
||||||
"""
|
"""
|
||||||
@@ -53,8 +51,8 @@ class Entity:
|
|||||||
if self.x < -self.width or self.x >= thumby.display.width:
|
if self.x < -self.width or self.x >= thumby.display.width:
|
||||||
return False
|
return False
|
||||||
max = current_depth
|
max = current_depth
|
||||||
min = current_depth - thumby.display.height
|
min = max - thumby.display.height
|
||||||
if self.y < (min - self.height) or self.y >= max:
|
if self.y < (min - self.height) or self.y > max:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -91,8 +89,8 @@ class Entity:
|
|||||||
should be hidden.
|
should be hidden.
|
||||||
"""
|
"""
|
||||||
if self.sprite:
|
if self.sprite:
|
||||||
self.sprite.y = self.y - self.current_depth
|
self.sprite.y = int(self.y - current_depth + thumby.display.height)
|
||||||
self.sprite.x = self.x
|
self.sprite.x = int(self.x)
|
||||||
if self.can_render(current_depth):
|
if self.can_render(current_depth):
|
||||||
thumby.display.drawSprite(self.sprite)
|
thumby.display.drawSprite(self.sprite)
|
||||||
return True
|
return True
|
||||||
@@ -103,7 +101,7 @@ class Obstacle(Entity):
|
|||||||
return self.can_render(current_depth)
|
return self.can_render(current_depth)
|
||||||
|
|
||||||
|
|
||||||
def update_entities(current_slice: ObstacleSlice, current_depth: int, prev_depth: int) -> List[Entity]:
|
def update_entities(current_slice: ObstacleSlice, current_depth: int, prev_depth: int):
|
||||||
"""
|
"""
|
||||||
Checks the current game state and generates new sprites based on said state.
|
Checks the current game state and generates new sprites based on said state.
|
||||||
|
|
||||||
@@ -122,12 +120,18 @@ def update_entities(current_slice: ObstacleSlice, current_depth: int, prev_depth
|
|||||||
"""
|
"""
|
||||||
if current_depth == prev_depth:
|
if current_depth == prev_depth:
|
||||||
# If we haven't moved, we don't need to spawn anything
|
# If we haven't moved, we don't need to spawn anything
|
||||||
return []
|
return set()
|
||||||
min_height = min(current_depth, prev_depth)
|
# Local y relative to the top of the slice
|
||||||
max_height = max(current_depth, prev_depth)
|
slice_y = (current_depth) % ObstacleSlice.height
|
||||||
spawned = []
|
slice_prev_y = (prev_depth) % ObstacleSlice.height
|
||||||
|
if slice_prev_y > slice_y:
|
||||||
|
slice_prev_y -= ObstacleSlice.height
|
||||||
|
spawned = set()
|
||||||
for entity in current_slice.obstacle_map:
|
for entity in current_slice.obstacle_map:
|
||||||
if y >= min_height and y < max_height:
|
# The position the entity should spawn at, relative to the slice top
|
||||||
|
entity_y = entity[1]
|
||||||
|
if entity_y >= slice_prev_y and entity_y < slice_y:
|
||||||
sprite_image = OBSTACLES[entity[2]]
|
sprite_image = OBSTACLES[entity[2]]
|
||||||
sprite = thumby.Sprite(sprite_image.width, sprite_image.height, sprite_image.sprite, entity[0], entity[1], -1, entity[3] - current_depth, entity[4])
|
sprite = thumby.Sprite(sprite_image.width, sprite_image.height, sprite_image.image, 0, 0, 0, entity[3], entity[4])
|
||||||
spawned = Obstacle(entity[0], entity[1], sprite_image.width, sprite_image.height, sprite_image.collision, sprite)
|
spawned.add(Obstacle(entity[0], entity_y + current_depth // ObstacleSlice.height * ObstacleSlice.height, sprite_image.width, sprite_image.height, sprite_image.collision, sprite))
|
||||||
|
return spawned
|
||||||
|
|||||||
Reference in New Issue
Block a user