320x100

tkinter 를 이용하여 메뉴 만들기 코드 입니다.

아래 이미지파일을 다운로드받고 소스코드와 같은 폴더에서 복사하여 주세요

arrow.png
0.32MB

from tkinter import *

class Menu:
    def __init__(self):
        window = Tk()
        window.title("키보드 이벤트")
        window.geometry("640x480")
        self.menu_idx = 0
        self.canvas=Canvas(window, bg ="white")
        self.canvas.pack(expand=True, fill=BOTH)
        window.bind("<KeyPress>",self.keyPressHandler)
        window.bind("<KeyRelease>",self.keyReleaseHandler)
        self.canvas.create_text(320,360,font="Times 15 italic bold",text="Menu Example")
                
        self.canvas.create_text(320,160,font="Times 15 italic bold",text="Menu 1")
        self.canvas.create_text(320,200,font="Times 15 italic bold",text="Menu 2")
        self.canvas.create_text(320,240,font="Times 15 italic bold",text="Menu 3")

        self.menustr = "Menu selection: "
        self.menu_id = self.canvas.create_text(320,320,font="Times 15 italic bold",text=self.menustr)    


        self.arrowimg = PhotoImage(file="arrow.png").subsample(20)
        self.arrow = self.canvas.create_image(250,160, image = self.arrowimg,tags="arrow")
        while True:
            #
            #
            window.after(33)
            window.update()

    def keyReleaseHandler(self, event):
        if event.keycode == 38 and self.menu_idx > 0: # up direction key
            self.menu_idx = self.menu_idx - 1
            self.canvas.move(self.arrow, 0, -40)
        if event.keycode == 40 and self.menu_idx < 2: # down direction key
            self.menu_idx = self.menu_idx + 1
            self.canvas.move(self.arrow, 0, 40)
        if event.keycode == 32:
            self.menustr = "Menu selection: " + str(self.menu_idx)
            self.canvas.itemconfigure(self.menu_id, text=self.menustr)#object 속성 수정

    def keyPressHandler(self,event):
        print(event.keycode)


Menu()

게임 사운드 코드

 

게임 사운드

from tkinter import * import pygame class GameSound: def __init__(self): window = Tk() # 윈도우 생성 window.title("게임사운드") # 제목을 설정 window.geometry("640x480") # 윈도우 크기 설정 window.resizable(0,0) self.canvas = Canvas(win

ckang.tistory.com

네트워크 채팅 코드

 

파이썬 네트워크 통신 채팅 프로그램 서버 클라이언트 예제

# 서버코드import socketimport argparseimport threadingimport timeuser_list = {}def handle_receive(client_socket, addr, user): while 1: data = client_socket.recv(1024) data = data.decode() if data == "/종료" or data == "/exit" : break print(user,data)

ckang.tistory.com

슈팅 게임 서버 클라인 언트 코드

 

파이썬 네트워크 게임 서버 클라이언트 (socket, ast, json, threading)

클라이언트 코드 입니다. from tkinter import * # tkinter에서 모든 정의를 임포트한다.import timeimport pygameimport randomimport timeimport socketimport astimport jsonimport threadingclass GameClient: def __init__(self,user,host,port):

ckang.tistory.com

 

반응형
320x100

tkinter 를 이용한 마우스 이벤트는

window에 bind 함수를 이용하여 마우스 이벤트를 각각 연결시킨다.

 

이때 bind() 함수는 다음과 같이 두 개의 이자를 가져야 한다.

 - bind("이벤트명",연결함수) #이벤트 연결을 위한 가장 중요한 함수!!!!!

 

이벤트 종류는 다음과 같다.

<Button-1> : 마우스 왼쪽 버튼 클릭
<Button-2> : 마우스 중간 버튼 클릭
<Button-3> : 마우스 오른쪽 버튼 클릭
<Button-4> : 마우스 휠을 스크롤바에서 위로 올릴 때(scroll up event)
<Button-5> : 마우스 휠을 스크롤바에서 아래로 내릴 때(scroll down event)
<ButtonPress> : 아무 마우스 버튼이라도 눌리면 호출 된다. 휠까지도
<Double-Button-1> : 마우스 왼쪽 버튼 더블 클릭
<Double-Button-2> : 마우스 중간 버튼 더블 클릭
<Double-Button-3> : 마우스 오른쪽 버튼 더블 클릭
<Return> : 엔터가 눌러짐
<Key> : 키가 눌러짐
<Enter> : 마우스 포인터가 위젯에 들어올 때
<Leave> : 마우스 포인터가 위젯을 떠날때
<Configure> : 위젯 사이즈에 변화가 있을때

 

이중에서 마우스와 관련 된 이벤트를 적용한 코드 예제는 아래와 같다.

from tkinter import *

class MouseEvent:
    def __init__(self):
        window = Tk()
        window.title("마우스 이벤트")
        window.geometry("640x480")
        
        self.canvas=Canvas(window, bg ="white")
        self.canvas.pack(expand=True, fill=BOTH)
        window.bind("<Button-1>",self.MouseClickEvent)
        window.bind('<Double-1>', self.MouseDoubleClickEvent)
        window.bind('<B1-Motion>', self.MouseMotionEvent) 

        self.mousestr = "Mouse: "
        self.mouse_id = self.canvas.create_text(320,240,font="Times 15 italic bold",text=self.mousestr)    
        self.canvas.create_text(320,360,font="Times 15 italic bold",text="Mouse Event Example")
        
        while True:
            #
            self.canvas.itemconfigure(self.mouse_id, text=self.mousestr)
            #
            window.after(33)
            window.update()

    def MouseClickEvent(self, event):
        self.mousestr = "Mouse: " + str(event.x) + ", " + str(event.y) + "에서 마우스 클릭 이벤트 발생"
        

    def MouseDoubleClickEvent(self, event):
        self.mousestr = "Mouse: " + str(event.x) + ", " + str(event.y) + "에서 마우스 더블 클릭 이벤트 발생"

    def MouseMotionEvent(self, event):
        self.mousestr = "Mouse: " + str(event.x) + ", " + str(event.y) + "에서 마우스 모션 이벤트 발생"


MouseEvent()
반응형
320x100

애니메이션 이미지는 여러개의 이미지가 겹쳐진 gif 포맷으로 되어 있다

그 이미지를 파이썬에 적용하기 위해서는 gif 가 몇장의 이미지로 구성되어 있는지 확인을 해야한다.

[gif png, jpg 이미지 추출 방법]

gif 읽기 방법은 gif 의 이미지들 모두 읽어서 각각 리스트에 저장하고

 

다음 이미지를 한장씩 보여주면서 애니메이션이 재생되는 방식이다.

 

그래서 리스트에 gif 에 포함된 모든 이미지를 저장하고 index를 증가시키면서 다음이미지를 보여준다.

 

for 문과 PhotoImage 함수를 이용하여 gif 파일 안에 이미지를 하나씩 읽어 올 수 있다. 이때 중요한 부분은 format 설정임(아래 코드 참조)

 

dragon-gif.gif
0.43MB

 

from tkinter import * # tkinter에서 모든 정의를 임포트한다.


class LoadGIFImage:
	def __init__(self):
		window = Tk() # 윈도우 생성
		window.title("GIF Image Example") # 제목을 설정
		window.geometry("640x480") # 윈도우 크기 설정
		window.resizable(0,0)        
		self.canvas = Canvas(window, bg = "white")
		self.canvas.pack(expand=True,fill=BOTH)	
		
		self.my_image_number = 0 
		#마지막 range(60) 에서 60 은 gif 이미지 수를 나타냄
		#gif 파일의 이미지를 한장씩 읽고 리스트에 저장함
		self.myimages = [PhotoImage(file='dragon-gif.gif',format = 'gif -index %i' %(i)) for i in range(60)]
		
		
		#아래 코드에서 subsample(2) 는 이미지 크기를 작게함. 인수 값에 따라 작아짐
		#self.myimages = [PhotoImage(file='dragon-gif.gif',format = 'gif -index %i' %(i)).subsample(1) for i in range(60)]

		#이미지를 canvas에 그리고 id 값을 생성후 self.dragon 변수에 저장
		self.dragon = self.canvas.create_image(300,240, image = self.myimages[0],tags="dragon")

		self.canvas.create_text(320,360,font="Times 15 italic bold",text="Load GIF Image")

		while True:

			#canvas에서 self.dragon 이미지를 읽어오고 gif의 다음 이미지로 교체함
			self.canvas.itemconfig(self.dragon, image = self.myimages[self.my_image_number%len(self.myimages)])    

			self.my_image_number += 1
			window.after(33)
			window.update()

		#window.mainloop() # 이벤트 루프를 생성한다.


LoadGIFImage() # GUI 생성한다.

 

반응형
320x100

아래 이미지, 사운드(효과음) 파일을 다운로드 받고 소스코드 폴더에 함께 복사한 후 실행시키기 바랍니다.

tank.png
0.14MB
tankmove.MP3
0.29MB

from tkinter import *
import pygame

class ObjectControlByKeyEvent:
    def __init__(self):
        window = Tk()
        window.title("키보드를 이용한 이미지 컨트롤")
        window.geometry("640x480")
        self.keys = set()
        self.canvas=Canvas(window, bg ="white")
        self.canvas.pack(expand=True, fill=BOTH)
        window.bind("<KeyPress>",self.keyPressHandler)
        window.bind("<KeyRelease>",self.keyReleaseHandler)
        
        self.tankimg = PhotoImage(file="tank.png").subsample(8)
        self.tank = self.canvas.create_image(320,240, image = self.tankimg,tags="tank")

        #Effect sound
        self.sounds = pygame.mixer
        self.sounds.init()
        self.s_effect1 = self.sounds.Sound("tankmove.mp3")
        
        self.canvas.create_text(320,350,font="Times 15 italic bold",text="← 또는 → 키를 입력하시오")
        self.canvas.create_text(320,450,font="Times 15 italic bold",text="Object Control By KeyEvent")

        while True:
            #
            self.display()
            window.after(33)
            window.update()

    def display(self):
        for key in self.keys:
            if key == 39: # right direction key                
                #self.s_effect1.play()
                self.canvas.move(self.tank, 5, 0)
            if key == 37: # left direction key                
                #self.s_effect1.play()
                self.canvas.move(self.tank, -5, 0)

    def keyReleaseHandler(self, event):
        if event.keycode in self.keys:
            #self.s_effect1.stop()
            self.keys.remove(event.keycode)

    def keyPressHandler(self,event):        
        self.keys.add(event.keycode)
        
ObjectControlByKeyEvent()
반응형
320x100

파이썬에서 모든 이벤트 처리는 bind를 통해서 이루어진다. bind는 "묶다" 라는 의미로서 이벤트가 발생할 때 어떠 함수가 호출 되도록 할 것인지를 연결하는 역할을 합니다. 다른 언어에도 bind 이외에 다른 용어 또는 키워드를 사용하지만 동일한 의미를 가지고 있습니다.
 
파이썬에서 이벤트와 함수와의 연결은 아래와 같은 형식으로 작성을 합니다.
 

widget.bind("이벤트 종류",함수명)
 

위젯은 윈도우, 버튼, 라벨 등 을 작성하고 bind() 함수를 이용하여 위젯에 발생한 이벤트를 두번째로 작성된 함수명으로 전달을 합니다.  아래 코드는 window 위젯에 키 이벤트처리를 위한 기본 예제 코드입니다.

from tkinter import *


def keyPressHandler(event):
	print("Press: ",event.keycode)

def keyReleaseHandler(event):
	print("Release: ",event.keycode)

window = Tk()
window.geometry("640x480")

window.bind("<KeyPress>",keyPressHandler)
window.bind("<KeyRelease>",keyReleaseHandler)

window.mainloop()

키를 눌렀을 때 KeyPressHandler 함수가 호출되고 호출된 함수안에 작성된 print() 함수를 실행합니다(Line 4, 5). 이때 계속 누르고 있으면 연속으로 계속 호출되는 것이 아닌 키를 누르는 시점에 한 번 호출됩니다. 반대로 키를 떼는 순간 keyReleaseHandler() 함수를 호출합니다.
이벤트에 의해 호출되는 함수를 정의할 때는 항상 매개변수 1개를 선언해야 합니다. 매개변수의 역할은 이벤트가 발생할 때 이벤트에 대한 정보를 함께 함수로 전달하는데 이때 전달된 정보가 매개변수에 저장됩니다. 위 예제의 키 이벤트의 경우 어떤 키가 눌러졌는지 키 정보가 event 변수에 저장됩니다. 그리고 event.keycode는 눌러진 키의 아스키코드 값을 알 수 있습니다.
키보드 이외에 마우스와 같은 많은 이벤트들이 있으며 필요에 따라 직접 찾아서 사용해보기 바랍니다.
 
이제 키보드 이벤트 기능을 게임 기본구조 코드에 적용하도록 하겠습니다.
일반적으로 게임에서는 키 입력에 따른 콘텐츠를 조작을 위해 키보드 이벤트를 사용한다. 이때 2가지 중요한 이슈가 있는데,
 
첫번째는 2개 이상의 키입력을 어떻게 처리 할 것인가?
두번째는 이벤트 처리 시점 입니다.
 
2개 이상의 키를 눌렀을 때 눌러진 상태를 알려주는 친절한 프로그래밍 언어는 없습니다.(라이브러리에서 지원해주는 경우는 있음) 가령, 대각선 위(북동 방향)로 계속 이동하도록 프로그래밍을 한다고 가정을 하였을 때, →, ↑ 방향 키를 동시에 누르고 있으면 두 키가 눌러진 시점에서 이벤트만 한번이 발생하고 끝입니다. 아래와 같이 프로그래밍을 한다면 누르는 시점 한번만 이동하고 더이상 움직임이 없다는 것입니다.

def keyPressHandler(event):
	if (event.keycode==38):#아스키코드 38 는 ↑ 키
    	# 콘텐츠 위로 이동 코드
	elif (event.keycode==39):#아스키코드 39 는 → 키
    	# 콘텐츠 앞으로 이동 코드

그래서
1. 키 이벤트 발생한 시점에서 콘텐츠(이미지)의 이동 코드를 작성하면 안되고, 콘텐츠의 이동 코드는 다른 코드영역(무한루프 영역)에서 작성해야 합니다.
2. KeyPress 이벤트 처리 함수에는 어떤 키가 눌러졌는지에 대한 키 정보를 저장하는 코드를 작성합니다. 그리고 KeyRelease 에는 저장된 키 정보에서 떼어진 키를 삭제하는 코드를 작성합니다.
 
 
앞에 내용들을 포함하여 작성한 코드는 아래와 같습니다.

from tkinter import *

keys = set()

def keyReleaseHandler(event):
    if event.keycode in keys:
        keys.remove(event.keycode)

def keyPressHandler(event):
    keys.add(event.keycode)
        
window = Tk()
window.geometry("640x480")

window.bind("<KeyPress>",keyPressHandler)
window.bind("<KeyRelease>",keyReleaseHandler)                

while True:
	#
	if (len(keys)>0):
		print("Key: ", keys)
	#
	window.after(33)
	window.update()

눌러진 키 정보를 저장할 때는 파이썬 자료구조 중 집합인 set() 을 이용하였습니다. set() 의 경우 유일한 값만 가지기 때문에 동일한 키값을 입력해도 자동으로 하나로 처리가 되는 장점이 있습니다.
 
위 코드를 게임 기본 코드 구조에 적용하면 아래와 같습니다. 이벤트 처리 함수의 경우, 클래스 멤버함수이기 때문에 매개변수가 하나 더 추가 되며 두번째 매개변수에 이벤트 정보가 저장됩니다.

from tkinter import *

class KeyboardEvent:
    def __init__(self):
        window = Tk()
        window.title("키보드 이벤트")
        window.geometry("640x480")
        
        self.keys = set()
        self.canvas=Canvas(window, bg ="white")
        self.canvas.pack(expand=True, fill=BOTH)
        
        window.bind("<KeyPress>",self.keyPressHandler)
        window.bind("<KeyRelease>",self.keyReleaseHandler)                
        
        self.canvas.create_text(320,400,font="Times 15 italic bold",text="Key Event Example")
        
        while True:
            #
            if(len(self.keys)>0):
            	print("Key: ", self.keys)            
            #
            window.after(33)
            window.update()

    def keyReleaseHandler(self, event):
        if event.keycode in self.keys:
            self.keys.remove(event.keycode)

    def keyPressHandler(self,event):
        self.keys.add(event.keycode)

KeyboardEvent()
반응형
320x100
from tkinter import *
import pygame

class GameSound:
	def __init__(self):
		window = Tk() # 윈도우 생성
		window.title("게임사운드") # 제목을 설정
		window.geometry("640x480") # 윈도우 크기 설정
		window.resizable(0,0)        
		
		
		self.canvas = Canvas(window, bg = "white")
		self.canvas.pack(expand=True,fill=BOTH)
		window.bind("<KeyPress>",self.keyPressHandler)
		window.bind("<KeyRelease>",self.keyReleaseHandler)

		#pygame 에서 music vs sound
		# music: 배경음악 재생을 위해 사용
		# sound: 효과음을 위해 사용

        #BG sound.
		pygame.init()
		pygame.mixer.music.load("bgm.wav") #Loading File Into Mixer
		pygame.mixer.music.play(-1) #Playing It In The Whole Device
		self.canvas.create_text(320,400,font="Times 15 italic bold",text="Sound Example")

		#Effect sound
		self.sounds = pygame.mixer
		self.sounds.init()
		self.s_effect1 = self.sounds.Sound("gunsound.mp3")
				
		while True:
			#
			window.after(33)
			window.update()

	def keyReleaseHandler(self, event):
		if event.keycode in self.keys:
		    self.keys.remove(event.keycode)

	def keyPressHandler(self, event):		
		self.s_effect1.play()
		self.keys.add(event.keycode)

GameSound()

tkinter에서는 사운드와 관련된 클래스 및 함수를 제공하지 않습니다.  그래서 코드에서는 pygame 모듈을 이용하여 사운드 재생방법을 설명을 하도록 하겠습니다. (앞서 설명된 게임 기본 코드 구조 위에서 추가된 내용들만 설명)

 

사운드의 종류는 크게 기본적으로 배경사운드, 이펙트사운드로 구분될 수 있습니다. 배경사운드는 게임의 전체적인 분위기를 담당하고 이펙트 사운드는 그 순간의 효과 또는 느낌(타격감, 행위(점프, 스피드업, 아이템 획득), 죽음 등)을 담당하며, 사운드를 게임의 진행에 있어서 필수적인 요소입니다. 그래서 위 코드에서는 배경사운드와 이펙트사운드의 재생 방법에 대해서 설명하도록 하겠습니다.

 

pygame에서 사운드 재생 방법은 music와 sound 이렇게 2가지를 제공하고 있습니다.

차이점은 music의 경우 하나의 재생만 가능하고 만약 다른 파일을 load() 해서 재생하면 기존 재생은 멈추게 되며, 반대로 sound 는 여러 개가 동시 재생이 가능하고 같은 사운드의 중첩해서 재생도 가능합니다.

그리고 music의 경우 파일이 저장된 장치(ssd 또는 hard disk 등)에서 재생을 하지만 sound의 경우 파일 전체를 메모리에 가져온 후 재생하게 됩니다. 즉 music은 큰 용량을 가진 음악 파일 재생에 유리하며 sound의 경우 작은 용량과 짧은 사운드(이펙트)에 유리합니다.

그러므로 music의 경우 배경사운드에 이용되고 sound의 경우 이펙트사운드에 사용합니다.

 

위 소스에 대한 주요 코드 설명은 아래와 같습니다.

  • pygame 모듈을 사용하기 위해 pygame을 import 한다.(line 2)
  • pygame을 사용하기 위해서는 pygame.init()함수를 호출해야한다.(line 21)
  • 위 코드에서 music.load(), music.play() 함수를 이용하여 배경음악을 무한반복 재생한다.(line 22, 23)
  • effect sound를 위해 sounds 를 초기화 한다.(line 28)
  • 이펙트 사운드 'gunsound.mp3'  파일을 읽고 sound 객체를 반환한다. sound 객체는 이펙트 사운드는 게임중 재생 및 멈춤을 컨트롤할 수 있다.
  • line 41에서 이펙트 사운드를 재생한다.

위 코드만으로 간단히 게임에서 필요한 음악 재생은 가능하며 좀 더 다양한 기능을 구현하기 위해서는 아래의 링크를 참조하기 바랍니다.

 

 

https://www.pygame.org/docs/ref/music.html

 

pygame.mixer.music — pygame v2.1.1 documentation

Resets playback of the current music to the beginning. If pause() has previoulsy been used to pause the music, the music will remain paused. Note rewind() supports a limited number of file types and notably WAV files are NOT supported. For unsupported file

www.pygame.org

https://www.pygame.org/docs/ref/mixer.html

 

pygame.mixer — pygame v2.1.1 documentation

begin sound playback play(loops=0, maxtime=0, fade_ms=0) -> Channel Begin playback of the Sound (i.e., on the computer's speakers) on an available Channel. This will forcibly select a Channel, so playback may cut off a currently playing sound if necessary.

www.pygame.org

 

 

반응형

+ Recent posts