Commit 256181fc authored by Alexander Palmisano's avatar Alexander Palmisano
Browse files

added base 2p snake

parents
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# PyCharm
.idea
# Dolphin
.directory
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### PyCharm Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/**/sonarlint/
# SonarQube Plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# End of https://www.toptal.com/developers/gitignore/api/pycharm
\ No newline at end of file
This diff is collapsed.
<h1>PySnake for 2 players</h1>
A Snake game for two players, implemented using PyGame and Python 3
<h3>Main features:</h3>
- Collect apples and race with your friends
- Score counter for both players
- Splash Screen
<h3>Screenshots:</h3>
<img src="https://i.imgur.com/ZFCMEdb.png" alt="Splash Screen">
<img src="https://i.imgur.com/xfimUEa.png" alt="Gameplay">
<h3>Used sources:</h3>
- PyGame tutorial by Sentdex & TheNewBoston: https://youtu.be/K5F-aGDIYaM
import pygame, random
import maps
#collect certain amount of apples to win
#or cutoff your enemy
pygame.init()
white = (255, 255, 255)
black = (0, 0, 0)
grey = (60, 60, 60)
red = (200, 0, 0)
light_red = (255, 0, 0)
green = (0, 155, 0)
light_green = (0, 205, 0) # Hovering
dark_green = (0, 80, 0)
purple = (214, 32, 211)
blue = (0, 0, 255)
light_blue = (61,178,253)
yellow = (200, 200, 0)
light_yellow = (255, 255, 0)
green_head = pygame.image.load('data/SnakeHeadGreen.png')
purple_head = pygame.image.load('data/SnakeHeadPurple.png')
blue_head = pygame.image.load('data/SnakeHeadBlue.png')
green_apple = pygame.image.load('data/AppleGreen.png')
purple_apple = pygame.image.load('data/ApplePurple.png')
font = pygame.font.SysFont("comicsansms", 50)
smallfont = pygame.font.SysFont("comicsansms", 25)
bigfont = pygame.font.SysFont("comicsansms", 85)
res_x = 600
res_y = 600
Display = pygame.display.set_mode((res_x, res_y))
FPS = 50
update_frame = 6
block_size = 20
path = 20
apple_size = 20
apple_count = 3
apple_win = 20
pygame.display.set_caption("Snake Game")
pygame.display.set_icon(green_head)
clock = pygame.time.Clock()
direction = "right"
apples = [(set([]), green_apple),(set([]), purple_apple)]
startpos = maps.startpos2
map = maps.map2
class Snake:
def __init__(self, pos, vel, angle, image, color=green, apple_img=green_apple):
self.pos = pos
self.vel = vel
self.angle = angle
self.img = image
self.list = []
self.vellist = []
self.length = 10
self.head = self.img
self.color = color
self.count = 0
self.start = True
self.direction = ""
self.score = 0
self.apple_img = apple_img
def score_display(self, pos):
score(self.score, pos, self.color)
def key_event(self, direction):
self.angle = direction
def getscore(self):
return score
def eat(self):
for a,img in apples:
for apple in a:
if self.pos[0] > apple.pos[0] and self.pos[0] < apple.pos[0] + apple_size or self.pos[0] + block_size > apple.pos[0] and self.pos[0] < apple.pos[0] + apple_size:
if self.pos[1] > apple.pos[1] and self.pos[1] < apple.pos[1] + apple.size or self.pos[1] + block_size > apple.pos[1] and self.pos[1] < apple.pos[1] + apple.size:
if self.apple_img is img:
a.remove(apple)
a.add(randAppleGen(img))
self.score += 1
def turn_right(self):
self.vel[0] = +block_size
self.vel[1] = 0
self.head = pygame.transform.rotate(self.img, 270)
self.direction="right"
def turn_left(self):
self.vel[0] = -block_size
self.vel[1] = 0
self.head = pygame.transform.rotate(self.img, 90)
self.direction="left"
def turn_up(self):
self.head = self.img
self.vel[1] = -block_size
self.vel[0] = 0
self.direction="up"
def turn_down(self):
self.vel[1] = +block_size
self.vel[0] = 0
self.head = pygame.transform.rotate(self.img, 180)
self.direction="down"
def get_surround(self):
left = (map[int(self.pos[1] // path)][int((self.pos[0] - block_size) // path)] == 0)
right = (map[int(self.pos[1] // path)][int((self.pos[0] + block_size) // path)] == 0)
down = (map[int((self.pos[1] + block_size) // path)][int((self.pos[0]) // path)] == 0)
up = (map[int((self.pos[1] - block_size) // path)][int((self.pos[0]) // path)] == 0)
return left, right, up, down
def auto_turn(self):
gameOver = False
self.pos[0] -= self.vel[0]
self.pos[1] -= self.vel[1]
left, right, up, down = self.get_surround()
# print(left, right, up, down)
if self.direction == "down" and right and not down:
self.turn_right()
self.angle = "right"
elif self.direction == "down" and left and not down:
self.turn_left()
self.angle = "left"
elif self.direction == "up" and right and not up:
self.turn_right()
self.angle = "right"
elif self.direction == "up" and left and not up:
self.turn_left()
self.angle = "left"
elif self.direction == "left" and up and not left:
self.turn_up()
self.angle = "up"
elif self.direction == "left" and down and not left:
self.turn_down()
self.angle = "down"
elif self.direction == "right" and up and not right:
self.turn_up()
self.angle = "up"
elif self.direction == "right" and down and not right:
self.turn_down()
self.angle = "down"
else:
gameOver = True
self.pos[0] += self.vel[0]
self.pos[1] += self.vel[1]
return gameOver
def update(self):
gameOver = False
if self.count % update_frame == 0:
left, right, up, down = self.get_surround()
if (self.angle == "right") and (self.vel[0] != -block_size) and right:
self.turn_right()
elif (self.angle == "left") and (self.vel[0] != block_size) and left:
self.turn_left()
elif (self.angle == "up") and (self.vel[1] != block_size) and up:
self.turn_up()
elif (self.angle == "down") and (self.vel[1] != -block_size) and down:
self.turn_down()
# update movement
self.pos[0] += self.vel[0]
self.pos[1] += self.vel[1]
# check if out of boundaries
# if self.pos[0] < 0 or self.pos[0] >= res_x or self.pos[1] < 0 or self.pos[1] >= res_y:
# gameOver = True
if map[int(self.pos[1]//path)][int(self.pos[0]//path)] == 1:
gameOver = self.auto_turn()
# build the snake
snakeHead = []
snakeHead.append(self.pos[0])
snakeHead.append(self.pos[1])
self.vellist.append((self.vel[0],self.vel[1]))
self.list.append(snakeHead)
if len(self.list) > self.length:
del self.list[0]
del self.vellist[0]
if snakeHead in self.list[:-1] and not self.start:
gameOver = True
# draw the snake
if len(self.list) >= 2:
for i,XnY in enumerate(self.list[:-2]):
pygame.draw.rect(Display, self.color, [int(XnY[0]), int(XnY[1]), block_size, block_size])
pygame.draw.rect(Display, self.color, [int(self.list[0][0]+((self.count%update_frame)/update_frame-1)*self.vellist[0][0]),
int(self.list[0][1]+((self.count%update_frame)/update_frame-1)*self.vellist[0][1]), block_size, block_size])
pygame.draw.rect(Display, self.color, [int(self.list[-2][0]+((self.count%update_frame)/update_frame-1)*self.vellist[-2][0]),
int(self.list[-2][1]+((self.count%update_frame)/update_frame-1)*self.vellist[-2][1]), block_size, block_size])
# draw the snake's head
Display.blit(self.head, (int(self.list[-1][0]+((self.count%update_frame)/update_frame-1)*self.vel[0]),
int(self.list[-1][1]+((self.count%update_frame)/update_frame-1)*self.vel[1])))
self.count += 1
if self.count == (self.count * update_frame):
self.start = False
return gameOver
def snakeCrash(snakes):
for snake1 in snakes:
for snake2 in snakes:
if snake1 is not snake2 and snake1.pos in snake2.list:
return True
class Apple:
def __init__(self, pos, size, image = None):
self.pos = pos
self.img = image
self.size = size
def draw(self):
#pygame.draw.rect(Display, red,[self.pos[0], self.pos[1], self.size, self.size])
Display.blit(self.img, self.pos)
def pause():
paused = True
message_screen("Paused", black, -100, "large")
message_screen("Press Space to continue or Escape to quit", black, 25)
pygame.display.update()
while paused:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_game()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
paused = False
elif event.key == pygame.K_ESCAPE:
exit_game()
clock.tick(10)
def score(score, pos, color):
text = smallfont.render("Score: "+str(score)+" / "+str(apple_win), True, color)
Display.blit(text, pos)
def text_objects(text, color, size = "small"):
if size == "small":
textSurface = smallfont.render(text, True, color)
elif size == "medium":
textSurface = font.render(text, True, color)
elif size == "large":
textSurface = bigfont.render(text, True, color)
return textSurface, textSurface.get_rect()
def text_to_button(msg, color, pos, size = "small"):
text_surf, text_rect = text_objects(msg, color, size)
text_rect.center = (int(pos[0])+int(pos[2]/2), int(pos[1])+int(pos[3]/2))
Display.blit(text_surf, text_rect)
def message_screen(msg, color, y_displace=0, size = "small"):
text_surf, text_rect = text_objects(msg, color, size)
text_rect.center = int(res_x/2), int((res_y/2)+y_displace)
Display.blit(text_surf, text_rect)
def randAppleGen(image):
j = random.randint(0, len(map)-1)
i = random.randint(0, len(map[0])-1)
while map[j][i] == 1:
j = random.randint(0, len(map)-1)
i = random.randint(0, len(map[0])-1)
new_apple = Apple([i * block_size, j * block_size], apple_size, image)
return new_apple
def game_controls():
controls = True
Display.fill(white)
message_screen("Controls", green, -120, "large")
message_screen("Green movement: Arrow keys", green, -30, "small")
message_screen("Purple movement: W, A, S, D keys", purple, 10, "small")
message_screen("Pause: P", black, 60, "small")
while controls:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_game()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
controls = False
elif event.key == pygame.K_ESCAPE:
exit_game()
controls = button("Main Menu", (int(res_x/2-70), res_y-150, 140, 50), yellow, light_yellow, action = "switch")
button("Quit", (int(res_x/2+120), res_y-150, 100, 50), red, light_red, action = "quit")
clock.tick(30)
pygame.display.update()
def button(text, pos, color1, color2, action, text_color = black):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if pos[0]+pos[2] > cur[0] > pos[0] and pos[1]+pos[3] > cur[1] > pos[1]:
pygame.draw.rect(Display, color2, pos)
if click[0] == 1:
if action == "switch":
return False
elif action == "controls":
clock.tick(6)
game_controls()
clock.tick(6)
elif action == "quit":
exit_game()
else:
pygame.draw.rect(Display, color1, pos)
text_to_button(text, text_color, pos)
return True
def game_intro():
intro = True
while intro:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_game()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
intro = False
elif event.key == pygame.K_ESCAPE:
exit_game()
Display.fill(white)
message_screen("Snake Game", green, -120, "large")
message_screen("Collect "+str(apple_win)+" apples faster than your enemy,", black, -30, "small")
message_screen("without crashing!", black, 10, "small")
intro = button("Play", (int(res_x/2-220), res_y-150, 100, 50), green, light_green, action = "switch")
button("Controls", (int(res_x/2-60), res_y-150, 120, 50), yellow, light_yellow, action = "controls")
button("Quit", (int(res_x/2+120), res_y-150, 100, 50), red, light_red, action = "quit")
clock.tick(30)
pygame.display.update()
def gameLoop():
global apple_count
gameExit = False
gameOver = False
playerwin = 0
for a,img in apples:
while apple_count > len(a):
apple = randAppleGen(img)
a.add(apple)
snake1 = Snake([startpos[0][0], startpos[0][1]], [0, 0], None, green_head, green, green_apple)
snake2 = Snake([startpos[1][0], startpos[1][1]], [0, 0], None, purple_head, purple, purple_apple)
while not gameExit:
if gameOver == True or playerwin != 0:
if playerwin == 0:
message_screen("Game Over!", red, -50, "large")
if playerwin == 1:
message_screen("Player 1 wins !", green, -50, "large")
if playerwin == 2:
message_screen("Player 2 wins !", purple, -50, "large")
message_screen("Press Space to restart or Esc to quit.", black, 30)
pygame.display.update()
while gameOver == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit_game()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
exit_game()
if event.key == pygame.K_SPACE:
gameLoop()
for event in pygame.event.get(): # Events LEAD
if event.type == pygame.QUIT:
gameExit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT: # Snake1
snake1.key_event("left")
if event.key == pygame.K_RIGHT: