Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tkinter import *
- from random import randrange as rnd, choice
- from PIL import ImageTk, Image
- import os, sys
- import time
- #~ столкновение с блоками:
- #~ если блок слева, тогда:
- #~ если левая координата зашла за правую координату блока, то подвинуть
- #~ если блок справа, тогда:
- #~ если правая координата зашла за правую координату блока, то подвинуть
- #~ если блок снизу, тогда:
- #~ если нижняя координата зашла за верхнюю координату блока, то подвинуть (поставить на блок)
- #~ ....
- root = Tk()
- width = 900
- hight = 600
- padding = 50
- m = 40
- root.geometry(str(width)+'x'+str(hight)+'+100+100')
- canv = Canvas(bg='lightblue')
- canv.pack(fill=BOTH,expand=1)
- '''
- прокручивается с миром или центр камеры
- останавливает игрока/врагов/пули
- можно разрушать (блоки и врагов)
- можно толкать (только блоки)
- враг (наносит урон)
- предмет (можно взять)
- выносить свойства в отдельный класс только в том случае, если ими обладают и Блоки и Враги
- класс Разрушаемый
- класс НаносящийУрон поражает прикосновением любой стороны: шипы или враг
- класс Анимированный
- класс Предмет можно взять
- класс Предмет2 (нельзя брать)
- класс Враг(НаносящийУрон, Разрушаемый, Анимированный)
- класс Черепаха, ЛетающаяЧерепаха, Череп и т.д. (виды врагов)
- класс Предмет()
- класс Монета(Предмет)
- класс Ключ(Предмет)
- класс Портал(Предмет2)
- класс Дверь(Предмет2) (перегородка)
- класс Лампа(Предмет2)
- класс Блок() ограничивает движение
- класс РазрушаемыйБлок(Блок, Разрушаемый)
- класс ПадающийБлок(Блок)
- класс Платформа(Блок)
- класс РазрушаемаяПлатформа(Платформа,Разрушаемый)
- класс ТолкаемыйБлок(Блок)
- '''
- '''
- 1. Блоки неподвижные
- 2. Блоки перемещаемые (могут падать)
- 3. Блоки разрушаемые
- 4. Блоки падающие
- 5. Блоки-платформы
- 6. Предметы, которые можно собирать (ключи, монеты)
- 7. Предметы, с которыми можно взаимодействовать (двери, кнопки)
- 8. Враги стоящие на месте
- 9. Враги ходящие туда-сюда
- 10. Враги летающие туда-сюда
- Объект:
- 1. Перемещается вместе с миром
- 2. Отрисовывать себя на экране
- 3. Пересечение с другими объектами (список)
- Анимированный объект
- '''
- def pointInSegment(x,x1,x2):
- return x1 <= x <= x2
- def segmentInSegment(x1,x2,xx1,xx2):
- return pointInSegment(x1,xx1,xx2) or pointInSegment(x2,xx1,xx2) or \
- pointInSegment(xx1,x1,x2) or pointInSegment(xx2,x1,x2)
- def rectInRect(x1,y1,x2,y2,xx1,yy1,xx2,yy2):
- if segmentInSegment(x1,x2,xx1,xx2) and segmentInSegment(y1,y2,yy1,yy2):
- return True
- if segmentInSegment(xx1,xx2,x1,x2) and segmentInSegment(yy1,yy2,y1,y2):
- return True
- return False
- class Base():
- def __init__(self,*args,**kwargs):
- pass
- class Object():
- def __init__(self,x,y,**kwargs):
- self.centerx = x
- self.centery = y
- imagePil = kwargs['images'][0]
- self.w = imagePil.width()
- self.h = imagePil.height()
- self.x1 = x - self.w/2
- self.y1 = y - self.h/2
- self.x2 = self.x1 + self.w
- self.y2 = self.y1 + self.h
- self.imagePil = imagePil
- self.vx = 0
- self.vy = 0
- self.image = canv.create_image(self.centerx,self.centery,image=self.imagePil)
- super().__init__(**kwargs)
- self.update()
- def paint(self):
- canv.coords(self.image,self.centerx,self.centery)
- def update(self):
- root.after(30,self.update)
- self.x1 = self.centerx - self.w/2
- self.y1 = self.centery - self.h/2
- self.x2 = self.x1 + self.w
- self.y2 = self.y1 + self.h
- self.paint()
- class MovableObject(Object,Base):
- def __init__(self,x,y,**kwargs):
- self.g = 1
- self.onGround = False
- self.active = True
- self.left_stop = 10000
- self.right_stop = 0
- self.up_stop = 10000
- self.down_stop = 0
- super().__init__(x,y,**kwargs)
- def collide(self,objects):
- res = []
- for item in objects:
- nx1 = item.x1+item.vx
- nx2 = item.x2+item.vx
- ny1 = item.y1+item.vy
- ny2 = item.y2+item.vy
- nxx1 = self.x1+self.vx
- nxx2 = self.x2+self.vx
- nyy1 = self.y1+self.vy
- nyy2 = self.y2+self.vy
- if rectInRect(nx1,ny1,nx2,ny2,nxx1,nyy1,nxx2,nyy2):
- res.append(item)
- return res
- def collide_first(self,objects):
- for item in objects:
- nx1 = item.x1+item.vx
- nx2 = item.x2+item.vx
- ny1 = item.y1+item.vy
- ny2 = item.y2+item.vy
- nxx1 = self.x1+self.vx
- nxx2 = self.x2+self.vx
- nyy1 = self.y1+self.vy
- nyy2 = self.y2+self.vy
- if rectInRect(nx1,ny1,nx2,ny2,nxx1,nyy1,nxx2,nyy2):
- return item
- def hitstop_(self,objects):
- items = self.collide(objects)
- #self.onGround = False
- #print(self.onGround)
- if not items:
- self.onGround = False
- for item in items:
- if self.vx > 0:
- self.vx = 0
- self.centerx = item.x1 - self.w/2
- elif self.vx < 0:
- self.vx = 0
- self.centerx = item.x2 + self.w/2
- if self.vy > 0:
- self.vy = 0
- self.onGround= True
- self.can_jump = True
- self.centery = item.y1 - self.h/2
- elif self.vy < 0:
- self.vy = 1
- self.centery = item.y2 + self.h/2
- def hitstop__(self,objects):
- #self.onGround = False
- for item in objects:
- nx1 = item.x1+item.vx
- nx2 = item.x2+item.vx
- ny1 = item.y1+item.vy
- ny2 = item.y2+item.vy
- nxx1 = self.x1+self.vx
- nxx2 = self.x2+self.vx
- nyy1 = self.y1+self.vy
- nyy2 = self.y2+self.vy
- if rectInRect(nx1,ny1,nx2,ny2,nxx1,nyy1,nxx2,nyy2):
- item.r = (item.centery-padding)//m
- item.c = (item.centerx-padding)//m
- self.r = (self.centery-padding)//m
- self.c = (self.centerx-padding)//m
- dr = item.r - self.r
- dc = item.c - self.c
- if dr == 0:
- if dc == 0:
- dx = item.centerx - self.centerx
- dy = item.centery - self.centery
- if dx > dy:
- if dx > 0:
- dc = 1
- else:
- dc = -1
- else:
- if dy > 0:
- dr = 1
- else:
- dr = -1
- #print(self.vx,self.vy)
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, outline = 'red', width = 5, tag = 'temp')
- if dc > 0:
- self.centerx = item.x1 - self.w/2-1
- self.vx = 0
- elif dc < 0:
- self.centerx = item.x2 + self.w/2+1
- self.vx = 0
- if dr > 0:
- self.vy = 0
- self.centery = item.y1 - self.h/2-1
- self.can_jump = True
- elif dr < 0:
- self.vy = 0
- self.centery = item.y2 + self.h/2+1
- def hitstop(self,objects):
- for item in objects:
- item.r = (item.centery-padding)//m
- item.c = (item.centerx-padding)//m
- self.r = (self.centery-padding)//m
- self.c = (self.centerx-padding)//m
- dr = item.r - self.r
- dc = item.c - self.c
- canv.create_rectangle(self.x1+self.vx,self.y1+self.vy,self.x2+self.vx,self.y2+self.vy, outline = 'orange', width = 1, tag = 'temp')
- if segmentInSegment(self.y1+2,self.y2-2,item.y1+2,item.y2-2) and -1 <= dc <= 0 : # блок слева
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, outline = 'green', width = 5, tag = 'temp')
- if self.x1+self.vx < item.x2:
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, fill = 'green', tag = 'temp')
- if self.vx < 0:
- self.vx = 0
- self.centerx = item.x2 + self.w/2 + 1
- if segmentInSegment(self.y1+2,self.y2-2,item.y1+2,item.y2-2) and dc == 1: # блок справа
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, outline = 'yellow', width = 5, tag = 'temp')
- if self.x2+self.vx > item.x1:
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, fill = 'yellow', tag = 'temp')
- if self.vx > 0:
- self.vx = 0
- self.centerx = item.x1 - self.w/2 - 1
- if -1 <= dr <= 0 and segmentInSegment(self.x1+2,self.x2-2,item.x1+2,item.x2-2): # блок сверху
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, outline = 'red', width = 5, tag = 'temp')
- if self.y1+self.vy < item.y2:
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, fill = 'red', tag = 'temp')
- if self.vy < 0:
- self.vy = 0
- self.centery = item.y2 + self.h/2 + 1
- if dr == 1 and segmentInSegment(self.x1+2,self.x2-2,item.x1+2,item.x2-2): # блок снизу
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, outline = 'blue', width = 5, tag = 'temp')
- if self.y2+self.vy > item.y1:
- canv.create_rectangle(item.x1,item.y1,item.x2,item.y2, fill = 'blue', tag = 'temp')
- self.can_jump = True
- if self.vy > 0:
- self.vy = 0
- self.centery = item.y1 - self.h/2
- def update(self):
- if self.active:
- self.vy += self.g
- self.centerx += self.vx
- self.centery += self.vy
- self.hitstop(blocks)
- self.x1 = self.centerx - self.w/2
- self.y1 = self.centery - self.h/2
- self.x2 = self.x1 + self.w
- self.y2 = self.y1 + self.h
- super().update()
- class Animation():
- def __init__(self,**kwargs):
- super().__init__(**kwargs)
- self.images = kwargs['images']
- self.frame = 0
- self.pause = kwargs['pause']
- self.active_animation = True
- self.update_animation()
- def update_animation(self):
- if self.active_animation:
- self.frame += 1
- if self.frame >= len(self.images):
- self.frame = 0
- canv.itemconfig(self.image,image=self.images[self.frame])
- self.paint()
- root.after(self.pause,self.update_animation)
- class Player(MovableObject,Animation,Base):
- def __init__(self,x,y,**kwargs):
- self.keys = set()
- self.id_vx = canv.create_text(100,100,text = '', font ='Arial 40')
- self.id_vy = canv.create_text(100,145,text = '', font ='Arial 40')
- super().__init__(x,y,**kwargs)
- self.bullets = []
- self.points = 0
- self.can_jump = True
- #self.id_vx = canv.create_text(100,100,text = self.vx, font ='Arial 40')
- def pickup_coin(self,coin):
- self.points += coin.value
- def shot(self,vx,vy):
- self.bullets.append(Bullet(self.x,self.y,vx,vy))
- def update_info(self):
- canv.itemconfig(self.id_vx,text = self.vx)
- canv.itemconfig(self.id_vy,text = self.vy)
- def update(self):
- self.vx = 0
- if 'left' in self.keys:
- self.vx = -5
- if 'right' in self.keys:
- self.vx = +5
- if 'down' in self.keys:
- self.vy = +5
- if 'up' in self.keys:
- self.vy = -5
- if 'jump' in self.keys:
- if self.can_jump:
- self.can_jump = False
- self.vy = -25
- super().update()
- self.update_info()
- #~ if self.centerx > 600:
- #~ dx = 600 - self.centerx
- #~ self.centerx = 600
- #~ for item in world:
- #~ item.centerx += dx
- #~ item.paint()
- #~ if self.centerx < 300:
- #~ dx = 300 - self.centerx
- #~ self.centerx = 300
- #~ for item in world:
- #~ item.centerx += dx
- #~ item.paint()
- #~ if self.centery > 500:
- #~ dy = 500 - self.centery
- #~ self.centery = 500
- #~ for item in world:
- #~ item.centery += dy
- #~ item.paint()
- #~ if self.centery < 200:
- #~ dy = 200 - self.centery
- #~ self.centery = 200
- #~ for item in world:
- #~ item.centery += dy
- #~ item.paint()
- #self.active = False
- class Bullet():
- def __init__(self,x,y,vx,vy):
- self.x = x
- self.y = y
- self.r = 3
- self.w = self.r
- self.h = self.r
- self.vx = vx
- self.vy = vy
- self.g = 1
- self.active = True
- self.id = canv.create_oval(self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r,fill='gray')
- self.update()
- def update(self):
- self.vy += 0.8
- self.y += self.vy
- self.x += self.vx
- canv.coords(self.id,self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r)
- for enemy in enemies:
- if self.x-enemy.r <= enemy.x <= self.x+self.w+enemy.r and self.y-enemy.r <= enemy.y <= self.y + self.h + enemy.r:
- enemy.kill()
- self.kill()
- if self.active:
- root.after(30,self.update)
- def kill(self):
- canv.delete(self.id)
- self.active = False
- if self in player.bullets:
- player.bullets.remove(self)
- class Enemy(MovableObject,Animation,Base):
- def __init__(self,x,y,**kwargs):
- super().__init__(x,y,**kwargs)
- self.vx = -3
- def kill(self):
- canv.delete(self.id)
- world.remove(self)
- enemies.remove(self)
- self.active = False
- class Block(Object,Base):
- def __init__(self,x,y,**kwargs):
- super().__init__(x,y,**kwargs)
- #~ def update(self):
- #~ for unit in enemies + [player]:
- #~ hitside = self.hittest([unit])
- #~ dx = 5
- #~ dy = 1
- #~ # ~ if hitside:
- #~ # ~ print(hitside)
- #~ if hitside == 'up':
- #~ unit.vy = 0
- #~ unit.centery = self.y1-unit.h/2-dy
- #~ unit.can_jump = True
- #~ if hitside == 'down':
- #~ unit.vy = 0
- #~ unit.centery = self.y2 + unit.h/2 + dy
- #~ if hitside == 'left':
- #~ unit.vx = 0
- #~ unit.centerx = self.x1 - unit.w/2 - dx
- #~ # ~ canv.create_rectangle(self.x1,self.y1,self.x2,self.y2)
- #~ # ~ canv.create_rectangle(unit.x1,unit.y1,unit.x2,unit.y2,outline='orange')
- #~ # ~ unit.active = False
- #~ if hitside == 'right':
- #~ unit.vx = 0
- #~ unit.centerx = self.x2 + unit.w/2 + dx
- #~ super().update()
- class Coin(Object,Animation,Base):
- def __init__(self,x,y,**kwargs):
- self.value = 1
- super().__init__(x,y,**kwargs)
- self.update()
- # ~ def update(self):
- # ~ if self.hittest([player]):
- # ~ player.pickup_coin(self)
- # ~ self.kill()
- # ~ else:
- # ~ root.after(30,self.update)
- def kill(self):
- pass
- #canv.delete(self.image)
- #world.remove(self)
- blocks = []
- coin_images = []
- for i in range(1,7):
- coin_image = Image.open('coin'+str(i)+'.png').resize((m,m),Image.ANTIALIAS)
- coin_images.append(ImageTk.PhotoImage(image=coin_image))
- #canv.create_image(100+i*50,100,image=coin_images[-1])
- enemy_images = []
- for i in range(1,2):
- enemy_image = Image.open('enemy.png').resize((m,m),Image.ANTIALIAS)
- enemy_images.append(ImageTk.PhotoImage(image=enemy_image))
- player_images = []
- player_image = Image.open('enemy.png').resize((30,30),Image.ANTIALIAS)
- player_images.append(ImageTk.PhotoImage(image=player_image))
- block_image = Image.open('block.png').resize((m,m),Image.ANTIALIAS)
- block_image = ImageTk.PhotoImage(image=block_image)
- player = Player(300,300,images=player_images,pause=150)
- f = open('map1.py','r')
- r = 0
- x0 = 10
- y0 = 10
- world = []
- enemies = []
- blocks = []
- for line in f.readlines():
- c = 0
- for block in line.strip():
- x = x0 + c*m
- y = y0 + r*m
- if block == '1':
- block = Block(x,y,images=[block_image])
- world.append(block)
- blocks.append(block)
- elif block == 'c':
- world.append(Coin(x,y,images=coin_images,pause=100))
- #~ elif block == 'e':
- #~ en = Enemy(x,y,images=enemy_images,pause=100)
- #~ enemies.append(en)
- #~ world.append(en)
- c += 1
- r += 1
- f.close()
- def clearTemp():
- canv.delete('temp')
- root.after(3000,clearTemp)
- clearTemp()
- def keyDown(event):
- if event.keycode == 37 or event.keycode == 113:
- player.keys.add('left')
- if event.keycode == 39 or event.keycode == 114:
- player.keys.add('right')
- if event.keycode == 38 or event.keycode == 111:
- player.keys.add('jump')
- if event.keycode == 40 or event.keycode == 116:
- player.keys.add('down')
- def keyUp(event):
- if event.keycode == 37 or event.keycode == 113:
- if 'left' in player.keys:
- player.keys.remove('left')
- if event.keycode == 39 or event.keycode == 114:
- if 'right' in player.keys:
- player.keys.remove('right')
- if event.keycode == 38 or event.keycode == 111:
- if 'jump' in player.keys:
- player.keys.remove('jump')
- if 'up' in player.keys:
- player.keys.remove('up')
- if event.keycode == 40 or event.keycode == 116:
- if 'down' in player.keys:
- player.keys.remove('down')
- def mm(event):
- player.active = True
- def click(event):
- #~ vx = (event.x - player.x)/10
- #~ vy = (event.y - player.y)/10
- #~ player.shot(vx,vy)
- player.active = True
- canv.bind('<1>',click)
- canv.bind('<Motion>',mm)
- root.bind('<Key>',keyDown)
- root.bind('<KeyRelease>',keyUp)
- mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement