Hi,
Here is a basic Raycasting renderer. It runs quite well on my iPhone 4S, even though it can still be optimized a lot !
https://gist.github.com/momorprods/7cb1739e8f8444b1b0e3
Hi,
Here is a basic Raycasting renderer. It runs quite well on my iPhone 4S, even though it can still be optimized a lot !
https://gist.github.com/momorprods/7cb1739e8f8444b1b0e3
This is really cool and it runs fast
Great, thank you for sharing. Maybe you like to import motion?
# RayCast
# Simple raycasting based renderer
# Touch the left part to rotate, and touch the right part to move forward
# Coded in a few hours during my holidays, July 2014, straight from my iPhone - thanks Pythonista !!!
# Feel free to upgrade !
# Enjoy !
# Emmanuel ICART
# eicart@momorprods.com
from scene import *
from math import *
import motion
# rendering step - 1=best(slower)
RENDERING_STEP=2
# level data
# 1 = wall, 0 = empty
level = [[1,1,1,1,1,1,1,1],
[1,1,0,0,0,0,0,1],
[1,0,0,0,0,1,0,1],
[1,0,1,0,0,0,0,1],
[1,1,0,0,0,1,0,1],
[1,0,0,1,1,0,0,1],
[1,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1]]
LX=len(level[0])
LZ=len(level)
CellSize=128
scan=10
# player
xo=CellSize*LX/2
zo=CellSize*LZ/2
angle=45.0
fov=80
class RayCastScene (Scene):
def setup(self):
motion.start_updates()
# preload the texture
self.texture='PC_Chest_Closed'
self.screenWidth=int(self.size.w)
self.screenHeight=int(self.size.h)
self.xTouchStart, self.yTouchStart, self.zTouchStart = motion.get_gravity()
load_image(self.texture)
def draw(self):
global angle
global xo
global zo
# This will be called for every frame (typically 60 times per second).
# clear background
background(0, 0, 0)
focale=0.5*self.screenWidth/tan(radians(fov/2))
# compute each screen column
for column in xrange(0,self.screenWidth,RENDERING_STEP):
scan_angle=angle+((float(column)-self.screenWidth/2)*fov)/self.screenWidth
c=cos(radians(scan_angle))
s=sin(radians(scan_angle))
if abs(c)<0.001:
if c>0:
c=0.001
else:
c=-0.001
if abs(s)<0.001:
if s>0:
s=0.001
else:
s=-0.001
t2=s/c
t1=c/s
ok1=True
ok2=True
#Initialization of ray casting
pz1=t2*CellSize
if c>0:
px1=CellSize
ini=0
else:
px1=-CellSize
pz1=-pz1
ini=CellSize-1
xp1=ini+(((int)(xo/CellSize))*CellSize)
zp1=zo+((xp1-xo)*pz1)/px1
px2=t1*CellSize
if s>0:
pz2=CellSize
ini=0
else:
pz2=-CellSize
px2=-px2
ini=CellSize-1
zp2=ini+(((int)(zo/CellSize))*CellSize)
xp2=xo+((zp2-zo)*px2)/pz2
#****** cast a ray for z walls ******
compteur=0
while True:
xp1+=px1
zp1+=pz1
compteur+=1
xd=(int)(xp1/CellSize) % LX
zd=(int)(zp1/CellSize) % LZ
if (xd<0): xd=0
if (zd<0): zd=0
if level[xd][zd]!=0 or compteur>=scan: break
if (compteur==scan):ok1=False
distance1=(xp1-xo)/c
col1=(zp1 % CellSize)
if (px1<=0): col1=CellSize-1-col1
#****** cast a ray for x walls ******
compteur=0
while True:
xp2+=px2
zp2+=pz2
compteur+=1
xd=(int)(xp2/CellSize) % LX
zd=(int)(zp2/CellSize) % LZ
if (xd<0):xd=0
if (zd<0):zd=0
if level[xd][zd]!=0 or compteur>=scan: break
if (compteur==scan): ok2=False
distance2=(zp2-zo)/s
col2=(xp2 % CellSize)
if (pz2>=0):col2=CellSize-1-col2
#Choose the nearest wall (x or z)
if (distance1<distance2):
distance=1+(distance1)
colonne=col1
else:
distance=1+(distance2)
colonne=col2
if ok1 or ok2:
# fix the fishbowl effect
distance=distance*cos(radians(angle-scan_angle))
#compute the wall screen height
hauteur = ((CellSize*focale)/distance)
# draw the column
ximage=(colonne*128)/CellSize # 101 x 171 tile
image(self.texture,column,(self.screenHeight-hauteur)/2,RENDERING_STEP,hauteur,ximage,0,RENDERING_STEP,171)
# rotation/displacement control
x,y,z = motion.get_gravity()
angle += 0.01*(y-self.yTouchStart)
speed=(self.xTouchStart-x)*0.05
dx=speed*cos(radians(angle))
dz=speed*sin(radians(angle))
if level[int((xo+dx)/CellSize)][int(zo/CellSize)]!=0:dx=0
if level[int(xo/CellSize)][int((zo+dz)/CellSize)]!=0:dz=0
xo+=dx
zo+=dz
def touch_began(self, touch):
pass
def touch_moved(self, touch):
pass
def touch_ended(self, touch):
pass
run(RayCastScene(),LANDSCAPE)
Thanks brumm for this update.
@momorprods Hey, I have been messing with this code for about a week and can’t figure out how to add another wall, like for the finish for the level, I added the number 2 to the level numbers, and replicated some stuff, but I am not skilled enough yet... could you please give me a script to do that? And also could you please tell me how to make the level bigger? I tried that too, but I got an error, sorry for bothering you when ya probs have much better things to do...
@brumm Hey, if you can, could you please check this thread and see what I said to the creator and try to achieve that? I don’t think he uses this website anymore considering that last time he was on here was three months ago...
(NO OFFENSE creator if you are reading this!)