Collision Detection between Objects w/ Joystick Hat Control (Micropython)
-
I made a proof of concept for the M5Stick with Joystick hat. Using the joystick hat you can move a circle around the screen. Said circle has simple collision detection. Currently there is only one obstacle though. Adding more would be my next step.
Also I included the ability to pause using button B. While paused you can even adjust the display brightness with the joystick.
from m5stack import axp, btnA, btnB from m5ui import M5Rect, M5Circle, setScreenColor from uiflow import wait_ms import time import hat # configure size of deadzone on joystick input joyTolerance = 0.5 # configure display intDisplayBrightness = 35 setScreenColor(0x111111) axp.setLcdBrightness(intDisplayBrightness) # configure cursor position and size lstCursorCrd = [20, 5] # initial position cursorRad = 4 circle0 = M5Circle(lstCursorCrd[0], lstCursorCrd[1], cursorRad, 0xFFFFFF, 0xFFFFFF) # rectangular obstruction and hit box around it obs = (29, 109, 20, 20) rectangle0 = M5Rect(obs[0], obs[1], obs[2], obs[3], 0xFF5500, 0xFF5500) rectLeadX = obs[0] rectLeadY = obs[1] rectEndX = obs[0] + obs[2] rectEndY = obs[1] + obs[3] # define joystick hat joy0 = hat.get(hat.JOYSTICK) #get center positions on joystick for calibration joyX = joy0.InvertX joyY = joy0.InvertY # store booleans of invalid motion boolXPlus = True boolXMinus = True boolYPlus = True boolYMinus = True # store timeouts to reduce collision flicker yTimeoutDur = None xTimeoutDur = None yTimedout = False xTimedout = False #store current state for play/pause play = True while True: while play is True: # move cursor hitbox circLeadY = round(lstCursorCrd[0]) - cursorRad - 2 circLeadX = round(lstCursorCrd[1]) - cursorRad - 2 circEndY = round(lstCursorCrd[0]) + cursorRad + 2 circEndX = round(lstCursorCrd[1]) + cursorRad + 2 if not ((circEndY > rectLeadY) and (circLeadY < rectEndY) and (circLeadX < rectEndX) and (circEndX > rectLeadX)): # left if lstCursorCrd[0] < 153 and (joy0.InvertY - joyY) > (0 + joyTolerance) and yTimedout is False: lstCursorCrd[0] += abs((joy0.InvertY - joyY)/75) # right if lstCursorCrd[0] > 5 and (joy0.InvertY - joyY) < (0 - joyTolerance) and yTimedout is False: lstCursorCrd[0] -= abs((joy0.InvertY - joyY)/75) # down if lstCursorCrd[1] > 4 and (joy0.InvertX - joyX) > (0 + joyTolerance) and xTimedout is False: lstCursorCrd[1] -= abs((joy0.InvertX - joyX)/75) # up if lstCursorCrd[1] < 75 and (joy0.InvertX - joyX) < (0 - joyTolerance) and xTimedout is False: lstCursorCrd[1] += abs((joy0.InvertX - joyX)/75) #collision detection code elif circEndY >= rectLeadY and circLeadY < rectLeadY: # time out the cursor to prevent blink yTimeoutDur = time.ticks_ms() yTimedout = True # move cusor back lstCursorCrd[0] -= 1 elif circLeadY <= rectEndY and circEndY > rectEndY: # time out the cursor to prevent blink yTimeoutDur = time.ticks_ms() yTimedout = True # move cursor back lstCursorCrd[0] += 1 elif circEndX >= rectLeadX and circLeadX < rectLeadX: # time out the cursor to prevent blink xTimeoutDur = time.ticks_ms() xTimedout = True # move cursor back lstCursorCrd[1] -= 1 elif circLeadX <= rectEndX and circEndX > rectEndX: # time out the cursor to prevent blink xTimeoutDur = time.ticks_ms() xTimedout = True # move cursor back lstCursorCrd[1] += 1 #render cursor in current position circle0.setPosition(y=round(lstCursorCrd[0]), x=round(lstCursorCrd[1])) # unpause cursor movement after set duration from collision if time.ticks_diff(time.ticks_ms(), yTimeoutDur) > 200: yTimedout = False if time.ticks_diff(time.ticks_ms(), xTimeoutDur) > 200: xTimedout = False # pause game with button if btnB.wasPressed(): play = False rectangle0.show() # adjust display brightness while paused if (joy0.InvertX - joyX) < (0 - joyTolerance) and intDisplayBrightness < 100: intDisplayBrightness += 5 axp.setLcdBrightness(intDisplayBrightness) wait_ms(100) if (joy0.InvertX - joyX) > (0 + joyTolerance) and intDisplayBrightness > 20: intDisplayBrightness -= 5 axp.setLcdBrightness(intDisplayBrightness) wait_ms(100) # resume game if btnB.wasPressed(): play = True