This code integrates a joystick with a simple Snake Game using the pygame library. It also utilizes the ACROME SMD platform to receive joystick inputs and provide feedback, like turning on a buzzer when food is consumed.
Joystick Input:
The joystick connected via the ACROME SMD platform is used to control the snake's direction. The snake moves left, right, up, or down based on the joystick's X and Y-axis values. A button on the joystick can be used to pause and resume the game.
Start and Game Over Menus:
The game starts with a simple menu where you can choose to start the game or quit. If the game ends (snake hits a wall or itself), a game over menu is displayed, with options to retry or quit.
Game Logic:
The snake grows when it eats food, and the length is increased. The snake's movement speed is fixed but can be controlled by the joystick. A buzzer sound is triggered when the snake eats the food.
Pause Functionality:
A button on the joystick allows pausing and resuming the game.
Project Wiring Diagram
Workflow:
Start Menu:
When the program is run, the start menu is displayed. The user can click on "Start" to begin the game or "Quit" to exit.
Snake Movement:
During the game, the joystick's position controls the snake's movement. Moving the joystick in any direction updates the snake’s position.
Eating Food:
When the snake's head collides with the food, the snake grows, and a buzzer sound is triggered.
Game Over:
The game ends when the snake hits the boundaries or itself. A "Game Over" menu is displayed with options to retry or quit.
Pausing the Game:
The game can be paused and resumed using the joystick's button
import pygameimport timeimport randomfrom smd.red import*from serial.tools.list_ports import comportsfrom platform import systemdefUSB_Port():ifsystem()=="Windows": ports =list(comports())if ports:for port, desc, hwid insorted(ports):if'USB Serial Port'in desc: SMD_Port = portreturn SMD_Portelse: SMD_Port =Nonereturn SMD_Portelifsystem()=="Linux": ports =list(serial.tools.list_ports.comports())if ports:for port, desc, hwid insorted(ports):if'/dev/ttyUSB'in port: SMD_Port = portreturn SMD_Portelifsystem()=="Darwin":# macOS ports =list(serial.tools.list_ports.comports())if ports:for port, desc, hwid insorted(ports):if'/dev/tty.usbserial'in port or'/dev/tty.usbmodem'in port: SMD_Port = portreturn SMD_Portelse: SMD_Port =Nonereturn SMD_Portport =USB_Port()m =Master(port)m.attach(Red(0))# Attach the Red device# Initialize the gamepygame.init()# Define colorswhite = (255,255,255)yellow = (255,255,102)black = (0,0,0)red = (213,50,80)green = (0,255,0)blue = (50,153,213)# Set display dimensionswidth, height =600,400display = pygame.display.set_mode((width, height))pygame.display.set_caption('Snake Game')# Clock to control game speedclock = pygame.time.Clock()# Snake settingssnake_block =10snake_speed =10# Font stylesfont_style = pygame.font.SysFont("bahnschrift", 25)score_font = pygame.font.SysFont("comicsansms", 35)defdisplay_score(score): value = score_font.render("Score: "+str(score), True, black) display.blit(value, [0, 0])defdraw_snake(snake_block,snake_list):for x in snake_list: pygame.draw.rect(display, black, [x[0], x[1], snake_block, snake_block])defmessage(msg,color,y_displace=0): mesg = font_style.render(msg, True, color) display.blit(mesg, [width /6, height /3+ y_displace])# Button function to create clickable buttonsdefbutton(text,x,y,w,h,inactive_color,active_color,action=None): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed()# Change color if mouse is over the buttonif x + w > mouse[0]> x and y + h > mouse[1]> y: pygame.draw.rect(display, active_color, (x, y, w, h))if click[0]==1and action !=None:action()else: pygame.draw.rect(display, inactive_color, (x, y, w, h))# Render the button text text_surf = font_style.render(text, True, black) display.blit(text_surf, [x + (w /4), y + (h /4)])# Start menu screendefstart_menu(): start_game =Falsewhilenot start_game: display.fill(blue)message("Welcome to Snake Game!", white, -50)# Create Start and Quit buttonsbutton("Start", 150, 200, 100, 50, green, yellow, game_loop)# Calls game_loop() when clickedbutton("Quit", 350, 200, 100, 50, red, yellow, pygame.quit)# Calls pygame.quit() when clicked pygame.display.update()for event in pygame.event.get():if event.type == pygame.QUIT: pygame.quit()quit()# Game over menu with Retry and Quit optionsdefgame_over_menu(): game_over_screen =Truewhile game_over_screen: display.fill(blue)message("You Lost!", red, -50)message("Score: "+str(length_of_snake -1), white, 0)# Create Retry and Quit buttonsbutton("Retry", 150, 200, 100, 50, green, yellow, game_loop)# Restart the gamebutton("Quit", 350, 200, 100, 50, red, yellow, pygame.quit)# Quit the game pygame.display.update()for event in pygame.event.get():if event.type == pygame.QUIT: pygame.quit()quit()defgame_loop():global length_of_snake paused =False game_over =False game_close =False# Initial snake settings x1 = width /2 y1 = height /2 x1_change =0 y1_change =0 snake_list = [] length_of_snake =1# Food position foodx =round(random.randrange(0, width - snake_block) /10.0)*10.0 foody =round(random.randrange(0, height - snake_block) /10.0)*10.0whilenot game_over: joystick = m.get_joystick(0, 1)while game_close ==True:game_over_menu()for event in pygame.event.get():if event.type == pygame.QUIT: game_over =True# Read joystick values x_val = joystick[0] y_val = joystick[1] y_val =-y_val# Check if the pause button (e.g., button 1) is pressedif m.get_button(0, 1):# Assuming button 1 is used for pause (check your joystick mapping) paused =not paused # Toggle pause state# If the game is paused, display the pause messageif paused: display.fill(blue)message("Paused! Press the button to Resume", yellow) pygame.display.update()continue# Skip the rest of the loop while paused# Control snake direction based on joystick positionif x_val <-20:# Left x1_change =-snake_block y1_change =0elif x_val >20:# Right x1_change = snake_block y1_change =0elif y_val <-20:# Up y1_change =-snake_block x1_change =0elif y_val >20:# Down y1_change = snake_block x1_change =0# Check for wall collisionsif x1 >= width or x1 <0or y1 >= height or y1 <0: game_close =True x1 += x1_change y1 += y1_change display.fill(blue) pygame.draw.rect(display, green, [foodx, foody, snake_block, snake_block]) snake_head = [] snake_head.append(x1) snake_head.append(y1) snake_list.append(snake_head)iflen(snake_list)> length_of_snake:del snake_list[0]for x in snake_list[:-1]:if x == snake_head: game_close =Truedraw_snake(snake_block, snake_list)display_score(length_of_snake -1) pygame.display.update()if x1 == foodx and y1 == foody: foodx =round(random.randrange(0, width - snake_block) /10.0)*10.0 foody =round(random.randrange(0, height - snake_block) /10.0)*10.0 length_of_snake +=1 m.set_buzzer(0, 1, 10)# Buzzer on collision time.sleep(0.1) m.set_buzzer(0, 1, 0)# Turn off buzzer clock.tick(snake_speed) pygame.quit() m.detach(0)# Detach the Red device using the correct integer IDprint("Disconnected from device.")# Start the gamestart_menu()# Display the start menu first
Conclusion:
This is a fun and interactive way to use the ACROME SMDjoystick to control the classic Snake game, providing a hardware-based gaming experience.