├── .gitpod.yml ├── README.md ├── images ├── 0.png ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── S1.png ├── S2.png ├── S3.png ├── S4.png ├── S5.png ├── SAW0.png ├── SAW1.png ├── SAW2.png ├── SAW3.png ├── bg.png └── spike.png ├── main.py ├── requirements.txt └── starterFile.py /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: gitpod/workspace-full-vnc 2 | ports: 3 | - port: 5900 4 | onOpen: ignore 5 | - port: 6080 6 | onOpen: open-preview 7 | tasks: 8 | - init: pip3 install -r requirements.txt 9 | command: python3 main.py 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Side Scroller 2 | 3 | This is the code base for the side scroller tutorial videos posted on my YouTube channel. 4 | 5 | You can check out the tutorial videos here: https://www.youtube.com/watch?v=PjgLeP0G5Yw&t=53s 6 | 7 | # Requirements 8 | - Python 3.x 9 | - pygame 10 | 11 | # 💻 Launch Your Software Development Career Today! 12 | 13 | 🎓 **No degree? No problem!** My program equips you with everything you need to break into tech and land an entry-level software development role. 14 | 15 | 🚀 **Why Join?** 16 | - 💼 **$70k+ starting salary potential** 17 | - 🕐 **Self-paced:** Complete on your own time 18 | - 🤑 **Affordable:** Low risk compared to expensive bootcamps or degrees 19 | - 🎯 **45,000+ job openings** in the market 20 | 21 | 👉 **[Start your journey today!](https://techwithtim.net/dev)** 22 | No experience needed—just your determination. Future-proof your career and unlock six-figure potential like many of our students have! 23 | -------------------------------------------------------------------------------- /images/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/0.png -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/1.png -------------------------------------------------------------------------------- /images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/10.png -------------------------------------------------------------------------------- /images/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/11.png -------------------------------------------------------------------------------- /images/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/12.png -------------------------------------------------------------------------------- /images/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/13.png -------------------------------------------------------------------------------- /images/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/14.png -------------------------------------------------------------------------------- /images/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/15.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/3.png -------------------------------------------------------------------------------- /images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/4.png -------------------------------------------------------------------------------- /images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/5.png -------------------------------------------------------------------------------- /images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/6.png -------------------------------------------------------------------------------- /images/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/7.png -------------------------------------------------------------------------------- /images/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/8.png -------------------------------------------------------------------------------- /images/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/9.png -------------------------------------------------------------------------------- /images/S1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/S1.png -------------------------------------------------------------------------------- /images/S2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/S2.png -------------------------------------------------------------------------------- /images/S3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/S3.png -------------------------------------------------------------------------------- /images/S4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/S4.png -------------------------------------------------------------------------------- /images/S5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/S5.png -------------------------------------------------------------------------------- /images/SAW0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/SAW0.png -------------------------------------------------------------------------------- /images/SAW1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/SAW1.png -------------------------------------------------------------------------------- /images/SAW2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/SAW2.png -------------------------------------------------------------------------------- /images/SAW3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/SAW3.png -------------------------------------------------------------------------------- /images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/bg.png -------------------------------------------------------------------------------- /images/spike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/techwithtim/Side-Scroller-Game/37d54e001d615a0927c3f99b9675de77f671ddc7/images/spike.png -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from pygame.locals import * 3 | import os 4 | import random 5 | 6 | pygame.init() 7 | 8 | W, H = 800, 437 9 | win = pygame.display.set_mode((W,H)) 10 | pygame.display.set_caption('Side Scroller') 11 | 12 | bg = pygame.image.load(os.path.join('images', 'bg.png')).convert() 13 | bgX = 0 14 | bgX2 = bg.get_width() 15 | 16 | clock = pygame.time.Clock() 17 | 18 | class player(object): 19 | run = [pygame.image.load(os.path.join('images', str(x) + '.png')) for x in range(8, 16)] 20 | jump = [pygame.image.load(os.path.join('images', str(x) + '.png')) for x in range(1, 8)] 21 | slide = [pygame.image.load(os.path.join('images', 'S1.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')),pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S3.png')), pygame.image.load(os.path.join('images', 'S4.png')), pygame.image.load(os.path.join('images', 'S5.png'))] 22 | fall = pygame.image.load(os.path.join('images', '0.png')) 23 | jumpList = [1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4] 24 | 25 | def __init__(self, x, y, width, height): 26 | self.x = x 27 | self.y = y 28 | self.width = width 29 | self.height = height 30 | self.jumping = False 31 | self.sliding = False 32 | self.falling = False 33 | self.slideCount = 0 34 | self.jumpCount = 0 35 | self.runCount = 0 36 | self.slideUp = False 37 | 38 | def draw(self, win): 39 | if self.falling: 40 | win.blit(self.fall, (self.x, self.y + 30)) 41 | elif self.jumping: 42 | self.y -= self.jumpList[self.jumpCount] * 1.3 43 | win.blit(self.jump[self.jumpCount//18], (self.x, self.y)) 44 | self.jumpCount += 1 45 | if self.jumpCount > 108: 46 | self.jumpCount = 0 47 | self.jumping = False 48 | self.runCount = 0 49 | self.hitbox = (self.x+ 4, self.y, self.width-24, self.height-10) 50 | elif self.sliding or self.slideUp: 51 | if self.slideCount < 20: 52 | self.y += 1 53 | self.hitbox = (self.x+ 4, self.y, self.width-24, self.height-10) 54 | elif self.slideCount == 80: 55 | self.y -= 19 56 | self.sliding = False 57 | self.slideUp = True 58 | elif self.slideCount > 20 and self.slideCount < 80: 59 | self.hitbox = (self.x, self.y+3, self.width-8, self.height-35) 60 | 61 | if self.slideCount >= 110: 62 | self.slideCount = 0 63 | self.runCount = 0 64 | self.slideUp = False 65 | self.hitbox = (self.x+ 4, self.y, self.width-24, self.height-10) 66 | win.blit(self.slide[self.slideCount//10], (self.x, self.y)) 67 | self.slideCount += 1 68 | 69 | else: 70 | if self.runCount > 42: 71 | self.runCount = 0 72 | win.blit(self.run[self.runCount//6], (self.x,self.y)) 73 | self.runCount += 1 74 | self.hitbox = (self.x+ 4, self.y, self.width-24, self.height-13) 75 | 76 | #pygame.draw.rect(win, (255,0,0),self.hitbox, 2) 77 | 78 | class saw(object): 79 | rotate = [pygame.image.load(os.path.join('images', 'SAW0.png')), pygame.image.load(os.path.join('images', 'SAW1.png')), pygame.image.load(os.path.join('images', 'SAW2.png')), pygame.image.load(os.path.join('images', 'SAW3.png'))] 80 | 81 | def __init__(self, x, y, width, height): 82 | self.x = x 83 | self.y = y 84 | self.width = width 85 | self.height = height 86 | self.rotateCount = 0 87 | self.vel = 1.4 88 | 89 | def draw(self, win): 90 | self.hitbox = (self.x + 10, self.y + 5, self.width - 20, self.height - 5) 91 | # pygame.draw.rect(win, (255,0,0), self.hitbox, 2) 92 | if self.rotateCount >= 8: 93 | self.rotateCount = 0 94 | win.blit(pygame.transform.scale(self.rotate[self.rotateCount//2], (64,64)), (self.x,self.y)) 95 | self.rotateCount += 1 96 | 97 | def collide(self, rect): 98 | if rect[0] + rect[2] > self.hitbox[0] and rect[0] < self.hitbox[0] + self.hitbox[2]: 99 | if rect[1] + rect[3] > self.hitbox[1]: 100 | return True 101 | return False 102 | 103 | 104 | class spike(saw): 105 | img = pygame.image.load(os.path.join('images', 'spike.png')) 106 | 107 | def draw(self, win): 108 | self.hitbox = (self.x + 10, self.y, 28,315) 109 | # pygame.draw.rect(win, (255,0,0), self.hitbox, 2) 110 | win.blit(self.img, (self.x, self.y)) 111 | 112 | def collide(self, rect): 113 | if rect[0] + rect[2] > self.hitbox[0] and rect[0] < self.hitbox[0] + self.hitbox[2]: 114 | if rect[1] < self.hitbox[3]: 115 | return True 116 | return False 117 | 118 | 119 | def updateFile(): 120 | f = open('scores.txt','r') 121 | file = f.readlines() 122 | last = int(file[0]) 123 | 124 | if last < int(score): 125 | f.close() 126 | file = open('scores.txt', 'w') 127 | file.write(str(score)) 128 | file.close() 129 | 130 | return score 131 | 132 | return last 133 | 134 | 135 | 136 | def endScreen(): 137 | global pause, score, speed, obstacles 138 | pause = 0 139 | speed = 30 140 | obstacles = [] 141 | 142 | run = True 143 | while run: 144 | pygame.time.delay(100) 145 | for event in pygame.event.get(): 146 | if event.type == pygame.QUIT: 147 | run = False 148 | pygame.quit() 149 | if event.type == pygame.MOUSEBUTTONDOWN: 150 | run = False 151 | runner.falling = False 152 | runner.sliding = False 153 | runner.jumpin = False 154 | 155 | win.blit(bg, (0,0)) 156 | largeFont = pygame.font.SysFont('comicsans', 80) 157 | lastScore = largeFont.render('Best Score: ' + str(updateFile()),1,(255,255,255)) 158 | currentScore = largeFont.render('Score: '+ str(score),1,(255,255,255)) 159 | win.blit(lastScore, (W/2 - lastScore.get_width()/2,150)) 160 | win.blit(currentScore, (W/2 - currentScore.get_width()/2, 240)) 161 | pygame.display.update() 162 | score = 0 163 | 164 | def redrawWindow(): 165 | largeFont = pygame.font.SysFont('comicsans', 30) 166 | win.blit(bg, (bgX, 0)) 167 | win.blit(bg, (bgX2,0)) 168 | text = largeFont.render('Score: ' + str(score), 1, (255,255,255)) 169 | runner.draw(win) 170 | for obstacle in obstacles: 171 | obstacle.draw(win) 172 | 173 | win.blit(text, (700, 10)) 174 | pygame.display.update() 175 | 176 | 177 | pygame.time.set_timer(USEREVENT+1, 500) 178 | pygame.time.set_timer(USEREVENT+2, 3000) 179 | speed = 30 180 | 181 | score = 0 182 | 183 | run = True 184 | runner = player(200, 313, 64, 64) 185 | 186 | obstacles = [] 187 | pause = 0 188 | fallSpeed = 0 189 | 190 | while run: 191 | if pause > 0: 192 | pause += 1 193 | if pause > fallSpeed * 2: 194 | endScreen() 195 | 196 | score = speed//10 - 3 197 | 198 | for obstacle in obstacles: 199 | if obstacle.collide(runner.hitbox): 200 | runner.falling = True 201 | 202 | if pause == 0: 203 | pause = 1 204 | fallSpeed = speed 205 | if obstacle.x < -64: 206 | obstacles.pop(obstacles.index(obstacle)) 207 | else: 208 | obstacle.x -= 1.4 209 | 210 | bgX -= 1.4 211 | bgX2 -= 1.4 212 | 213 | if bgX < bg.get_width() * -1: 214 | bgX = bg.get_width() 215 | if bgX2 < bg.get_width() * -1: 216 | bgX2 = bg.get_width() 217 | 218 | for event in pygame.event.get(): 219 | if event.type == pygame.QUIT: 220 | pygame.quit() 221 | run = False 222 | 223 | if event.type == USEREVENT+1: 224 | speed += 1 225 | 226 | if event.type == USEREVENT+2: 227 | r = random.randrange(0,2) 228 | if r == 0: 229 | obstacles.append(saw(810, 310, 64, 64)) 230 | elif r == 1: 231 | obstacles.append(spike(810, 0, 48, 310)) 232 | 233 | if runner.falling == False: 234 | keys = pygame.key.get_pressed() 235 | 236 | if keys[pygame.K_SPACE] or keys[pygame.K_UP]: 237 | if not(runner.jumping): 238 | runner.jumping = True 239 | 240 | if keys[pygame.K_DOWN]: 241 | if not(runner.sliding): 242 | runner.sliding = True 243 | 244 | clock.tick(speed) 245 | redrawWindow() 246 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pygame 2 | -------------------------------------------------------------------------------- /starterFile.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from pygame.locals import * 3 | import os 4 | import sys 5 | import math 6 | 7 | pygame.init() 8 | 9 | W, H = 800, 447 10 | win = pygame.display.set_mode((W,H)) 11 | pygame.display.set_caption('Side Scroller') 12 | 13 | bg = pygame.image.load(os.path.join('images','bg.png')).convert() 14 | bgX = 0 15 | bgX2 = bg.get_width() 16 | 17 | clock = pygame.time.Clock() 18 | 19 | class player(object): 20 | run = [pygame.image.load(os.path.join('images', str(x) + '.png')) for x in range(8,16)] 21 | jump = [pygame.image.load(os.path.join('images', str(x) + '.png')) for x in range(1,8)] 22 | slide = [pygame.image.load(os.path.join('images', 'S1.png')),pygame.image.load(os.path.join('images', 'S2.png')),pygame.image.load(os.path.join('images', 'S2.png')),pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')),pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S2.png')), pygame.image.load(os.path.join('images', 'S3.png')), pygame.image.load(os.path.join('images', 'S4.png')), pygame.image.load(os.path.join('images', 'S5.png'))] 23 | jumpList = [1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4] 24 | def __init__(self, x, y, width, height): 25 | self.x = x 26 | self.y = y 27 | self.width = width 28 | self.height = height 29 | self.jumping = False 30 | self.sliding = False 31 | self.slideCount = 0 32 | self.jumpCount = 0 33 | self.runCount = 0 34 | self.slideUp = False 35 | 36 | def draw(self, win): 37 | if self.jumping: 38 | self.y -= self.jumpList[self.jumpCount] * 1.2 39 | win.blit(self.jump[self.jumpCount//18], (self.x,self.y)) 40 | self.jumpCount += 1 41 | if self.jumpCount > 108: 42 | self.jumpCount = 0 43 | self.jumping = False 44 | self.runCount = 0 45 | elif self.sliding or self.slideUp: 46 | if self.slideCount < 20: 47 | self.y += 1 48 | elif self.slideCount == 80: 49 | self.y -= 19 50 | self.sliding = False 51 | self.slideUp = True 52 | if self.slideCount >= 110: 53 | self.slideCount = 0 54 | self.slideUp = False 55 | self.runCount = 0 56 | win.blit(self.slide[self.slideCount//10], (self.x,self.y)) 57 | self.slideCount += 1 58 | 59 | else: 60 | if self.runCount > 42: 61 | self.runCount = 0 62 | win.blit(self.run[self.runCount//6], (self.x,self.y)) 63 | self.runCount += 1 64 | --------------------------------------------------------------------------------