├── Games_master ├── readme ├── main.py ├── ssd1306.py ├── lht.py ├── snake.py ├── invader.py └── pong.py ├── Dino Jump Cactus ├── bg.pbm ├── cacti.pbm ├── player.pbm ├── player1.pbm ├── player2.pbm ├── gameover.pbm ├── README.md ├── main.py ├── ssd1306.py └── gfx.py └── README.md /Games_master/readme: -------------------------------------------------------------------------------- 1 | You can purchase it from: https://www.makerfabs.com/makepython-esp32.html 2 | -------------------------------------------------------------------------------- /Dino Jump Cactus/bg.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/Game/master/Dino Jump Cactus/bg.pbm -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Game 2 | 3 | You can purchase it from: https://www.makerfabs.com/makepython-esp32.html 4 | -------------------------------------------------------------------------------- /Dino Jump Cactus/cacti.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/Game/master/Dino Jump Cactus/cacti.pbm -------------------------------------------------------------------------------- /Dino Jump Cactus/player.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/Game/master/Dino Jump Cactus/player.pbm -------------------------------------------------------------------------------- /Dino Jump Cactus/player1.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/Game/master/Dino Jump Cactus/player1.pbm -------------------------------------------------------------------------------- /Dino Jump Cactus/player2.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/Game/master/Dino Jump Cactus/player2.pbm -------------------------------------------------------------------------------- /Dino Jump Cactus/gameover.pbm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shivasiddharth/Game/master/Dino Jump Cactus/gameover.pbm -------------------------------------------------------------------------------- /Dino Jump Cactus/README.md: -------------------------------------------------------------------------------- 1 | # Game 2 | 3 | You can purchase it from: https://www.makerfabs.com/makepython-esp32.html 4 | 5 | Code reference source:https://github.com/OpensourceBooks/chrome_offline_game_on_esp8266 6 | -------------------------------------------------------------------------------- /Games_master/main.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import sys 4 | import gc 5 | from machine import Pin, I2C 6 | from utime import sleep_ms, ticks_ms, ticks_diff 7 | module_name = "" 8 | 9 | def pressed (btn, wait_release=False) : 10 | if not btn.value(): 11 | sleep_ms (30) 12 | if btn.value(): 13 | return False 14 | #wait for key release 15 | while wait_release and not btn.value() : 16 | sleep_ms (5) 17 | return True 18 | return False 19 | def do_menu () : 20 | global module_name 21 | """ 22 | btnLeft = Pin(12, Pin.IN, Pin.PULL_UP) 23 | btnRight = Pin(13, Pin.IN, Pin.PULL_UP) 24 | btnUp = Pin(14, Pin.IN, Pin.PULL_UP) 25 | btnDown = Pin(2, Pin.IN, Pin.PULL_UP) 26 | """ 27 | btnLeft = Pin(13, Pin.IN, Pin.PULL_UP) 28 | btnRight = Pin(14, Pin.IN, Pin.PULL_UP) 29 | btnUp = Pin(15, Pin.IN, Pin.PULL_UP) 30 | btnDown = Pin(18, Pin.IN, Pin.PULL_UP) 31 | import ssd1306 32 | 33 | # configure oled display I2C SSD1306 34 | i2c = I2C(-1, Pin(5), Pin(4)) # SCL, SDA 35 | display = ssd1306.SSD1306_I2C(128, 64, i2c) 36 | 37 | 38 | SKIP_NAMES = ("boot", "main", "menu") 39 | 40 | 41 | files = [item[0] for item in os.ilistdir(".") if item[1] == 0x8000] 42 | # print("Files: %r" % files) 43 | 44 | module_names = [ 45 | filename.rsplit(".", 1)[0] 46 | for filename in files 47 | if (filename.endswith(".py") or filename.endswith(".mpy") ) and not filename.startswith("_") 48 | ] 49 | module_names = [module_name for module_name in module_names if not module_name in SKIP_NAMES] 50 | module_names.sort() 51 | tot_file = len(module_names) 52 | tot_rows = const(5) 53 | screen_pos = 0 54 | file_pos = 0 55 | 56 | launched = False 57 | while not launched : 58 | gc.collect() 59 | display.fill(0) 60 | display.text(sys.platform + " " + str(gc.mem_free()), 5, 0, 1) 61 | i = 0 62 | for j in range (file_pos, min(file_pos+tot_rows, tot_file)) : 63 | current_row = 12 + 10 *i 64 | if i == screen_pos : 65 | display.fill_rect(5, current_row, 118, 10, 1) 66 | display.text(str(j) + " " + module_names[j], 5, current_row, 0) 67 | else: 68 | display.fill_rect(5, current_row, 118, 10, 0) 69 | display.text(str(j) + " " + module_names[j], 5, current_row, 1) 70 | i+=1 71 | 72 | if pressed(btnUp): 73 | if screen_pos > 0 : 74 | screen_pos -= 1 75 | else : 76 | if file_pos > 0 : 77 | file_pos = max (0, file_pos - tot_rows) 78 | screen_pos=tot_rows-1 79 | 80 | if pressed(btnDown): 81 | if screen_pos < min(tot_file - file_pos - 1, tot_rows -1) : 82 | screen_pos = min(tot_file-1, screen_pos + 1) 83 | else : 84 | if file_pos + tot_rows < tot_file : 85 | file_pos = min (tot_file, file_pos + tot_rows) 86 | screen_pos=0 87 | 88 | if pressed(btnRight): 89 | display.fill(0) 90 | display.text("launching " , 5, 20, 1) 91 | display.text(module_names[file_pos + screen_pos], 5, 40, 1) 92 | display.show() 93 | sleep_ms(1000) 94 | module_name = module_names[file_pos + screen_pos] 95 | return True 96 | 97 | if pressed(btnLeft): 98 | launched = True 99 | display.fill(0) 100 | display.text("exited ", 5, 24, 1) 101 | display.show() 102 | return False 103 | display.show() 104 | 105 | go_on = True 106 | while go_on : 107 | go_on = do_menu() 108 | if go_on : 109 | gc.collect() 110 | module = __import__(module_name) 111 | del sys.modules[module_name] 112 | gc.collect() 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /Dino Jump Cactus/main.py: -------------------------------------------------------------------------------- 1 | from machine import Pin,I2C,SPI 2 | import ssd1306 3 | import gfx 4 | from time import sleep 5 | import framebuf 6 | pin_blue = Pin(14, Pin.IN) 7 | pin_red = Pin(15, Pin.IN) 8 | 9 | i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000) 10 | oled = ssd1306.SSD1306_I2C(128,64, i2c) 11 | 12 | graphics = gfx.GFX(128, 64, oled.pixel) 13 | oled.poweron() 14 | oled.init_display() 15 | oled.fill(0) 16 | 17 | oled.show() 18 | 19 | def blue_click(): 20 | if(status["is_jumpfinish"]): 21 | status["is_jump"]=True 22 | status["is_jumpfinish"]=False 23 | 24 | def red_click(): 25 | if(status["game"]=="ready"): 26 | status["game"]="playing" 27 | elif(status["game"]=="playing"): 28 | status["game"]="pause" 29 | elif(status["game"]=="pause"): 30 | status["game"]="playing" 31 | elif(status["game"]=="gameover"): 32 | begin() 33 | status["game"]="playing" 34 | 35 | def fire(): 36 | pass 37 | 38 | status={} 39 | 40 | status["game"]="loading" 41 | 42 | status["gametime"]=0 43 | status["km"]=0 44 | 45 | status["is_jump"]=False 46 | status["is_fire"]=False 47 | status["is_jumpfinish"]=True 48 | 49 | player = {} 50 | player["x"] = 10 51 | player["y"] = 44 52 | player["leg_status"]="1" 53 | #鎭愰緳 54 | with open('player.pbm', 'rb') as f: 55 | f.readline() # Magic number 56 | f.readline() # Creator comment 57 | f.readline() # Dimensions 58 | data = bytearray(f.read()) 59 | player["buf_jump"] = framebuf.FrameBuffer(data, 20, 20, framebuf.MONO_HLSB) 60 | 61 | with open('player1.pbm', 'rb') as f: 62 | f.readline() # Magic number 63 | f.readline() # Creator comment 64 | f.readline() # Dimensions 65 | data = bytearray(f.read()) 66 | player["buf1"] = framebuf.FrameBuffer(data, 20, 20, framebuf.MONO_HLSB) 67 | 68 | with open('player2.pbm', 'rb') as f: 69 | f.readline() # Magic number 70 | f.readline() # Creator comment 71 | f.readline() # Dimensions 72 | data = bytearray(f.read()) 73 | player["buf2"] = framebuf.FrameBuffer(data, 20, 20, framebuf.MONO_HLSB) 74 | player["buf"] = player["buf_jump"] 75 | 76 | obj={} 77 | obj["x"] = 130 78 | obj["y"] = 44 79 | with open('cacti.pbm', 'rb') as f: 80 | f.readline() # Magic number 81 | f.readline() # Creator comment 82 | f.readline() # Dimensions 83 | data = bytearray(f.read()) 84 | obj["buf"] = framebuf.FrameBuffer(data, 10, 20, framebuf.MONO_HLSB) 85 | 86 | bg={} 87 | bg["x"] = 0 88 | bg["y"] = 53 89 | with open('bg.pbm', 'rb') as f: 90 | f.readline() # Magic number 91 | f.readline() # Creator comment 92 | f.readline() # Dimensions 93 | data = bytearray(f.read()) 94 | bg["buf"] = framebuf.FrameBuffer(data, 256, 10, framebuf.MONO_HLSB) 95 | 96 | with open('gameover.pbm', 'rb') as f: 97 | f.readline() # Magic number 98 | f.readline() # Creator comment 99 | f.readline() # Dimensions 100 | data = bytearray(f.read()) 101 | gameover_buf = framebuf.FrameBuffer(data, 128, 64, framebuf.MONO_HLSB) 102 | 103 | def begin(): 104 | status["game"]="loading" 105 | status["gametime"]=0 106 | status["km"]=0 107 | status["is_jump"]=False 108 | status["is_fire"]=False 109 | status["is_jumpfinish"]=True 110 | 111 | obj["x"] = 130 112 | obj["y"] = 44 113 | player["y"] = 44 114 | 115 | def draw_player(): 116 | if(status["is_jump"]): 117 | player["y"]-=3 118 | oled.blit(player["buf_jump"], player["x"], player["y"]) 119 | if(player["y"]<15): 120 | status["is_jump"]=False 121 | else: 122 | player["buf"] = player["buf1"] 123 | player["y"]+=3 124 | 125 | if(player["y"]>=43): 126 | player["y"]=43 127 | status["is_jumpfinish"]=True 128 | if (player["leg_status"]=="1" ): 129 | oled.blit(player["buf1"], player["x"], player["y"]) 130 | player["leg_status"]="2" 131 | elif (player["leg_status"]=="2" ): 132 | oled.blit(player["buf2"], player["x"], player["y"]) 133 | player["leg_status"]="1" 134 | 135 | def draw_obj(): 136 | obj["x"]-=4 137 | 138 | oled.blit(obj["buf"], obj["x"], obj["y"]) 139 | 140 | if(obj["x"]<=-10): 141 | obj["x"]=130 142 | 143 | def draw_bg(): 144 | bg["x"]-=4 145 | 146 | oled.blit(bg["buf"], bg["x"], bg["y"]) 147 | oled.text("{0} km makerfabs".format(status["km"]),2,0) 148 | if(bg["x"]<=-10): 149 | bg["x"]=0 150 | 151 | def check(): 152 | if(obj["x"]-player["x"]<15 and obj["y"]-player["y"]<15): 153 | status["game"]="gameover" 154 | pass 155 | 156 | while (True): 157 | oled.fill(0) 158 | oled.contrast(1) 159 | 160 | blue = pin_blue.value() 161 | red = pin_red.value() 162 | 163 | if(pin_red.value() == 1): 164 | red_click() 165 | if(status["game"]=="loading"): 166 | oled.text("loading.".format(status["km"]),10,30) 167 | oled.show() 168 | sleep(1) 169 | oled.text("loading..".format(status["km"]),10,30) 170 | oled.show() 171 | sleep(1) 172 | oled.text("loading...".format(status["km"]),10,30) 173 | oled.show() 174 | status["game"]="ready" 175 | elif(status["game"]=="ready"): 176 | oled.text("-> 1 Player".format(status["km"]),15,10) 177 | oled.text("Start Jump".format(status["km"]),10,30) 178 | oled.text("-Makerfabs.com-".format(status["km"]),2,55) 179 | elif(status["game"]=="pause"): 180 | oled.text("pause",25,30) 181 | elif(status["game"]=="playing"): 182 | if(pin_blue.value() == 1): 183 | blue_click() 184 | status["km"]+=1 185 | status["gametime"]+=1 186 | #graphics.line(0, 63, 127, 63, 1) 187 | draw_bg() 188 | draw_player() 189 | draw_obj() 190 | check() 191 | elif(status["game"]=="gameover"): 192 | oled.text("{0} km".format(status["km"]),2,0) 193 | oled.text("makerfabs",25,20) 194 | oled.blit(gameover_buf, 0,28) 195 | oled.show() 196 | 197 | -------------------------------------------------------------------------------- /Dino Jump Cactus/ssd1306.py: -------------------------------------------------------------------------------- 1 | # MicroPython SSD1306 OLED driver, I2C and SPI interfaces 2 | from micropython import const 3 | import time 4 | import framebuf 5 | import sys 6 | 7 | currentBoard="" 8 | if(sys.platform=="esp8266"): 9 | currentBoard="esp8266" 10 | elif(sys.platform=="esp32"): 11 | currentBoard="esp32" 12 | elif(sys.platform=="pyboard"): 13 | currentBoard="pyboard" 14 | import pyb 15 | # register definitions 16 | SET_CONTRAST = const(0x81) 17 | SET_ENTIRE_ON = const(0xa4) 18 | SET_NORM_INV = const(0xa6) 19 | SET_DISP = const(0xae) 20 | SET_MEM_ADDR = const(0x20) 21 | SET_COL_ADDR = const(0x21) 22 | SET_PAGE_ADDR = const(0x22) 23 | SET_DISP_START_LINE = const(0x40) 24 | SET_SEG_REMAP = const(0xa0) 25 | SET_MUX_RATIO = const(0xa8) 26 | SET_COM_OUT_DIR = const(0xc0) 27 | SET_DISP_OFFSET = const(0xd3) 28 | SET_COM_PIN_CFG = const(0xda) 29 | SET_DISP_CLK_DIV = const(0xd5) 30 | SET_PRECHARGE = const(0xd9) 31 | SET_VCOM_DESEL = const(0xdb) 32 | SET_CHARGE_PUMP = const(0x8d) 33 | class SSD1306: 34 | def __init__(self, width, height, external_vcc): 35 | self.width = width 36 | self.height = height 37 | self.external_vcc = external_vcc 38 | self.pages = self.height // 8 39 | self.buffer = bytearray(self.pages * self.width) 40 | self.framebuf = framebuf.FrameBuffer(self.buffer, self.width, self.height, framebuf.MVLSB) 41 | self.poweron() 42 | self.init_display() 43 | def init_display(self): 44 | for cmd in ( 45 | SET_DISP | 0x00, # off 46 | # address setting 47 | SET_MEM_ADDR, 0x00, # horizontal 48 | # resolution and layout 49 | SET_DISP_START_LINE | 0x00, 50 | SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 51 | SET_MUX_RATIO, self.height - 1, 52 | SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 53 | SET_DISP_OFFSET, 0x00, 54 | SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12, 55 | # timing and driving scheme 56 | SET_DISP_CLK_DIV, 0x80, 57 | SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1, 58 | SET_VCOM_DESEL, 0x30, # 0.83*Vcc 59 | # display 60 | SET_CONTRAST, 0xff, # maximum 61 | SET_ENTIRE_ON, # output follows RAM contents 62 | SET_NORM_INV, # not inverted 63 | # charge pump 64 | SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14, 65 | SET_DISP | 0x01): # on 66 | self.write_cmd(cmd) 67 | self.fill(0) 68 | self.show() 69 | def poweroff(self): 70 | self.write_cmd(SET_DISP | 0x00) 71 | def contrast(self, contrast): 72 | self.write_cmd(SET_CONTRAST) 73 | self.write_cmd(contrast) 74 | def invert(self, invert): 75 | self.write_cmd(SET_NORM_INV | (invert & 1)) 76 | def show(self): 77 | x0 = 0 78 | x1 = self.width - 1 79 | if self.width == 64: 80 | # displays with width of 64 pixels are shifted by 32 81 | x0 += 32 82 | x1 += 32 83 | self.write_cmd(SET_COL_ADDR) 84 | self.write_cmd(x0) 85 | self.write_cmd(x1) 86 | self.write_cmd(SET_PAGE_ADDR) 87 | self.write_cmd(0) 88 | self.write_cmd(self.pages - 1) 89 | self.write_data(self.buffer) 90 | def fill(self, col): 91 | self.framebuf.fill(col) 92 | def pixel(self, x, y, col): 93 | self.framebuf.pixel(x, y, col) 94 | def scroll(self, dx, dy): 95 | self.framebuf.scroll(dx, dy) 96 | def text(self, string, x, y, col=1): 97 | self.framebuf.text(string, x, y, col) 98 | def hline(self, x, y, w, col): 99 | self.framebuf.hline(x, y, w, col) 100 | def vline(self, x, y, h, col): 101 | self.framebuf.vline(x, y, h, col) 102 | def line(self, x1, y1, x2, y2, col): 103 | self.framebuf.line(x1, y1, x2, y2, col) 104 | def rect(self, x, y, w, h, col): 105 | self.framebuf.rect(x, y, w, h, col) 106 | def fill_rect(self, x, y, w, h, col): 107 | self.framebuf.fill_rect(x, y, w, h, col) 108 | def blit(self, fbuf, x, y): 109 | self.framebuf.blit(fbuf, x, y) 110 | 111 | class SSD1306_I2C(SSD1306): 112 | def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False): 113 | self.i2c = i2c 114 | self.addr = addr 115 | self.temp = bytearray(2) 116 | super().__init__(width, height, external_vcc) 117 | def write_cmd(self, cmd): 118 | self.temp[0] = 0x80 # Co=1, D/C#=0 119 | self.temp[1] = cmd 120 | #IF SYS : 121 | global currentBoard 122 | if currentBoard=="esp8266" or currentBoard=="esp32": 123 | self.i2c.writeto(self.addr, self.temp) 124 | elif currentBoard=="pyboard": 125 | self.i2c.send(self.temp,self.addr) 126 | #ELSE: 127 | 128 | def write_data(self, buf): 129 | self.temp[0] = self.addr << 1 130 | self.temp[1] = 0x40 # Co=0, D/C#=1 131 | global currentBoard 132 | if currentBoard=="esp8266" or currentBoard=="esp32": 133 | self.i2c.start() 134 | self.i2c.write(self.temp) 135 | self.i2c.write(buf) 136 | self.i2c.stop() 137 | elif currentBoard=="pyboard": 138 | #self.i2c.send(self.temp,self.addr) 139 | #self.i2c.send(buf,self.addr) 140 | self.i2c.mem_write(buf,self.addr,0x40) 141 | def poweron(self): 142 | pass 143 | 144 | class SSD1306_SPI(SSD1306): 145 | def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): 146 | self.rate = 10 * 1024 * 1024 147 | dc.init(dc.OUT, value=0) 148 | res.init(res.OUT, value=0) 149 | cs.init(cs.OUT, value=1) 150 | self.spi = spi 151 | self.dc = dc 152 | self.res = res 153 | self.cs = cs 154 | super().__init__(width, height, external_vcc) 155 | def write_cmd(self, cmd): 156 | global currentBoard 157 | if currentBoard=="esp8266" or currentBoard=="esp32": 158 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 159 | elif currentBoard=="pyboard": 160 | self.spi.init(mode = pyb.SPI.MASTER,baudrate=self.rate, polarity=0, phase=0) 161 | self.cs.high() 162 | self.dc.low() 163 | self.cs.low() 164 | global currentBoard 165 | if currentBoard=="esp8266" or currentBoard=="esp32": 166 | self.spi.write(bytearray([cmd])) 167 | elif currentBoard=="pyboard": 168 | self.spi.send(bytearray([cmd])) 169 | self.cs.high() 170 | def write_data(self, buf): 171 | global currentBoard 172 | if currentBoard=="esp8266" or currentBoard=="esp32": 173 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 174 | elif currentBoard=="pyboard": 175 | self.spi.init(mode = pyb.SPI.MASTER,baudrate=self.rate, polarity=0, phase=0) 176 | self.cs.high() 177 | self.dc.high() 178 | self.cs.low() 179 | global currentBoard 180 | if currentBoard=="esp8266" or currentBoard=="esp32": 181 | self.spi.write(buf) 182 | elif currentBoard=="pyboard": 183 | self.spi.send(buf) 184 | self.cs.high() 185 | def poweron(self): 186 | self.res.high() 187 | time.sleep_ms(1) 188 | self.res.low() 189 | time.sleep_ms(10) 190 | self.res.high() 191 | 192 | 193 | -------------------------------------------------------------------------------- /Games_master/ssd1306.py: -------------------------------------------------------------------------------- 1 | # MicroPython SSD1306 OLED driver, I2C and SPI interfaces 2 | from micropython import const 3 | import time 4 | import framebuf 5 | import sys 6 | 7 | currentBoard="" 8 | if(sys.platform=="esp8266"): 9 | currentBoard="esp8266" 10 | elif(sys.platform=="esp32"): 11 | currentBoard="esp32" 12 | elif(sys.platform=="pyboard"): 13 | currentBoard="pyboard" 14 | import pyb 15 | # register definitions 16 | SET_CONTRAST = const(0x81) 17 | SET_ENTIRE_ON = const(0xa4) 18 | SET_NORM_INV = const(0xa6) 19 | SET_DISP = const(0xae) 20 | SET_MEM_ADDR = const(0x20) 21 | SET_COL_ADDR = const(0x21) 22 | SET_PAGE_ADDR = const(0x22) 23 | SET_DISP_START_LINE = const(0x40) 24 | SET_SEG_REMAP = const(0xa0) 25 | SET_MUX_RATIO = const(0xa8) 26 | SET_COM_OUT_DIR = const(0xc0) 27 | SET_DISP_OFFSET = const(0xd3) 28 | SET_COM_PIN_CFG = const(0xda) 29 | SET_DISP_CLK_DIV = const(0xd5) 30 | SET_PRECHARGE = const(0xd9) 31 | SET_VCOM_DESEL = const(0xdb) 32 | SET_CHARGE_PUMP = const(0x8d) 33 | class SSD1306: 34 | def __init__(self, width, height, external_vcc): 35 | self.width = width 36 | self.height = height 37 | self.external_vcc = external_vcc 38 | self.pages = self.height // 8 39 | self.buffer = bytearray(self.pages * self.width) 40 | self.framebuf = framebuf.FrameBuffer(self.buffer, self.width, self.height, framebuf.MVLSB) 41 | self.poweron() 42 | self.init_display() 43 | def init_display(self): 44 | for cmd in ( 45 | SET_DISP | 0x00, # off 46 | # address setting 47 | SET_MEM_ADDR, 0x00, # horizontal 48 | # resolution and layout 49 | SET_DISP_START_LINE | 0x00, 50 | SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 51 | SET_MUX_RATIO, self.height - 1, 52 | SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 53 | SET_DISP_OFFSET, 0x00, 54 | SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12, 55 | # timing and driving scheme 56 | SET_DISP_CLK_DIV, 0x80, 57 | SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1, 58 | SET_VCOM_DESEL, 0x30, # 0.83*Vcc 59 | # display 60 | SET_CONTRAST, 0xff, # maximum 61 | SET_ENTIRE_ON, # output follows RAM contents 62 | SET_NORM_INV, # not inverted 63 | # charge pump 64 | SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14, 65 | SET_DISP | 0x01): # on 66 | self.write_cmd(cmd) 67 | self.fill(0) 68 | self.show() 69 | def poweroff(self): 70 | self.write_cmd(SET_DISP | 0x00) 71 | def contrast(self, contrast): 72 | self.write_cmd(SET_CONTRAST) 73 | self.write_cmd(contrast) 74 | def invert(self, invert): 75 | self.write_cmd(SET_NORM_INV | (invert & 1)) 76 | def show(self): 77 | x0 = 0 78 | x1 = self.width - 1 79 | if self.width == 64: 80 | # displays with width of 64 pixels are shifted by 32 81 | x0 += 32 82 | x1 += 32 83 | self.write_cmd(SET_COL_ADDR) 84 | self.write_cmd(x0) 85 | self.write_cmd(x1) 86 | self.write_cmd(SET_PAGE_ADDR) 87 | self.write_cmd(0) 88 | self.write_cmd(self.pages - 1) 89 | self.write_data(self.buffer) 90 | def fill(self, col): 91 | self.framebuf.fill(col) 92 | def pixel(self, x, y, col): 93 | self.framebuf.pixel(x, y, col) 94 | def scroll(self, dx, dy): 95 | self.framebuf.scroll(dx, dy) 96 | def text(self, string, x, y, col=1): 97 | self.framebuf.text(string, x, y, col) 98 | def hline(self, x, y, w, col): 99 | self.framebuf.hline(x, y, w, col) 100 | def vline(self, x, y, h, col): 101 | self.framebuf.vline(x, y, h, col) 102 | def line(self, x1, y1, x2, y2, col): 103 | self.framebuf.line(x1, y1, x2, y2, col) 104 | def rect(self, x, y, w, h, col): 105 | self.framebuf.rect(x, y, w, h, col) 106 | def fill_rect(self, x, y, w, h, col): 107 | self.framebuf.fill_rect(x, y, w, h, col) 108 | def blit(self, fbuf, x, y): 109 | self.framebuf.blit(fbuf, x, y) 110 | 111 | class SSD1306_I2C(SSD1306): 112 | def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False): 113 | self.i2c = i2c 114 | self.addr = addr 115 | self.temp = bytearray(2) 116 | super().__init__(width, height, external_vcc) 117 | def write_cmd(self, cmd): 118 | self.temp[0] = 0x80 # Co=1, D/C#=0 119 | self.temp[1] = cmd 120 | #IF SYS : 121 | global currentBoard 122 | if currentBoard=="esp8266" or currentBoard=="esp32": 123 | self.i2c.writeto(self.addr, self.temp) 124 | elif currentBoard=="pyboard": 125 | self.i2c.send(self.temp,self.addr) 126 | #ELSE: 127 | 128 | def write_data(self, buf): 129 | self.temp[0] = self.addr << 1 130 | self.temp[1] = 0x40 # Co=0, D/C#=1 131 | global currentBoard 132 | if currentBoard=="esp8266" or currentBoard=="esp32": 133 | self.i2c.start() 134 | self.i2c.write(self.temp) 135 | self.i2c.write(buf) 136 | self.i2c.stop() 137 | elif currentBoard=="pyboard": 138 | #self.i2c.send(self.temp,self.addr) 139 | #self.i2c.send(buf,self.addr) 140 | self.i2c.mem_write(buf,self.addr,0x40) 141 | def poweron(self): 142 | pass 143 | 144 | class SSD1306_SPI(SSD1306): 145 | def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): 146 | self.rate = 10 * 1024 * 1024 147 | dc.init(dc.OUT, value=0) 148 | res.init(res.OUT, value=0) 149 | cs.init(cs.OUT, value=1) 150 | self.spi = spi 151 | self.dc = dc 152 | self.res = res 153 | self.cs = cs 154 | super().__init__(width, height, external_vcc) 155 | def write_cmd(self, cmd): 156 | global currentBoard 157 | if currentBoard=="esp8266" or currentBoard=="esp32": 158 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 159 | elif currentBoard=="pyboard": 160 | self.spi.init(mode = pyb.SPI.MASTER,baudrate=self.rate, polarity=0, phase=0) 161 | self.cs.high() 162 | self.dc.low() 163 | self.cs.low() 164 | global currentBoard 165 | if currentBoard=="esp8266" or currentBoard=="esp32": 166 | self.spi.write(bytearray([cmd])) 167 | elif currentBoard=="pyboard": 168 | self.spi.send(bytearray([cmd])) 169 | self.cs.high() 170 | def write_data(self, buf): 171 | global currentBoard 172 | if currentBoard=="esp8266" or currentBoard=="esp32": 173 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 174 | elif currentBoard=="pyboard": 175 | self.spi.init(mode = pyb.SPI.MASTER,baudrate=self.rate, polarity=0, phase=0) 176 | self.cs.high() 177 | self.dc.high() 178 | self.cs.low() 179 | global currentBoard 180 | if currentBoard=="esp8266" or currentBoard=="esp32": 181 | self.spi.write(buf) 182 | elif currentBoard=="pyboard": 183 | self.spi.send(buf) 184 | self.cs.high() 185 | def poweron(self): 186 | self.res.high() 187 | time.sleep_ms(1) 188 | self.res.low() 189 | time.sleep_ms(10) 190 | self.res.high() 191 | 192 | 193 | -------------------------------------------------------------------------------- /Games_master/lht.py: -------------------------------------------------------------------------------- 1 | 2 | # 在这里写上你的代码 :-) 3 | # ESP8266 iot humdity temperature sensor with LED switch and pump switch , MQTT and NTP time. 4 | # press LEFT button to exit the program. 5 | 6 | import machine 7 | import network 8 | import time 9 | from time import sleep, sleep_ms, ticks_ms, ticks_diff 10 | from machine import Pin, I2C 11 | 12 | import os 13 | import sys 14 | import ssd1306 15 | 16 | from struct import unpack as unp 17 | """ 18 | led = Pin(14, Pin.OUT) 19 | pump = Pin(13, Pin.OUT) 20 | btnLeft = Pin(12, Pin.IN, Pin.PULL_UP) 21 | btnDown = Pin(2, Pin.IN, Pin.PULL_UP) 22 | btnA = Pin(0, Pin.IN, Pin.PULL_UP) 23 | buzzer = Pin(15, Pin.OUT) 24 | """ 25 | led = Pin(27, Pin.OUT) 26 | pump = Pin(28, Pin.OUT) 27 | btnLeft = Pin(13, Pin.IN, Pin.PULL_UP) 28 | btnDown = Pin(18, Pin.IN, Pin.PULL_UP) 29 | btnA = Pin(19, Pin.IN, Pin.PULL_UP) 30 | buzzer = Pin(25, Pin.OUT) 31 | 32 | 33 | 34 | i2c = I2C(-1, Pin(5), Pin(4)) # SCL, SDA 35 | display = ssd1306.SSD1306_I2C(128, 64, i2c) 36 | 37 | # turn off everything 38 | led.on() 39 | pump.on() 40 | 41 | def pressed (btn, wait_release=False) : 42 | if not btn.value(): 43 | sleep_ms (30) 44 | if btn.value(): 45 | return False 46 | #wait for key release 47 | while wait_release and not btn.value() : 48 | sleep_ms (5) 49 | return True 50 | return False 51 | 52 | 53 | reported_err = 0 54 | measure_period_ms = const(20000) 55 | display_period_ms = const(1000) 56 | last_measure_ms = 0 57 | last_display_ms = 0 58 | 59 | ledOn = False 60 | pumpOn = False 61 | h = 72.5 62 | h0 = 1.0 63 | t = 28.3 64 | t0 = 1.0 65 | lux = 1000 66 | lux0 = 0 67 | 68 | 69 | 70 | # SHT20 default address 71 | SHT20_I2CADDR = 64 72 | 73 | # SHT20 Command 74 | TRI_T_MEASURE_NO_HOLD = b'\xf3' 75 | TRI_RH_MEASURE_NO_HOLD = b'\xf5' 76 | READ_USER_REG = b'\xe7' 77 | WRITE_USER_REG = b'\xe6' 78 | SOFT_RESET = b'\xfe' 79 | 80 | # SHT20 class to read temperature and humidity sensors 81 | class SHT20(object): 82 | 83 | def __init__(self, scl_pin=5, sda_pin=4, clk_freq=100000): 84 | self._address = SHT20_I2CADDR 85 | 86 | pin_c = Pin(scl_pin) 87 | pin_d = Pin(sda_pin) 88 | self._bus = I2C(scl=pin_c, sda=pin_d, freq=clk_freq) 89 | 90 | def get_temperature(self): 91 | self._bus.writeto(self._address, TRI_T_MEASURE_NO_HOLD) 92 | sleep_ms(150) 93 | origin_data = self._bus.readfrom(self._address, 2) 94 | origin_value = unp('>h', origin_data)[0] 95 | value = -46.85 + 175.72 * (origin_value / 65536) 96 | return value 97 | 98 | def get_relative_humidity(self): 99 | self._bus.writeto(self._address, TRI_RH_MEASURE_NO_HOLD) 100 | sleep_ms(150) 101 | origin_data = self._bus.readfrom(self._address, 2) 102 | origin_value = unp('>H', origin_data)[0] 103 | value = -6 + 125 * (origin_value / 65536) 104 | return value 105 | 106 | # BH1750fvi light meter sensor 107 | OP_SINGLE_HRES1 = 0x20 108 | OP_SINGLE_HRES2 = 0x21 109 | OP_SINGLE_LRES = 0x23 110 | 111 | DELAY_HMODE = 180 # 180ms in H-mode 112 | DELAY_LMODE = 24 # 24ms in L-mode 113 | 114 | 115 | def bh1750fvi (i2c, mode=OP_SINGLE_HRES1, i2c_addr=0x23): 116 | """ 117 | Performs a single sampling. returns the result in lux 118 | """ 119 | 120 | i2c.writeto(i2c_addr, b"\x00") # make sure device is in a clean state 121 | i2c.writeto(i2c_addr, b"\x01") # power up 122 | i2c.writeto(i2c_addr, bytes([mode])) # set measurement mode 123 | 124 | time.sleep_ms(DELAY_LMODE if mode == OP_SINGLE_LRES else DELAY_HMODE) 125 | 126 | raw = i2c.readfrom(i2c_addr, 2) 127 | i2c.writeto(i2c_addr, b"\x00") # power down again 128 | 129 | # we must divide the end result by 1.2 to get the lux 130 | return ((raw[0] << 24) | (raw[1] << 16)) // 78642 131 | 132 | 133 | def fill_zero(n): 134 | if n < 10: 135 | return '0' + str(n) 136 | else: 137 | return str(n) 138 | 139 | def fill_blank(n): 140 | if n<10: 141 | return ' ' + str(n) 142 | else: 143 | return str(n) 144 | 145 | 146 | 147 | 148 | # WiFi connection information 149 | WIFI_SSID = 'makerfabs' 150 | WIFI_PASSWORD = '20160704' 151 | 152 | # turn off the WiFi Access Point 153 | ap_if = network.WLAN(network.AP_IF) 154 | ap_if.active(False) 155 | 156 | # connect the device to the WiFi network 157 | wifi = network.WLAN(network.STA_IF) 158 | wifi.active(True) 159 | wifi.connect(WIFI_SSID, WIFI_PASSWORD) 160 | 161 | # wait until the device is connected to the WiFi network 162 | MAX_ATTEMPTS = 20 163 | attempt_count = 0 164 | while not wifi.isconnected() and attempt_count < MAX_ATTEMPTS: 165 | attempt_count += 1 166 | time.sleep(1) 167 | 168 | if attempt_count == MAX_ATTEMPTS: 169 | print('could not connect to the WiFi network') 170 | sys.exit() 171 | 172 | 173 | # set time using NTP server on the internet 174 | 175 | import ntptime #NTP-time (from pool.ntp.org) 176 | import utime 177 | ntptime.settime() 178 | tm = utime.localtime(utime.mktime(utime.localtime()) + 8 * 3600) 179 | tm=tm[0:3] + (0,) + tm[3:6] + (0,) 180 | rtc = machine.RTC() 181 | rtc.datetime(tm) 182 | 183 | 184 | 185 | sht_sensor = SHT20() 186 | 187 | while not pressed (btnLeft, True): 188 | 189 | if pressed(btnDown,True): 190 | #LED buttun pressed and released 191 | if ledOn : 192 | # if led is previously ON, now turn it off by outputing High voltage 193 | led.on() 194 | msg = "OFF" 195 | ledOn = False 196 | else : 197 | # if led is previously OFF, now turn it on by outputing Low voltage 198 | led.off() 199 | msg = "ON" 200 | ledOn = True 201 | 202 | # pump switch pressed 203 | if pressed(btnA,True): 204 | #LED button pressed and released 205 | if pumpOn : 206 | # if pump was ON, turn it off by outputing High voltage 207 | pump.on() 208 | msg = "OFF" 209 | pumpOn = False 210 | else : 211 | # if pump was OFF, now turn it on by outputing Low voltage 212 | pump.off() 213 | msg = "ON" 214 | pumpOn = True 215 | 216 | 217 | 218 | if ticks_diff(ticks_ms(), last_measure_ms ) >= measure_period_ms : 219 | # time to take measurements 220 | lux = bh1750fvi(i2c) 221 | t = sht_sensor.get_temperature() 222 | h = sht_sensor.get_relative_humidity() 223 | 224 | if lux != lux0 : 225 | print('Publish: lux = {}'.format(lux)) 226 | lux0 = lux 227 | 228 | if h != h0 : 229 | print('Publish: humidity = {}'.format(h)) 230 | h0 = h 231 | 232 | msg = (b'{0:3.1f}'.format(t)) 233 | if t != t0 : 234 | print('Publish: airtemp = {}'.format(t)) 235 | t0 = t 236 | 237 | last_measure_ms = ticks_ms() 238 | 239 | if ticks_diff(ticks_ms(), last_display_ms) >= display_period_ms : 240 | # time to display 241 | display.fill(0) 242 | Y,M,D,H,m,S,ms,W=utime.localtime() 243 | timetext ='%s-%s %s:%s:%s' % (fill_zero(M),fill_zero(D),fill_zero(H),fill_zero(m),fill_zero(S)) 244 | display.text(timetext,0,0) 245 | display.text('Lux = {}'.format(lux), 0, 15) 246 | display.text(b'{0:3.1f} %'.format(h), 0, 30) 247 | display.text(b'{0:3.1f} C'.format(t), 64, 30) 248 | if ledOn : 249 | display.text("LED ON", 0, 48) 250 | else : 251 | display.text("LED OFF", 0, 48) 252 | 253 | if pumpOn : 254 | display.text("PUMP ON", 64, 48) 255 | else : 256 | display.text("PUMP OFF", 64, 48) 257 | 258 | display.show() 259 | last_display_ms = time.ticks_ms() 260 | 261 | 262 | 263 | 264 | 265 | -------------------------------------------------------------------------------- /Dino Jump Cactus/gfx.py: -------------------------------------------------------------------------------- 1 | # Port of Adafruit GFX Arduino library to MicroPython. 2 | # Based on: https://github.com/adafruit/Adafruit-GFX-Library 3 | # Author: Tony DiCola (original GFX author Phil Burgess) 4 | # License: MIT License (https://opensource.org/licenses/MIT) 5 | 6 | 7 | class GFX: 8 | 9 | def __init__(self, width, height, pixel, hline=None, vline=None): 10 | # Create an instance of the GFX drawing class. You must pass in the 11 | # following parameters: 12 | # - width = The width of the drawing area in pixels. 13 | # - height = The height of the drawing area in pixels. 14 | # - pixel = A function to call when a pixel is drawn on the display. 15 | # This function should take at least an x and y position 16 | # and then any number of optional color or other parameters. 17 | # You can also provide the following optional keyword argument to 18 | # improve the performance of drawing: 19 | # - hline = A function to quickly draw a horizontal line on the display. 20 | # This should take at least an x, y, and width parameter and 21 | # any number of optional color or other parameters. 22 | # - vline = A function to quickly draw a vertical line on the display. 23 | # This should take at least an x, y, and height paraemter and 24 | # any number of optional color or other parameters. 25 | self.width = width 26 | self.height = height 27 | self._pixel = pixel 28 | # Default to slow horizontal & vertical line implementations if no 29 | # faster versions are provided. 30 | if hline is None: 31 | self.hline = self._slow_hline 32 | else: 33 | self.hline = hline 34 | if vline is None: 35 | self.vline = self._slow_vline 36 | else: 37 | self.vline = vline 38 | 39 | def _slow_hline(self, x0, y0, width, *args, **kwargs): 40 | # Slow implementation of a horizontal line using pixel drawing. 41 | # This is used as the default horizontal line if no faster override 42 | # is provided. 43 | if y0 < 0 or y0 > self.height or x0 < -width or x0 > self.width: 44 | return 45 | for i in range(width): 46 | self._pixel(x0+i, y0, *args, **kwargs) 47 | 48 | def _slow_vline(self, x0, y0, height, *args, **kwargs): 49 | # Slow implementation of a vertical line using pixel drawing. 50 | # This is used as the default vertical line if no faster override 51 | # is provided. 52 | if y0 < -height or y0 > self.height or x0 < 0 or x0 > self.width: 53 | return 54 | for i in range(height): 55 | self._pixel(x0, y0+i, *args, **kwargs) 56 | 57 | def rect(self, x0, y0, width, height, *args, **kwargs): 58 | # Rectangle drawing function. Will draw a single pixel wide rectangle 59 | # starting in the upper left x0, y0 position and width, height pixels in 60 | # size. 61 | if y0 < -height or y0 > self.height or x0 < -width or x0 > self.width: 62 | return 63 | self.hline(x0, y0, width, *args, **kwargs) 64 | self.hline(x0, y0+height-1, width, *args, **kwargs) 65 | self.vline(x0, y0, height, *args, **kwargs) 66 | self.vline(x0+width-1, y0, height, *args, **kwargs) 67 | 68 | def fill_rect(self, x0, y0, width, height, *args, **kwargs): 69 | # Filled rectangle drawing function. Will draw a single pixel wide 70 | # rectangle starting in the upper left x0, y0 position and width, height 71 | # pixels in size. 72 | if y0 < -height or y0 > self.height or x0 < -width or x0 > self.width: 73 | return 74 | for i in range(x0, x0+width): 75 | self.vline(i, y0, height, *args, **kwargs) 76 | 77 | def line(self, x0, y0, x1, y1, *args, **kwargs): 78 | # Line drawing function. Will draw a single pixel wide line starting at 79 | # x0, y0 and ending at x1, y1. 80 | steep = abs(y1 - y0) > abs(x1 - x0) 81 | if steep: 82 | x0, y0 = y0, x0 83 | x1, y1 = y1, x1 84 | if x0 > x1: 85 | x0, x1 = x1, x0 86 | y0, y1 = y1, y0 87 | dx = x1 - x0 88 | dy = abs(y1 - y0) 89 | err = dx // 2 90 | ystep = 0 91 | if y0 < y1: 92 | ystep = 1 93 | else: 94 | ystep = -1 95 | while x0 <= x1: 96 | if steep: 97 | self._pixel(y0, x0, *args, **kwargs) 98 | else: 99 | self._pixel(x0, y0, *args, **kwargs) 100 | err -= dy 101 | if err < 0: 102 | y0 += ystep 103 | err += dx 104 | x0 += 1 105 | 106 | def circle(self, x0, y0, radius, *args, **kwargs): 107 | # Circle drawing function. Will draw a single pixel wide circle with 108 | # center at x0, y0 and the specified radius. 109 | f = 1 - radius 110 | ddF_x = 1 111 | ddF_y = -2 * radius 112 | x = 0 113 | y = radius 114 | self._pixel(x0, y0 + radius, *args, **kwargs) 115 | self._pixel(x0, y0 - radius, *args, **kwargs) 116 | self._pixel(x0 + radius, y0, *args, **kwargs) 117 | self._pixel(x0 - radius, y0, *args, **kwargs) 118 | while x < y: 119 | if f >= 0: 120 | y -= 1 121 | ddF_y += 2 122 | f += ddF_y 123 | x += 1 124 | ddF_x += 2 125 | f += ddF_x 126 | self._pixel(x0 + x, y0 + y, *args, **kwargs) 127 | self._pixel(x0 - x, y0 + y, *args, **kwargs) 128 | self._pixel(x0 + x, y0 - y, *args, **kwargs) 129 | self._pixel(x0 - x, y0 - y, *args, **kwargs) 130 | self._pixel(x0 + y, y0 + x, *args, **kwargs) 131 | self._pixel(x0 - y, y0 + x, *args, **kwargs) 132 | self._pixel(x0 + y, y0 - x, *args, **kwargs) 133 | self._pixel(x0 - y, y0 - x, *args, **kwargs) 134 | 135 | def fill_circle(self, x0, y0, radius, *args, **kwargs): 136 | # Filled circle drawing function. Will draw a filled circule with 137 | # center at x0, y0 and the specified radius. 138 | self.vline(x0, y0 - radius, 2*radius + 1, *args, **kwargs) 139 | f = 1 - radius 140 | ddF_x = 1 141 | ddF_y = -2 * radius 142 | x = 0 143 | y = radius 144 | while x < y: 145 | if f >= 0: 146 | y -= 1 147 | ddF_y += 2 148 | f += ddF_y 149 | x += 1 150 | ddF_x += 2 151 | f += ddF_x 152 | self.vline(x0 + x, y0 - y, 2*y + 1, *args, **kwargs) 153 | self.vline(x0 + y, y0 - x, 2*x + 1, *args, **kwargs) 154 | self.vline(x0 - x, y0 - y, 2*y + 1, *args, **kwargs) 155 | self.vline(x0 - y, y0 - x, 2*x + 1, *args, **kwargs) 156 | 157 | def triangle(self, x0, y0, x1, y1, x2, y2, *args, **kwargs): 158 | # Triangle drawing function. Will draw a single pixel wide triangle 159 | # around the points (x0, y0), (x1, y1), and (x2, y2). 160 | self.line(x0, y0, x1, y1, *args, **kwargs) 161 | self.line(x1, y1, x2, y2, *args, **kwargs) 162 | self.line(x2, y2, x0, y0, *args, **kwargs) 163 | 164 | def fill_triangle(self, x0, y0, x1, y1, x2, y2, *args, **kwargs): 165 | # Filled triangle drawing function. Will draw a filled triangle around 166 | # the points (x0, y0), (x1, y1), and (x2, y2). 167 | if y0 > y1: 168 | y0, y1 = y1, y0 169 | x0, x1 = x1, x0 170 | if y1 > y2: 171 | y2, y1 = y1, y2 172 | x2, x1 = x1, x2 173 | if y0 > y1: 174 | y0, y1 = y1, y0 175 | x0, x1 = x1, x0 176 | a = 0 177 | b = 0 178 | y = 0 179 | last = 0 180 | if y0 == y2: 181 | a = x0 182 | b = x0 183 | if x1 < a: 184 | a = x1 185 | elif x1 > b: 186 | b = x1 187 | if x2 < a: 188 | a = x2 189 | elif x2 > b: 190 | b = x2 191 | self.hline(a, y0, b-a+1, *args, **kwargs) 192 | return 193 | dx01 = x1 - x0 194 | dy01 = y1 - y0 195 | dx02 = x2 - x0 196 | dy02 = y2 - y0 197 | dx12 = x2 - x1 198 | dy12 = y2 - y1 199 | if dy01 == 0: 200 | dy01 = 1 201 | if dy02 == 0: 202 | dy02 = 1 203 | if dy12 == 0: 204 | dy12 = 1 205 | sa = 0 206 | sb = 0 207 | if y1 == y2: 208 | last = y1 209 | else: 210 | last = y1-1 211 | for y in range(y0, last+1): 212 | a = x0 + sa // dy01 213 | b = x0 + sb // dy02 214 | sa += dx01 215 | sb += dx02 216 | if a > b: 217 | a, b = b, a 218 | self.hline(a, y, b-a+1, *args, **kwargs) 219 | sa = dx12 * (y - y1) 220 | sb = dx02 * (y - y0) 221 | while y <= y2: 222 | a = x1 + sa // dy12 223 | b = x0 + sb // dy02 224 | sa += dx12 225 | sb += dx02 226 | if a > b: 227 | a, b = b, a 228 | self.hline(a, y, b-a+1, *args, **kwargs) 229 | y += 1 230 | -------------------------------------------------------------------------------- /Games_master/snake.py: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------- 2 | # Snake Game I2C OLED 3 | # ESP8266 (node MCU D1 mini) micropython 4 | # by Billy Cheung 2019 08 31 5 | # 6 | 7 | # 8 | # I2C OLED SSD1306 9 | # GPIO4 D2--- SDA OLED 10 | # GPIO5 D1--- SCL OLED 11 | # 12 | # Speaker 13 | # GPIO15  D8 Speaker 14 | # 15 | #buttons 16 | # GPIO12  D6—— Left   17 | # GPIO13  D7—— Right     18 | # GPIO14  D5—— UP     19 | # GPIO2   D4——   Down     20 | # GPIO0   D3——   A 21 | import gc 22 | gc.collect() 23 | print (gc.mem_free()) 24 | import utime 25 | from utime import sleep_us, sleep_ms, ticks_ms, ticks_us, ticks_diff 26 | from machine import Pin, I2C,PWM, ADC 27 | 28 | import ssd1306 29 | from random import getrandbits, seed 30 | 31 | # ---------------------------------------------------------- 32 | # Global variables 33 | # ---------------------------------------------------------- 34 | 35 | SCREEN_WIDTH = const(128) 36 | SCREEN_HEIGHT = const(64) 37 | 38 | 39 | 40 | # configure oled display I2C SSD1306 41 | i2c = I2C(-1, Pin(5), Pin(4)) # SCL, SDA 42 | display = ssd1306.SSD1306_I2C(128, 64, i2c) 43 | # ESP8266 ADC A0 values 0-1023 44 | 45 | #--------- pin layout 46 | 47 | """ 48 | btnL = Pin(12, Pin.IN, Pin.PULL_UP) 49 | btnR = Pin(13, Pin.IN, Pin.PULL_UP) 50 | btnU = Pin(14, Pin.IN, Pin.PULL_UP) 51 | btnD = Pin(2, Pin.IN, Pin.PULL_UP) 52 | btnA = Pin(0, Pin.IN, Pin.PULL_UP) 53 | buzzer = Pin(15, Pin.OUT) 54 | """ 55 | btnL = Pin(13, Pin.IN, Pin.PULL_UP) 56 | btnR = Pin(14, Pin.IN, Pin.PULL_UP) 57 | btnU = Pin(15, Pin.IN, Pin.PULL_UP) 58 | btnD = Pin(18, Pin.IN, Pin.PULL_UP) 59 | btnA = Pin(19, Pin.IN, Pin.PULL_UP) 60 | buzzer = Pin(25, Pin.OUT) 61 | 62 | 63 | def getBtn() : 64 | pass 65 | 66 | def pressed (btn, wait_release=False) : 67 | if not btn.value(): 68 | if btn.value(): 69 | return False 70 | #wait for key release 71 | while wait_release and not btn.value() : 72 | sleep_ms (5) 73 | return True 74 | return False 75 | 76 | def getPaddle (maxvalue=1024) : 77 | return int (ADC(0).read() / (1024 / maxvalue)) 78 | 79 | tones = { 80 | 'c4': 262, 81 | 'd4': 294, 82 | 'e4': 330, 83 | 'f4': 349, 84 | 'f#4': 370, 85 | 'g4': 392, 86 | 'g#4': 415, 87 | 'a4': 440, 88 | "a#4": 466, 89 | 'b4': 494, 90 | 'c5': 523, 91 | 'c#5': 554, 92 | 'd5': 587, 93 | 'd#5': 622, 94 | 'e5': 659, 95 | 'f5': 698, 96 | 'f#5': 740, 97 | 'g5': 784, 98 | 'g#5': 831, 99 | 'a5': 880, 100 | 'b5': 988, 101 | 'c6': 1047, 102 | 'c#6': 1109, 103 | 'd6': 1175, 104 | ' ': 0 105 | } 106 | 107 | 108 | def playTone(tone, tone_duration, total_duration): 109 | beeper = PWM(buzzer, freq=tones[tone], duty=512) 110 | utime.sleep_ms(tone_duration) 111 | beeper.deinit() 112 | utime.sleep_ms(int(total_duration * 1000)-tone_duration) 113 | 114 | # ---------------------------------------------------------- 115 | # Game management 116 | # ---------------------------------------------------------- 117 | SNAKE_SIZE = 4 118 | SNAKE_LENGTH = 4 119 | SNAKE_EXTENT = 2 120 | COLS = (SCREEN_WIDTH - 4) // SNAKE_SIZE 121 | ROWS = (SCREEN_HEIGHT - 4) // SNAKE_SIZE 122 | OX = (SCREEN_WIDTH - COLS * SNAKE_SIZE) // 2 123 | OY = (SCREEN_HEIGHT - ROWS * SNAKE_SIZE) // 2 124 | COLOR_BG = 0 125 | COLOR_WALL = 1 126 | COLOR_SNAKE = 1 127 | COLOR_APPLE = 1 128 | COLOR_SCORE = 1 129 | COLOR_LOST_BG = 1 130 | COLOR_LOST_FG = 0 131 | MODE_START = 0 132 | MODE_READY = 1 133 | MODE_PLAY = 2 134 | MODE_LOST = 3 135 | MODE_EXIT = 4 136 | 137 | def tick(): 138 | if not game['refresh']: 139 | clearSnakeTail() 140 | 141 | if game['mode'] == MODE_START: 142 | resetSnake() 143 | spawnApple() 144 | game['mode'] = MODE_READY 145 | game['score'] = 0 146 | game['time'] = 0 147 | elif game['mode'] == MODE_READY: 148 | game['refresh'] = False 149 | 150 | handleButtons() 151 | moveSnake() 152 | if snakeHasMoved(): 153 | playTone('c5', 100, 0.5) 154 | game['mode'] = MODE_PLAY 155 | elif game['mode'] == MODE_PLAY: 156 | handleButtons() 157 | moveSnake() 158 | if game['refresh']: 159 | game['refresh'] = False 160 | if didSnakeEatApple(): 161 | playTone('d6', 20, 0.02) 162 | playTone('c5', 20, 0.02) 163 | playTone('f4', 20, 0.02) 164 | game['score'] += 1 165 | game['refresh'] = True 166 | extendSnakeTail() 167 | spawnApple() 168 | if didSnakeBiteItsTail() or didSnakeHitTheWall(): 169 | playTone('c4', 500, 1) 170 | game['mode'] = MODE_LOST 171 | game['refresh'] = True 172 | elif game['mode'] == MODE_EXIT: 173 | return 174 | else: 175 | handleButtons() 176 | 177 | draw() 178 | game['time'] += 1 179 | 180 | 181 | def spawnApple(): 182 | apple['x'] = getrandbits (6) % (COLS - 1) 183 | apple['y'] = getrandbits (7) % (ROWS - 1) 184 | 185 | def handleButtons(): 186 | if game['mode'] == MODE_LOST : 187 | if pressed(btnA): 188 | game['mode'] = MODE_START 189 | elif pressed(btnL): 190 | game['mode'] = MODE_EXIT 191 | elif pressed(btnL) : 192 | dirSnake(-1, 0) 193 | elif pressed(btnR) : 194 | dirSnake(1, 0) 195 | elif pressed(btnU): 196 | dirSnake(0, -1) 197 | elif pressed(btnD) : 198 | dirSnake(0, 1) 199 | 200 | 201 | 202 | # ---------------------------------------------------------- 203 | # Snake management 204 | # ---------------------------------------------------------- 205 | 206 | def resetSnake(): 207 | x = COLS // 2 208 | y = ROWS // 2 209 | snake['x'] = [] 210 | snake['y'] = [] 211 | for _ in range(SNAKE_LENGTH): 212 | snake['x'].append(x) 213 | snake['y'].append(y) 214 | snake['head'] = SNAKE_LENGTH - 1 215 | snake['len'] = SNAKE_LENGTH 216 | snake['vx'] = 0 217 | snake['vy'] = 0 218 | 219 | def dirSnake(dx, dy): 220 | snake['vx'] = dx 221 | snake['vy'] = dy 222 | 223 | def moveSnake(): 224 | h = snake['head'] 225 | x = snake['x'][h] 226 | y = snake['y'][h] 227 | h = (h + 1) % snake['len'] 228 | snake['x'][h] = x + snake['vx'] 229 | snake['y'][h] = y + snake['vy'] 230 | snake['head'] = h 231 | 232 | def snakeHasMoved(): 233 | return snake['vx'] or snake['vy'] 234 | 235 | def didSnakeEatApple(): 236 | h = snake['head'] 237 | return snake['x'][h] == apple['x'] and snake['y'][h] == apple['y'] 238 | 239 | def extendSnakeTail(): 240 | i = snake['head'] 241 | n = snake['len'] 242 | i = (i + 1) % n 243 | x = snake['x'][i] 244 | y = snake['y'][i] 245 | for _ in range(SNAKE_EXTENT): 246 | snake['x'].insert(i, x) 247 | snake['y'].insert(i, y) 248 | snake['len'] += SNAKE_EXTENT 249 | 250 | def didSnakeBiteItsTail(): 251 | h = snake['head'] 252 | n = snake['len'] 253 | x = snake['x'][h] 254 | y = snake['y'][h] 255 | i = (h + 1) % n 256 | for _ in range(n-1): 257 | if snake['x'][i] == x and snake['y'][i] == y: 258 | return True 259 | i = (i + 1) % n 260 | return False 261 | 262 | def didSnakeHitTheWall(): 263 | h = snake['head'] 264 | x = snake['x'][h] 265 | y = snake['y'][h] 266 | return x < 0 or x == COLS or y < 0 or y == ROWS 267 | 268 | # ---------------------------------------------------------- 269 | # Graphic display 270 | # ---------------------------------------------------------- 271 | 272 | def draw(): 273 | if game['mode'] == MODE_LOST: 274 | drawGameover() 275 | elif game['refresh']: 276 | clearScreen() 277 | drawWalls() 278 | drawSnake() 279 | else: 280 | drawSnakeHead() 281 | drawScore() 282 | drawApple() 283 | display.show() 284 | 285 | def clearScreen(): 286 | color = COLOR_LOST_BG if game['mode'] == MODE_LOST else COLOR_BG 287 | sleep_ms (20) 288 | display.fill(color) 289 | def drawGameover(): 290 | display.fill_rect(10,20,100,35,0) 291 | display.text("GAME OVER",20,20,1) 292 | display.text("A to Play",20,30,1) 293 | display.text("L to Stop",20,40,1) 294 | 295 | def drawWalls(): 296 | color = COLOR_LOST_FG if game['mode'] == MODE_LOST else COLOR_WALL 297 | display.rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,color) 298 | 299 | def drawSnake(): 300 | isTimeToBlink = game['time'] % 4 < 2 301 | color = COLOR_LOST_FG if game['mode'] == MODE_LOST and isTimeToBlink else COLOR_SNAKE 302 | n = snake['len'] 303 | for i in range(n): 304 | drawDot(snake['x'][i], snake['y'][i], color) 305 | sleep_ms (20) 306 | 307 | def drawSnakeHead(): 308 | h = snake['head'] 309 | drawDot(snake['x'][h], snake['y'][h], COLOR_SNAKE) 310 | 311 | def clearSnakeTail(): 312 | h = snake['head'] 313 | n = snake['len'] 314 | t = (h + 1) % n 315 | drawDot(snake['x'][t], snake['y'][t], COLOR_BG) 316 | sleep_ms (20) 317 | 318 | def drawScore(): 319 | display.text(str(game['score']),2,2,1) 320 | 321 | def drawApple(): 322 | drawDot(apple['x'], apple['y'], COLOR_APPLE) 323 | 324 | def drawDot(x, y, color): 325 | display.fill_rect(OX + x * SNAKE_SIZE, OY + y * SNAKE_SIZE, SNAKE_SIZE, SNAKE_SIZE,color) 326 | sleep_ms (20) 327 | 328 | def waitForUpdate(): 329 | # wait the amount of them that makes up 30 frame per second 330 | timer_dif = 1000000/30 - ticks_diff(ticks_us(), timer) 331 | if timer_dif > 0: 332 | sleep_us(timer_dif) 333 | sleep_ms (20) 334 | return 335 | 336 | 337 | # ---------------------------------------------------------- 338 | # Initialization 339 | # ---------------------------------------------------------- 340 | 341 | # Seed random numbers 342 | seed(ticks_us()) 343 | 344 | game = { 345 | 'mode': MODE_START, 346 | 'score': 0, 347 | 'time': 0, 348 | 'refresh': True 349 | } 350 | 351 | snake = { 352 | 'x': [], 353 | 'y': [], 354 | 'head': 0, 355 | 'len': 0, 356 | 'vx': 0, 357 | 'vy': 0 358 | } 359 | 360 | apple = { 'x': 0, 'y': 0 } 361 | 362 | # ---------------------------------------------------------- 363 | # Main loop 364 | # ---------------------------------------------------------- 365 | while game['mode'] != MODE_EXIT : 366 | timer = ticks_us() 367 | tick() 368 | waitForUpdate() 369 | 370 | 371 | 372 | 373 | -------------------------------------------------------------------------------- /Games_master/invader.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 在这里写上你的代码 :-) 4 | # invader.py I2C 5 | # 6 | # ESP8266 (node MCU D1 mini) micropython 7 | # by Billy Cheung 2019 08 31 8 | # 9 | 10 | # 11 | # I2C OLED SSD1306 12 | # GPIO4 D2--- SDA OLED 13 | # GPIO5 D1--- SCL OLED 14 | # 15 | # Speaker 16 | # GPIO15  D8 Speaker 17 | # 18 | #buttons 19 | # GPIO12  D6—— Left   20 | # GPIO13  D7—— Right     21 | # GPIO14  D5—— UP     22 | # GPIO2   D4——   Down     23 | # GPIO0   D3——   A 24 | 25 | # 26 | import gc 27 | import sys 28 | gc.collect() 29 | print (gc.mem_free()) 30 | import network 31 | import utime 32 | from utime import sleep_ms,ticks_ms, ticks_us, ticks_diff 33 | from machine import Pin, I2C, PWM, ADC 34 | from math import sqrt 35 | import ssd1306 36 | from random import getrandbits, seed 37 | 38 | """ 39 | btnL = Pin(12, Pin.IN, Pin.PULL_UP) 40 | btnR = Pin(13, Pin.IN, Pin.PULL_UP) 41 | btnU = Pin(14, Pin.IN, Pin.PULL_UP) 42 | btnD = Pin(2, Pin.IN, Pin.PULL_UP) 43 | btnA = Pin(0, Pin.IN, Pin.PULL_UP) 44 | buzzer = Pin(15, Pin.OUT) 45 | """ 46 | btnL = Pin(13, Pin.IN, Pin.PULL_UP) 47 | btnR = Pin(14, Pin.IN, Pin.PULL_UP) 48 | btnU = Pin(15, Pin.IN, Pin.PULL_UP) 49 | btnD = Pin(18, Pin.IN, Pin.PULL_UP) 50 | btnA = Pin(19, Pin.IN, Pin.PULL_UP) 51 | buzzer = Pin(25, Pin.OUT) 52 | # configure oled display I2C SSD1306 53 | i2c = I2C(-1, Pin(5), Pin(4)) # SCL, SDA 54 | display = ssd1306.SSD1306_I2C(128, 64, i2c) 55 | # ESP8266 ADC A0 values 0-1023 56 | #adc = ADC(32) 57 | adc = ADC(Pin(32)) 58 | 59 | def pressed (btn, wait_release=False) : 60 | if not btn.value(): 61 | 62 | if btn.value(): 63 | return False 64 | #wait for key release 65 | while wait_release and not btn.value() : 66 | sleep_ms (5) 67 | return True 68 | return False 69 | 70 | #---buttons 71 | 72 | 73 | #buzzer = Pin(15, Pin.OUT) 74 | buzzer = Pin(25, Pin.OUT) 75 | #adc = ADC(0) 76 | adc = ADC(Pin(32)) 77 | 78 | def getPaddle () : 79 | return adc.read() 80 | 81 | 82 | 83 | 84 | tones = { 85 | 'c4': 262, 86 | 'd4': 294, 87 | 'e4': 330, 88 | 'f4': 349, 89 | 'f#4': 370, 90 | 'g4': 392, 91 | 'g#4': 415, 92 | 'a4': 440, 93 | "a#4": 466, 94 | 'b4': 494, 95 | 'c5': 523, 96 | 'c#5': 554, 97 | 'd5': 587, 98 | 'd#5': 622, 99 | 'e5': 659, 100 | 'f5': 698, 101 | 'f#5': 740, 102 | 'g5': 784, 103 | 'g#5': 831, 104 | 'a5': 880, 105 | 'b5': 988, 106 | 'c6': 1047, 107 | 'c#6': 1109, 108 | 'd6': 1175, 109 | ' ': 0 110 | } 111 | 112 | 113 | def playTone(tone, tone_duration, rest_duration=0): 114 | beeper = PWM(buzzer, freq=tones[tone], duty=512) 115 | utime.sleep_ms(tone_duration) 116 | beeper.deinit() 117 | utime.sleep_ms(rest_duration) 118 | 119 | def playSound(freq, tone_duration, rest_duration=0): 120 | beeper = PWM(buzzer, freq, duty=512) 121 | utime.sleep_ms(tone_duration) 122 | beeper.deinit() 123 | utime.sleep_ms(rest_duration) 124 | 125 | 126 | 127 | frameRate = 30 128 | screenW = const(128) 129 | screenH = const(64) 130 | xMargin = const (5) 131 | yMargin = const(10) 132 | screenL = const (5) 133 | screenR = const(117) 134 | screenT = const (10) 135 | screenB = const (58) 136 | dx = 5 137 | vc = 3 138 | gunW= const(5) 139 | gunH = const (5) 140 | invaderSize = const(4) 141 | invaders_rows = const(5) 142 | invaders_per_row = const(11) 143 | 144 | 145 | 146 | class Rect (object): 147 | def __init__(self, x, y, w, h): 148 | self.x = x 149 | self.y = y 150 | self.x2 = x + w - 1 151 | self.y2 = y + h - 1 152 | def move_ip (self, vx, vy) : 153 | self.x = self.x + vx 154 | self.y = self.y + vy 155 | self.x2 = self.x2 + vx 156 | self.y2 = self.y2 + vy 157 | 158 | def colliderect (self, rect1) : 159 | if (self.x2 >= rect1.x and 160 | self.x <= rect1.x2 and 161 | self.y2 >= rect1.y and 162 | self.y <= rect1.y2) : 163 | return True 164 | else: 165 | return False 166 | 167 | 168 | def setUpInvaders (): 169 | y = yMargin 170 | while y < yMargin + (invaderSize+2) * invaders_rows : 171 | x = xMargin 172 | while x < xMargin + (invaderSize+2) * invaders_per_row : 173 | invaders.append(Rect(x,y,invaderSize, invaderSize)) 174 | x = x + invaderSize + 2 175 | y = y + invaderSize + 2 176 | 177 | def drawSpaceships (posture) : 178 | if posture : 179 | for i in spaceships : 180 | display.fill_rect(i.x+2, i.y, 5 , 3, 1) 181 | display.fill_rect(i.x, i.y+1, 9, 1, 1) 182 | display.fill_rect(i.x+1, i.y+1, 2, 1, 0) 183 | else : 184 | for i in spaceships : 185 | display.fill_rect(i.x+2, i.y, 5 , 3, 1) 186 | display.fill_rect(i.x, i.y+1, 9, 1, 1) 187 | display.fill_rect(i.x+5, i.y+1, 2, 1, 0) 188 | 189 | def drawInvaders (posture) : 190 | if posture : 191 | for i in invaders : 192 | display.fill_rect(i.x, i.y, invaderSize , invaderSize, 1) 193 | display.fill_rect(i.x+1, i.y+2, invaderSize-2, invaderSize-2, 0) 194 | else : 195 | for i in invaders : 196 | display.fill_rect(i.x, i.y, invaderSize , invaderSize, 1) 197 | display.fill_rect(i.x+1, i.y, invaderSize-2, invaderSize-2, 0) 198 | def drawGun () : 199 | display.fill_rect(gun.x+2, gun.y, 1, 2,1) 200 | display.fill_rect(gun.x, gun.y+2, gunW, 3,1) 201 | 202 | def drawBullets () : 203 | for b in bullets: 204 | display.fill_rect(b.x, b.y, 1,3,1) 205 | 206 | def drawAbullets () : 207 | for b in aBullets: 208 | display.fill_rect(b.x, b.y, 1,3,1) 209 | 210 | def drawScore () : 211 | display.text('S:{}'.format (score), 0,0,1) 212 | display.text('L:{}'.format (level), 50,0,1) 213 | for i in range (0, life) : 214 | display.fill_rect(92 + (gunW+2)*i, 0, 1, 2,1) 215 | display.fill_rect(90 + (gunW+2)*i, 2, gunW, 3,1) 216 | 217 | seed(ticks_us()) 218 | 219 | exitGame = False 220 | 221 | while not exitGame: 222 | gameOver = False 223 | usePaddle = False 224 | demo = False 225 | life = 3 226 | display.fill(0) 227 | display.text('Invaders', 5, 0, 1) 228 | display.text('A = Button', 5, 20, 1) 229 | display.text('U = Paddle', 5,30, 1) 230 | display.text('D = Demo', 5, 40, 1) 231 | display.text('L = Exit', 5, 50, 1) 232 | display.show() 233 | 234 | #menu screen 235 | while True: 236 | 237 | if pressed(btnL,True) : 238 | gameOver = True 239 | exitGame = True 240 | break 241 | elif pressed(btnA,True) : 242 | usePaddle = False 243 | break 244 | elif pressed(btnU,True) : 245 | usePaddle = True 246 | break 247 | elif pressed(btnD,True) : 248 | demo = True 249 | usePddle = False 250 | wait_for_keys=False 251 | display.fill(0) 252 | display.text('DEMO', 5, 0, 1) 253 | display.text('A or B to Stop', 5, 30, 1) 254 | display.show() 255 | sleep_ms(2000) 256 | break 257 | 258 | #reset the game 259 | score = 0 260 | frameCount = 0 261 | level = 0 262 | loadLevel = True 263 | postureA = False 264 | postureS = False 265 | # Chance from 1 to 128 266 | aBulletChance = 1 267 | spaceshipChance = 1 268 | 269 | while not gameOver: 270 | 271 | timer = ticks_ms() 272 | lost = False 273 | frameCount = (frameCount + 1 ) % 120 274 | display.fill(0) 275 | 276 | if loadLevel : 277 | loadLevel = False 278 | spaceships = [] 279 | invaders = [] 280 | bullets = [] 281 | aBullets = [] 282 | setUpInvaders() 283 | gun = Rect(screenL+int((screenR-screenL)/2), screenB, gunW, gunH) 284 | aBulletChance = 50 + level * 10 285 | 286 | 287 | 288 | #generate space ships 289 | if getrandbits(8) < spaceshipChance and len(spaceships) < 1 : 290 | spaceships.append(Rect(0,9, 9, 9)) 291 | 292 | if len(spaceships) : 293 | if not frameCount % 3 : 294 | postureS = not postureS 295 | # move spaceships once every 4 frames 296 | for i in spaceships: 297 | i.move_ip(2,0) 298 | if i.x >= screenR : 299 | spaceships.remove(i) 300 | if frameCount % 20 == 10 : 301 | playTone ('e5', 20) 302 | elif frameCount % 20 == 0 : 303 | playTone ('c5', 20) 304 | 305 | 306 | if not frameCount % 15 : 307 | postureA = not postureA 308 | # move Aliens once every 15 frames 309 | if postureA : 310 | playSound (80, 10) 311 | else: 312 | playSound (120, 10) 313 | for i in invaders: 314 | if i.x > screenR or i.x < screenL : 315 | dx = -dx 316 | for alien in invaders : 317 | alien.move_ip (0, invaderSize) 318 | if alien.y2 > gun.y : 319 | lost = True 320 | loadLevel = True 321 | playTone ('f4',300) 322 | playTone ('d4',100) 323 | playTone ('c5',100) 324 | break 325 | break 326 | 327 | for i in invaders : 328 | i.move_ip (dx, 0) 329 | 330 | 331 | # Fire 332 | if pressed(btnA) and len(bullets) < 2: 333 | bullets.append(Rect(gun.x+3, gun.y-1, 1, 3)) 334 | playSound (200,5) 335 | playSound (300,5) 336 | playSound (400,5) 337 | # move gun 338 | if usePaddle : 339 | gun.x = int(getPaddle() / (1024/(screenR-screenL))) 340 | gun.x2 = gun.x+gunW-1 341 | else : 342 | if pressed(btnL) and gun.x - 3 > 0 : 343 | vc = -3 344 | elif pressed(btnR) and (gun.x + 3 + gunW ) < screenW : 345 | vc = 3 346 | else : 347 | vc = 0 348 | gun.move_ip (vc, 0) 349 | 350 | # move bullets 351 | 352 | for b in bullets: 353 | b.move_ip(0,-3) 354 | if b.y < 0 : 355 | bullets.remove(b) 356 | else : 357 | for i in invaders: 358 | if i.colliderect(b) : 359 | invaders.remove(i) 360 | bullets.remove(b) 361 | score +=1 362 | playTone ('c6',10) 363 | break 364 | for i in spaceships : 365 | if i.colliderect(b) : 366 | spaceships.remove(i) 367 | bullets.remove(b) 368 | score +=10 369 | playTone ('b4',30) 370 | playTone ('e5',10) 371 | playTone ('c4',30) 372 | break 373 | 374 | # Launch Alien bullets 375 | for i in invaders: 376 | if getrandbits(10) * len (invaders) < aBulletChance and len(aBullets) < 3 : 377 | aBullets.append(Rect(i.x+2, i.y, 1, 3)) 378 | 379 | # move Alien bullets 380 | for b in aBullets: 381 | b.move_ip(0,3) 382 | if b.y > screenH : 383 | aBullets.remove(b) 384 | elif b.colliderect(gun) : 385 | lost = True 386 | #print ('{} {} {} {} : {} {} {} {}'.format(b.x,b.y,b.x2,b.y2,gun.x,gun.y,gun.x2,gun.y2)) 387 | aBullets.remove(b) 388 | playTone ('c5',30) 389 | playTone ('e4',30) 390 | playTone ('b4',30) 391 | break 392 | 393 | drawSpaceships (postureS) 394 | drawInvaders (postureA) 395 | drawGun() 396 | drawBullets() 397 | drawAbullets() 398 | drawScore() 399 | 400 | 401 | if len(invaders) == 0 : 402 | level += 1 403 | loadLevel = True 404 | playTone ('c4',100) 405 | playTone ('d4',100) 406 | playTone ('e4',100) 407 | playTone ('f4',100) 408 | playTone ('g4',100) 409 | 410 | if lost : 411 | lost = False; 412 | life -= 1 413 | if life < 0 : 414 | gameOver = True 415 | 416 | if gameOver : 417 | display.fill_rect (3, 15, 120,20,0) 418 | display.text ("GAME OVER", 5, 20, 1) 419 | playTone ('b4',300) 420 | playTone ('e4',100) 421 | playTone ('c4',100) 422 | display.show() 423 | 424 | sleep_ms(2000) 425 | 426 | display.show() 427 | 428 | timer_dif = int(1000/frameRate) - ticks_diff(ticks_ms(), timer) 429 | 430 | if timer_dif > 0 : 431 | sleep_ms(timer_dif) 432 | 433 | 434 | 435 | 436 | 437 | 438 | -------------------------------------------------------------------------------- /Games_master/pong.py: -------------------------------------------------------------------------------- 1 | 2 | # 在这里写上你的代码 :-) 3 | # pong.py I2C OLED version 4 | # ESP8266 (node MCU D1 mini) micropython 5 | # 6 | # by Billy Cheung 2019 09 27 7 | # 8 | 9 | # 10 | # I2C OLED SSD1306 11 | # GPIO4 D2--- SDA OLED 12 | # GPIO5 D1--- SCL OLED 13 | # 14 | # Speaker 15 | # GPIO15  D8 Speaker 16 | # 17 | #buttons 18 | # GPIO12  D6—— Left   19 | # GPIO13  D7—— Right     20 | # GPIO14  D5—— UP     21 | # GPIO2   D4——   Down     22 | # GPIO0   D3——   A 23 | # 24 | import gc 25 | import sys 26 | gc.collect() 27 | print (gc.mem_free()) 28 | import network 29 | import utime 30 | from utime import sleep_ms,ticks_ms, ticks_us, ticks_diff 31 | from machine import Pin, I2C, PWM, ADC 32 | from math import sqrt 33 | import ssd1306 34 | from random import getrandbits, seed 35 | 36 | 37 | #---buttons 38 | 39 | SCREEN_WIDTH = const(128) 40 | SCREEN_HEIGHT = const(64) 41 | paddle_width = 22 42 | """ 43 | btnL = Pin(12, Pin.IN, Pin.PULL_UP) 44 | btnR = Pin(13, Pin.IN, Pin.PULL_UP) 45 | btnU = Pin(14, Pin.IN, Pin.PULL_UP) 46 | btnD = Pin(2, Pin.IN, Pin.PULL_UP) 47 | btnA = Pin(0, Pin.IN, Pin.PULL_UP) 48 | btnB = Pin(3, Pin.IN, Pin.PULL_UP) 49 | buzzer = Pin(15, Pin.OUT) 50 | """ 51 | btnL = Pin(13, Pin.IN, Pin.PULL_UP) 52 | btnR = Pin(14, Pin.IN, Pin.PULL_UP) 53 | btnU = Pin(15, Pin.IN, Pin.PULL_UP) 54 | btnD = Pin(18, Pin.IN, Pin.PULL_UP) 55 | btnA = Pin(19, Pin.IN, Pin.PULL_UP) 56 | btnB = Pin(26, Pin.IN, Pin.PULL_UP) 57 | buzzer = Pin(25, Pin.OUT) 58 | 59 | # configure oled display I2C SSD1306 60 | i2c = I2C(-1, Pin(5), Pin(4)) # SCL, SDA 61 | display = ssd1306.SSD1306_I2C(128, 64, i2c) 62 | # ESP8266 ADC A0 values 0-1023 63 | #adc = ADC(0) 64 | adc = ADC(Pin(32)) 65 | 66 | def getBtn() : 67 | pass 68 | 69 | def pressed (btn, wait_release=False) : 70 | if not btn.value(): 71 | if btn.value(): 72 | return False 73 | #wait for key release 74 | while wait_release and not btn.value() : 75 | sleep_ms (5) 76 | return True 77 | return False 78 | 79 | 80 | 81 | def getPaddle (maxvalue=1024) : 82 | return int (ADC(0).read() / (1024 / maxvalue)) 83 | 84 | def getPaddle2 (maxvalue=1024) : 85 | return int (ADC(0).read() / (1024 / maxvalue)) 86 | 87 | 88 | 89 | 90 | 91 | tones = { 92 | 'c4': 262, 93 | 'd4': 294, 94 | 'e4': 330, 95 | 'f4': 349, 96 | 'f#4': 370, 97 | 'g4': 392, 98 | 'g#4': 415, 99 | 'a4': 440, 100 | "a#4": 466, 101 | 'b4': 494, 102 | 'c5': 523, 103 | 'c#5': 554, 104 | 'd5': 587, 105 | 'd#5': 622, 106 | 'e5': 659, 107 | 'f5': 698, 108 | 'f#5': 740, 109 | 'g5': 784, 110 | 'g#5': 831, 111 | 'a5': 880, 112 | 'b5': 988, 113 | 'c6': 1047, 114 | 'c#6': 1109, 115 | 'd6': 1175, 116 | ' ': 0 117 | } 118 | 119 | 120 | def playTone(tone, tone_duration, rest_duration=0): 121 | beeper = PWM(buzzer, freq=tones[tone], duty=512) 122 | utime.sleep_ms(tone_duration) 123 | beeper.deinit() 124 | utime.sleep_ms(rest_duration) 125 | 126 | def playSound(freq, tone_duration, rest_duration=0): 127 | beeper = PWM(buzzer, freq, duty=512) 128 | utime.sleep_ms(tone_duration) 129 | beeper.deinit() 130 | utime.sleep_ms(rest_duration) 131 | 132 | 133 | 134 | frameRate = 60 135 | 136 | scores = [0,0] 137 | maxScore = 15 138 | gameOver = False 139 | exitGame = False 140 | 141 | class Rect (object): 142 | def __init__(self, x, y, w, h): 143 | self.x = x 144 | self.y = y 145 | self.x2 = x + w - 1 146 | self.y2 = y + h - 1 147 | 148 | def move_ip (self, vx, vy) : 149 | self.x = self.x + vx 150 | self.y = self.y + vy 151 | self.x2 = self.x2 + vx 152 | self.y2 = self.y2 + vy 153 | 154 | def colliderect (self, rect1) : 155 | if (self.x2 >= rect1.x and 156 | self.x <= rect1.x2 and 157 | self.y2 >= rect1.y and 158 | self.y <= rect1.y2) : 159 | return True 160 | else: 161 | return False 162 | 163 | 164 | 165 | class bat(Rect): 166 | def __init__(self, velocity, up_key, down_key, *args, **kwargs): 167 | self.velocity = velocity 168 | self.up_key = up_key 169 | self.down_key = down_key 170 | super().__init__(*args, **kwargs) 171 | 172 | def move_bat(self, board_height, bat_HEIGHT, ballY): 173 | getBtn() 174 | 175 | if self.up_key == 0 : # use AI 176 | self.y = max(min(ballY - 10 + getrandbits(10) % 16, board_height-pong.bat_HEIGHT),0) 177 | 178 | elif self.up_key == -1 : # use Paddle 179 | self.y = getPaddle(board_height-pong.bat_HEIGHT) 180 | 181 | elif self.up_key == -2 : # use 2nd Paddle 182 | self.y = getPaddle2(board_height-pong.bat_HEIGHT) 183 | 184 | else : 185 | if pressed(self.up_key): 186 | if self.y - self.velocity > 0: 187 | self.y -= self.velocity 188 | 189 | if pressed(self.down_key): 190 | if self.y + self.velocity < board_height - bat_HEIGHT : 191 | self.y += self.velocity 192 | self.y2 = self.y + pong.bat_HEIGHT 193 | 194 | class Ball(Rect): 195 | def __init__(self, velocity, *args, **kwargs): 196 | self.velocity = velocity 197 | self.angle = 0 198 | super().__init__(*args, **kwargs) 199 | 200 | def move_ball(self): 201 | self.x += self.velocity 202 | self.y += self.angle 203 | self.x2 = self.x + pong.BALL_WIDTH 204 | self.y2 = self.y + pong.BALL_WIDTH 205 | 206 | 207 | class Pong: 208 | HEIGHT = 64 209 | WIDTH = 128 210 | 211 | bat_WIDTH = 3 212 | bat_HEIGHT = 15 213 | bat_VELOCITY = 5 214 | 215 | BALL_WIDTH = 3 216 | BALL_VELOCITY = 5 217 | BALL_ANGLE = 0 218 | 219 | COLOUR = 1 220 | scores = [0,0] 221 | maxScore = 15 222 | 223 | 224 | def init (self, onePlayer, demo, usePaddle): 225 | # Setup the screen 226 | global scores 227 | scores = [0,0] 228 | # Create the player objects. 229 | self.bats = [] 230 | self.balls = [] 231 | 232 | if demo or onePlayer : 233 | self.bats.append(bat( # The left bat, AI 234 | self.bat_VELOCITY, 235 | 0, 236 | 0, 237 | 0, 238 | int(self.HEIGHT / 2 - self.bat_HEIGHT / 2), 239 | self.bat_WIDTH, 240 | self.bat_HEIGHT)) 241 | elif usePaddle : 242 | self.bats.append(bat( # The left bat, use Paddle 243 | self.bat_VELOCITY, 244 | -2, 245 | -2, 246 | 0, 247 | int(self.HEIGHT / 2 - self.bat_HEIGHT / 2), 248 | self.bat_WIDTH, 249 | self.bat_HEIGHT)) 250 | else : 251 | 252 | self.bats.append(bat( # The left bat, button controlled 253 | self.bat_VELOCITY, 254 | btnU, 255 | btnD, 256 | 0, 257 | int(self.HEIGHT / 2 - self.bat_HEIGHT / 2), 258 | self.bat_WIDTH, 259 | self.bat_HEIGHT)) 260 | 261 | if demo : 262 | self.bats.append(bat( # The right bat, AI 263 | self.bat_VELOCITY, 264 | 0, 265 | 0, 266 | self.WIDTH - self.bat_WIDTH-1, 267 | int(self.HEIGHT / 2 - self.bat_HEIGHT / 2), 268 | self.bat_WIDTH, 269 | self.bat_HEIGHT 270 | )) 271 | elif usePaddle : 272 | self.bats.append(bat( # The right bat, buse Paddle 273 | self.bat_VELOCITY, 274 | -1, 275 | -1, 276 | self.WIDTH - self.bat_WIDTH-1, 277 | int(self.HEIGHT / 2 - self.bat_HEIGHT / 2), 278 | self.bat_WIDTH, 279 | self.bat_HEIGHT 280 | )) 281 | else : 282 | self.bats.append(bat( # The right bat, button controlled 283 | self.bat_VELOCITY, 284 | btnB, 285 | btnA, 286 | self.WIDTH - self.bat_WIDTH-1, 287 | int(self.HEIGHT / 2 - self.bat_HEIGHT / 2), 288 | self.bat_WIDTH, 289 | self.bat_HEIGHT 290 | )) 291 | 292 | self.balls.append(Ball( 293 | self.BALL_VELOCITY, 294 | int(self.WIDTH / 2 - self.BALL_WIDTH / 2), 295 | int(self.HEIGHT / 2 - self.BALL_WIDTH / 2), 296 | self.BALL_WIDTH, 297 | self.BALL_WIDTH)) 298 | 299 | 300 | def score(self, player, ball): 301 | global gameOver 302 | global scores 303 | scores[player] += 1 304 | ball.velocity = - ball.velocity 305 | ball.angle = getrandbits(10) % 4 - 2 306 | ball.x = int(self.WIDTH / 2 - self.BALL_WIDTH / 2) 307 | ball.y = int(self.HEIGHT / 2 - self.BALL_WIDTH / 2) 308 | ball.x2 = ball.x + self.BALL_WIDTH 309 | ball.y2 = ball.y + self.BALL_WIDTH 310 | playTone ('g4', 100) 311 | 312 | if scores[player] >= maxScore : 313 | gameOver = True 314 | 315 | def check_ball_hits_wall(self): 316 | for ball in self.balls: 317 | 318 | if ball.x < 0: 319 | self.score(1, ball) 320 | 321 | 322 | if ball.x > self.WIDTH : 323 | self.score(0, ball) 324 | 325 | if ball.y > self.HEIGHT - self.BALL_WIDTH or ball.y < 0: 326 | ball.angle = -ball.angle 327 | 328 | 329 | def check_ball_hits_bat(self): 330 | for ball in self.balls: 331 | for bat in self.bats: 332 | #print (' {} {} {} {} : {} {} {} {}'.format (ball.x, ball.y, ball.x2, ball.y2, bat.x,bat.y, bat.x2, bat.y2)) 333 | if ball.colliderect(bat): 334 | ball.velocity = -ball.velocity 335 | ball.angle = (getrandbits(10) % 4 ) - 2 336 | playTone ('c6', 10) 337 | break 338 | 339 | def game_loop(self): 340 | global gameOver 341 | global exitGame 342 | global scores 343 | global frameRate 344 | 345 | exitGame = False 346 | while not exitGame: 347 | frameRate = 40 348 | usePaddle = False 349 | onePlayer = True 350 | demo = False 351 | gameOver = False 352 | display.fill(0) 353 | display.text('D-Demo L-Quit', 5, 0, 1) 354 | display.text('A 1-Button', 5, 20, 1) 355 | display.text('B 1-Paddle', 5,30, 1) 356 | display.text('U 2-Button', 5, 40, 1) 357 | display.text('R 2-Paddle', 5, 50, 1) 358 | display.show() 359 | 360 | #menu screen 361 | while True: 362 | getBtn() 363 | if pressed(btnL,True) : 364 | exitGame = True 365 | gameOver= True 366 | break 367 | elif pressed(btnA,True) : 368 | onePlayer = True 369 | usePaddle = False 370 | break 371 | elif pressed(btnB,True) : 372 | onePlayer = True 373 | usePaddle = True 374 | break 375 | elif pressed(btnU,True) : 376 | onePlayer = False 377 | usePaddle = False 378 | break 379 | elif pressed(btnR,True) : 380 | onePlayer = False 381 | usePaddle = True 382 | break 383 | elif pressed(btnD,True) : 384 | demo = True 385 | usePaddle = False 386 | frameRate = 120 387 | display.fill(0) 388 | display.text('DEMO', 5, 0, 1) 389 | display.text('A or B to Stop', 5, 30, 1) 390 | display.show() 391 | sleep_ms(2000) 392 | break 393 | 394 | 395 | self.init(onePlayer, demo, usePaddle) 396 | #game loop 397 | display.fill(0) 398 | while not gameOver: 399 | 400 | timer=ticks_ms() 401 | 402 | getBtn() 403 | 404 | self.check_ball_hits_bat() 405 | self.check_ball_hits_wall() 406 | 407 | for bat in self.bats: 408 | display.fill_rect(bat.x,bat.y,self.bat_WIDTH, self.bat_HEIGHT, 0) 409 | bat.move_bat(self.HEIGHT, self.bat_HEIGHT, self.balls[0].y) 410 | display.fill_rect(bat.x,bat.y,self.bat_WIDTH, self.bat_HEIGHT, self.COLOUR) 411 | 412 | for ball in self.balls: 413 | display.fill_rect(ball.x,ball.y,self.BALL_WIDTH ,self.BALL_WIDTH, 0) 414 | ball.move_ball() 415 | display.fill_rect(ball.x,ball.y,self.BALL_WIDTH ,self.BALL_WIDTH, self.COLOUR) 416 | 417 | display.fill_rect(40, 0, 60, 10,0) 418 | display.text ('{} : {}'.format (scores[0], scores[1]), 45, 0, 1) 419 | 420 | if gameOver : 421 | display.fill_rect(25,25,100, 30,0) 422 | display.text ("Game Over", 30, 30, 1) 423 | display.show() 424 | playTone ('c5', 200) 425 | playTone ('g4', 200) 426 | playTone ('g4', 200) 427 | playTone ('a4', 200) 428 | playTone ('g4', 400) 429 | playTone ('b4', 200) 430 | playTone ('c5', 400) 431 | display.show() 432 | 433 | timer_dif = int(1000/frameRate) - ticks_diff(ticks_ms(), timer) 434 | 435 | if timer_dif > 0 : 436 | sleep_ms(timer_dif) 437 | 438 | 439 | #if __name__ == '__main__': 440 | pong = Pong() 441 | 442 | pong.game_loop() 443 | print ("game exit") 444 | 445 | 446 | 447 | 448 | --------------------------------------------------------------------------------