So, I've been coding in Python for a few weeks and I felt like trying to make a game. I've gotten to a point where I have no clue what is wrong with my code except for the fact that when I try to draw a textured polygon the texture stretches across the display and only reveals on the cubes. It creates a really cool effect but it isn't what I'm looking for. The goal is to render the texture onto the face of the cube like in Minecraft. import pygame, sys, os, math from pygame import gfxdraw def rotate2d(pos,rad) : x,y=pos; s,c = math.sin(rad), math.cos(rad); return x*c-y*s, y*c+x*s class Cam: def __init__(self,pos=(0,0,0), rot=(0,0)): self.pos = list(pos) self.rot = list(rot) def events (self, event): if event.type == pygame.MOUSEMOTION: x,y = event.rel; x/=200; y/=200 self.rot[0]+=y; self.rot[1]+=x def update(self,dt,key): s = dt*10 if key[pygame.K_c]: self.pos[1]+=s if key[pygame.K_SPACE]: self.pos[1]-=s x,y = s*math.sin(self.rot[1]),s*math.cos(self.rot[1]) if self.rot[0] <= -1.58: self.rot[0] = -1.58 if self.rot[0] >= 1.58: self.rot[0] = 1.58 if key[pygame.K_w]: self.pos[0]+=x; self.pos[2]+=y if key[pygame.K_s]: self.pos[0]-=x; self.pos[2]-=y if key[pygame.K_a]: self.pos[0]-=y; self.pos[2]+=x if key[pygame.K_d]: self.pos[0]+=y; self.pos[2]-=x if key[pygame.K_ESCAPE]: pygame.quit(); sys.exit() #Quits Game# pygame.init() w,h = 800,600; cx,cy = w//2, h//2; fov = min(w,h) os.environ['SDL_VIDEO_CENTERED'] = '1' pygame.display.set_caption('PyCraft') screen = pygame.display.set_mode((w,h)) clock = pygame.time.Clock() ## Textures ## dirt_texture = pygame.image.load("textures/dirt.png").convert() stone_texture = pygame.image.load("textures/stone.png").convert() bedrock_texture = pygame.image.load("textures/bedrock.png").convert() class Dirt: vertices = (-1,-1,-1),(1,-1,-1),(1,1,-1),(-1,1,-1),(-1,-1,1),(1,-1,1),(1,1,1),(-1,1,1) edges = (0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),(0,4),(1,5),(2,6),(3,7) faces = (0,1,2,3),(4,5,6,7),(0,1,5,4),(2,3,7,6),(0,3,7,4),(1,2,6,5) colours = (225,10,0),(255,128,0),(10,250,250),(128,128,128),(0,0,255),(0,255,0) texture = dirt_texture def __init__(self,pos=(0,0,0)): x,y,z = pos self.verts = [(x+X/2,y+Y/2,z+Z/2) for X,Y,Z in self.vertices] class Stone: vertices = (-1,-1,-1),(1,-1,-1),(1,1,-1),(-1,1,-1),(-1,-1,1),(1,-1,1),(1,1,1),(-1,1,1) edges = (0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),(0,4),(1,5),(2,6),(3,7) faces = (0,1,2,3),(4,5,6,7),(0,1,5,4),(2,3,7,6),(0,3,7,4),(1,2,6,5) colours = (0,255,0),(255,128,0),(0,0,250),(128,133,128),(0,0,200),(200,0,255) texture = stone_texture def __init__(self,pos=(0,0,0)): x,y,z = pos self.verts = [(x+X/2,y+Y/2,z+Z/2) for X,Y,Z in self.vertices] def TextUI(msg,colour,pos): screen_text = font.render(msg, True, colour) screen.blit(screen_text, (pos)) def Draw_Crosshair(colour, width): pygame.draw.line(screen, colour, (cursorpos1, cursorpos2), (cursorpos3,cursorpos4), width) pygame.draw.line(screen, colour, (cursorpos5, cursorpos6), (cursorpos7,cursorpos8), width) cam = Cam((0,0,-5)) pygame.event.get(); pygame.mouse.get_rel() pygame.mouse.set_visible(0); pygame.event.set_grab(1) font = pygame.font.SysFont("calibri", 25) cursorpos1, cursorpos2, cursorpos3, cursorpos4 = w/2, h/2+10, w/2, h/2-10 cursorpos5, cursorpos6, cursorpos7, cursorpos8 = w/2+10, h/2, w/2-10, h/2 cubes = [Dirt((0,0,0)),Stone((2,0,0)),Stone((-2,0,0)),Dirt((0,2,0)),Stone((2,2,0)),Dirt((-2,2,0))] ##cubes = [Dirt((1,0,0)), Dirt((2,0,0)),Dirt((3,0,0)),Dirt((4,0,0)),Dirt((5,0,0)),Dirt((5,1,0)),Dirt((6,1,0)),] while True: dt = clock.tick()/1000 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit(); sys.exit() cam.events(event) screen.fill((100,100,100)) face_list = []; face_colour = []; depth = []; for obj in cubes: vert_list = []; screen_coords = [] for x,y,z in obj.verts: x-=cam.pos[0]; y-=cam.pos[1]; z-=cam.pos[2] x,z = rotate2d((x,z), cam.rot[1]) y,z = rotate2d((y,z), cam.rot[0]) vert_list += [(x,y,z)] f = fov/z x,y = x*f,y*f screen_coords+=[(cx+int(x),cy+int(y))] for f in range (len(obj.faces)): face = obj.faces[f] on_screen = False for i in face: x,y = screen_coords if vert_list[2]>0 and x>0 and x<w and y>0 and y<h: on_screen = True ; break if on_screen: coords = [screen_coords for i in face] face_list += [coords] face_colour += [obj.colours[f]] depth += [sum(sum(vert_list[j] for j in face) **2 for i in range (3))] order = sorted(range(len(face_list)), key=lambda i:depth, reverse=1) for i in order: try: pygame.gfxdraw.textured_polygon(screen, face_list, obj.texture, 0, 0); pygame.gfxdraw.aapolygon(screen, face_list, (0,0,0)) except: pass ## OLD CODE - pygame.draw.polygon(screen, face_colour, face_list) ## ## NEW CODE - pygame.gfxdraw.textured_polygon(screen, face_list, obj.texture, 0, 0) ## ## TEST CODE - pygame.gfxdraw.filled_polygon(screen, face_list, face_colour) ## Draw_Crosshair((255,255,255),2) TextUI("Press ESCAPE to exit", (255,255,255), (20,20)) TextUI("Movement Controls: W, A, S, D, SPACE and C", (255,255,255), (20,60)) pygame.display.update() key = pygame.key.get_pressed() cam.update(dt, key) Continue reading...