Difference between revisions of "Roguelike Tutorial, using python3+tdl, part 2 code"

From RogueBasin
Jump to navigation Jump to search
m (Screen height)
m (Updated version to 3.1.0. No changes in code.)
 
(3 intermediate revisions by the same user not shown)
Line 2: Line 2:
This is part of a series of tutorials; the main page can be found [[Roguelike Tutorial, using python3+tdl|here]].
This is part of a series of tutorials; the main page can be found [[Roguelike Tutorial, using python3+tdl|here]].


The tutorial uses tdl version 1.5.3 and Python 3.5
The tutorial uses tdl version 3.1.0 and Python 3.5


</center></td></tr></table></center>
</center></td></tr></table></center>
Line 60: Line 60:
     if user_input.key == 'ENTER' and user_input.alt:
     if user_input.key == 'ENTER' and user_input.alt:
         #Alt+Enter: toggle fullscreen
         #Alt+Enter: toggle fullscreen
         tdl.set_fullscreen(True)
         tdl.set_fullscreen(not tdl.get_fullscreen())
   
   
     elif user_input.key == 'ESCAPE':
     elif user_input.key == 'ESCAPE':
Line 95: Line 95:
     print('go')
     print('go')
     #draw all objects in the list
     #draw all objects in the list
     for object in objects:
     for obj in objects:
         object.draw()
         obj.draw()


     #blit the contents of "con" to the root console and present it
     #blit the contents of "con" to the root console and present it
Line 103: Line 103:


     #erase all objects at their old locations, before they move
     #erase all objects at their old locations, before they move
     for object in objects:
     for obj in objects:
         object.clear()
         obj.clear()


     #handle keys and exit game if needed
     #handle keys and exit game if needed
Line 266: Line 266:


     #erase all objects at their old locations, before they move
     #erase all objects at their old locations, before they move
     for object in objects:
     for obj in objects:
         object.clear()
         obj.clear()


     #handle keys and exit game if needed
     #handle keys and exit game if needed

Latest revision as of 08:14, 30 May 2017

This is part of a series of tutorials; the main page can be found here.

The tutorial uses tdl version 3.1.0 and Python 3.5


Generalizing

#!/usr/bin/env python3

import tdl

#actual size of the window
SCREEN_WIDTH = 80
SCREEN_HEIGHT = 50

REALTIME = False
LIMIT_FPS = 20  #20 frames-per-second maximum

class GameObject:
    #this is a generic object: the player, a monster, an item, the stairs...
    #it's always represented by a character on screen.
    def __init__(self, x, y, char, color):
        self.x = x
        self.y = y
        self.char = char
        self.color = color
 
    def move(self, dx, dy):
        #move by the given amount
        self.x += dx
        self.y += dy
 
    def draw(self):
        #draw the character that represents this object at its position
        con.draw_char(self.x, self.y, self.char, self.color, bg=None)

    def clear(self):
        #erase the character that represents this object
        con.draw_char(self.x, self.y, ' ', self.color, bg=None)

def handle_keys(realtime):
    global playerx, playery
    
    if realtime:
        keypress = False
        for event in tdl.event.get():
            if event.type == 'KEYDOWN':
               user_input = event
               keypress = True
        if not keypress:
            return

    else: #turn-based
        user_input = tdl.event.key_wait()

    if user_input.key == 'ENTER' and user_input.alt:
        #Alt+Enter: toggle fullscreen
        tdl.set_fullscreen(not tdl.get_fullscreen())
 
    elif user_input.key == 'ESCAPE':
        return True  #exit game

    #movement keys
    if user_input.key == 'UP':
        player.move(0, -1)

    elif user_input.key == 'DOWN':
        player.move(0, 1)

    elif user_input.key == 'LEFT':
        player.move(-1, 0)

    elif user_input.key == 'RIGHT':
        player.move(1, 0)
 

#############################################
# Initialization & Main Loop                #
#############################################

tdl.set_font('arial10x10.png', greyscale=True, altLayout=True)
root = tdl.init(SCREEN_WIDTH, SCREEN_HEIGHT, title="Roguelike", fullscreen=False)
con = tdl.Console(SCREEN_WIDTH, SCREEN_HEIGHT)
tdl.setFPS(LIMIT_FPS)

player = GameObject(SCREEN_WIDTH//2, SCREEN_HEIGHT//2, '@', (255,255,255))
npc = GameObject(SCREEN_WIDTH//2 - 5, SCREEN_HEIGHT//2, '@', (255,255,0))
objects = [npc, player]

while not tdl.event.is_window_closed():
    print('go')
    #draw all objects in the list
    for obj in objects:
        obj.draw()

    #blit the contents of "con" to the root console and present it
    root.blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0)
    tdl.flush()

    #erase all objects at their old locations, before they move
    for obj in objects:
        obj.clear()

    #handle keys and exit game if needed
    exit_game = handle_keys(REALTIME)
    if exit_game:
        break


The Map

#!/usr/bin/env python3

import tdl

#actual size of the window
SCREEN_WIDTH = 80
SCREEN_HEIGHT = 50

#size of the map
MAP_WIDTH = 80
MAP_HEIGHT = 45

REALTIME = False
LIMIT_FPS = 20  #20 frames-per-second maximum

color_dark_wall = (0, 0, 100)
color_dark_ground = (50, 50, 150)


class Tile:
    #a tile of the map and its properties
    def __init__(self, blocked, block_sight=None):
        self.blocked = blocked
 
        #by default, if a tile is blocked, it also blocks sight
        if block_sight is None: 
            block_sight = blocked
        self.block_sight = block_sight

class GameObject:
    #this is a generic object: the player, a monster, an item, the stairs...
    #it's always represented by a character on screen.
    def __init__(self, x, y, char, color):
        self.x = x
        self.y = y
        self.char = char
        self.color = color
 
    def move(self, dx, dy):
        #move by the given amount, if the destination is not blocked
        if not my_map[self.x + dx][self.y + dy].blocked:
            self.x += dx
            self.y += dy
 
    def draw(self):
        #draw the character that represents this object at its position
        con.draw_char(self.x, self.y, self.char, self.color, bg=None)

    def clear(self):
        #erase the character that represents this object
        con.draw_char(self.x, self.y, ' ', self.color, bg=None)


def make_map():
    global my_map
 
    #fill map with "unblocked" tiles
    my_map = [[Tile(False) for y in range(MAP_HEIGHT)] for x in range(MAP_WIDTH)]

    #place two pillars to test the map
    my_map[30][22].blocked = True
    my_map[30][22].block_sight = True
    my_map[50][22].blocked = True
    my_map[50][22].block_sight = True


def render_all():

    #go through all tiles, and set their background color
    for y in range(MAP_HEIGHT):
        for x in range(MAP_WIDTH):
            wall = my_map[x][y].block_sight
            if wall:
                con.draw_char(x, y, None, fg=None, bg=color_dark_wall)
            else:
                con.draw_char(x, y, None, fg=None, bg=color_dark_ground)

    #draw all objects in the list
    for obj in objects:
        obj.draw()

    #blit the contents of "con" to the root console and present it
    root.blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0)

def handle_keys(realtime):
    global playerx, playery
    
    if realtime:
        keypress = False
        for event in tdl.event.get():
            if event.type == 'KEYDOWN':
               user_input = event
               keypress = True
        if not keypress:
            return

    else: #turn-based
        user_input = tdl.event.key_wait()

    if user_input.key == 'ENTER' and user_input.alt:
        #Alt+Enter: toggle fullscreen
        tdl.set_fullscreen(True)
 
    elif user_input.key == 'ESCAPE':
        return True  #exit game

    #movement keys
    if user_input.key == 'UP':
        player.move(0, -1)

    elif user_input.key == 'DOWN':
        player.move(0, 1)

    elif user_input.key == 'LEFT':
        player.move(-1, 0)

    elif user_input.key == 'RIGHT':
        player.move(1, 0)
 

#############################################
# Initialization & Main Loop                #
#############################################

tdl.set_font('arial10x10.png', greyscale=True, altLayout=True)
root = tdl.init(SCREEN_WIDTH, SCREEN_HEIGHT, title="Roguelike", fullscreen=False)
tdl.setFPS(LIMIT_FPS)
con = tdl.Console(SCREEN_WIDTH, SCREEN_HEIGHT)

#create object representing the player
player = GameObject(SCREEN_WIDTH//2, SCREEN_HEIGHT//2, '@', (255,255,255))

#create an NPC
npc = GameObject(SCREEN_WIDTH//2 - 5, SCREEN_HEIGHT//2, '@', (255,255,0))

#the list of objects with those two
objects = [npc, player]

#generate map (at this point it's not drawn to the screen)
make_map()


while not tdl.event.is_window_closed():

    #draw all objects in the list
    render_all()

    tdl.flush()

    #erase all objects at their old locations, before they move
    for obj in objects:
        obj.clear()

    #handle keys and exit game if needed
    exit_game = handle_keys(REALTIME)
    if exit_game:
        break