Last active
November 20, 2023 19:10
-
-
Save bened-h/9d56a03e9a14b917980c1d4039bf1687 to your computer and use it in GitHub Desktop.
This script implements Convey's "Game of Life" in Blender 2.8.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# blender 2.8 | |
""" | |
This script implements Convey's "Game of Life" in Blender 2.8 | |
It relies on the blender file containing a mesh called "Cube" | |
(sidelength = 1) and an empty collection called "Grid". | |
""" | |
import bpy | |
from random import random | |
gridsize = 20 # number of tiles in the grid (x/y-axis) | |
tile_size = 10./gridsize # the number descirbes grid dimension | |
time_stretch = 3 # distance between keyframes (iteration steps) | |
class Tile(): | |
grid = [[None for x in range(gridsize)] for y in range(gridsize)] | |
stepnr = 1 | |
def __init__(self,x,y): | |
self.grid[x][y] = self # put the Tile object in the grid array | |
self.x, self.y = x, y | |
# make a new object from the default cube: | |
obj = bpy.data.objects.new("Cube", bpy.data.meshes["Cube"]) | |
obj.location = (x*tile_size,y*tile_size,0) | |
obj.scale = [tile_size, tile_size, tile_size] | |
bpy.data.collections["Grid"].objects.link(obj) | |
self.obj = obj | |
self.life = False | |
self.nextlife = False | |
def get_neighbors(self): | |
x, y = self.x, self.y | |
l = x-1 | |
r = x+1 if x<gridsize-1 else 0 | |
d = y-1 | |
u = y+1 if y<gridsize-1 else 0 | |
g = self.grid | |
self.neighbors = [g[l][u], g[x][u], g[r][u], g[r][y], | |
g[r][d], g[x][d], g[l][d], g[l][y]] | |
def random_life(self): | |
if random() < .2: | |
self.nextlife = True | |
self.update() | |
def check(self): | |
sum = len([1 for n in self.neighbors if n.life]) | |
if self.life and (sum < 2 or sum > 3): | |
self.nextlife = False | |
elif sum == 3: | |
self.nextlife = True | |
def update(self): | |
if self.nextlife: | |
if self.life: # staying alive | |
self.obj.scale.z += .5*tile_size | |
else: # birth | |
self.obj.scale.z = 3 * tile_size | |
else: self.obj.scale.z = 1 * tile_size | |
self.life = self.nextlife | |
self.obj.keyframe_insert(data_path = "scale", | |
index = 2, frame = Tile.stepnr * 2) | |
# delete old tiles | |
for obj in bpy.data.collections["Grid"].objects: | |
bpy.data.collections["Grid"].objects.unlink(obj) | |
# initialize grid of tiles: | |
tiles = [Tile(x,y) for x in range(gridsize) for y in range(gridsize)] | |
for t in tiles: | |
t.random_life() | |
t.get_neighbors() | |
# main loop: | |
iterations = 200 | |
# set timeline length | |
bpy.context.scene.frame_end = time_stretch*iterations | |
for i in range(iterations): | |
for t in tiles: t.check() | |
for t in tiles: t.update() | |
Tile.stepnr += 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment