Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys, pygame, math, random
- from pygame.locals import *
- pygame.init()
- width, height = 1080, 680
- screen = pygame.display.set_mode((width, height))
- pygame.display.toggle_fullscreen()
- #screen.toggle_fullscreen()
- teles = []
- hitMap = []
- for x in range(width):
- hitTab = []
- for y in range(height):
- hitTab.append([1, [255, 255, 255]])
- hitMap.append(hitTab)
- def drawLine(x1, y1, x2, y2):
- points = []
- if (x2-x1) > 0:
- grad = (y2-y1)/(x2-x1)
- c = y1 - (x1*grad)
- for x in range(min(x1, x2), max(x1, x2)):
- y = math.floor((x*grad) + c)
- points.append([x, y])
- for y in range(min(y1, y2), max(y1, y2)):
- x = math.floor((y/grad) - (c/grad))
- points.append([x, y])
- else:
- for y in range(min(y1, y2), max(y1, y2)):
- points.append([x1, y])
- return points
- pi = math.pi
- def getXY(x, y, a, h):
- ra = a
- if a < pi/2:
- ra = a
- elif a < pi:
- ra = pi-a
- elif a < pi + (pi/2):
- ra = a-pi
- elif a < 2*pi:
- ra = (2*pi)-a
- nx = (math.sin(ra)*h)
- ny = (math.sqrt( (h*h) - (nx*nx) ) )
- if a < pi/2:
- #print("GOT < 90 (pi/2)")
- return [math.floor(x + nx), math.floor(y + ny)]
- elif a < pi:
- #print("GOT < 180 (pi)")
- return [math.floor(x + nx), math.floor(y - ny)]
- elif a < pi + (pi/2):
- #print("GOT < 270 (pi + pi/2)")
- return [math.floor(x - nx), math.floor(y - ny)]
- elif a < 2*pi:
- #print("GOT < 360 (2pi)")
- return [math.floor(x - nx), math.floor(y + ny)]
- elif a == 0 or 2*pi:
- return [math.floor(x), math.floor(y + ny)]
- elif a == pi/2:
- return [math.floor(x + nx), math.floor(y)]
- elif a == pi:
- return [math.floor(x), math.floor(y - ny)]
- elif a == pi + (pi/2):
- return [math.floor(x - nx), math.floor(y)]
- else:
- return [x, y]
- def castRay2(x, y, a, fov):
- ray = []
- if a == math.radians(0) or a == math.radians(180) or a == math.radians(360):
- step = 1
- if a == math.radians(180):
- step = -1
- typ = 0
- for ye in range(fov):
- cy = y + (ye*step)
- if cy >= 0 and cy < height:
- if hitMap[x][cy][0] != 1:
- if hitMap[x][cy][0] == 2:
- typ = 2
- ray.append([x, cy, typ, hitMap[x][cy][1]])
- if hitMap[x][cy][0] == 2:
- typ = 3
- else:
- ray.append([x, cy, 1, hitMap[x][cy][1]])
- break
- else:
- break
- elif a == math.radians(90) or a == math.radians(270):
- step = 1
- if a == math.radians(270):
- step = -1
- typ = 0
- for xe in range(fov):
- cx = x + (xe*step)
- if cx >= 0 and cx < width:
- if hitMap[cx][y][0] != 1:
- if hitMap[cx][y][0] == 2:
- typ = 2
- ray.append([cx, y, typ, hitMap[cx][y][1]])
- if hitMap[cx][y][0] == 2:
- typ = 3
- else:
- ray.append([cx, y, typ, hitMap[cx][y][1]])
- break
- else:
- break
- else:
- typ = 0
- for i in range(fov):
- pos = getXY(x, y, a, i)
- if pos[0] >= 0 and pos[0] < width and pos[1] >= 0 and pos[1] < height:
- if hitMap[pos[0]][pos[1]][0] != 1:
- if hitMap[pos[0]][pos[1]][0] == 2:
- typ = 2
- ray.append([pos[0], pos[1], typ, hitMap[pos[0]][pos[1]][1]])
- if hitMap[pos[0]][pos[1]][0] == 2:
- typ = 3
- else:
- ray.append([pos[0], pos[1], typ, hitMap[pos[0]][pos[1]][1]])
- break
- return ray
- def getAngle(x1, y1, x2, y2):
- distx = max(x1, x2) - min(x1, x2)
- disty = max(y1, y2) - min(y1, y2)
- dist = math.sqrt( (distx*distx) + (disty*disty) )
- a = math.degrees(math.asin( distx/dist ))
- if x2 > x1 and y2 > y1:
- return a+1
- elif x2 > x1 and y2 < y1:
- return 180 - a
- elif x2 < x1 and y2 < y1:
- return 180 + a
- elif x2 < x1 and y2 > y1:
- return 360 - a
- return a
- def setCluster(x, y, t):
- for xa in range(-1, 1):
- for ya in range(-1, 1):
- if (x+xa) >= 0 and (x+xa) < width and (y+ya) >= 0 and (y+ya) < height:
- hitMap[x+xa][y+ya][0] = t
- def addLine(x1, y1, x2, y2):
- points = drawLine(x1, y1, x2, y2)
- for i in range(len(points)):
- x, y = points[i][0], points[i][1]
- setCluster(x, y, 1)
- def clearLine(x1, y1, x2, y2):
- points = drawLine(x1, y1, x2, y2)
- for i in range(len(points)):
- x, y = points[i][0], points[i][1]
- setCluster(x, y, 0)
- def drawHitMap(hmap):
- for x in range(len(hmap)):
- htab = hmap[x]
- for y in range(len(htab)):
- typ = htab[y][0]
- if typ == 1:
- screen.set_at((x, y), htab[y][1])
- elif typ == 2:
- screen.set_at((x, y), [255, 0, 0])
- def drawRay(ray, fov):
- for i in range(len(ray)):
- p = ray[i]
- if p[2] != 1:
- per = (i/fov)*100
- red = math.floor((255/100)*(100-per))
- if p[2] == 2:
- screen.set_at((p[0], p[1]), [int(red/3), 0, 0])
- elif p[2] == 0:
- screen.set_at((p[0], p[1]), [red, red, red])
- elif p[2] == 3:
- screen.set_at((p[0], p[1]), [int(red), 0, 0])
- def drawWolf(x, y, angle, fov, sight):
- app = (fov/width)
- for cx in range(0, width+1):
- curx = (x*math.cos(x-(width/2)))
- a = ((cx*app) + angle)
- if a > 360:
- a = a - 360
- ray = castRay2(x, y, math.radians(a), sight)
- lowerY = 0
- upperY = 0
- if len(ray) > 0:
- pos = ray[len(ray)-1]
- pos[0] = pos[0]
- dist = math.sqrt( ((pos[0]-x)**2) + ((pos[1]-y)**2) )
- per = 101-((dist/sight)*100)
- h = (height/100)*per
- rh = int(h/2)
- midy = math.floor(height/2)
- lowerY = midy-rh
- upperY = midy+rh
- #print(height, " = height; ", midy, " = midY; ", rh, " = diff H; ", lowerY, " = lowerY; ", upperY, " = upperY")
- #print(pos[3])
- for cy in range(0, height+1):
- if cy < lowerY or (pos[2] == 1 and cy <= midy):
- screen.set_at((cx, cy), [100, 100, 100])
- elif cy >= lowerY and cy <= upperY and pos[2] != 1:
- screen.set_at((cx, cy), pos[3])
- elif cy > upperY or pos[2] == 1:
- screen.set_at((cx, cy), [200, 200, 200])
- def addRandLine():
- addLine(random.randint(1, width), random.randint(1, height), random.randint(1, width), random.randint(1, height))
- def addRandSquare():
- pos = [random.randint(1, width), random.randint(1, height)]
- w = random.randint(40, 100)
- h = random.randint(40, 100)
- addLine(pos[0], pos[1], pos[0]+w, pos[1])
- addLine(pos[0]+w, pos[1], pos[0]+w, pos[1]+h)
- addLine(pos[0], pos[1]+h, pos[0]+w, pos[1]+h)
- addLine(pos[0], pos[1]+h, pos[0], pos[1])
- dW = 5
- possible = [
- [pos[0] + int(w/2) - dW, pos[1], pos[0] + int(w/2) + dW, pos[1]],
- [pos[0] + int(w/2) - dW, pos[1] + int(h), pos[0] + int(w/2) + dW, pos[1] + int(h)],
- [pos[0] + int(w), pos[1] + int(h/2) - dW, pos[0] + int(w), pos[1] + int(h/2) + dW],
- [pos[0], pos[1] + int(h/2) - dW, pos[0], pos[1] + int(h/2) + dW]
- ]
- if random.randint(1, 100) <= 60:
- dpos = possible[random.randint(0, len(possible)-1)]
- clearLine(dpos[0], dpos[1], dpos[2], dpos[3])
- def genDungeon(cell, length):
- gw = math.floor(width/cell) - 2
- gh = math.floor(height/cell) - 2
- grid = []
- for x in range(gw):
- gridTab = []
- for y in range(gh):
- gridTab.append([1, [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]])
- grid.append(gridTab)
- cur = [random.randint(0, len(grid)-1), random.randint(0, len(grid[0])-1)]
- startPos = [(cur[0]*cell) + cell + int(cell/2), (cur[1]*cell) + cell + int(cell/2), 45]
- tele = False
- for i in range(length):
- if tele == False:
- grid[cur[0]][cur[1]][0] = 0
- else:
- grid[cur[0]][cur[1]][0] = 2
- teles.append([(cur[0]*cell) + cell + int(cell/2), (cur[1]*cell) + cell + int(cell/2)])
- tele = False
- ncur = [cur[0], cur[1]]
- nStop = 0
- while (ncur[0] == cur[0] and ncur[1] == cur[1]) or (ncur[0] < 0 or ncur[0] >= gw or ncur[1] < 0 or ncur[1] >= gh) or (grid[ncur[0]][ncur[1]][0]) == 0 or (grid[ncur[0]][ncur[1]][0]) == 2:
- tpos = random.randint(0, 1)
- dirTy = [-1, 1]
- ncur[tpos] = cur[tpos] + dirTy[random.randint(0, 1)]
- nStop = nStop + 1
- if nStop > 25:
- break
- if nStop > 25:
- ncur = [cur[0], cur[1]]
- grid[cur[0]][cur[1]][0] = 2
- teles.append([(cur[0]*cell) + cell + int(cell/2), (cur[1]*cell) + cell + int(cell/2)])
- tele = True
- while grid[ncur[0]][ncur[1]][0] == 0 or grid[ncur[0]][ncur[1]][0] == 2:
- ncur = [random.randint(0, len(grid)-1), random.randint(0, len(grid[0])-1)]
- cur = ncur
- for gx in range(len(grid)):
- tab = grid[gx]
- for gy in range(len(tab)):
- typ = tab[gy][0]
- #print(typ)
- #if typ == 0:
- startX = gx*cell + cell
- startY = gy*cell + cell
- endX = startX + cell
- endY = startY + cell
- midX = int((startX+endX)/2)
- midY = int((startY+endY)/2)
- gapSize = cell/6
- for x in range(startX, endX):
- for y in range(startY, endY):
- if typ == 2:
- if x < (midX-gapSize) or y < midY - gapSize or x > midX + gapSize or y > midY + gapSize:
- hitMap[x][y][0] = 0
- else:
- hitMap[x][y][0] = 2
- else:
- hitMap[x][y][0] = typ
- if typ == 1:
- hitMap[x][y][1] = tab[gy][1]
- return startPos
- stepper = 1
- sight = 90
- fov = 70
- def drawGame(pos, af, wolf):
- screen.fill([0, 0, 0])
- #drawHitMap(hitMap)
- #print(af)
- change = (fov*stepper)
- #if fov + af > 360:
- # for a in range(int(360-af), int(360-af+fov)):
- # ra = a
- # if ra < 0:
- # ra =
- # drawRay(castRay2(pos[0], pos[1], math.radians(a), sight), sight)
- #else:
- if wolf:
- drawWolf(player[0], player[1], player[2], fov, sight)
- else:
- #drawHitMap(hitMap)
- for a in range(0, int(fov*stepper), 1):
- ra = int( (a/stepper) + af )
- if ra < 0:
- ra = 360 + ra
- if ra >= 360:
- ra = (ra - 360)
- drawRay(castRay2(pos[0], pos[1], math.radians(ra), sight), sight)
- screen.set_at((player[0], player[1]), [0, 0, 255])
- pygame.display.flip()
- isWolf = False
- player = genDungeon(15, 500)
- drawGame(player, player[2], isWolf)
- speed = 2
- slow = 25
- turnSpeed = 5
- ltick = pygame.time.get_ticks()
- teled = False
- while 1:
- for event in pygame.event.get():
- if event.type == QUIT:
- sys.exit()
- if pygame.time.get_ticks() - ltick > slow:
- ltick = pygame.time.get_ticks()
- prsd = pygame.key.get_pressed()
- mpr = pygame.mouse.get_pressed()
- mx, my = pygame.mouse.get_pos()
- lpos = [player[0], player[1], player[2]]
- if prsd[pygame.K_UP] or prsd[pygame.K_w]:
- if isWolf == False:
- player[1] = player[1] - speed
- else:
- npos = getXY(player[0], player[1], math.radians(player[2] + (fov/2)), speed)
- player = [npos[0], npos[1], player[2]]
- if prsd[pygame.K_LEFT] or prsd[pygame.K_a]:
- if isWolf == False:
- player[0] = player[0] - speed
- else:
- npos = getXY(player[0], player[1], math.radians(player[2] + (fov/2) + 270), speed)
- player = [npos[0], npos[1], player[2]]
- if prsd[pygame.K_DOWN] or prsd[pygame.K_s]:
- if isWolf == False:
- player[1] = player[1] + speed
- else:
- npos = getXY(player[0], player[1], math.radians(player[2] + (fov/2) + 180), speed)
- player = [npos[0], npos[1], player[2]]
- if prsd[pygame.K_RIGHT] or prsd[pygame.K_d]:
- if isWolf == False:
- player[0] = player[0] + speed
- else:
- npos = getXY(player[0], player[1], math.radians(player[2] + (fov/2) + 90), speed)
- player = [npos[0], npos[1], player[2]]
- if mpr[0] or mpr[1]:
- npos = getXY(player[0], player[1], math.radians(player[2] + (fov/2)), speed)
- player = [npos[0], npos[1], player[2]]
- if prsd[pygame.K_q]:
- player[2] = player[2] - turnSpeed
- if player[2] < 0:
- player[2] = 360 + player[2]
- if prsd[pygame.K_e]:
- player[2] = player[2] + turnSpeed
- if player[2] > 360:
- player[2] = 360 - player[2]
- if prsd[pygame.K_r]:
- isWolf = (isWolf == False)
- drawGame(player, player[2], isWolf)
- if isWolf == False:
- player[2] = int(getAngle(player[0], player[1], mx, my)) - (fov/2)
- if player[2] < 0:
- player[2] = 360 + player[2]
- if player[2] > 360:
- player[2] = player[2] - 360
- if lpos[0] != player[0] or lpos[1] != player[1] or lpos[2] != player[2]:
- if player[0] < 0 or player[0] >= width or player[1] < 0 or player[1] >= height or hitMap[player[0]][player[1]][0] == 1:
- player = lpos
- if hitMap[player[0]][player[1]][0] == 2 and teled == False:
- telepos = teles[random.randint(0, len(teles)-1)]
- player = [telepos[0], telepos[1], player[2]]
- teled = True
- elif hitMap[player[0]][player[1]][0] != 2 and teled == True:
- teled = False
- drawGame(player, player[2], isWolf)
- #print(player[2], "degrees, (", mx, ",", my, "), (", player[0], ",", player[1], ")")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement