УРОК 11 Курсовая работа 4 курса
Самые распространенные задания средних курсов вузов есть создание игры с появляющимися объектами разного цвета и уничтожающиеся при соприкосновении или расположении рядом. За основу возмём такую задачу: на игровом поле в случайных местах появляются три разноцветных шара, при перемещении любого объекта на один шаг - появляются еще один шарик случайного цвета в случайных координатах и т. д..Задача собирать шарики по цвету в ряд - 3 одного цвета уничтожаются. На мой взгляд - это бредовая игра, но задание очень часто встречающееся... Попробуем его решить. Прежде всего нужно определиться что для создания подобного скрипта нам нужно?
1) Нарисовать поле с клеточками - создавали раньше
2) порождать рандомно объекты - создавали
3) перемещать при помощи мышки - не умеем
4)уничтожать три одинаковых объекта рядом - не умеем
Начнем с перемещения объектов по клеточному полю при помощи мышки, при чём существуют ограничения - нельзя занимать уже занятые клетки, перемещение возможно только на соседние клетки(вверх,низ,вправо,влево).
И так пишем скрипт на захват объекта лкм, перемещения его пока нажата лкм и установка объекта в клетку где находится курсор мышки.
if e.type == pygame.MOUSEBUTTONDOWN and e.button ==1:
mp = pygame.mouse.get_pos()
for i in all_s :# захват объекта
i.bum()
if e.type == pygame.MOUSEBUTTONUP and e.button ==1:# если отпущена лкм
koor = []# список координат разницы между обьуктом и мышкой
for i in all_s:
if i.action ==True:
i.funtion()# перемещение объекта точно в клетку
for i in all_s :
i.action = False# движение запрещено
koo = []# обнуление списка захвачен. объекта
for i in all_s:# запись положения объекта в список grid
i.mesto() # запись положения объектов в список грид
for i in all_s:
if i.action == True:
i.mouv()# перемещение объекта мышкой
Идея такова - если была нажата лкм - то получаем координаты мышки и проверяем какой объект из списка всех объектов мы выбрали( метод bum). Затем перемещаем обьект (привязываем его к курсору мышки-метод mouv).Если бала отпущена лкм - то для объета который переместили присваиваем координаты клеточки в которой был курсор в момент отпуска лкм.Запрещаем движения всем объектам.Записываем положение всех объектов в список грид. Теперь рассмотрим каждый метод и его особенности:
Метод bum() - захват объекта мышкой.
def bum (self):# проверка попадания мышки на объект
if self.x<mp[0]<self.x+self.w and self.y<mp[1]<self.y+self.h:
a = mp[0]-self.x# разница кооздинаты мышки и объекта
b = mp[1]-self.y
koor.append(a)# запись в список координат
koor.append(b)
self.action = True# разрешение на перемещение
c = self.x# первоначальные кооздинаты объекта
d = self.y
koo.append(c)# запись первоначального положения выбранного объекта
koo.append(d)
Условие попадания курсора на объект - стандартное. Далее надо учесть, что координаты курсора мышки и нашего объекта имеют разницу - эту разницу(по х и у координатам) мы должны занести в список - koor и обязательно обнулить его при условии отпуска лкм.
Записываем разрешение на перемещения выбранного объекта.Запоминаем первоначальные координаты объекта и заносим их в список koo( в случае не правильного перемещения объекта - вернем его на место).
Метод mouv()- перемещение объекта мышкой( лкм - нажата)
def mouv(self):# движение объекта с мышкой
# Получить текущее положение мыши. Это возвращает позицию
# в виде списка двух чисел.
pos = pygame.mouse.get_pos()
# Теперь игрок имеет координаты мышки с учетом разницы координат
self.x = pos[0]-koor[0]
self.y = pos[1]-koor[1]
В основном цикле для всего списка объектов проверяем условие разрешения перемещения и для объекта которому оно правдиво передаем метод mouv() . В котором координатам объекта передаем координаты мышки с учетом разницы их положения.
Метод funtion() - устанавливаем объект точно в клетку.
def funtion (self):# функция движения точно в клетку
mp = pygame.mouse.get_pos()# получ коорд мышки
self.x = (mp[0]// (width + margin))*(width + margin)+margin# коорд. клетки где находится мышь
self.y = (mp[1] // (height + margin))*(height + margin)+margin
self.column = self.x // (width + margin)# координ. в списке грид
self.row = self.y // (height + margin)
grid[ koo[1] // (height + margin)][ koo[0]// (width + margin)] =0# старой клетке = 0
if grid[self.row][self.column] ==1: # если клетка куда переместили занята
self.x = koo[0]# откат на обратные координаты
self.y = koo[1]
В момент отпуска лкм определяем координаты мышки и расчитываем координаты верхнего левого угла клетки где находился курсор и присваиваем эти координаты объекту. Расчитываем какая это клетка в списке грид и присваиваем клетке с первоначальными координатами значение = 0. Если клетка в которую мы переместили - занята (==1), то объект возвращаем на старое место- присваиваем ему первоначальные координаты.
Метод mesto()- запись положения всех объектов в список грид.
def mesto(self):# запись положения объектов в список грид
self.column = self.x // (width + margin)
self.row = self.y // (height + margin)
grid[self.row][self.column] = 1
Расчитываем и получаем для объектов колонки и строки для списка грид путем деления без остатка с округлением к меньшему координат объектов . И записываем значение = 1.
Полный код перемещения объектов мышкой с точным занятием клетки.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# захват лкм и отпуск по отпуску лкм с ограничением занятой клетки
import sys
import os
import pygame
WHITE = ( 255, 255, 255)
pygame.init()
n=4# количество клеток квадратного поля игры
width = 48#ширина клетки( и объекта)
height = 48#высота клетки ( и объекта)
margin = 5# промежуток между клетками
window = pygame.display.set_mode(((width +margin)*n+margin,(height+margin)*n+margin))# создаём окно
pygame.display.set_caption('Masha and Misha') # титул строка
screen = pygame.Surface(((width +margin)*n+margin,(height+margin)*n+margin)) # создаем игровое поле(экран)
koo = []# список нач. координат до перемещения
all_s = []# список всех объектов
screen = pygame.Surface((600,600)) # создаем игровое поле(экран)
koor = []# список координат разницы между обьуктом и мышкой
class Sprite:
# (нач.коорд-х,у,имя файла,нач.скорость-х,у)
def __init__(self,xpos,ypos,filename):
self.x = xpos
self.y = ypos
self.image=pygame.image.load(filename) # создаем рисунок-загрузка из файла
self.rect = self.image.get_rect() # представляем его прямоугольником
all_s.append(self)
self.w = self.image.get_width() #ширина
self.h = self.image.get_height() #высота
self.row = None
self.column = None
self.action = False
def bum (self):# проверка попадания мышки на объект
if self.x<mp[0]<self.x+self.w and self.y<mp[1]<self.y+self.h:
a = mp[0]-self.x# разница кооздинаты мышки и объекта
b = mp[1]-self.y
koor.append(a)# запись в список координат
koor.append(b)
self.action = True# разрешение на перемещение
c = self.x# первоначальные кооздинаты объекта
d = self.y
koo.append(c)# запись первоначального положения выбранного объекта
koo.append(d)
def funtion (self):# функция движения точно в клетку
mp = pygame.mouse.get_pos()# получ коорд мышки
self.x = (mp[0]// (width + margin))*(width + margin)+margin# коорд. клетки где находится мышь
self.y = (mp[1] // (height + margin))*(height + margin)+margin
self.column = self.x // (width + margin)# координ. в списке грид
self.row = self.y // (height + margin)
grid[ koo[1] // (height + margin)][ koo[0]// (width + margin)] =0# старой клетке = 0
if grid[self.row][self.column] ==1: # если клетка куда переместили занята
self.x = koo[0]# откат на обратные координаты
self.y = koo[1]
def render (self):# отображение обьекта на игровом поле(экране)
screen.blit(self.image,(self.x,self.y))
def mouv(self):# движение объекта с мышкой
#pygame.mouse.set_visible(False) # скрытие курсора
# Получить текущее положение мыши. Это возвращает позицию
# в виде списка двух чисел.
pos = pygame.mouse.get_pos()
# Теперь игрок имеет координаты мышки с учетом разницы координат
self.x = pos[0]-koor[0]
self.y = pos[1]-koor[1]
def mesto(self):# запись положения объектов в список грид
self.column = self.x // (width + margin)
self.row = self.y // (height + margin)
grid[self.row][self.column] = 1
hero1 = Sprite(margin,margin,('abcd.png'))
hero2 = Sprite(margin+(width +margin),margin,('abcd1.png'))
hero3 = Sprite((width +margin)*2+margin,margin,('abcd2.png'))
grid = []# список занятых и свободных клеток
for row in range(n):
# заполняем пустую матрицу
grid.append([])
for column in range(n):
grid[row].append(0)
dum = True
while dum:# условие существования игрового цикла
screen.fill((0,0,90))
for e in pygame.event.get():# для любого события
if e.type == pygame.QUIT:# если было закрытие окна
sys.exit()
# захват объекта лкм и перемещение при удержании кнопки
if e.type == pygame.MOUSEBUTTONDOWN and e.button ==1:
mp = pygame.mouse.get_pos()
for i in all_s :# захват объекта
i.bum()
if e.type == pygame.MOUSEBUTTONUP and e.button ==1:# если отпущена лкм
koor = []# список координат разницы между обьуктом и мышкой
for i in all_s:
if i.action ==True:
i.funtion()# перемещение объекта точно в клетку
for i in all_s :
i.action = False# движение запрещено
koo = []# обнуление списка захвачен. объекта
for i in all_s:# запись положения объекта в список grid
i.mesto() # запись положения объектов в список грид
for i in all_s:
if i.action == True:
i.mouv()# перемещение объекта мышкой
for row in range(n):# рисуем игровое поле
for column in range(n):
color = WHITE
pygame.draw.rect(screen,
color,
[(margin+width)*column+margin,
(margin+height)*row+margin,
width,
height])
for i in all_s:# отображаем все объекты
i.render()
window.blit(screen,(0,0))# на окне прорисовываем поле игры
pygame.display.flip()# отображаем полностью дисплей(окно)
Добавим ограничения выхода за границы поля:
# условие границ поля
if self.x<margin and self.x+width>((margin+width)*n+margin) and self.y<margin and self.y+height>((margin+height)*n+margin):
self.x = koo[0]
self.y = koo[1]
self.action = False
|