En este artículo, veremos cómo podemos diseñar el juego de la serpiente simple usando PyQt5.
Snake es el nombre común de un concepto de videojuego en el que el jugador maniobra una línea que crece en longitud, siendo la línea en sí misma un obstáculo principal. El concepto se originó en el juego de arcade Blockade de 1976, y la facilidad de implementar Snake ha llevado a cientos de versiones (algunas de las cuales tienen la palabra serpiente o gusano en el título) para muchas plataformas.
Pasos de implementación:
1. Cree una ventana principal, agréguele una barra de estado para mostrar la puntuación y cree un objeto de clase de tablero y agréguelo como widget central
2. Cree una clase llamada tablero que herede el QFrame
3. Dentro de la clase de tablero cree un objeto de temporizador que llama al método de temporizador después de cierta cantidad de tiempo
4. Dentro del método de temporizador llama a otra acción del juego de la serpiente como movimiento, comida comida y si la serpiente se suicidó
5. Cree un método de evento de pulsación de tecla que verifique si las teclas de flecha están pulsado y cambiar la dirección de la serpiente de acuerdo con él.
6. Cree un método de evento de pintura que dibuje la serpiente y la comida
7. Cree un método de movimiento para mover la serpiente según la dirección
8. Cree un método de comida consumida que verifique la posición actual de la serpiente y la posición si se come comida, elimine la comida actual, aumente la longitud de la serpiente y suelte una nueva comida en una ubicación aleatoria.
9. Cree un método de verificación de suicidio que verifique si la posición de la cabeza de serpiente es similar a la posición del cuerpo o no, si las coincidencias detienen el temporizador y muestran el mensaje
A continuación se muestra la implementación.
# importing libraries from PyQt5.QtCore import * from PyQt5.QtWidgets import * from PyQt5.QtGui import * import random import sys # creating game window class Window(QMainWindow): def __init__(self): super(Window, self).__init__() # creating a board object self.board = Board(self) # creating a status bar to show result self.statusbar = self.statusBar() # adding border to the status bar self.statusbar.setStyleSheet("border : 2px solid black;") # calling showMessage method when signal received by board self.board.msg2statusbar[str].connect(self.statusbar.showMessage) # adding board as a central widget self.setCentralWidget(self.board) # setting title to the window self.setWindowTitle('Snake game') # setting geometry to the window self.setGeometry(100, 100, 600, 400) # starting the board object self.board.start() # showing the main window self.show() # creating a board class # that inherits QFrame class Board(QFrame): # creating signal object msg2statusbar = pyqtSignal(str) # speed of the snake # timer countdown time SPEED = 80 # block width and height WIDTHINBLOCKS = 60 HEIGHTINBLOCKS = 40 # constructor def __init__(self, parent): super(Board, self).__init__(parent) # creating a timer self.timer = QBasicTimer() # snake self.snake = [[5, 10], [5, 11]] # current head x head self.current_x_head = self.snake[0][0] # current y head self.current_y_head = self.snake[0][1] # food list self.food = [] # growing is false self.grow_snake = False # board list self.board = [] # direction self.direction = 1 # called drop food method self.drop_food() # setting focus self.setFocusPolicy(Qt.StrongFocus) # square width method def square_width(self): return self.contentsRect().width() / Board.WIDTHINBLOCKS # square height def square_height(self): return self.contentsRect().height() / Board.HEIGHTINBLOCKS # start method def start(self): # msg for status bar # score = current len - 2 self.msg2statusbar.emit(str(len(self.snake) - 2)) # starting timer self.timer.start(Board.SPEED, self) # paint event def paintEvent(self, event): # creating painter object painter = QPainter(self) # getting rectangle rect = self.contentsRect() # board top boardtop = rect.bottom() - Board.HEIGHTINBLOCKS * self.square_height() # drawing snake for pos in self.snake: self.draw_square(painter, rect.left() + pos[0] * self.square_width(), boardtop + pos[1] * self.square_height()) # drawing food for pos in self.food: self.draw_square(painter, rect.left() + pos[0] * self.square_width(), boardtop + pos[1] * self.square_height()) # drawing square def draw_square(self, painter, x, y): # color color = QColor(0x228B22) # painting rectangle painter.fillRect(x + 1, y + 1, self.square_width() - 2, self.square_height() - 2, color) # key press event def keyPressEvent(self, event): # getting key pressed key = event.key() # if left key pressed if key == Qt.Key_Left: # if direction is not right if self.direction != 2: # set direction to left self.direction = 1 # if right key is pressed elif key == Qt.Key_Right: # if direction is not left if self.direction != 1: # set direction to right self.direction = 2 # if down key is pressed elif key == Qt.Key_Down: # if direction is not up if self.direction != 4: # set direction to down self.direction = 3 # if up key is pressed elif key == Qt.Key_Up: # if direction is not down if self.direction != 3: # set direction to up self.direction = 4 # method to move the snake def move_snake(self): # if direction is left change its position if self.direction == 1: self.current_x_head, self.current_y_head = self.current_x_head - 1, self.current_y_head # if it goes beyond left wall if self.current_x_head < 0: self.current_x_head = Board.WIDTHINBLOCKS - 1 # if direction is right change its position if self.direction == 2: self.current_x_head, self.current_y_head = self.current_x_head + 1, self.current_y_head # if it goes beyond right wall if self.current_x_head == Board.WIDTHINBLOCKS: self.current_x_head = 0 # if direction is down change its position if self.direction == 3: self.current_x_head, self.current_y_head = self.current_x_head, self.current_y_head + 1 # if it goes beyond down wall if self.current_y_head == Board.HEIGHTINBLOCKS: self.current_y_head = 0 # if direction is up change its position if self.direction == 4: self.current_x_head, self.current_y_head = self.current_x_head, self.current_y_head - 1 # if it goes beyond up wall if self.current_y_head < 0: self.current_y_head = Board.HEIGHTINBLOCKS # changing head position head = [self.current_x_head, self.current_y_head] # inset head in snake list self.snake.insert(0, head) # if snake grow is False if not self.grow_snake: # pop the last element self.snake.pop() else: # show msg in status bar self.msg2statusbar.emit(str(len(self.snake)-2)) # make grow_snake to false self.grow_snake = False # time event method def timerEvent(self, event): # checking timer id if event.timerId() == self.timer.timerId(): # call move snake method self.move_snake() # call food collision method self.is_food_collision() # call is suicide method self.is_suicide() # update the window self.update() # method to check if snake collides itself def is_suicide(self): # traversing the snake for i in range(1, len(self.snake)): # if collision found if self.snake[i] == self.snake[0]: # show game ended msg in status bar self.msg2statusbar.emit(str("Game Ended")) # making background color black self.setStyleSheet("background-color : black;") # stopping the timer self.timer.stop() # updating the window self.update() # method to check if the food cis collied def is_food_collision(self): # traversing the position of the food for pos in self.food: # if food position is similar of snake position if pos == self.snake[0]: # remove the food self.food.remove(pos) # call drop food method self.drop_food() # grow the snake self.grow_snake = True # method to drop food on screen def drop_food(self): # creating random co-ordinates x = random.randint(3, 58) y = random.randint(3, 38) # traversing if snake position is not equal to the # food position so that food do not drop on snake for pos in self.snake: # if position matches if pos == [x, y]: # call drop food method again self.drop_food() # append food location self.food.append([x, y]) # main method if __name__ == '__main__': app = QApplication([]) window = Window() sys.exit(app.exec_())
Producción :
Publicación traducida automáticamente
Artículo escrito por rakshitarora y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA