Skip to content

Hello, we are university students in Korea #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,94 @@ You can also run Snake-Game in Gitpod, a free online dev environment for GitHub:
If you're intersted in a paid subscription with GitPod use the coupon code: **TECHWITHTIM19**

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/techwithtim/Snake-Game/blob/master/snake.py)



------------------------------------------




1. 게임 속도 조절
기존에 빠르게 움직이던 뱀의 속도를 늦추고 5레벨씩 달성 시
뱀의 속도를 전의 속도보다 1.5배 빨라지게 설정했습니다.

pygame을 모듈내장함수 init함수로 초기화하고
clock변수에 게임의 시간을 받았습니다.

기존 코드 속 class snake 에 있는 move함수를 수정해
level변수에 5단계 단위로 정수를 저장하고
최초 속도를 6으로 하고 5단계 단위로 속도를 1.5배 해 fps 변수에 넣었습니다.
그리고 내장함수 tick 이용해 조절한 속도를 적용하였습니다.


2.최종 레벨 25로 달성 시 종료
-class snake안에 end_game함수 생성, sys.exit(0)에 의해 게임 종료
-기존 main함수에서 최종 레벨 25달성시, 게임을 종료하는 end_함수를 실행하는 코드 추가


3. Tk()를 이용하여 window라는 윈도우를 생성하고 타이틀은 "NEW Snake Game"으로 정한다. window.geometry 명령어를 통해 사이즈 설정과 윈도우 창이 뜨는 위치를 설정해 주었습니다.
label1을 라벨 객체로 생성하고 “Game Start \n Let’s go”를 텍스트에 넣어 윈도우 창에 뜨웁니다. 글씨의 색상은 파란색으로 정했습니다. relief는 라벨의 테두리 모양을 저지정하는 함수로 “sunken”을 써서 오목하게 보여줬습니다.
b1을 버튼 객체로 생성하고 command=window.destroy 코드를 통해 window 윈도우창을 닫고 메인 보드 게임으로 들어갑니다.
라벨과 버튼 둘 다 pack()을 통해 윈도우창에 띄웠습니다.


4. 게임판에 레벨 출력
메인 게임판 위에 뱀의 길이에 따른 레벨이 담긴 정보를 보여줍니다.

기존 코드 속 class snake 에 show_info함수를 정의하였습니다.
font 변수로 폰트의 정보를 지정하고
내장함수 render로 뱀의 길이에 따른 레벨을 출력합니다.
출력 내용을 게임보드의 위치를 왼쪽 상단으로 지정합니다.

게임판을 출력하는 redrawWindow 함수에서
스네이크 객체 s를 이용해 show_info를 호출합니다.


5. finish_game함수를 정의해줍니다.
fin 윈도우를 만들고 label2객체를 생성하여 “!! SUCCESS !!”를 출력해줍니다.
b2 객체를 생성하여 “끝내기”버튼을 생성하고 버튼을 클릭시 command = fin.destroy 코드를 통해 윈도우를 종료 시켜줍니다.


6. 메인 게임 보드 설정 조절
메인 게임 보드 속 사소한 부분의 설정을 조절하였습니다.

win.full으로 배경 색을 바꾸고
게임보드의 크기를 500제곱에서 700제곱으로 변경합니다.
rows도 20 줄에서 25줄로 격자의 양을 늘립니다.
class cube 내의 설정을 위한 변수의 크기도 변경 시킵니다.
gird 의 라인 색상도 변경합니다.
늘어난 메인 게임 보드의 크기만큼 뱀이 보들를 벗어 날 시
발생하는 충돌 reset에 대한 설정도 20에서 25로 넓힙니다.


7.종료시 게임 total time 출력
- start_ticks객체는 main함수가 호출된 시점의 시작시간을 tick를 통해 받아옴(start_tick=고정값)
-while문 안에서 pygame이 호출된 이후 증가하며 흐르는 시간을 리턴하는 함수를 이용해 경과 시간을 구하기 위해 seconds객체 생성
경과 시간 계산은 밀리세컨들 출력되므로 1000으로 나눠 1초로 표시
-finish_game함수에서 게임이 종료되면 뜨는 윈도우창에 경과시간를 나타낸 객체 seconds를 출력


8. 점수가 있는 큐브 생성

뱀과 충돌시 점수를 내는 변수 버그와 스낵을 선언하고
메인 게임 보드에 정보를 출력합니다.

랜덤큐브를 생성하는 bug를 main에서 선언합니다.

if문을 이용해 스낵과 뱀의 머리가 충돌하면
뱀의 바디를 늘리는 함수를 addcube를 객체 호출하고
다음 레벨에서 다시 랜덤 큐브를 생성시킵니다.
그리고 score 변수에 점수를 +10으로 계산합니다.

같은 방법으로 if문을 이용해 버그와 뱀의 머리가 충돌하면
다음 레벨에서 랜덤큐브를 생성하고 점수를 -10으로 계산합니다.

redrawWindow 안에서 호출한 show_info로
계산한 점수를 게임 메인 모드에 출력합니다.


9. main 함수 안에 Sound 객체인 eatsnack, eatbug, gameoversound를 생성하여
gameoversound는 뱀이 메인 게임보드 밖에 나갔을 때 play되도록 gameoversound.play()를 넣어줍니다.(243줄)
eatsnack 사운드는 뱀이 snack을 먹었을 때 나오도록 eatsnack.play()를 넣어줍니다.(248줄)
eatbug 사운드는 뱀이 bug를 먹었을 때 나오도록 eatbug.play()를 넣어줍니다.(256줄)
Binary file added gameover.wav
Binary file not shown.
Binary file added grow.wav
Binary file not shown.
Binary file added shrink.wav
Binary file not shown.
132 changes: 106 additions & 26 deletions snake.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,69 @@
import pygame
import random
import tkinter as tk
from tkinter import messagebox
from tkinter import *

width = 500
height = 500

width = 700
height = 700
cols = 25
rows = 20
rows = 25

pygame.init()
clock = pygame.time.Clock()
background = pygame.display.set_mode((width, height))


window=Tk()
window.title("NEW Snake Game")
window.geometry('300x120+470+200')

label1=Label(window, text="Game Start\nLet's go",width=30,height=5,fg="blue",relief="sunken")
label1.pack()

b1=Button(window,text="시작하기",width=10,bg='yellow',command = window.destroy)
b1.pack(padx = 10, pady = 5)

window.mainloop()


class cube():
rows = 20
w = 500
rows = 25
w = 700
def __init__(self, start, dirnx=1, dirny=0, color=(255,0,0)):
self.pos = start
self.dirnx = dirnx
self.dirny = dirny # "L", "R", "U", "D"
self.dirny = dirny
self.color = color

def move(self, dirnx, dirny):
self.dirnx = dirnx
self.dirny = dirny
self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny)


def draw(self, surface, eyes=False):
dis = self.w // self.rows
i = self.pos[0]
j = self.pos[1]

pygame.draw.rect(surface, self.color, (i*dis+1,j*dis+1,dis-2,dis-2))

if eyes:
centre = dis//2
radius = 3
circleMiddle = (i*dis+centre-radius,j*dis+8)
circleMiddle2 = (i*dis + dis -radius*2, j*dis+8)
pygame.draw.circle(surface, (0,0,0), circleMiddle, radius)
pygame.draw.circle(surface, (0,0,0), circleMiddle2, radius)




class snake():
body = []
turns = {}

def __init__(self, color, pos):
#pos is given as coordinates on the grid ex (1,5)
self.color = color
self.head = cube(pos)
self.body.append(self.head)
Expand Down Expand Up @@ -88,7 +105,10 @@ def move(self):
self.turns.pop(p)
else:
c.move(c.dirnx,c.dirny)


level = int(len(self.body) / 5)
fps = 6 + (1.5*level)
clock.tick(fps)

def reset(self,pos):
self.head = cube(pos)
Expand Down Expand Up @@ -121,31 +141,58 @@ def draw(self, surface):
else:
c.draw(surface)

def end_game():
print("Score:", len(self.body))
sys.exit(0)


def show_info(self,score):
font = pygame.font.SysFont('malgungothic',30,bold=5)
image = font.render(f' {len(self.body)} .Lv 점수 : {score}', True, (0,0,0))
pos = image.get_rect()
pos.move_ip(20,20)
pygame.draw.rect(image, (0,0,0),(pos.x-15, pos.y-15, pos.width, pos.height), 2)
background.blit(image, pos)


def finish_game(seconds):
fin=Tk()
fin.title("Full Level")
fin.geometry('400x150+500+200')
b=int(seconds)
print ("Total Time :", b)
label2=Label(fin, text="!! SUCCESS !!\nTotal Time :"+str(b),width=30,height=5,fg="red",relief="raised")
label2.pack()

b2=Button(fin, text="끝내기",width=20,bg='yellow',command = fin.destroy)
b2.pack(padx = 10, pady = 20)

fin.mainloop()


def redrawWindow():
global win
win.fill((0,0,0))
win.fill((176,224,230))
drawGrid(width, rows, win)
s.draw(win)
snack.draw(win)
bug.draw(win)
s.show_info(score)
pygame.display.update()
pass



def drawGrid(w, rows, surface):
sizeBtwn = w // rows

sizeBtwn = w // rows
x = 0
y = 0

for l in range(rows):
x = x + sizeBtwn
y = y +sizeBtwn

pygame.draw.line(surface, (255,255,255), (x, 0),(x,w))
pygame.draw.line(surface, (255,255,255), (0, y),(w,y))

pygame.draw.line(surface, (150,150,150), (x, 0),(x,w))
pygame.draw.line(surface, (150,150,150), (0, y),(w,y))


def randomSnack(rows, item):
Expand All @@ -163,36 +210,69 @@ def randomSnack(rows, item):


def main():
global s, snack, win

global s, snack,bug, win, b, score

win = pygame.display.set_mode((width,height))
s = snake((255,0,0), (10,10))
s.addCube()
snack = cube(randomSnack(rows,s), color=(0,255,0))
bug = cube(randomSnack(rows,s), color=(0,0,255))
flag = True
clock = pygame.time.Clock()

start_ticks=pygame.time.get_ticks()

score=0

eatsnack = pygame.mixer.Sound('grow.wav')
eatsnack.set_volume(0.8)
eatbug = pygame.mixer.Sound('shrink.wav')
eatbug.set_volume(0.8)
gameoversound = pygame.mixer.Sound('gameover.wav')
gameoversound.set_volume(0.8)


while flag:
pygame.time.delay(50)
clock.tick(10)
s.move()
headPos = s.head.pos
if headPos[0] >= 20 or headPos[0] < 0 or headPos[1] >= 20 or headPos[1] < 0:
seconds=(pygame.time.get_ticks()-start_ticks)/1000

if headPos[0] >= 25 or headPos[0] < 0 or headPos[1] >= 25 or headPos[1] < 0:
gameoversound.play()
print("Score:", len(s.body))
s.reset((10, 10))

if s.body[0].pos == snack.pos:
eatsnack.play()
s.addCube()
snack = cube(randomSnack(rows,s), color=(0,255,0))
bug = cube(randomSnack(rows,s), color=(0,0,255))
score +=10
redrawWindow()

if s.body[0].pos == bug.pos:
eatbug.play()
snack = cube(randomSnack(rows,s), color=(0,255,0))
bug = cube(randomSnack(rows,s), color=(0,0,255))
score -= 10
redrawWindow()



for x in range(len(s.body)):
if s.body[x].pos in list(map(lambda z:z.pos,s.body[x+1:])):
print("Score:", len(s.body))
s.reset((10,10))
break



if len(s.body) > 25:
finish_game(seconds)
end_game()

redrawWindow()

main()