initial commit

This commit is contained in:
= 2021-03-04 14:07:44 +01:00
parent f4b8389ef0
commit ee2e5092bc
24 changed files with 336 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/../../../:\ai-project\.idea/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

8
.idea/ai-project.iml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ai-project.iml" filepath="$PROJECT_DIR$/.idea/ai-project.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

BIN
assets/apple.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
assets/map1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
assets/map2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
assets/map3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
assets/map4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
assets/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
assets/stone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

BIN
assets/tree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
assets/water.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
assets/wood.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

44
survival/__init__.py Normal file
View File

@ -0,0 +1,44 @@
import pygame
from game.game_map import GameMap
window_width = 1280
window_height = 720
def draw_game():
game_map.draw(win)
pygame.display.update()
def update_game(pressed_keys):
game_map.update(pressed_keys)
pass
if __name__ == '__main__':
pygame.init()
win = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("AI Project")
clock = pygame.time.Clock()
game_map = GameMap(int(window_width/32), int(window_height/32) + 1)
run = True
while run:
# Set the framerate
clock.tick(60)
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
draw_game()
update_game(keys)

16
survival/camera.py Normal file
View File

@ -0,0 +1,16 @@
from pygame.rect import Rect
class Camera:
def __init__(self, width, height):
self.camera = Rect(0, 0, width, height)
self.width = width
self.height = height
def apply(self, game_object):
return game_object.get_rect().move(self.camera.topleft)
def update(self, target_object):
x = -target_object.get_rect().x + int(self.width / 2)
y = -target_object.get_rect().y + int(self.height / 2)
self.camera = Rect(x, y, self.width, self.height)

50
survival/game_map.py Normal file
View File

@ -0,0 +1,50 @@
import os
import pygame
from pygame.rect import Rect
from game.player import Player
from game.quad_tree import QuadTree
from game.stone import Stone
from game.tile import Tile
class GameMap:
def __init__(self, width, height):
self.width = width
self.height = height
self.game_objects = []
self.player = Player()
self.game_objects.append(self.player)
self.tiles = [[Tile() for x in range(width)] for y in range(height)]
self.textures = [pygame.image.load(os.path.join('..', 'assets', 'map1.png')),
pygame.image.load(os.path.join('..', 'assets', 'map2.png')),
pygame.image.load(os.path.join('..', 'assets', 'map3.png')),
pygame.image.load(os.path.join('..', 'assets', 'map4.png'))]
self.game_objects.append(Stone([100, 200]))
self.quad_tree = QuadTree(0, Rect(0, 0, width * 32, height * 32))
def draw(self, window):
for y in range(self.height):
for x in range(self.width):
window.blit(self.textures[self.tiles[y][x].background_id], (x * 32, y * 32))
for game_object in self.game_objects:
game_object.draw(window)
def update(self, pressed_keys):
self.quad_tree.clear()
for game_object in self.game_objects:
self.quad_tree.insert(game_object)
self.player.update(pressed_keys)
for game_object in self.game_objects:
possible_colliders = []
self.quad_tree.retrieve(possible_colliders, game_object)
for collider in possible_colliders:
if game_object.get_rect().colliderect(collider.get_rect()) and game_object != collider:
game_object.velocity = [0, 0]
game_object.pos = game_object.last_pos

20
survival/game_object.py Normal file
View File

@ -0,0 +1,20 @@
import pygame
from pygame.rect import Rect
class GameObject:
def __init__(self, pos, texture):
self.pos = pos
self.last_pos = pos
self.texture = pygame.image.load(texture)
self.texture = pygame.transform.scale(self.texture, (64, 64))
self.width = self.texture.get_width()
self.height = self.texture.get_height()
self.velocity = [0, 0]
def draw(self, window):
window.blit(self.texture, self.pos)
def get_rect(self):
return Rect(self.pos[0], self.pos[1], self.width, self.height)

34
survival/player.py Normal file
View File

@ -0,0 +1,34 @@
import os
import pygame
from game.game_object import GameObject
class Player(GameObject):
def __init__(self):
super().__init__([0, 0], os.path.join('..', 'assets', 'player.png'))
def draw(self, window):
super().draw(window)
def update(self, pressed_keys):
if pressed_keys[pygame.K_LEFT]:
self.velocity[0] = -1
elif pressed_keys[pygame.K_RIGHT]:
self.velocity[0] = 1
else:
self.velocity[0] = 0
if pressed_keys[pygame.K_DOWN]:
self.velocity[1] = 1
elif pressed_keys[pygame.K_UP]:
self.velocity[1] = -1
else:
self.velocity[1] = 0
self.last_pos = [self.pos[0], self.pos[1]]
self.pos[0] += self.velocity[0]
self.pos[1] += self.velocity[1]

116
survival/quad_tree.py Normal file
View File

@ -0,0 +1,116 @@
import pygame
from pygame.rect import Rect
class QuadTree:
"""
How to use:
1) Create new quadtree: QuadTree(0, Rect(0, 0, width, height))
2) Every frame clear the quadtree and insert all objects into it.
3) Get the possible colliders for each objects and check if they collide.
for object in objects:
possible_colliders = []
possible_colliders = quad_tree.retrieve(possible_colliders, object)
for collider in possible_colliders:
# Check collision here
"""
MAX_OBJECTS = 10
MAX_LEVELS = 5
def __init__(self, level, bounds):
self.level = level
self.bounds = bounds
self.objects = []
self.nodes = []
def clear(self):
"""
Clears the quadtree recursively.
"""
self.objects.clear()
for node in self.nodes:
if node is not None:
node.clear()
def split(self):
"""
Splits the node into 4 sub nodes.
"""
sub_width = int(self.bounds.width / 2)
sub_height = int(self.bounds.height / 2)
x = int(self.bounds.x)
y = int(self.bounds.y)
self.nodes.append(QuadTree(self.level + 1, Rect(x + sub_width, y, sub_width, sub_height)))
self.nodes.append(QuadTree(self.level + 1, Rect(x, y, sub_width, sub_height)))
self.nodes.append(QuadTree(self.level + 1, Rect(x, y + sub_height, sub_width, sub_height)))
self.nodes.append(QuadTree(self.level + 1, Rect(x + sub_width, y + sub_height, sub_width, sub_height)))
def get_index(self, rect):
"""
Checks which node the object belongs to.
"""
index = -1
vertical_point = self.bounds.x + (self.bounds.width / 2)
horizontal_point = self.bounds.y + (self.bounds.height / 2)
top_quadrant = rect.y < horizontal_point and rect.y + rect.height < horizontal_point
bot_quadrant = rect.y > horizontal_point
if rect.x < vertical_point and rect.x + rect.width < vertical_point:
if top_quadrant:
index = 1
elif bot_quadrant:
index = 2
elif rect.x > vertical_point:
if top_quadrant:
index = 0
elif bot_quadrant:
index = 3
return index
def insert(self, game_object):
"""
Inserts given game object into the quadtree.
If objects count exceeds the limit the node is split and
all objects are added to their corresponding nodes.
"""
rect = Rect(game_object.pos[0], game_object.pos[1], game_object.width, game_object.height)
if len(self.nodes) > 0:
index = self.get_index(rect)
if index != -1:
self.nodes[index].insert(rect)
return
self.objects.append(game_object)
if len(self.objects) > self.MAX_OBJECTS and self.level < self.MAX_LEVELS:
if len(self.nodes) == 0:
self.split()
i = 0
while i < len(self.objects):
index = self.get_index(self.objects[i])
if index == -1:
i += 1
else:
self.nodes[index].insert(self.objects.remove(i))
def retrieve(self, objects, game_object):
"""
Returns all objects that collide with given rectangle.
"""
rect = game_object.get_rect()
index = self.get_index(rect)
if index != -1 and len(self.nodes) > 0:
self.nodes[index].retrieve(objects, rect)
objects.extend(self.objects)

9
survival/stone.py Normal file
View File

@ -0,0 +1,9 @@
import os
from game.game_object import GameObject
class Stone(GameObject):
def __init__(self, pos):
super().__init__(pos, os.path.join('..', 'assets', 'stone.png'))

7
survival/tile.py Normal file
View File

@ -0,0 +1,7 @@
import pygame
from random import randrange
class Tile:
def __init__(self):
self.background_id = randrange(4)