def check_collision(): p = char['pos'] f = char['forw'] char['block_f'] = False char['block_b'] = False for i in range(char['hei'] - char['slopelim']): qf = v3.add(v3.Vec(p.x, p.y + i, p.z), v3.normalize(v3.Vec(f.x, 0, f.z))) qb = v3.add(v3.Vec(p.x, p.y + i, p.z), v3.normalize(v3.Vec(-f.x, 0, -f.z))) qf = v3.Vec(int(round(qf.x)), int(round(qf.y)), int(round(qf.z))) qb = v3.Vec(int(round(qb.x)), int(round(qb.y)), int(round(qb.z))) if vf.check(L, qf) != 0: char['block_f'] = True break if vf.check(L, qb) != 0: char['block_b'] = True break if char['block_f'] == False: for i in range(char['hei'] - char['slopelim'], char['hei']): q = v3.add(v3.Vec(p.x, p.y + i, p.z), v3.normalize(v3.Vec(f.x, 0, f.z))) q = v3.Vec(int(round(q.x)), int(round(q.y)), int(round(q.z))) if vf.check(L, q) != 0: addto(char, 'pos', v3.Vec(0, -1, 0))
def check_gravity(): p = char['pos'] p = v3.Vec(round(p.x), round(p.y) + char['hei'], round(p.z)) if vf.check(L, p) == 0 and p.y < L['size'].y: char['grounded'] = False addto(char, 'v', v3.Vec(0, 0.01, 0)) else: char['v'] = v3.Vec(0, 0, 0) char['grounded'] = True
def newchar(): return { 'rot': v3.Vec(0, math.pi / 4, 0), 'pos': v3.Vec(0, 0, 0), 'forw': v3.forward, 'hei': 5, 'slopelim': 1, 'block_f': False, 'block_b': False, 'grounded': False, 'v': v3.Vec(0, 0, 0) }
def main(stdscr, game): global size, t, canvas assert issubclass(game, GameTemplate) height, width = stdscr.getmaxyx() size = v3.Vec(min(100, width), min(30, height), 0) canvas = curses.newpad(size.y + 1, size.x + 1) # initialize colors for k in colors.pairs.keys(): v = colors.pairs[k] curses.init_pair(k, v[0], v[1]) G = game() G.start() # main loop while True: t += 1 stdscr.nodelay(1) c = stdscr.getch() G.update() G.draw() G.keypressed(c) try: canvas.refresh(0, 0, 0, 0, size.y - 1, size.x - 1) except: pass
def move_back(char, m=1, fly=False): if not char['block_b']: f = char['forw'] f = v3.normalize(v3.Vec(f.x, f.y * fly, f.z)) addto(char, 'pos', v3.scale(f, -0.5 * m)) return True return False
def tostr2d(L): s = "" for zi in range(L['size'].z): for yi in range(L['size'].y): for xi in range(L['size'].x): s += ["#", "."][check(L, v3.Vec(xi, yi, zi)) == 0] s += " " s += "\n" return s
def raycast(L, pos, rot, maxdist=128, cam=v3.Vec(0.3, 0.2, 0.3), win=v3.Vec(10, 10, 0)): field = {} step = 1 forw = v3.roteuler(v3.Vec(0, 0, 1), rot) def ray(v, forwstep): backstep = v3.scale(forwstep, -0.1) for k in range(0, int(maxdist / step)): n = k * step v = v3.add(v, forwstep) b = check(L, v) if b != 0: for m in range(10): v = v3.add(v, backstep) if check(L, v) == 0: return n - m * 0.1, v, b b = check(L, v) return n, v, b return -1, v, 1 for i in range(-win.x / 2, win.x / 2): for j in range(-win.y / 2, win.y / 2): xi = i / (win.x / 2.0) * (cam.x / 2.0) yi = j / (win.y / 2.0) * (cam.y / 2.0) v = v3.Vec(xi, yi, cam.z) v = v3.roteuler(v, rot) fs = v3.scale(v3.normalize(v), step) v = v3.add(pos, v) n, p, b = ray(v, fs) field[i + win.x / 2, j + win.y / 2] = (n, b) field['size'] = win return field
def loadGox(file): L = {} l = [] lvls = open(file, 'r').read().replace("\r", "\n").replace("\n\n", "\n").split("\n") for i in range(len(lvls)): if lvls[i].startswith('#') or lvls[i].strip() == '': continue pos = lvls[i][:-7].split(' ') pos = (int(pos[0]), int(pos[2]), int(pos[1])) col = lvls[i][-6:] r, g, b = int(col[:2], 16), int(col[2:4], 16), int(col[4:], 16) ansi = [ None, (0, 0, 0), (255, 0, 0), (0, 255, 0), (255, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255), (255, 255, 255) ] mindist = 500 minind = 0 for j in range(1, len(ansi)): d = math.sqrt((r - ansi[j][0])**2 + (g - ansi[j][1])**2 + (b - ansi[j][2])**2) if d <= mindist: minind = j mindist = d col = minind l.append((pos, col)) xmin, xmax, ymin, ymax, zmin, zmax = None, None, None, None, None, None for i in range(len(l)): if xmin == None or l[i][0][0] < xmin: xmin = l[i][0][0] if xmax == None or l[i][0][0] > xmax: xmax = l[i][0][0] if ymin == None or l[i][0][1] < ymin: ymin = l[i][0][1] if ymax == None or l[i][0][1] > ymax: ymax = l[i][0][1] if zmin == None or l[i][0][2] < zmin: zmin = l[i][0][2] if zmax == None or l[i][0][2] > zmax: zmax = l[i][0][2] print xmin, xmax, ymin, ymax, zmin, zmax size = v3.Vec(xmax - xmin + 1, ymax - ymin + 1, zmax - zmin + 1) for i in range(len(l)): p = l[i][0] L[p[0] - xmin, size.y - (p[1] - ymin) - 1, p[2] - zmin] = l[i][1] L['size'] = size return L
# asciimare main engine import time import curses import v3, colors, grays, noise, voxfield, charctrl from abc import ABCMeta, abstractmethod size = v3.Vec(0, 0, 0) canvas = None t = 0 # abstract class for a game class GameTemplate(object): __metaclass__ = ABCMeta @abstractmethod def start(self): pass @abstractmethod def update(self): pass @abstractmethod def draw(self): pass @abstractmethod def keypressed(self, c): pass
def jump(char, m=1): if char['grounded']: addto(char, 'v', v3.Vec(0, -0.3, 0)) return True return False
def look_down(char, m=1): addto(char, 'rot', v3.Vec(-0.1 * m, 0, 0))
def look_up(char, m=1): addto(char, 'rot', v3.Vec(0.1 * m, 0, 0))
def turn_right(char, m=1): addto(char, 'rot', v3.Vec(0, 0.1, 0))
def turn_left(char, m=1): addto(char, 'rot', v3.Vec(0, -0.1 * m, 0))
def addto(char, nm, inc): char[nm] = v3.Vec(char[nm].x + inc.x, char[nm].y + inc.y, char[nm].z + inc.z)