Last active
April 10, 2022 18:59
-
-
Save NovaSquirrel/3d00d3da77c453067308a98890e9faf4 to your computer and use it in GitHub Desktop.
Thumby platformer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import thumby | |
import math | |
import random | |
thumby.display.setFPS(60) | |
playerSprite = thumby.Sprite(8, 8, bytearray([126,129,173,225,225,173,129,126]), 0, 0, 0) | |
levelGfx = bytearray([0,0,0,0,0,0,0,0,255,129,141,177,141,177,129,255,0,0,92,244,94,116,0,0,255,153,159,153,153,249,153,255,255,129,133,213,213,157,129,255,255,129,165,153,153,165,129,255,255,129,129,129,129,129,129,255,255,255,102,102,102,102,255,255,32,80,208,80,80,208,80,32,64,160,160,160,160,160,160,64,15,9,9,9,9,9,9,15,240,144,144,144,144,144,144,240,15,11,13,11,13,11,13,15,240,176,208,176,208,176,208,240]) | |
class Tilemap: | |
def __init__(self, width, height): | |
self.data = bytearray(width*height) | |
self.screenBytes = bytearray(72*6) | |
self.width = width | |
self.height = height | |
def put(self, x, y, value): | |
self.data[y*self.height+x] = value | |
def get(self, x, y): | |
return self.data[y*self.width+x] | |
def getp(self, x, y): | |
if x < 0 or y < 0 or x >= self.width*8 or y >= self.height*8: | |
return 0 | |
return self.data[int(y//8)*self.width+int(x//8)] | |
@micropython.viper | |
def draw(self, cameraX : int, cameraY : int): | |
screen = ptr8(self.screenBytes) | |
data = ptr8(self.data) | |
gfx = ptr8(levelGfx) | |
width = int(self.width) | |
topleft = cameraX//8 + (cameraY//8*width) | |
for tileRow in range(6): | |
write = 72*tileRow | |
read = data[topleft + tileRow*width]*8 | |
fineX = cameraX & 7 | |
side = 8 - fineX | |
for col in range(side): | |
screen[write] = gfx[read + 8 - side + col] | |
write += 1 | |
for col in range(1,9): | |
read = data[topleft + tileRow*width + col]*8 | |
screen[write+0] = gfx[read+0] | |
screen[write+1] = gfx[read+1] | |
screen[write+2] = gfx[read+2] | |
screen[write+3] = gfx[read+3] | |
screen[write+4] = gfx[read+4] | |
screen[write+5] = gfx[read+5] | |
screen[write+6] = gfx[read+6] | |
screen[write+7] = gfx[read+7] | |
write += 8 | |
side = fineX | |
if side != 0: | |
read = data[topleft + tileRow*width + 9]*8 | |
for col in range(side): | |
screen[write] = gfx[read + col] | |
write += 1 | |
thumby.display.blit(screen, 0, 0-(cameraY&7), 72, 48, -1, 0, 0) | |
def solidOnTop(id): | |
return id != 0 | |
def solidOnBottom(id): | |
return id != 0 | |
def solidOnLeft(id): | |
return id != 0 | |
def solidOnRight(id): | |
return id != 0 | |
level = Tilemap(30, 30) | |
level.put(1, 0, 1) | |
level.put(0, 3, 1) | |
level.put(0, 4, 1) | |
level.put(1, 4, 1) | |
level.put(2, 4, 1) | |
level.put(3, 4, 1) | |
level.put(4, 4, 1) | |
level.put(4, 3, 1) | |
level.put(5, 3, 1) | |
level.put(6, 3, 1) | |
level.put(6, 2, 1) | |
level.put(3, 8, 1) | |
level.put(4, 8, 1) | |
level.put(5, 8, 1) | |
level.put(6, 8, 1) | |
level.put(7, 7, 1) | |
level.put(8, 6, 1) | |
level.put(9, 5, 1) | |
level.put(10, 4, 1) | |
level.put(11, 3, 1) | |
level.put(12, 2, 1) | |
playerPX = 4 | |
playerPY = 0 | |
playerPYGround = 0 | |
playerVX = 0 | |
playerVY = 0 | |
jumpGracePeriod = 0 | |
playerWantsToJump = 0 | |
lastJumpPress = 0 | |
jumpCanceled = 0 | |
upHeld = 0 | |
downHeld = 0 | |
cameraX = 0 | |
cameraY = 0 | |
exit = False | |
while not exit: | |
playerVX = 0 | |
playerOnGround = 0 | |
if jumpGracePeriod: | |
jumpGracePeriod -= 1 | |
if playerWantsToJump: | |
playerWantsToJump -= 1 | |
if thumby.buttonL.pressed(): | |
playerVX = -1 | |
if thumby.buttonR.pressed(): | |
playerVX = 1 | |
playerPX += playerVX | |
if playerVX > 0 and (solidOnLeft(level.getp(playerPX+3, playerPY-7)) or solidOnLeft(level.getp(playerPX+3, playerPY-1))): | |
playerPX = (int(playerPX) & ~7) + 4 | |
if playerVX < 0 and (solidOnLeft(level.getp(playerPX-4, playerPY-7)) or solidOnLeft(level.getp(playerPX-4, playerPY-1))): | |
playerPX = (int(playerPX) & ~7) + 4 | |
if thumby.buttonU.pressed(): | |
upHeld += 1 | |
else: | |
upHeld = 0 | |
if thumby.buttonD.pressed(): | |
downHeld += 1 | |
else: | |
downHeld = 0 | |
jumpButton = thumby.buttonA.pressed() | |
if jumpButton and not lastJumpPress: | |
playerWantsToJump = 3 | |
lastJumpPress = jumpButton | |
if playerVY < 0 and not jumpCanceled and not jumpButton: | |
jumpCanceled = 1 | |
playerVY = -0.1 | |
playerVY = min(4, playerVY + 0.1) | |
playerPY += playerVY | |
if solidOnBottom(level.getp(playerPX-4, playerPY-7)) or solidOnBottom(level.getp(playerPX+3, playerPY-7)): | |
playerVY = 0 | |
playerPY = (int(playerPY) & ~7) + 8 | |
if solidOnTop(level.getp(playerPX-4, playerPY)) or solidOnTop(level.getp(playerPX+3, playerPY)): | |
playerVY = 0 | |
playerPY = int(playerPY) & ~7 | |
playerOnGround = 1 | |
jumpCanceled = 0 | |
playerPYGround = playerPY | |
jumpGracePeriod = 4 | |
if playerPY > playerPYGround: | |
playerPYGround = playerPY | |
if playerWantsToJump and (playerOnGround or jumpGracePeriod): | |
jumpGradePeriod = 0 | |
playerWantsToJump = 0 | |
playerVY = -2 | |
if playerPY > level.height*8: | |
playerPX = 4 | |
playerPY = 0 | |
if thumby.buttonB.pressed(): | |
exit = True | |
# ------------------------------------------ | |
targetCameraX = int(playerPX) - 72//2 | |
targetCameraX = min(max(targetCameraX, 0), level.width*8-72) | |
targetCameraY = int(playerPYGround) - 60//2 | |
if upHeld > 20: | |
targetCameraY -= 20 | |
if downHeld > 20: | |
targetCameraY += 20 | |
targetCameraY = min(max(targetCameraY, 0), level.height*8-40) | |
cameraX += (targetCameraX-cameraX)/4 | |
cameraY += (targetCameraY-cameraY)/8 | |
cameraPixelX = int(round(cameraX)) | |
cameraPixelY = int(round(cameraY)) | |
level.draw(cameraPixelX, cameraPixelY) | |
playerSprite.x = round(playerPX) - 4 - cameraPixelX | |
playerSprite.y = round(playerPY) - 8 - cameraPixelY | |
thumby.display.drawSprite(playerSprite) | |
thumby.display.update() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment