Posts: 544
Threads: 15
Joined: Oct 2016
Dec-09-2018, 10:44 PM
(This post was last modified: Dec-13-2018, 12:32 PM by metulburr.)
Simple improvement would to put images in a list or dict.
This would stop if block. When more image are added.
DISPLAYSURF.blit(tileImage[tile], (centered_x, centered_y)) #display the actual tile My example. My math could be improve.
import pygame
class Square:
def __init__(self, color):
self.surface = pygame.Surface((64, 64))
self.surface = self.surface.convert_alpha()
self.surface.fill((0,0,0,0))
pygame.draw.polygon(self.surface, color, [(32,32), (64,48), (32,64), (0,48)])
def draw(self, surface, pos):
surface.blit(self.surface, pos)
class Block:
def __init__(self, color):
self.surface = pygame.Surface((64, 64)).convert_alpha()
self.surface.fill((0,0,0,0))
pygame.draw.polygon(self.surface, color, [(32,32), (0,16), (32,0), (64,16)])
c = color.hsla
color.hsla = c[0], c[1], c[2] * 0.75, c[3]
pygame.draw.polygon(self.surface, color, [(0,16), (32,32), (32,64), (0,48)])
c = color.hsla
color.hsla = c[0], c[1], c[2] * 0.75, c[3]
pygame.draw.polygon(self.surface, color, [(32,32), (64,16), (64,48), (32,64)])
def draw(self, surface, pos):
surface.blit(self.surface, pos)
class Scene:
def __init__(self):
self.rect = pygame.Rect(0, 0, 800, 600)
pygame.display.set_caption('Example')
self.surface = pygame.display.set_mode(self.rect.size)
self.clock = pygame.time.Clock()
self.images = [Square(pygame.Color('lawngreen')),
Block(pygame.Color('cyan')),
Block(pygame.Color('firebrick'))
]
self.map = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0, 2, 2, 2, 0],
[0, 1, 0, 0, 1, 0, 0, 2, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 2, 0, 0],
[0, 1, 0, 0, 1, 0, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
def loop(self):
self.running = True
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
self.surface.fill((0,0,0))
cx = self.rect.centerx // 2 + len(self.map) * 32
cy = self.rect.centery // 2 - len(self.map[0]) * 4
w, h = self.rect.size
for row, line in enumerate(self.map):
for col, tile in enumerate(line):
pos = w - (row * 32 + cx) + col * 32, (col + row) * 16 + cy
self.images[tile].draw(self.surface, pos)
pygame.display.flip()
self.clock.tick(30)
pygame.quit()
scene = Scene()
scene.loop()
99 percent of computer problems exists between chair and keyboard.
Posts: 9
Threads: 2
Joined: Dec 2018
Dec-10-2018, 07:25 AM
(This post was last modified: Dec-10-2018, 07:27 AM by ThePhi.)
What you're proposing is probably faster in term of CPU (I didn't time it though) but the usual way in a 2d game is to use 2d assets, not drawing them in the program.
You can use free 2d assets like here: https://devilsworkshop.itch.io/big-pixel...2d-sprites
Posts: 5,150
Threads: 396
Joined: Sep 2016
(Dec-10-2018, 07:25 AM)ThePhi Wrote: the usual way in a 2d game is to use 2d assets, not drawing them in the program. I would do this as well. I think its easier and when you need top-down assets something like Tiled makes it really easy to place positions and edit them in the future being able to see them. Not to mention you can make minute details in image software that would be horrific trying to replicate them.
Recommended Tutorials:
Posts: 544
Threads: 15
Joined: Oct 2016
Creating image in game and/or loading image is just a personal preference.
Loading image have higher quality. If you are going that way.
Creating image I can program to have different colors quickly.
So I can test out different task quickly.
Then if I want higher quality images. I can just replace it.
99 percent of computer problems exists between chair and keyboard.
Posts: 9
Threads: 2
Joined: Dec 2018
(Dec-10-2018, 03:19 PM)Windspar Wrote: Creating image in game and/or loading image is just a personal preference. A bit more than that... Even you didn't manage to create the same image as in my example (see the red line around each face of the cube? Not so easy drawing that by the program isn't it?).
(Dec-10-2018, 03:19 PM)Windspar Wrote: Loading image have higher quality. If you are going that way. Creating image I can program to have different colors quickly. So I can test out different task quickly. Then if I want higher quality images. I can just replace it. To get the same result with image assets, you can still use vertex images in pygame. Even if I didn't try it, it seems to work ( https://stackoverflow.com/questions/4001...vector-art)
Posts: 544
Threads: 15
Joined: Oct 2016
(Dec-11-2018, 07:34 AM)ThePhi Wrote: A bit more than that... Even you didn't manage to create the same image as in my example (see the red line around each face of the cube? Not so easy drawing that by the program isn't it?).
Example with my poor quality red lines.
import pygame
BRED = pygame.Color(200, 110, 110)
class Square:
def __init__(self, color):
self.surface = pygame.Surface((64, 64))
self.surface = self.surface.convert_alpha()
self.surface.fill((0,0,0,0))
pygame.draw.polygon(self.surface, color, [(32,32), (64,48), (32,64), (0,48)])
pygame.draw.polygon(self.surface, BRED, [(32,32), (64,48), (32,64), (0,48)], 1)
def draw(self, surface, pos):
surface.blit(self.surface, pos)
class Block:
def __init__(self, color):
self.surface = pygame.Surface((64, 64)).convert_alpha()
self.surface.fill((0,0,0,0))
pygame.draw.polygon(self.surface, color, [(32,32), (0,16), (32,0), (64,16)])
c = color.hsla
color.hsla = c[0], c[1], c[2] * 0.75, c[3]
pygame.draw.polygon(self.surface, color, [(0,16), (32,32), (32,64), (0,48)])
c = color.hsla
color.hsla = c[0], c[1], c[2] * 0.75, c[3]
pygame.draw.polygon(self.surface, color, [(32,32), (64,16), (64,48), (32,64)])
pygame.draw.polygon(self.surface, BRED, [(32,32), (0,16), (32,0), (64,16)], 1)
pygame.draw.polygon(self.surface, BRED, [(0,16), (32,32), (32,64), (0,48)], 1)
pygame.draw.polygon(self.surface, BRED, [(32,32), (64,16), (64,48), (32,64)], 1)
def draw(self, surface, pos):
surface.blit(self.surface, pos)
class BlockHalf:
def __init__(self, color):
self.surface = pygame.Surface((64, 64)).convert_alpha()
self.surface.fill((0,0,0,0))
# top
pygame.draw.polygon(self.surface, color, [(32,48), (0,32), (32,16), (64,32)])
# left
c = color.hsla
color.hsla = c[0], c[1], c[2] * 0.75, c[3]
pygame.draw.polygon(self.surface, color, [(0,32), (32,48), (32,64), (0,56)])
# right
c = color.hsla
color.hsla = c[0], c[1], c[2] * 0.75, c[3]
pygame.draw.polygon(self.surface, color, [(32,48), (64,32), (64,56), (32,64)])
def draw(self, surface, pos):
surface.blit(self.surface, pos)
class Scene:
def __init__(self):
self.rect = pygame.Rect(0, 0, 800, 600)
pygame.display.set_caption('Example')
self.surface = pygame.display.set_mode(self.rect.size)
self.clock = pygame.time.Clock()
self.images = [Square(pygame.Color('lawngreen')),
Block(pygame.Color('cyan')),
Block(pygame.Color('firebrick'))
]
self.map = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0, 2, 2, 2, 0],
[0, 1, 0, 0, 1, 0, 0, 2, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 2, 0, 0],
[0, 1, 0, 0, 1, 0, 2, 2, 2, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
def loop(self):
self.running = True
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
self.surface.fill((0,0,0))
cx = self.rect.centerx // 2 + len(self.map) * 32 + 16
cy = self.rect.centery // 2 - len(self.map[0]) * 4
w, h = self.rect.size
for row, line in enumerate(self.map):
for col, tile in enumerate(line):
pos = w - (row * 32 + cx) + col * 32, (col + row) * 16 + cy
self.images[tile].draw(self.surface, pos)
pygame.display.flip()
self.clock.tick(30)
pygame.quit()
scene = Scene()
scene.loop() One good thing about low quality images. You can see how fast it program runs. Then see how much slow down with high quality images. In programming everything has it cost.
99 percent of computer problems exists between chair and keyboard.
Posts: 9
Threads: 2
Joined: Dec 2018
You gave yourself a lot of work. Try with a sprite of an hospital, a tree now
Posts: 544
Threads: 15
Joined: Oct 2016
(Dec-11-2018, 06:28 PM)ThePhi Wrote: You gave yourself a lot of work.
Example with a trees
import pygame
BRED = pygame.Color(200, 110, 110)
def darken_color(color, darken=0.75):
c = color.hsla
color.hsla = c[0], c[1], c[2] * darken, c[3]
def lower_points(points, by=32):
return tuple([(p[0], p[1] + by) for p in points])
def top_points(x=0, y=0, w=64, h=32):
if w < 0:
w = 64 + w
if h < 0:
h = 32 + h
w -= x
h -= y
topleft = x, y + h * 0.5
topright = x + w * 0.5, y + x * 0.5
bottomleft = x + w * 0.5, y + h - x * 0.5
bottomright = x + w, y + h * 0.5
return topleft, topright, bottomright, bottomleft
def side_points(top_points, height=32):
return ((top_points[0],
top_points[3],
(top_points[3][0], top_points[3][1] + height),
(top_points[0][0], top_points[0][1] + height)),
(top_points[3],
top_points[2],
(top_points[2][0], top_points[2][1] + height),
(top_points[3][0], top_points[3][1] + height)))
class Square:
def __init__(self, color):
self.surface = pygame.Surface((64, 64)).convert_alpha()
self.surface.fill((0,0,0,0))
pygame.draw.polygon(self.surface, color, [(0,48), (32,32), (64,48), (32,64)])
pygame.draw.polygon(self.surface, BRED, [(0,48), (32,32), (66,48), (32,64)], 1)
def draw(self, surface, pos):
surface.blit(self.surface, pos)
class Block:
def __init__(self, color):
self.surface = pygame.Surface((64, 64)).convert_alpha()
self.surface.fill((0,0,0,0))
self.create_image(color)
def create_image(self, color):
top = top_points()
left, right = side_points(top)
# top
pygame.draw.polygon(self.surface, color, top)
# left
darken_color(color)
pygame.draw.polygon(self.surface, color, left)
# right
darken_color(color)
pygame.draw.polygon(self.surface, color, right)
#pygame.draw.polygon(self.surface, BRED, [(32,32), (0,16), (32,0), (64,16)], 1)
#pygame.draw.polygon(self.surface, BRED, [(0,16), (32,32), (32,64), (0,48)], 1)
#pygame.draw.polygon(self.surface, BRED, [(32,32), (64,16), (64,48), (32,64)], 1)
def draw(self, surface, pos):
surface.blit(self.surface, pos)
class Tree:
def __init__(self, color, trunk_color, ground_color):
self.tree_top = pygame.Surface((64, 64)).convert_alpha()
self.tree_top.fill((0,0,0,0))
self.trunk = pygame.Surface((64, 64)).convert_alpha()
self.trunk.fill((0,0,0,0))
self.create_image(color, trunk_color, ground_color)
def create_image(self, color, trunk_color, ground_color):
# Tree Top
top, left, right = self.layer(top_points(), 24, 8)
self.draw_polygons(self.tree_top, top, left, right, pygame.Color(*color))
top, left, right = self.layer(top_points(8, w=-8), 16, 8)
self.draw_polygons(self.tree_top, top, left, right, pygame.Color(*color))
top, left, right = self.layer(top_points(16, w=-16), 8, 8)
self.draw_polygons(self.tree_top, top, left, right, pygame.Color(*color))
top, left, right = self.layer(top_points(24, w=-24), 0, 8)
self.draw_polygons(self.tree_top, top, left, right, pygame.Color(*color))
# Trunk
top = lower_points(top_points())
pygame.draw.polygon(self.trunk, ground_color, top)
top, left, right = self.layer(top_points(20, w=-20), 0, 32)
self.draw_polygons(self.trunk, top, left, right, trunk_color)
def draw_polygons(self, surface, top, left, right, color):
# top
pygame.draw.polygon(surface, color, top)
# left
darken_color(color)
pygame.draw.polygon(surface, color, left)
# right
darken_color(color)
pygame.draw.polygon(surface, color, right)
def layer(self, toptop, height, diff):
top = lower_points(toptop, height)
left, right = side_points(top, diff)
return top, left, right
def draw(self, surface, pos):
surface.blit(self.trunk, pos)
position = pos[0], pos[1] - 16
surface.blit(self.tree_top, position)
class Scene:
def __init__(self):
self.rect = pygame.Rect(0, 0, 800, 600)
pygame.display.set_caption('Example')
self.surface = pygame.display.set_mode(self.rect.size)
self.clock = pygame.time.Clock()
self.images = [Square(pygame.Color('lawngreen')),
Block(pygame.Color('cyan')),
Block(pygame.Color('firebrick')),
Tree(pygame.Color('forestgreen'), pygame.Color('brown'), pygame.Color('lawngreen'))
]
self.map = [[3, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0, 2, 2, 2, 0],
[0, 1, 0, 0, 1, 0, 0, 2, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 2, 0, 3],
[0, 1, 0, 0, 1, 0, 2, 2, 2, 0],
[3, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
def loop(self):
self.running = True
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
self.surface.fill((0,0,0))
cx = self.rect.centerx // 2 + len(self.map) * 32 + 16
cy = self.rect.centery // 2 - len(self.map[0]) * 4
w, h = self.rect.size
for row, line in enumerate(self.map):
for col, tile in enumerate(line):
pos = w - (row * 32 + cx) + col * 32, (col + row) * 16 + cy
self.images[tile].draw(self.surface, pos)
pygame.display.flip()
self.clock.tick(30)
pygame.quit()
scene = Scene()
scene.loop()
99 percent of computer problems exists between chair and keyboard.
Posts: 5,150
Threads: 396
Joined: Sep 2016
(Dec-10-2018, 03:19 PM)Windspar Wrote: Creating image in game and/or loading image is just a personal preference.
Loading image have higher quality. If you are going that way.
Creating image I can program to have different colors quickly.
So I can test out different task quickly.
Then if I want higher quality images. I can just replace it. In my opinion the opposite is true. I think it is much more faster to throw an image in GIMP (or PhotoShop ) to change it than to program it. If your planning on replacing your placeholder images anyways, then it was a complete waste of time writing the code to make trees, rather than just using the actual image you would be using in the first place.
Recommended Tutorials:
Posts: 544
Threads: 15
Joined: Oct 2016
Dec-13-2018, 02:44 AM
(This post was last modified: Dec-13-2018, 07:49 AM by buran.)
It's probably just me, but I like programming image code. I always use blender over gimp when I can. I can do some math in blender. I like dealing objects over layers. I use gimp for normals and diffuse maps.
I believe I can have 50 colors of every image before you can do it gimp.
It all comes down to how fancy you want your images.
Since I not very good at make fancy images.
99 percent of computer problems exists between chair and keyboard.
|