Skip to content

Commit 289e49e

Browse files
Merge pull request #36 from Stephenson-Software/world-screen
World Screen
2 parents 84abdd5 + 2fbaf7d commit 289e49e

File tree

3 files changed

+355
-336
lines changed

3 files changed

+355
-336
lines changed

src/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def __init__(self):
1212
self.fullscreen = False
1313
self.black = (0,0,0)
1414
self.white = (255,255,255)
15-
self.tickSpeed = 0.1
15+
self.tickSpeed = 1/30 # 30 frames per second
1616
self.limitTickSpeed = True
1717
self.gridSize = 16
1818
self.playerMovementEnergyCost = 0.2

src/roam.py

Lines changed: 9 additions & 335 deletions
Original file line numberDiff line numberDiff line change
@@ -1,365 +1,39 @@
1-
import datetime
21
from math import ceil, floor
3-
import time
42
import pygame
5-
from apple import Apple
6-
from grid import Grid
7-
from location import Location
8-
from wood import Wood
93
from config import Config
10-
from food import Food
114
from graphik import Graphik
12-
from grass import Grass
13-
from leaves import Leaves
14-
from map import Map
15-
from player import Player
165
from status import Status
6+
from worldScreen import WorldScreen
177

188

199
# @author Daniel McCoy Stephenson
2010
# @since August 8th, 2022
2111
class Roam:
2212
def __init__(self):
23-
self.config = Config()
24-
self.running = True
25-
self.tick = 0
2613
pygame.init()
2714
pygame.display.set_caption("Roam")
28-
self.initializeGameDisplay()
2915
pygame.display.set_icon(pygame.image.load('src/icon.PNG'))
16+
self.config = Config()
17+
self.running = True
18+
self.tick = 0
19+
self.gameDisplay = self.initializeGameDisplay()
3020
self.graphik = Graphik(self.gameDisplay)
31-
self.map = Map(self.config.gridSize, self.graphik)
32-
self.currentRoom = self.map.getSpawnRoom()
33-
self.initializeLocationWidthAndHeight()
34-
self.player = Player()
35-
self.score = 0
36-
self.numApplesEaten = 0
3721
self.status = Status(self.graphik)
3822
self.status.set("entered the world", self.tick)
39-
self.numDeaths = 0
23+
self.worldScreen = WorldScreen(self.graphik, self.config, self.status, self.tick)
4024

4125
def initializeGameDisplay(self):
4226
if self.config.fullscreen:
43-
self.gameDisplay = pygame.display.set_mode((self.config.displayWidth, self.config.displayHeight), pygame.FULLSCREEN)
27+
return pygame.display.set_mode((self.config.displayWidth, self.config.displayHeight), pygame.FULLSCREEN)
4428
else:
45-
self.gameDisplay = pygame.display.set_mode((self.config.displayWidth, self.config.displayHeight), pygame.RESIZABLE)
46-
47-
def initializeLocationWidthAndHeight(self):
48-
x, y = self.gameDisplay.get_size()
49-
self.locationWidth = x/self.currentRoom.getGrid().getRows()
50-
self.locationHeight = y/self.currentRoom.getGrid().getColumns()
51-
52-
def printStats(self):
53-
print("=== Stats ===")
54-
print("Rooms Explored: " + str(len(self.map.getRooms())) + "/" + str((self.config.worldBorder + 1)*(self.config.worldBorder + 1)))
55-
print("Apples eaten: " + str(self.numApplesEaten))
56-
print("Items in inventory: " + str(len(self.player.getInventory().getContents())))
57-
print("Number of deaths: " + str(self.numDeaths))
58-
print("")
59-
print("Score: " + str(self.score))
60-
print("----------")
29+
return pygame.display.set_mode((self.config.displayWidth, self.config.displayHeight), pygame.RESIZABLE)
6130

6231
def quitApplication(self):
63-
self.printStats()
6432
pygame.quit()
6533
quit()
66-
67-
def getLocationOfPlayer(self):
68-
return self.map.getLocation(self.player, self.currentRoom)
69-
70-
def getLocationDirection(self, direction: int, grid: Grid, location: Location):
71-
if direction == 0:
72-
return grid.getUp(location)
73-
elif direction == 1:
74-
return grid.getLeft(location)
75-
elif direction == 2:
76-
return grid.getDown(location)
77-
elif direction == 3:
78-
return grid.getRight(location)
79-
80-
def getCoordinatesForNewRoomBasedOnPlayerLocation(self):
81-
location = self.getLocationOfPlayer()
82-
x = self.currentRoom.getX()
83-
y = self.currentRoom.getY()
84-
if location.getX() == self.config.gridSize - 1:
85-
# we are on the right side of this room
86-
x += 1
87-
elif location.getX() == 0:
88-
# we are on the left side of this room
89-
x -= 1
90-
elif location.getY() == self.config.gridSize - 1:
91-
# we are at the bottom of this room
92-
y += 1
93-
elif location.getY() == 0:
94-
# we are at the top of this room
95-
y -= 1
96-
return x, y
97-
98-
def changeRooms(self):
99-
x, y = self.getCoordinatesForNewRoomBasedOnPlayerLocation()
100-
101-
if abs(x) > self.config.worldBorder or abs(y) > self.config.worldBorder:
102-
self.status.set("reached world border", self.tick)
103-
return
104-
105-
playerLocation = self.getLocationOfPlayer()
106-
self.currentRoom.removeEntity(self.player)
107-
108-
room = self.map.getRoom(x, y)
109-
if room == -1:
110-
x, y = self.getCoordinatesForNewRoomBasedOnPlayerLocation()
111-
self.currentRoom = self.map.generateNewRoom(x, y)
112-
self.status.set("new area discovered", self.tick)
113-
else:
114-
self.currentRoom = room
115-
116-
targetX = playerLocation.getX()
117-
targetY = playerLocation.getY()
118-
119-
min = 0
120-
max = self.config.gridSize - 1
121-
if playerLocation.getY() == min:
122-
targetY = max
123-
elif playerLocation.getY() == max:
124-
targetY = min
125-
126-
if playerLocation.getX() == min:
127-
targetX = max
128-
elif playerLocation.getX() == max:
129-
targetX = min
130-
131-
targetLocation = self.currentRoom.getGrid().getLocationByCoordinates(targetX, targetY)
132-
self.currentRoom.addEntityToLocation(self.player, targetLocation)
133-
self.initializeLocationWidthAndHeight()
134-
pygame.display.set_caption(("Roam " + str(self.currentRoom.getName())))
135-
136-
def movePlayer(self, direction: int):
137-
if direction == -1:
138-
return
139-
140-
location = self.getLocationOfPlayer()
141-
newLocation = self.getLocationDirection(direction, self.currentRoom.getGrid(), location)
142-
143-
if newLocation == -1:
144-
# we're at a border
145-
self.changeRooms()
146-
return
147-
148-
if self.map.locationContainsEntity(newLocation, Wood):
149-
# apple trees are solid
150-
return
151-
152-
# search for food
153-
for entity in newLocation.getEntities():
154-
if isinstance(entity, Food):
155-
newLocation.removeEntity(entity)
156-
scoreIncrease = 1 * len(self.map.getRooms())
157-
self.score += scoreIncrease
158-
self.player.addEnergy(entity.getEnergy())
159-
160-
if isinstance(entity, Apple):
161-
self.numApplesEaten += 1
162-
self.status.set("ate '" + entity.getName() + "'", self.tick)
163-
164-
# move player
165-
location.removeEntity(self.player)
166-
newLocation.addEntity(self.player)
16734

168-
# decrease energy
169-
self.player.removeEnergy(self.config.playerMovementEnergyCost)
170-
171-
def canBePickedUp(self, entity):
172-
itemTypes = [Wood, Leaves, Grass, Apple]
173-
for itemType in itemTypes:
174-
if isinstance(entity, itemType):
175-
return True
176-
return False
177-
178-
def executeInteractAction(self):
179-
playerLocation = self.getLocationOfPlayer()
180-
181-
toCheck = []
182-
toCheck.append(playerLocation)
183-
toCheck.append(self.currentRoom.getGrid().getUp(playerLocation))
184-
toCheck.append(self.currentRoom.getGrid().getLeft(playerLocation))
185-
toCheck.append(self.currentRoom.getGrid().getDown(playerLocation))
186-
toCheck.append(self.currentRoom.getGrid().getRight(playerLocation))
187-
188-
toRemove = -1
189-
for location in toCheck:
190-
if location == -1:
191-
continue
192-
reversedEntityList = list(reversed(location.getEntities()))
193-
for entity in reversedEntityList:
194-
if self.canBePickedUp(entity):
195-
toRemove = entity
196-
break
197-
if toRemove != -1:
198-
break
199-
200-
if toRemove == -1:
201-
return
202-
203-
self.currentRoom.removeEntity(toRemove)
204-
self.player.getInventory().place(toRemove)
205-
self.status.set("picked up '" + entity.getName() + "'", self.tick)
206-
207-
def executePlaceAction(self):
208-
if len(self.player.getInventory().getContents()) == 0:
209-
self.status.set("no items", self.tick)
210-
return
211-
212-
playerLocation = self.getLocationOfPlayer()
213-
targetLocation = self.currentRoom.getGrid().getUp(playerLocation)
214-
if targetLocation == -1:
215-
self.status.set("no location above player", self.tick)
216-
return
217-
if self.map.locationContainsEntity(targetLocation, Wood):
218-
self.status.set("blocked by apple tree", self.tick)
219-
return
220-
221-
toPlace = self.player.getInventory().getContents().pop()
222-
223-
if toPlace == -1:
224-
return
225-
226-
self.currentRoom.addEntityToLocation(toPlace, targetLocation)
227-
self.status.set("placed '" + toPlace.getName() + "'", self.tick)
228-
229-
# @source https://stackoverflow.com/questions/63342477/how-to-take-screenshot-of-entire-display-pygame
230-
def captureScreen(self, name, pos, size): # (pygame Surface, String, tuple, tuple)
231-
image = pygame.Surface(size) # Create image surface
232-
image.blit(self.gameDisplay, (0,0), (pos, size)) # Blit portion of the display to the image
233-
pygame.image.save(image, name) # Save the image to the disk**
234-
235-
def handleKeyDownEvent(self, key):
236-
if key == pygame.K_ESCAPE:
237-
self.quitApplication()
238-
elif key == pygame.K_F11:
239-
if self.config.fullscreen:
240-
self.config.fullscreen = False
241-
else:
242-
self.config.fullscreen = True
243-
self.initializeGameDisplay()
244-
elif key == pygame.K_l:
245-
if self.config.limitTickSpeed:
246-
self.config.limitTickSpeed = False
247-
else:
248-
self.config.limitTickSpeed = True
249-
elif key == pygame.K_w or key == pygame.K_UP:
250-
self.player.setDirection(0)
251-
elif key == pygame.K_a or key == pygame.K_LEFT:
252-
self.player.setDirection(1)
253-
elif key == pygame.K_s or key == pygame.K_DOWN:
254-
self.player.setDirection(2)
255-
elif key == pygame.K_d or key == pygame.K_RIGHT:
256-
self.player.setDirection(3)
257-
elif key == pygame.K_e:
258-
self.player.setInteracting(True)
259-
elif key == pygame.K_q:
260-
self.player.setPlacing(True)
261-
elif key == pygame.K_PRINTSCREEN:
262-
x, y = self.gameDisplay.get_size()
263-
self.captureScreen("screenshot-" + str(datetime.datetime.now()).replace(" ", "-").replace(":", ".") +".png", (0,0), (x,y))
264-
self.status.set("screenshot saved", self.tick)
265-
266-
def handleKeyUpEvent(self, key):
267-
if (key == pygame.K_w or key == pygame.K_UP) and self.player.getDirection() == 0:
268-
self.player.setDirection(-1)
269-
elif (key == pygame.K_a or key == pygame.K_LEFT) and self.player.getDirection() == 1:
270-
self.player.setDirection(-1)
271-
elif (key == pygame.K_s or key == pygame.K_DOWN) and self.player.getDirection() == 2:
272-
self.player.setDirection(-1)
273-
elif (key == pygame.K_d or key == pygame.K_RIGHT) and self.player.getDirection() == 3:
274-
self.player.setDirection(-1)
275-
elif key == pygame.K_e:
276-
self.player.setInteracting(False)
277-
elif key == pygame.K_q:
278-
self.player.setPlacing(False)
279-
280-
def respawnPlayer(self):
281-
self.currentRoom.removeEntity(self.player)
282-
self.map.getSpawnRoom().addEntity(self.player)
283-
self.currentRoom = self.map.getSpawnRoom()
284-
self.player.energy = self.player.maxEnergy
285-
self.player.getInventory().clear()
286-
self.status.set("respawned", self.tick)
287-
pygame.display.set_caption(("Roam - " + str(self.currentRoom.getName())))
288-
289-
def displayInfo(self):
290-
x, y = self.gameDisplay.get_size()
291-
startingX = x/8
292-
startingY = y/8
293-
size = 30
294-
self.displayEnergy(startingX, startingY, size)
295-
296-
def displayEnergy(self, startingX, startingY, size):
297-
self.graphik.drawText("Energy:", startingX, startingY - size/2, size, self.config.black)
298-
self.graphik.drawText(str(floor((self.player.getEnergy()))), startingX, startingY + size/2, size, self.config.black)
299-
300-
def displayInventoryTopItem(self):
301-
x, y = self.gameDisplay.get_size()
302-
xpos = x - x/8
303-
ypos = y/10
304-
size = 15
305-
inventory = self.player.getInventory()
306-
if len(inventory.getContents()) == 0:
307-
return
308-
topItem = inventory.getContents()[-1]
309-
self.graphik.drawText("Next item: " + topItem.getName(), xpos, ypos, size, self.config.black)
310-
31135
def run(self):
312-
self.currentRoom.addEntity(self.player)
313-
while self.running:
314-
for event in pygame.event.get():
315-
if event.type == pygame.QUIT:
316-
self.quitApplication()
317-
elif event.type == pygame.KEYDOWN:
318-
self.handleKeyDownEvent(event.key)
319-
elif event.type == pygame.KEYUP:
320-
self.handleKeyUpEvent(event.key)
321-
elif event.type == pygame.WINDOWRESIZED:
322-
self.initializeLocationWidthAndHeight()
323-
elif event.type == pygame.VIDEORESIZE:
324-
self.simulation.initializeLocationWidthAndHeight()
325-
326-
self.movePlayer(self.player.direction)
327-
328-
if self.player.isInteracting():
329-
self.executeInteractAction()
330-
elif self.player.isPlacing():
331-
self.executePlaceAction()
332-
333-
# remove energy and check for death
334-
self.player.removeEnergy(0.05)
335-
if self.player.isDead():
336-
self.status.set("you died", self.tick)
337-
self.score = ceil(self.score * 0.9)
338-
self.numDeaths += 1
339-
340-
self.status.checkForExpiration(self.tick)
341-
342-
# draw
343-
self.gameDisplay.fill(self.currentRoom.getBackgroundColor())
344-
self.currentRoom.draw(self.locationWidth, self.locationHeight)
345-
self.status.draw()
346-
347-
# display
348-
self.displayInfo()
349-
self.displayInventoryTopItem()
350-
351-
# update
352-
pygame.display.update()
353-
354-
if self.config.limitTickSpeed:
355-
time.sleep(self.config.tickSpeed)
356-
self.tick += 1
357-
358-
if self.player.isDead():
359-
time.sleep(3)
360-
self.respawnPlayer()
361-
362-
self.quitApplication()
36+
self.worldScreen.run()
36337

36438
roam = Roam()
36539
roam.run()

0 commit comments

Comments
 (0)