Merge remote-tracking branch 'origin/master'

This commit is contained in:
Wirus 2020-04-06 12:23:12 +02:00
commit 6e96b1dfd6
17 changed files with 546 additions and 105 deletions

View File

@ -7,5 +7,18 @@ Skład zespołu:
- Michał Czekański - Michał Czekański
- Marcin Kostrzewski - Marcin Kostrzewski
Poruszanie się: *WASD* ## Wymagania
Podnoszenie obiektów: *SPACJA* ```
Python 3.x
pygame: 1.9.x
```
## Uruchomienie
```
$ python Run.py
```
## Konfiguracja
Plik z konfiguracją znajduje w ```data/config/mainConfig.json```.
## Sterowanie
* Poruszanie się: *WASD*
* Interakcja: *SPACJA*

3
Run.py Normal file
View File

@ -0,0 +1,3 @@
from src.game.Game import Game
game = Game()

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -74,5 +74,416 @@
"thirst": 0, "thirst": 0,
"hunger": -25 "hunger": -25
} }
},
{
"name" : "firepit",
"position" : {
"x": 10,
"y": 7
},
"isPickupable": false,
"effect" : {
"hp": 10,
"stamina": 15,
"thirst": 0,
"hunger": 0
}
},
{
"name" : "purewater",
"position" : {
"x": 3,
"y": 5
},
"isPickupable": false,
"effect" : {
"hp": 2,
"stamina": 2,
"thirst": -40,
"hunger": 0
}
},
{
"name" : "purewater",
"position" : {
"x": 3,
"y": 6
},
"isPickupable": false,
"effect" : {
"hp": 2,
"stamina": 2,
"thirst": -40,
"hunger": 0
}
},
{
"name" : "purewater",
"position" : {
"x": 3,
"y": 7
},
"isPickupable": false,
"effect" : {
"hp": 2,
"stamina": 2,
"thirst": -40,
"hunger": 0
}
},
{
"name" : "purewater",
"position" : {
"x": 2,
"y": 7
},
"isPickupable": false,
"effect" : {
"hp": 2,
"stamina": 2,
"thirst": -40,
"hunger": 0
}
},
{
"name" : "purewater",
"position" : {
"x": 2,
"y": 8
},
"isPickupable": false,
"effect" : {
"hp": 2,
"stamina": 2,
"thirst": -40,
"hunger": 0
}
},
{
"name" : "purewater",
"position" : {
"x": 1,
"y": 8
},
"isPickupable": false,
"effect" : {
"hp": 2,
"stamina": 2,
"thirst": -40,
"hunger": 0
}
},
{
"name" : "rock",
"position" : {
"x": 3,
"y": 4
},
"isPickupable" : false
},
{
"name" : "rock",
"position" : {
"x": 2,
"y": 5
},
"isPickupable" : false
},
{
"name" : "rock",
"position" : {
"x": 4,
"y": 5
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 2,
"y": 2
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 2,
"y": 3
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 2,
"y": 4
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 3,
"y": 2
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 3,
"y": 3
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 13,
"y": 8
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 13,
"y": 7
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 12,
"y": 17
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 12,
"y": 14
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 13,
"y": 14
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 15,
"y": 14
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 13,
"y": 15
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 13,
"y": 16
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 10,
"y": 16
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 10,
"y": 17
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 11,
"y": 17
},
"isPickupable" : false
},
{
"name" : "cranberry",
"position" : {
"x": 12,
"y": 15
},
"isPickupable" : true,
"effect" : {
"hp" : 0,
"stamina" : 5,
"thirst" : -2,
"hunger" : -10
}
},
{
"name" : "berry",
"position" : {
"x": 11,
"y": 16
},
"isPickupable" : true,
"effect" : {
"hp" : -10,
"stamina" : 5,
"thirst" : 0,
"hunger" : -20
}
},
{
"name" : "cranberry",
"position" : {
"x": 5,
"y": 12
},
"isPickupable" : true,
"effect" : {
"hp" : 0,
"stamina" : 5,
"thirst" : -2,
"hunger" : -10
}
},
{
"name" : "cranberry",
"position" : {
"x": 5,
"y": 13
},
"isPickupable" : true,
"effect" : {
"hp" : 0,
"stamina" : 5,
"thirst" : -2,
"hunger" : -10
}
},
{
"name" : "tree",
"position" : {
"x": 6,
"y": 13
},
"isPickupable" : false
},
{
"name" : "rock",
"position" : {
"x": 7,
"y": 15
},
"isPickupable" : false
},
{
"name" : "tree",
"position" : {
"x": 6,
"y": 15
},
"isPickupable" : false
}
,
{
"name" : "tree",
"position" : {
"x": 6,
"y": 14
},
"isPickupable" : false
},
{
"name" : "rabbit",
"position" : {
"x": 17,
"y": 6
},
"isPickupable" : true,
"effect" : {
"hp": 30,
"stamina": -5,
"thirst": -5,
"hunger": -40
}
},
{
"name" : "rabbit",
"position" : {
"x": 3,
"y": 14
},
"isPickupable" : true,
"effect" : {
"hp": 30,
"stamina": -5,
"thirst": -5,
"hunger": -40
}
},
{
"name" : "berry",
"position" : {
"x": 5,
"y": 16
},
"isPickupable" : true,
"effect" : {
"hp" : -10,
"stamina" : 5,
"thirst" : 0,
"hunger" : -20
}
},
{
"name" : "berry",
"position" : {
"x": 7,
"y": 13
},
"isPickupable" : true,
"effect" : {
"hp" : -10,
"stamina" : 5,
"thirst" : 0,
"hunger" : -20
}
},
{
"name" : "bush",
"position" : {
"x": 7,
"y": 5
},
"isPickupable" : false
},
{
"name" : "bush",
"position" : {
"x": 10,
"y": 15
},
"isPickupable" : false
} }
] ]

View File

@ -1,3 +0,0 @@
from game.Game import Game
game = Game()

View File

@ -1,31 +0,0 @@
from src.entities.Entity import Entity
class Collidable(Entity):
def __init__(self, texture, pos, id):
super().__init__(texture, pos, id)
def check_for_collision(self, x_pos, y_pos):
if self.pos[0] == x_pos:
if self.pos[1] == y_pos:
return True
return False
#col = Collidable(1, 1, 1)
"""
def interact_with_hp(self, hp, Statistics):
Statistics.set_hp(hp)
def interact_with_hunger(self, hunger, Statistics):
Statistics.set_hunger(hunger)
def interact_with_thirst(self, thirst, Statistics):
Statistics.set_thirst(thirst)
def interact_with_stamina(self, stamina, Statistics):
Statistics.set_stamina(stamina)"""

View File

@ -2,23 +2,13 @@ from src.entities.Entity import Entity
class Interactable(Entity): class Interactable(Entity):
def __init__(self, texture, size, pos, Statistics):
super().__init__(texture, size, pos)
self.Statistics = Statistics
def __init__(self, texture, pos, id): def on_interaction(self, Player):
super().__init__(texture, pos, id) Player.statistics.set_hp(self.Statistics.hp)
Player.statistics.set_stamina(self.Statistics.stamina)
@staticmethod Player.statistics.set_thirst(self.Statistics.thirst)
def interact_with_hp(hp, Statistics): Player.statistics.set_hunger(self.Statistics.hunger)
Statistics.set_hp(hp)
@staticmethod
def interact_with_hunger(hunger, Statistics):
Statistics.set_hunger(hunger)
@staticmethod
def interact_with_thirst(thirst, Statistics):
Statistics.set_thirst(thirst)
@staticmethod
def interact_with_stamina(stamina, Statistics):
Statistics.set_stamina(stamina)

View File

@ -1,16 +1,8 @@
from src.entities import Statistics, Player
from src.entities.Interactable import Interactable from src.entities.Interactable import Interactable
class Pickupable(Interactable): class Pickupable(Interactable):
def __init__(self, texture, size, pos, Statistics): def __init__(self, texture, size, pos, Statistics):
super().__init__(texture, size, pos) super().__init__(texture, size, pos, Statistics)
self.is_pickupable = True self.is_pickupable = True
self.Statistics = Statistics
def on_pickup(self, Player):
Player.statistics.set_hp(self.Statistics.hp)
Player.statistics.set_stamina(self.Statistics.stamina)
Player.statistics.set_thirst(self.Statistics.thirst)
Player.statistics.set_hunger(self.Statistics.hunger)

View File

@ -1,4 +1,5 @@
from enum import Enum from enum import Enum
import random
from src.entities.Entity import Entity from src.entities.Entity import Entity
from src.entities.Statistics import Statistics from src.entities.Statistics import Statistics
@ -6,8 +7,6 @@ import pygame
class Player(Entity): class Player(Entity):
statistics: Statistics
def __init__(self, spawnpoint, size): def __init__(self, spawnpoint, size):
super().__init__("player.png", size, (spawnpoint[0] * size, spawnpoint[1] * size)) super().__init__("player.png", size, (spawnpoint[0] * size, spawnpoint[1] * size))
# Where the player is facing, 0 - north, 1 # Where the player is facing, 0 - north, 1
@ -15,31 +14,51 @@ class Player(Entity):
self.statistics = Statistics(100, 0, 0, 100) self.statistics = Statistics(100, 0, 0, 100)
# How many steps has the player taken through its lifetime # How many steps has the player taken through its lifetime
self.movePoints = 0 self.movePoints = 0
# Tracks how much time has passed since the player is alive
self.timer = pygame.time.Clock()
self.timeAlive = 1
# Used to determine fatigue
self.fatigueTimeout = 0
self.alive = True
# If a player dies, the death reason is stored here
self.deathReason = None
# Move in a desired direction # Move in a desired direction
def move(self, rotation): def move(self, rotation):
self.movePoints += 1 self.movePoints += 1
# Player gets tired aswell! # You can only move if you have enough stamina
self.applyFatigue() if self.statistics.stamina > 1:
if rotation.value == Rotations.NORTH.value: self.applyWalkingFatigue()
self.rect.y -= self.rect.w if rotation.value == Rotations.NORTH.value:
elif rotation.value == Rotations.EAST.value: self.rect.y -= self.rect.w
self.rect.x += self.rect.w elif rotation.value == Rotations.EAST.value:
elif rotation.value == Rotations.SOUTH.value: self.rect.x += self.rect.w
self.rect.y += self.rect.w elif rotation.value == Rotations.SOUTH.value:
elif rotation.value == Rotations.WEST.value: self.rect.y += self.rect.w
self.rect.x -= self.rect.w elif rotation.value == Rotations.WEST.value:
self.rect.x -= self.rect.w
def applyFatigue(self): def applyWalkingFatigue(self):
# looses hunger every 10 steps taken # looses hunger every 10 steps taken
if self.movePoints % 10 == 0: if self.movePoints % 10 == 0:
self.statistics.set_hunger(10) self.statistics.set_hunger(5)
# gets more thirsty every 5 steps # gets more thirsty every 5 steps
if self.movePoints % 5 == 0: if self.movePoints % 5 == 0:
self.statistics.set_thirst(10) self.statistics.set_thirst(6)
# gets tired every step # gets tired every step
self.statistics.set_stamina(-2) self.statistics.set_stamina(-2)
def applyTimeFatigue(self, tickTime):
self.fatigueTimeout += tickTime
if self.fatigueTimeout >= 700:
self.statistics.set_thirst(5)
self.statistics.set_hunger(3)
# A player can randomly regenerate stamina
if random.randrange(5) == 0:
self.statistics.set_stamina(2)
self.fatigueTimeout = 0
def getFacingCoord(self): def getFacingCoord(self):
if self.rotation == Rotations.NORTH: if self.rotation == Rotations.NORTH:
return self.rect.x, self.rect.y - (self.rect.h) return self.rect.x, self.rect.y - (self.rect.h)
@ -71,6 +90,31 @@ class Player(Entity):
self.image = pygame.transform.rotate(self.image, ((self.rotation.value - rotation.value) * 90)) self.image = pygame.transform.rotate(self.image, ((self.rotation.value - rotation.value) * 90))
self.rotation = rotation self.rotation = rotation
# Updates self.alive if any of the statistic reaches critical value
def determineLife(self):
if self.statistics.hunger == 100:
self.alive = False
self.deathReason = StatisticNames.HUNGER
elif self.statistics.thirst == 100:
self.alive = False
self.deathReason = StatisticNames.THIRST
elif self.statistics.hp == 0:
self.alive = False
self.deathReason = StatisticNames.HP
# Change texture after dying
if not self.alive:
self.image, null = self.getTexture("gravestone.png", self.rect.h)
# Called every frame
def update(self):
if self.alive:
self.timeAlive += self.timer.get_time()
# Player gets tired every once in a while
self.applyTimeFatigue(self.timer.get_time())
self.timer.tick()
self.determineLife()
class Rotations(Enum): class Rotations(Enum):
NORTH = 0 NORTH = 0

View File

@ -1,5 +1,6 @@
import pygame import pygame
from src.entities.Interactable import Interactable
from src.entities.Pickupable import Pickupable from src.entities.Pickupable import Pickupable
from src.entities.Player import Rotations from src.entities.Player import Rotations
@ -39,27 +40,35 @@ class EventManager:
def handlePlayerControls(self, keys): def handlePlayerControls(self, keys):
# Key names are temporary # Key names are temporary
# TODO: Load key bindings from JSON # TODO: Load key bindings from JSON
if keys[pygame.K_SPACE]:
object = self.game.map.getEntityOnCoord(self.player.getFacingCoord()) if self.player.alive:
if type(object) is Pickupable: # Picking up items
object.on_pickup(self.player) if keys[pygame.K_SPACE]:
self.game.map.removeSpriteFromMap(object) object = self.game.map.getEntityOnCoord(self.player.getFacingCoord())
if keys[pygame.K_w]: # Picked up item gets removed from the map
self.player.rotate(Rotations.NORTH) if type(object) is Pickupable:
if not self.game.map.collision(self.player.rect.x, self.player.rect.y - self.player.rect.w): object.on_interaction(self.player)
self.player.move(Rotations.NORTH) self.game.map.removeSpriteFromMap(object)
if keys[pygame.K_s]: elif type(object) is Interactable:
self.player.rotate(Rotations.SOUTH) object.on_interaction(self.player)
if not self.game.map.collision(self.player.rect.x, self.player.rect.y + self.player.rect.w):
self.player.move(Rotations.SOUTH) # Movement
if keys[pygame.K_d]: if keys[pygame.K_w]:
self.player.rotate(Rotations.EAST) self.player.rotate(Rotations.NORTH)
if not self.game.map.collision(self.player.rect.x + self.player.rect.w, self.player.rect.y): if not self.game.map.collision(self.player.rect.x, self.player.rect.y - self.player.rect.w):
self.player.move(Rotations.EAST) self.player.move(Rotations.NORTH)
if keys[pygame.K_a]: if keys[pygame.K_s]:
self.player.rotate(Rotations.WEST) self.player.rotate(Rotations.SOUTH)
if not self.game.map.collision(self.player.rect.x - self.player.rect.w, self.player.rect.y): if not self.game.map.collision(self.player.rect.x, self.player.rect.y + self.player.rect.w):
self.player.move(Rotations.WEST) self.player.move(Rotations.SOUTH)
if keys[pygame.K_d]:
self.player.rotate(Rotations.EAST)
if not self.game.map.collision(self.player.rect.x + self.player.rect.w, self.player.rect.y):
self.player.move(Rotations.EAST)
if keys[pygame.K_a]:
self.player.rotate(Rotations.WEST)
if not self.game.map.collision(self.player.rect.x - self.player.rect.w, self.player.rect.y):
self.player.move(Rotations.WEST)

View File

@ -3,13 +3,11 @@ import json
from pathlib import Path from pathlib import Path
from os import path from os import path
from game.EventManager import EventManager from src.game.EventManager import EventManager
from game.Screen import Screen from src.game.Screen import Screen
from game.Map import Map from src.game.Map import Map
from src.entities.Pickupable import Pickupable
from src.entities.Player import Player from src.entities.Player import Player
from src.entities.Statistics import Statistics
from src.game.Timer import Timer from src.game.Timer import Timer
@ -61,6 +59,7 @@ class Game:
while self.running: while self.running:
# Update ingame clock # Update ingame clock
self.ingameTimer.updateTime(self.pgTimer.tick()) self.ingameTimer.updateTime(self.pgTimer.tick())
self.spritesList.update()
self.eventManager.handleEvents() self.eventManager.handleEvents()
self.spritesList.draw(self.screen.pygameScreen) self.spritesList.draw(self.screen.pygameScreen)
pygame.display.flip() pygame.display.flip()

View File

@ -1,6 +1,8 @@
import json import json
import pygame import pygame
from src.entities.Interactable import Interactable
from src.game.TerrainTile import TerrainTile from src.game.TerrainTile import TerrainTile
from src.game.Screen import Locations from src.game.Screen import Locations
@ -41,6 +43,7 @@ class Map:
entityListJson = json.loads(file.read()) entityListJson = json.loads(file.read())
for entity in entityListJson: for entity in entityListJson:
try: try:
# Creates a pickupable object
if entity["isPickupable"]: if entity["isPickupable"]:
actualEntities.append(Pickupable(entity["name"] + ".png", actualEntities.append(Pickupable(entity["name"] + ".png",
self.tileSize, self.tileSize,
@ -49,6 +52,17 @@ class Map:
entity["effect"]["hunger"], entity["effect"]["hunger"],
entity["effect"]["thirst"], entity["effect"]["thirst"],
entity["effect"]["stamina"]))) entity["effect"]["stamina"])))
# Creates an interactable object
elif "effect" in entity:
actualEntities.append(Interactable(entity["name"] + ".png",
self.tileSize,
(entity["position"]["x"] * self.tileSize,
entity["position"]["y"] * self.tileSize),
Statistics(entity["effect"]["hp"],
entity["effect"]["hunger"],
entity["effect"]["thirst"],
entity["effect"]["stamina"])))
# Creates plain entity
else: else:
actualEntities.append(Entity(entity["name"] + ".png", actualEntities.append(Entity(entity["name"] + ".png",
self.tileSize, self.tileSize,

View File

@ -78,7 +78,7 @@ class Ui():
if self.thirstBar.value != statistics.thirst: if self.thirstBar.value != statistics.thirst:
self.thirstBar.updateFill(statistics.thirst) self.thirstBar.updateFill(statistics.thirst)
consoleLines.append(self.timer.getPrettyTime() + " - Stamina: " + str(statistics.thirst)) consoleLines.append(self.timer.getPrettyTime() + " - Thirst: " + str(statistics.thirst))
if len(consoleLines) > 0: if len(consoleLines) > 0:
self.console.addLinesToConsoleAndScrollToDisplayThem(consoleLines) self.console.addLinesToConsoleAndScrollToDisplayThem(consoleLines)