w=W, h=H, frames_per_second=fps, background=BACKGROUND_COLOR, display_config=pi3d.DISPLAY_CONFIG_HIDE_CURSOR | pi3d.DISPLAY_CONFIG_MAXIMIZED, use_glx=True) print(display.opengl.gl_id) # the type of glsl your pi is running if W is None or H is None: (W, H) = (display.width, display.height) print('setting display size to ' + str(W) + ' ' + str(H)) ## shadertoy shader stuff ## sprite = pi3d.Triangle(corners=((-1.0, -1.0), (-1.0, 3.0), (3.0, -1.0))) shader = pi3d.Shader('cloud') sprite.set_shader(shader) ## offscreen texture stuff ## cam = pi3d.Camera(is_3d=False) postsh = pi3d.Shader('post_vanilla') post = pi3d.PostProcess(camera=cam, shader=postsh, scale=SCALE) ## interactive inputs ## kbd = pi3d.Keyboard() mouse = pi3d.Mouse() # pi3d.Mouse(restrict = True) # changes input coordinates mouse.start() MX, MY = mouse.position() MXC, MYC = mouse.position() MC = mouse.button_status(
0.1 ) #could cause delay if flag has changed to -1 but can't run flat out! counter = [None] * 5 counter[0] = 0 if MASTER: DISPLAY = pi3d.Display.create(x=MARGIN, y=MARGIN) else: DISPLAY = pi3d.Display.create(x=MARGIN, y=MARGIN, frames_per_second=15) ############## edge masking for projection onto table ################## matsh = pi3d.Shader("mat_flat") left_edge = pi3d.Triangle(corners=((-1.0, 0.0), (0.0, 2.0), (0.0, -2.0)), x=-0.75, y=0.0, z=1.0, rz=5) left_edge.set_material((0, 0, 0)) left_edge.set_shader(matsh) right_edge = pi3d.Triangle(corners=((1.0, 0.0), (0.0, -2.0), (0.0, 2.0)), x=0.60, y=0.0, z=1.0, rz=15) right_edge.set_material((0, 0, 0)) right_edge.set_shader(matsh) top_edge = pi3d.Triangle(corners=((-2.0, 0.0), (0.0, 1.0), (2.0, 0.0)), x=0.0, y=0.36, z=1.0,
def init(): global seplines, degwind, weathericon, text, line, baroneedle, windneedle, linemin, linemax, acttemp, text, error try: owm = pyowm.OWM(API_key=config.owmkey, language=config.owmlanguage) place = owm.weather_at_place(config.owmcity) weather = place.get_weather() text.text_blocks = [] text._first_free_char = 0 if config.owmlanguage == 'de': weekdays = [ 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag' ] else: weekdays = [ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' ] if not os.path.exists('sprites/' + weather.get_weather_icon_name() + '.png'): import urllib.request urllib.request.urlretrieve( "http://openweathermap.org/img/wn/" + weather.get_weather_icon_name() + "@2x.png", "sprites/" + weather.get_weather_icon_name() + ".png") weathericon = pi3d.ImageSprite(config.installpath + 'sprites/' + weather.get_weather_icon_name() + '.png', shader=graphics.SHADER, camera=graphics.CAMERA, w=150, h=150, z=2, x=-220) city = pi3d.TextBlock(-390, 180, 0.1, 0.0, 150, text_format=place.get_location().get_name(), size=0.7, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(city) city = pi3d.TextBlock(-220, 80, 0.1, 0.0, 30, justify=0.5, text_format=weather.get_detailed_status(), size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(city) acttemp = pi3d.TextBlock( -350, -50, 0.1, 0.0, 10, text_format=str(weather.get_temperature(unit='celsius')['temp']) + u'°C', size=0.9, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(acttemp) #acttemp = pi3d.FixedString(config.installpath + 'fonts/opensans.ttf', str(weather.get_temperature(unit='celsius')['temp']) + '°C' , font_size=42, shadow_radius=1,justify='L', color= (255,255,255,255),camera=graphics.CAMERA, shader=graphics.SHADER, f_type='SMOOTH') #acttemp.sprite.position(-210, -50, 1) sunriset = weather.get_sunrise_time( timeformat='date') + datetime.timedelta(hours=2) sunsett = weather.get_sunset_time( timeformat='date') + datetime.timedelta(hours=2) sunset = pi3d.TextBlock(50, 100, 0.1, 0.0, 20, text_format=unichr(0xE041) + " %s:%02d" % (sunriset.hour, sunriset.minute) + ' ' + unichr(0xE042) + " %s:%02d" % (sunsett.hour, sunsett.minute), size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(sunset) barometer = pi3d.TextBlock(50, -50, 0.1, 0.0, 10, text_format=unichr(0xE00B) + ' ' + str(weather.get_pressure()['press']) + ' hPa', size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(barometer) baroneedle = pi3d.Triangle(camera=graphics.CAMERA, corners=((-2, 0, 0), (0, 7, 0), (2, 0, 0)), x=barometer.x + 16, y=barometer.y - 6, z=0.1) baroneedle.set_shader(graphics.MATSH) normalizedpressure = (weather.get_pressure()['press'] - 950) if normalizedpressure < 0: normalizedpressure = 0 if normalizedpressure > 100: normalizedpressure = 100 green = 0.02 * (normalizedpressure) if green > 1: green = 1 red = 0.02 * (100 - normalizedpressure) if red > 1: red = 1 barometer.colouring.set_colour([red, green, 0, 1.0]) baroneedle.set_material([red, green, 0]) baroneedle.rotateToZ(100 - (normalizedpressure * 2)) humidity = pi3d.TextBlock(50, 0, 0.1, 0.0, 10, text_format=unichr(0xE003) + ' ' + str(weather.get_humidity()) + '%', size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(humidity) if 'speed' in weather.get_wind(): wind = pi3d.TextBlock(50, 50, 0.1, 0.0, 10, text_format=unichr(0xE040) + ' ' + str(weather.get_wind()['speed']) + 'm/s', size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(wind) if 'deg' in weather.get_wind(): degwind = True windneedle = pi3d.Triangle(camera=graphics.CAMERA, corners=((-3, 0, 0), (0, 15, 0), (3, 0, 0)), x=wind.x + 180, y=wind.y, z=0.1) windneedle.set_shader(graphics.MATSH) windneedle.set_material([1, 1, 1]) windneedle.rotateToZ(weather.get_wind()['deg']) else: degwind = False fc = owm.three_hours_forecast(config.owmcity) f = fc.get_forecast() step = 780 / (len(f)) actualy = -400 + step temp_max = [] temp_min = [] temp = [] seplines = [] icons = [] maxdaytemp = -100 mindaytemp = 100 for weather in f: if not os.path.exists('sprites/' + weather.get_weather_icon_name() + '.png'): import urllib.request urllib.request.urlretrieve( "http://openweathermap.org/img/wn/" + weather.get_weather_icon_name() + "@2x.png", "sprites/" + weather.get_weather_icon_name() + ".png") icons.append( pi3d.ImageSprite('sprites/' + weather.get_weather_icon_name() + '.png', shader=graphics.SHADER, camera=graphics.CAMERA, w=20, h=20, z=1, x=actualy, y=-220)) if weather.get_reference_time('iso')[11:16] == '00:00': line = pi3d.Lines(vertices=[[actualy, -50, 2], [actualy, 50, 2]], line_width=1, y=-180, strip=True) line.set_shader(graphics.MATSH) line.set_material((0, 0, 0)) line.set_alpha(0.9) seplines.append(line) # if weather.get_reference_time('iso')[11:16] == '12:00': day = weather.get_reference_time(timeformat='date').weekday() if actualy < 300: city = pi3d.TextBlock(actualy + 65, -100, 0.1, 0.0, 30, text_format=weekdays[day], justify=0.5, size=0.23, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(city) if actualy > -300: city = pi3d.TextBlock( actualy - 6 * step, -150, 0.1, 0.0, 30, text_format=str(round(maxdaytemp, 1)) + u'°C', size=0.25, spacing="F", space=0.05, colour=(1.0, 0.0, 0.0, 1.0)) text.add_text_block(city) city = pi3d.TextBlock( actualy - 6 * step, -210, 0.1, 0.0, 30, text_format=str(round(mindaytemp, 1)) + u'°C', size=0.25, spacing="F", space=0.05, colour=(0.0, 0.0, 1.0, 1.0)) text.add_text_block(city) maxdaytemp = -100 mindaytemp = 100 if '3h' in weather.get_snow(): line = pi3d.Lines(vertices=[[ actualy, -50, 2 ], [actualy, (-50 + weather.get_snow()['3h'] * 30), 2]], line_width=3, y=-180, strip=True) line.set_shader(graphics.MATSH) line.set_material((0.5, 0.5, 1)) line.set_alpha(1) seplines.append(line) if '3h' in weather.get_rain(): line = pi3d.Lines(vertices=[[ actualy, -50, 2 ], [actualy, (-50 + weather.get_rain()['3h'] * 30), 2]], line_width=3, y=-180, strip=True) line.set_shader(graphics.MATSH) line.set_material((0, 0, 1)) line.set_alpha(1) seplines.append(line) temperatures = weather.get_temperature(unit='celsius') if temperatures['temp_max'] > maxdaytemp: maxdaytemp = temperatures['temp_max'] if temperatures['temp_min'] < mindaytemp: mindaytemp = temperatures['temp_min'] temp_max.append([actualy, temperatures['temp_max'] * 3, 2]) temp_min.append([actualy, temperatures['temp_min'] * 3, 2]) temp.append([actualy, temperatures['temp'] * 3, 2]) actualy += step lastvalue = 0 line = pi3d.Lines(vertices=temp, line_width=2, y=-220, strip=True) line.set_shader(graphics.MATSH) line.set_material((0, 0, 0)) line.set_alpha(0.9) #linemin = pi3d.Lines(vertices=temp_min, line_width=1,y=-220, strip=True) # linemin.set_shader(graphics.MATSH) # linemin.set_material((0,0,1)) # linemin.set_alpha(0.9) #linemax = pi3d.Lines(vertices=temp_max, line_width=1,y=-220, strip=True) # linemax.set_shader(graphics.MATSH) # linemax.set_material((1,0,0)) # linemax.set_alpha(0.9) except: error = pi3d.TextBlock(-390, 180, 0.1, 0.0, 150, text_format="OWM ERROR", size=0.7, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(error) error = True
y = json_data['coords'][0]['conformers'][0]['y'] z = json_data['coords'][0]['conformers'][0]['z'] n = len(element) '''NB if you download different molecules you might need to add to alter this. atomic number: name, radius, (r,g,b) tuple ''' atoms = { 1: ['hydrogen', 0.5 / scaleDownFactorAtom, (1.0, 0.0, 0.0)], 6: ['carbon', 0.8 / scaleDownFactorAtom, (0.1, 0.1, 0.1)], 7: ['nitrogen', 0.9 / scaleDownFactorAtom, (0.1, 0.9, 1.0)], 8: ['oxygen', 0.9 / scaleDownFactorAtom, (1.0, 1.0, 1.0)], 15: ['phosphorus', 1.5 / scaleDownFactorAtom, (1.0, 0.0, 1.0)] } shape1 = pi3d.Sphere(radius=atoms[6][1], y=2.5) empty = pi3d.Triangle(corners=((-0.01, 10.0), (0.0, 0.01), (0.01, 0.0)), z=10.0) elem = {} #made some changes here to make the elem variable a list so that each individual set of atoms can be manipulated later on #otherwise the elem variable will overwrite itself on each atom iteration and only the last set will be manipulable for e in atoms: if e != 6: # don't do carbon again shape1 = pi3d.Sphere(radius=atoms[e][1]) elem[e] = pi3d.MergeShape() for i in range(n): if element[i] == e: elem[e].add(shape1, x[i] / scaleDownFactor, y[i] / scaleDownFactor, z[i] / scaleDownFactor) elem[e].set_material(atoms[e][2])
def init(): global snowline, rainline, seplines, degwind, weathericon, text, line global windneedle, acttemp, text, error #global baroneedle, linemin, linemax from pyowm.commons.enums import SubscriptionTypeEnum languagedict = { 'subscription_type': SubscriptionTypeEnum.FREE, 'language': config.OWMLANGUAGE, 'connection': { 'use_ssl': True, 'verify_ssl_certs': True, 'use_proxy': False, 'timeout_secs': 5 }, 'proxies': { 'http': 'http://*****:*****@host:port', 'https': 'socks5://user:pass@host:port' } } owm = pyowm.OWM(config.OWMKEY, config=languagedict) mgr = owm.weather_manager() place = mgr.weather_at_place(config.OWMCITY) weather = place.weather text.text_blocks = [] text._first_free_char = 0 if config.OWMLANGUAGE == 'de': # TODO this needs untangling from stuff in config weekdays = [ 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag' ] else: weekdays = [ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday' ] file_path = resource_filename( "shpi", "sprites/{}.png".format(weather.weather_icon_name)) if os.path.exists(file_path): weathericon = pi3d.ImageSprite(file_path, shader=graphics.SHADER, camera=graphics.CAMERA, w=150, h=150, z=2, x=-220) # else: # import urllib.request # urllib.request.urlretrieve("http://openweathermap.org/img/wn/" + weather.get_weather_icon_name( # ) + "@2x.png", "sprites/" + weather.get_weather_icon_name() + ".png") city = pi3d.TextBlock(-390, 180, 0.1, 0.0, 150, text_format=place.location.name, size=0.7, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(city) city = pi3d.TextBlock(-220, 80, 0.1, 0.0, 30, justify=0.5, text_format=weather.detailed_status, size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(city) acttemp = pi3d.TextBlock( -350, -50, 0.1, 0.0, 10, text_format=str(weather.temperature('celsius')['temp']) + u'°C', size=0.9, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(acttemp) sunriset = weather.sunrise_time(timeformat='date') + datetime.timedelta( hours=2) sunsett = weather.sunset_time(timeformat='date') + datetime.timedelta( hours=2) sunset = pi3d.TextBlock(50, 100, 0.1, 0.0, 20, text_format="{} {}:{:02d} {} {}:{:02d}".format( unichr(0xE041), sunriset.hour, sunriset.minute, unichr(0xE042), sunsett.hour, sunsett.minute), size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(sunset) barometer = pi3d.TextBlock(50, -50, 0.1, 0.0, 10, text_format=unichr(0xE00B) + ' ' + str(weather.pressure['press']) + ' hPa', size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(barometer) # baroneedle = pi3d.Triangle(camera=graphics.CAMERA, corners=( # (-2, 0, 0), (0, 7, 0), (2, 0, 0)), x=barometer.x+16, y=barometer.y - 6, z=0.1) # baroneedle.set_shader(graphics.MATSH) normalizedpressure = (weather.pressure['press'] - 950) if normalizedpressure < 0: normalizedpressure = 0 if normalizedpressure > 100: normalizedpressure = 100 green = 0.02 * (normalizedpressure) if green > 1: green = 1 red = 0.02 * (100 - normalizedpressure) if red > 1: red = 1 barometer.colouring.set_colour([red, green, 0, 1.0]) #baroneedle.set_material([red, green, 0]) #baroneedle.rotateToZ(100 - (normalizedpressure*2)) humidity = pi3d.TextBlock(50, 0, 0.1, 0.0, 10, text_format=unichr(0xE003) + ' ' + str(weather.humidity) + '%', size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(humidity) if 'speed' in weather.wind(): wind = pi3d.TextBlock(50, 50, 0.1, 0.0, 10, text_format=unichr(0xE040) + ' ' + str(weather.wind()['speed']) + 'm/s', size=0.3, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(wind) if 'deg' in weather.wind(): degwind = True windneedle = pi3d.Triangle(camera=graphics.CAMERA, corners=((-3, 0, 0), (0, 15, 0), (3, 0, 0)), x=wind.x + 180, y=wind.y, z=0.1) windneedle.set_shader(graphics.MATSH) windneedle.set_material([1, 1, 1]) windneedle.rotateToZ(weather.wind()['deg']) else: degwind = False #fc = owm.three_hours_forecast(config.OWMCITY) f = mgr.forecast_at_place(config.OWMCITY, '3h').forecast step = 780 / (len(f)) actualy = -400 + step temp_max = [] temp_min = [] temp = [] seplinesarr = [] icons = [] rainarr = [] snowarr = [] maxdaytemp = -100 mindaytemp = 100 for weather in f: file_path = resource_filename( "shpi", "sprites/{}.png".format(weather.weather_icon_name)) if not os.path.exists(file_path): import urllib.request # TODO py2 py3 fix urllib.request.urlretrieve( "http://openweathermap.org/img/wn/" + weather.get_weather_icon_name() + "@2x.png", file_path) icons.append( pi3d.ImageSprite(file_path, shader=graphics.SHADER, camera=graphics.CAMERA, w=20, h=20, z=1, x=actualy, y=-220)) if weather.reference_time('iso')[11:16] == '00:00': seplinesarr.append([actualy, -50, 2]) seplinesarr.append([actualy, 50, 2]) seplinesarr.append([actualy, -50, 2]) # if weather.get_reference_time('iso')[11:16] == '12:00': day = weather.reference_time(timeformat='date').weekday() if actualy < 300: city = pi3d.TextBlock(actualy + 65, -100, 0.1, 0.0, 30, text_format=weekdays[day], justify=0.5, size=0.23, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(city) if actualy > -300: city = pi3d.TextBlock(actualy - 6 * step, -150, 0.1, 0.0, 30, text_format=str(round(maxdaytemp, 1)) + u'°C', size=0.25, spacing="F", space=0.05, colour=(1.0, 0.0, 0.0, 1.0)) text.add_text_block(city) city = pi3d.TextBlock(actualy - 6 * step, -210, 0.1, 0.0, 30, text_format=str(round(mindaytemp, 1)) + u'°C', size=0.25, spacing="F", space=0.05, colour=(0.0, 0.0, 1.0, 1.0)) text.add_text_block(city) maxdaytemp = -100 mindaytemp = 100 if '3h' in weather.snow: snowarr.append([actualy, (-50 + weather.snow['3h'] * 30), 2]) else: snowarr.append([actualy, -50, 2]) if '3h' in weather.rain: rainarr.append([actualy, (-50 + weather.rain['3h'] * 30), 2]) else: rainarr.append([actualy, -50, 2]) temperatures = weather.temperature(unit='celsius') if temperatures['temp_max'] > maxdaytemp: maxdaytemp = temperatures['temp_max'] if temperatures['temp_min'] < mindaytemp: mindaytemp = temperatures['temp_min'] temp_max.append([actualy, temperatures['temp_max'] * 3, 2]) temp_min.append([actualy, temperatures['temp_min'] * 3, 2]) temp.append([actualy, temperatures['temp'] * 3, 2]) actualy += step snowline = pi3d.Lines(vertices=snowarr, line_width=3, y=-180, strip=True) snowline.set_shader(graphics.MATSH) snowline.set_material((0.5, 0.5, 1)) snowline.set_alpha(0.7) rainline = pi3d.Lines(vertices=rainarr, line_width=3, y=-180, strip=True) rainline.set_shader(graphics.MATSH) rainline.set_material((0, 0, 1)) rainline.set_alpha(0.7) seplines = pi3d.Lines(vertices=seplinesarr, line_width=1, y=-180, strip=True) seplines.set_shader(graphics.MATSH) seplines.set_material((0, 0, 0)) seplines.set_alpha(0.9) line = pi3d.Lines(vertices=temp, line_width=2, y=-220, strip=True) line.set_shader(graphics.MATSH) line.set_material((0, 0, 0)) line.set_alpha(0.9)
if hasattr(peripherals.eg_object, 'pressure'): barometer = pi3d.TextBlock(80, -25, 0.1, 0.0, 2, text_format=unichr(0xE00B), size=0.6, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 0.9)) text.add_text_block(barometer) baroneedle = pi3d.Triangle(camera=graphics.CAMERA, corners=((-3, 0, 0), (0, 15, 0), (3, 0, 0)), x=barometer.x + 32, y=barometer.y - 12, z=0.1) baroneedle.set_shader(graphics.MATSH) newtxt = pi3d.TextBlock(270, -180, 0.1, 0.0, 15, text_format=unichr(0xE001), size=0.99, spacing="F", space=0.05, colour=(1.0, 1.0, 1.0, 1.0)) text.add_text_block(newtxt)
shader = pi3d.Shader("uv_bump") flatsh = pi3d.Shader("uv_flat") # Create monument (a sphere with video texture on) tex = pi3d.Texture( image) # can pass numpy array or PIL.Image rather than path as string monument = pi3d.Sphere(sx=W, sy=H, sz=W) monument.set_draw_details(shader, [tex, tex], 4.0, umult=2.0) # create 2D flat sprite instead, taking up the whole screen #sprite = pi3d.Triangle(corners=((-1.0, -1.0),(-1.0, 3.0),(3.0, -1.0))) #sprite.set_shader(flatsh) #sprite.set_draw_details(flatsh, [tex, tex], 4.0, umult=2.0) CAM2D = pi3d.Camera(is_3d=False) sprite = pi3d.Triangle(camera=CAM2D, corners=((-1.0, -1.0), (-1.0, 3.0), (3.0, -1.0))) #sprite = pi3d.Triangle(corners=((-1.0, -1.0),(-1.0, 3.0),(3.0, -1.0))) sprite.set_shader(flatsh) sprite.set_draw_details(flatsh, [tex], umult=2.0, vmult=2.0) ## Matrix ## # Configuration for the matrix """ options = RGBMatrixOptions() options.rows = 32 options.cols = 32 options.chain_length = 1 options.parallel = 1 options.hardware_mapping = 'adafruit-hat' # If you have an Adafruit HAT: 'adafruit-hat', else 'regular' matrix = RGBMatrix(options = options)
def __init__(self, x=0, y=0, inner=100, outer=200, values=[], colors=[], full_range=None, concentric=False, start=0.0, end=None, sides=36, text_format="{:.1f}", camera=graphics.CAMERA, shader=graphics.MATSH): self.x = x self.y = y self.inner = inner self.outer = outer self.full_range = full_range self.concentric = concentric self.start = start if end is None: self.end = start + 360 else: self.end = end if type(text_format) in (list, tuple): self.text_format = text_format else: self.text_format = [text_format] * len(values) self.slices = [] if full_range is None: full_range = sum(values) self.n = len(values) # simplest Shape only 3 vertices. z -1 so not drawn self.empty = pi3d.Triangle(x=x, y=y, z=-1.0) self.text = pi3d.PointText(graphics.pointFont, graphics.CAMERA, max_chars=(self.n * 26), point_size=64) tot = self.start step = (outer - inner) / self.n for i in range(self.n): end = (self.end - self.start) * values[i] / full_range if concentric: a_slice = Slice( camera=camera, inner=inner + i * step, outer=inner + (i + 1) * step, sides=sides, start=self.start, end=end, z=3.0 ) #z=3 to compensate for empty set to -1 and draw behind labels else: a_slice = Slice(camera=camera, inner=inner, outer=outer, start=tot, end=tot + end, z=3.0) tot += end buf = a_slice.buf[0].array_buffer # alias for brevity midv = len( buf ) // 2 # text half way round curve, miday between inner and outer text_x = (buf[midv, 0] + buf[midv + 1, 0]) / 2 + self.x text_y = (buf[midv, 1] + buf[midv + 1, 1]) / 2 + self.y slice_text = pi3d.TextBlock(text_x, text_y, 0.0, 0.0, 25, text_format=self.text_format[i].format( values[i]), size=0.5, spacing="C", space=0.6, justify=0.5) self.text.add_text_block(slice_text) a_slice.set_shader(shader) a_slice.set_material(colors[i]) self.slices.append(a_slice) self.empty.add_child(a_slice)
mapsize = 900.0 mapheight = 150.0 mymap = pi3d.ElevationMap("mars_height.png", name="map", width=mapsize, depth=mapsize, height=mapheight, divx=32, divy=32) mymap.set_draw_details(shader, [plntimg, mudnorm], 128.0, 0.0) mymap.set_fog(*FOG) # ball stuff DRAG = 0.02 # 2% reduction in speed each frame G = -0.01 # g -> change in y velocity each frame rot = 0.0 # rotation of camera about vertical axis ballrot = 180.0 # heading of ball about vert axis (y) tilt = 0.0 # rotation of camera about local x axis (left to right horizontal) RADIUS = 1.0 # radius of ball ball = pi3d.Triangle(corners=((-0.01, 0.0), (0.0, 0.01), (0.01, 0.0))) # an 'empty' game object ball_shape = pi3d.Sphere(radius=RADIUS, slices=24, sides=24) # the visible shape ball.add_child(ball_shape) # to get realistic 'rolling' ball_shape.set_draw_details(shader, [plntimg, plnnorm], 1.0) # platforms W = 8.0 H = 1.5 on_plat = False # flag if on a platform (for jumping) platforms = [ # locations of platforms pi3d.Cuboid(x=44, y=5, z=43), pi3d.Cuboid(x=32, y=3, z=28), pi3d.Cuboid(x=30, y=2, z=15), pi3d.Cuboid(x=15, y=1, z=5), pi3d.Cuboid(x=0, y=2, z=0), ]
def shallow_clone(shape): state = shape.__getstate__() clone = pi3d.Triangle( ) # just saves having to feed in all init arguments, any shape will do clone.__setstate__(state) # as everything is overwritten here return clone display = pi3d.Display.create(background=(0.0, 0.0, 0.0, 0.0)) camera = pi3d.Camera() shader = pi3d.Shader('uv_light') laser_shader = pi3d.Shader('mat_flat') # scene - empty to hold objects scene = pi3d.Triangle(corners=((0, 0), (1, 1), (-1, 1))) # pod, base and gun pod = pi3d.Model(file_string=MODEL_PATH.format('pod_2.obj'), z=20.0) laser_base = pi3d.Model(file_string=MODEL_PATH.format('laser_base_2.obj'), y=3.15) laser_gun = pi3d.Model(file_string=MODEL_PATH.format('laser_gun_2.obj'), y=0.4, z=-0.4) laser_base.add_child(laser_gun) pod.add_child(laser_base) pod.set_shader(shader) # all use uv_light shader # laser beam itself not a child laser_tip = pi3d.Cuboid(w=0.05, h=0.05, d=5.0) laser_tip.set_material((1.0, 0.0, 0.0))
def shallow_clone(shape): state = shape.__getstate__() clone = pi3d.Triangle( ) # just saves having to feed in all init arguments, any shape will do clone.__setstate__(state) # as everything is overwritten here return clone
class Main(object): # Setup display and initialise pi3d DISPLAY = pi3d.Display.create(depth=16) pi3d.Light(lightpos=(1, -1, -3), lightcol=(1.0, 1.0, 0.8), lightamb=(0.25, 0.2, 0.3)) # load shader shader = pi3d.Shader("uv_bump") shinesh = pi3d.Shader("uv_reflect") flatsh = pi3d.Shader("uv_flat") bumpimg = pi3d.Texture("textures/grasstile_n.jpg") reflimg = pi3d.Texture("textures/stars.jpg") rockimg = pi3d.Texture("textures/rock1.jpg") FOG = ((0.3, 0.3, 0.4, 0.8), 650.0) ectex = pi3d.loadECfiles("textures/ecubes", "sbox") myecube = pi3d.EnvironmentCube(size=900.0, maptype="FACES", name="cube") myecube.set_draw_details(flatsh, ectex) # Create elevation map mapsize = 1000.0 mapheight = 60.0 mountimg1 = pi3d.Texture("textures/mountains3_512.jpg") mymap = pi3d.ElevationMap("textures/mountainsHgt.png", name="map", width=mapsize, depth=mapsize, height=mapheight, divx=32, divy=32) mymap.set_draw_details(shader, [mountimg1, bumpimg, reflimg], 128.0, 0.0) mymap.set_fog(*FOG) #Create monument monument = pi3d.Model(file_string="models/pi3d.obj", name="monument") monument.set_shader(shinesh) monument.set_normal_shine(bumpimg, 16.0, reflimg, 0.4) monument.set_fog(*FOG) monument.translate(100.0, -mymap.calcHeight(100.0, 235) + 12.0, 235.0) monument.scale(20.0, 20.0, 20.0) monument.rotateToY(65) #Ball ball = pi3d.Triangle(corners=((-0.01, 0.0), (0.0, 0.01), (0.01, 0.0))) sphere = pi3d.Sphere() sphere.set_draw_details(shader, [rockimg, bumpimg], 1.0) ball.add_child(sphere) #avatar camera rot = 0.0 tilt = 0.0 avhgt = 1.0 xm = 0.0 zm = 0.0 ym = mymap.calcHeight(xm, zm) + avhgt go_flag = False vx, vz = 0.0, 0.0 gx, gz = 0.0, 0.0 CAMERA = pi3d.Camera.instance() CAMERA2D = pi3d.Camera(is_3d=False) font = pi3d.Pngfont("fonts/GillSansMT.png", (200, 30, 10, 255)) font.blend = True txt = None if pi3d.PLATFORM == pi3d.PLATFORM_ANDROID: #***************************** from jnius import autoclass Hardware = autoclass(b'org.renpy.android.Hardware') Hardware.accelerometerEnable(True) def pi3dloop(self, dt): self.DISPLAY.loop_running() self.CAMERA.relocate(self.rot, self.tilt, [self.xm, self.ym, self.zm], [-OFFSET, -OFFSET, -OFFSET]) self.myecube.position(self.xm, self.ym, self.zm) self.ball.position(self.xm, self.ym, self.zm) # for opaque objects it is more efficient to draw from near to far as the # shader will not calculate pixels already concealed by something nearer self.ball.draw() self.mymap.draw() self.myecube.draw() dx = math.copysign(self.mapsize, self.xm) dz = math.copysign(self.mapsize, self.zm) mid = 0.3 * self.mapsize if abs(self.xm) > mid: #nearing edge self.mymap.position(dx, 0.0, 0.0) self.mymap.draw() if abs(self.zm) > mid: #other edge self.mymap.position(0.0, 0.0, dz) self.mymap.draw() if abs(self.xm) > mid: #i.e. in corner, both edges self.mymap.position(dx, 0.0, dz) self.mymap.draw() self.mymap.position(0.0, 0.0, 0.0) self.monument.draw() if pi3d.PLATFORM == pi3d.PLATFORM_ANDROID: #***************************** if self.DISPLAY.android.screen.moved: self.rot -= self.DISPLAY.android.screen.touch.dx * 0.25 self.tilt += self.DISPLAY.android.screen.touch.dy * 0.25 self.DISPLAY.android.screen.moved = False self.DISPLAY.android.screen.tapped = False elif self.DISPLAY.android.screen.double_tapped: self.go_flag = not self.go_flag self.DISPLAY.android.screen.double_tapped = False from kivy.network.urlrequest import UrlRequest def url_success(req, results): self.txt = pi3d.String(camera=self.CAMERA2D, font=self.font, string=results, is_3d=False, y=self.DISPLAY.height / 2.0 + 30.0) self.txt.set_shader(self.flatsh) self.monument.rotateIncY(4) # rotate by some random amount req = UrlRequest( "http://www.eldwick.org.uk/files/rogo/test2.php?num=1", url_success) if self.txt is not None: self.txt.draw() (x, y, z) = self.Hardware.accelerometerReading() sr, _, cr = self.CAMERA.get_direction() self.gx = y * cr + (z - x) * sr self.gz = ( z - x) * cr - y * sr # i.e. hold at 45 degrees for neutral else: mx, my = self.mymouse.position() #if mx>display.left and mx<display.right and my>display.top and my<display.bottom: self.rot -= (mx - self.omx) * 0.2 self.tilt += (my - self.omy) * 0.2 self.omx = mx self.omy = my #Press ESCAPE to terminate k = self.mykeys.read() if k > -1: sr, _, cr = self.CAMERA.get_direction() if k == ord('w'): #key W self.go_flag = not self.go_flag elif k == 261 or k == 137: # rgt self.gx += 0.5 * cr self.gz -= 0.5 * sr elif k == 260 or k == 136: # lft self.gx -= 0.5 * cr self.gz += 0.5 * sr elif k == 259 or k == 134: # up self.gz += 0.5 * cr self.gx += 0.5 * sr elif k == 258 or k == 135: # dwn self.gz -= 0.5 * cr self.gx -= 0.5 * sr elif k == 27: #Escape key return False if self.go_flag: self.xm += self.vx self.zm += self.vz ht, norm = self.mymap.calcHeight(self.xm, self.zm, True) self.ym = ht + self.avhgt self.vx += norm[0] * SLOPE_F + self.gx * TILT_F self.vz += norm[2] * SLOPE_F + self.gz * TILT_F self.vx *= FRICTION self.vz *= FRICTION self.ball.rotateToY(math.degrees(math.atan2(self.vx, self.vz))) self.sphere.rotateIncX(math.degrees( (self.vx**2 + self.vz**2)**0.5)) halfmap = self.mapsize / 2.0 # save doing this four times! self.xm = (self.xm + halfmap) % self.mapsize - halfmap self.zm = (self.zm + halfmap) % self.mapsize - halfmap else: self.vx = 0.0 self.vz = 0.0 self.gx = 0.0 self.gz = 0.0 return True def run(self): if pi3d.PLATFORM == pi3d.PLATFORM_ANDROID: #***************************** self.DISPLAY.android.set_loop(self.pi3dloop) self.DISPLAY.android.run() self.Hardware.accelerometerEnable(False) else: # Fetch key presses self.mykeys = pi3d.Keyboard() self.mymouse = pi3d.Mouse(restrict=False) self.mymouse.start() self.omx, self.omy = self.mymouse.position() while self.pi3dloop(0.0): pass self.mykeys.close() self.mymouse.stop() self.DISPLAY.stop()
# laser beam itself not a child laser_tip = pi3d.Cuboid(w=0.05, h=0.05, d=5.0) laser_tip.set_material((1.0, 0.0, 0.0)) laser_tip.set_alpha(0.8) laser_tip.set_shader(laser_shader) # asteroid asteroid = pi3d.Model(file_string=MODEL_PATH.format('asteroid_large_1.obj'), z=50, y=10, x=20) asteroid.set_shader(shader) # rings ring = pi3d.Model(file_string=MODEL_PATH.format('straight_ring_2.obj')) empty = pi3d.Triangle(corners=((0, 0), (1, 1), (-1, 1))) empty.add_child(ring) ring.set_shader(shader) ring.set_fog((0.0, 0.0, 0.0, 0.0), 350.6) ring_list = [[0, -2, 50, 10, 5]] keys = pi3d.Keyboard() mouse = pi3d.Mouse(restrict=False) mouse.start() blast_dist = 0.0 while display.loop_running(): if np.sum(np.abs(camera.eye[0:2] - pod.unif[0:2])) > 0.05: camera.reset() camera.position((camera.eye[0] * 0.98 + pod.x() * 0.02,
class Main(object): # Setup display and initialise pi3d DISPLAY = pi3d.Display.create(w=1280, h=640, far=15000, frames_per_second=30.0) ##### cameras CAMERA = pi3d.Camera() CAMERA2D = pi3d.Camera(is_3d=False) ##### shaders shader = pi3d.Shader('uv_light') shinesh = pi3d.Shader('uv_reflect') flatsh = pi3d.Shader('uv_flat') matsh = pi3d.Shader('mat_flat') mflatsh = pi3d.Shader('mat_reflect') dustsh = pi3d.Shader('shaders/dust_point') ##### textures bumpimg = pi3d.Texture('textures/moon_nm.jpg') reflimg = pi3d.Texture('textures/stars.jpg') rockimg = pi3d.Texture('textures/rock1.jpg') goodimg = pi3d.Texture('textures/rock2.jpg') starimg = pi3d.Texture('textures/space1.jpg', flip=True) explimg = pi3d.Texture('models/ast_expl.png') cloudimg = pi3d.Texture('textures/earth_clouds.png', blend=True) earthimg = pi3d.Texture('textures/world_map.jpg') moonimg = pi3d.Texture('textures/moon.jpg') targimg = pi3d.Texture('textures/target.png', blend=True) magmaimg = pi3d.Texture('textures/magma.jpg') bronzeimg = pi3d.Texture('textures/bronze.png', blend=True) silverimg = pi3d.Texture('textures/silver.png', blend=True) goldimg = pi3d.Texture('textures/gold.png', blend=True) ansimg = {} fnames = glob.glob('textures/???.jpg') for f in fnames: ansimg[int(f[9:12])] = pi3d.Texture(f, flip=True) ##### environment sphere sphere = pi3d.Sphere(radius=4000.0, rz=90, invert=True) sphere.set_draw_details(flatsh, [starimg]) sphere.set_fog((0.0, 0.0, 0.0, 1.0), 15000) ##### earth earth = pi3d.Sphere(radius=1000.0, slices=16, sides=32) earth.set_draw_details(shader, [earthimg]) earth.set_fog((0.0, 0.0, 0.0, 1.0), 15000) earth.positionX(2400.0) earth.rotateToY(360.0 * random.random()) ##### clouds clouds = pi3d.Sphere(radius=1020.0, slices=16, sides=32) clouds.set_draw_details(shader, [cloudimg]) clouds.set_fog((0.0, 0.0, 0.0, 1.0), 15000) clouds.positionX(2400.0) ##### moon moon = pi3d.Sphere(radius=500.0, slices=32, sides=32) moon.set_draw_details(shinesh, [moonimg, bumpimg, reflimg], 1.0, 0.05) moon.set_fog((0.0, 0.0, 0.0, 1.0), 15000) moon.positionX(-2000.0) ##### target target = pi3d.Sprite(w=64, h=64, camera=CAMERA2D) target.set_draw_details(flatsh, [targimg]) ##### levels levels = levels ##### asteroids asteroid_stock = [] #stock of available asteroids to use asteroids = [] #list of 'active' asteroids asteroid_stock.append(Asteroid(bumpimg, reflimg, explimg)) #zeroth is prototype to clone for i in range(9): asteroid_stock.append( Asteroid(bumpimg, reflimg, explimg, clone=asteroid_stock[0])) ##### missile missiles = [] for i in range(5): missiles.append([]) # i.e. list of lists missiles[i].append(Missile(i, bumpimg, reflimg, shader)) #zeroth is prototype for j in range(4): missiles[i].append( Missile(i, bumpimg, reflimg, (shinesh if i < 2 else shader), clone=missiles[i][0])) ##### dust dust = None dust_damage_tally = 0 ##### meters w, h = DISPLAY.width, DISPLAY.height health_meter = Meter(matsh, CAMERA2D, -w / 2.3, w * 0.05, DISPLAY.height, value=0.0) energy_meter = Meter(matsh, CAMERA2D, w / 2.3, w * 0.05, DISPLAY.height, value=0.0) ##### skip button skip_button = pi3d.Triangle(camera=CAMERA2D, x=w * 0.45, y=h * 0.4, z=1.0, corners=((0, 0), (0, h * 0.1), (w * 0.05, h * 0.05))) skip_button.set_material((0.7, 0.8, 1.0)) skip_button.set_shader(matsh) skip_button.set_alpha(0.2) ##### pause button pause_button = pi3d.Triangle(camera=CAMERA2D, x=-w * 0.45, y=h * 0.4, z=1.0, corners=((0, 0), (-w * 0.05, h * 0.05), (0, h * 0.1))) pause_button.set_material((0.8, 1.0, 0.7)) pause_button.set_shader(matsh) pause_button.set_alpha(0.2) ##### fonts font = pi3d.Pngfont('fonts/Arial2.png', (200, 30, 10, 255)) font.blend = True font2 = pi3d.Pngfont('fonts/Arial2.png', (10, 200, 100, 255)) font2.blend = True ##### medals view_medals = False ##### strings default_string = pi3d.String(camera=CAMERA2D, font=font, string='RECHARGE', is_3d=False, y=DISPLAY.height / 2.0 - 50.0, size=0.4) default_string.set_shader(flatsh) q_text = default_string s_text = None flash_count = 0 ##### end sequence magma = pi3d.Sphere(radius=900.0, slices=16, sides=32) magma.set_draw_details(shader, [magmaimg]) magma.set_fog((0.0, 0.0, 0.0, 1.0), 15000) magma.set_alpha(0.45) end_count = -1 magma.positionX(2400.0) ##### avatar camera rot = 0.0 tilt = 0.0 drot = 0.0 # rate of rot, for touch screen 'gliding' dtilt = 0.0 moved_count = MOVED_FRAMES # for touch screen x, y, z = 0.0, 0.0, 0.0 dx, dy, dz = 0.0, 0.0, 0.0 go_speed = 0.2 mode = SHOOT # 0 is shooting mode, 1 is recharge mode last_ten = [] #####----------------------------#####-----------------------------##### def endgame(self): # write score to history if in top 5 self.l_number = 0 #start as 0 each time it runs self.health = 1.0 #start off full health each time self.last_ten = [] self.scores.append(self.score) self.scores.sort(reverse=True) self.scores = self.scores[0:5] # cut off the first 5 self.q_text = self.high_score_text() self.end_count = 500 self.x, self.y, self.z = -2300, 50, 590.0 self.CAMERA.position((self.x, self.y, self.z)) self.tilt, self.rot = self.CAMERA.point_at( [self.earth.x(), self.earth.y(), self.earth.z()]) #####----------------------------#####-----------------------------##### def high_score_text(self): text = '\n'.join(['{:,}'.format(i) for i in self.scores]) pi3d_string = pi3d.String(camera=self.CAMERA2D, font=self.font, string=text, justify='c', is_3d=False, y=50.0, x=100.0, size=0.3) pi3d_string.set_shader(self.flatsh) return pi3d_string #####----------------------------#####-----------------------------##### def score_mod(self, amount): ''' utility function to change score and flash up score and delta ''' w, h = self.DISPLAY.width, self.DISPLAY.height if amount < 0: # this is a reduction in health font = self.font # red self.health += amount amount = -100 * amount if self.health < 0.0: self.endgame() self.health_meter.change_reading(self.health) prefix = '%' else: self.score += amount font = self.font2 # green prefix = '+' self.s_text = pi3d.String(camera=self.CAMERA2D, font=font, string='{}{:,}'.format(prefix, amount), is_3d=False, y=-h / 2.0 + 50.0, size=0.6) self.s_text.set_shader(self.flatsh) self.flash_count = 0 #####----------------------------#####-----------------------------##### def toggle_pause(self): if self.view_medals: #i.e. already on moon, return to saved location self.view_medals = False self.x, self.y, self.z, self.rot, self.tilt = self.saved_location self.moon.rotateToX(0.0) else: self.view_medals = True self.saved_location = self.x, self.y, self.z, self.rot, self.tilt self.moon.rotateToX(14.5) #####----------------------------#####-----------------------------##### def get_level(self): ''' utility function to get level from current score and question ''' return self.levels[min(self.l_number, len(self.levels) - 1)] #####----------------------------#####-----------------------------##### def check(self): ''' timer, asteroid hits, question/answer ''' if self.mode == SHOOT and self.energy < RECHARGE_LEVEL: #for m in self.missiles[self.missile]: # tidy any still travelling missiles # m.flag = False self.mode = RECHARGE if (self.l_number % 10) != 1: self.q_text = self.default_string self.q_frames = 0 elif self.mode == RECHARGE and self.energy > SHOOT_LEVEL: self.mode = SHOOT if self.medals.q_check(self.questions, self.q_frames): self.toggle_pause() self.frame_count += 1 if self.frame_count > N_FRAMES: # out of time return True else: all_hit = True correct_answer = False for a in self.asteroids: if not ( a.hit and a.explode_seq > EXPLODE_N ): # an asteroid hasn't been hit or it's still exploding dist = ((a.loc[0] - self.x)**2 + (a.loc[1] - self.y)**2 + (a.loc[2] - self.z)**2)**0.5 if dist > MAX_DIST or self.frame_count == N_FRAMES: # too far or out of time, kill it off if a.good: # a good asteroid has got through, hurrah self.health += TOP_UP else: if len(self.last_ten) > 0: self.last_ten[-1][4] += 1 self.score_mod( ESCAPER) # penalty for escaping asteroid -1.5% a.hit = True a.explode_seq = 101 elif dist < MIN_DIST: if len(self.last_ten) > 0: self.last_ten[-1][4] += 1 a.hit = True a.explode_seq = 101 self.score_mod( BUMP) # penalty for bumping into asteroid -30% elif not a.good: all_hit = False elif a.correct_answer: # asteroid hit and it was correct answer correct_answer = True if self.q_frames == 0: # first question, but could have been a delay self.q_frames = 100 # set to standard delay else: self.q_frames += self.frame_count if all_hit: return True if correct_answer: return True return False #####----------------------------#####-----------------------------##### def reset(self): ''' put asteroids in start positions with correct textures etc. pass asteroid list to missile. NB this sets various variables so needs to be run before main loop and check() ''' if not FREE_VERSION: ##### in free version doesn't save with open('game.ini', 'wb') as fp: #save status medal_status = [ self.medals.m_list[i].achieved for i in range(0, 7) ] saved_status = { 'scores': self.scores, 'energy': self.energy, 'questions': self.questions, 'q_pointer': self.q_pointer, 'score': self.score, 'l_number': self.l_number, 'health': self.health, 'medal_status': medal_status } pickle.dump(saved_status, fp) self.frame_count = 0 self.q_number = -1 # also use as flag indicate actually asking q self.level = self.get_level() ############################################ if self.mode == SHOOT: # - launch new set of target asteroids self.last_ten.append( [0, 0, 0, self.level.num, 0]) # dust, missiles, hits, asteroids, escapees self.last_ten = self.last_ten[-10:] if self.medals.s_check(self.last_ten, self.l_number): self.toggle_pause() (self.x, self.y, self.z) = (self.level.start_location) self.asteroids = [] for i in range(self.level.num): a = self.asteroid_stock[i] if i < self.level.num_good: tex = self.goodimg good = True else: tex = self.rockimg good = False a.launch(self.shinesh, tex, self.level.start_loc, self.level.start_range, (self.x, self.y, self.z), self.level.speed, self.level.speed_range, threshold=self.level.threshold, good=good) self.asteroids.append(a) if self.level.dust: self.dust = Dust(self.dustsh, self.level.dust) self.dust.launch(self.level.start_loc, self.level.start_range, (self.x, self.y, self.z), self.level.speed, self.level.speed_range) self.dust_damage_tally = 0 else: self.dust = None self.go_speed = self.level.go_speed #self.q_text = self.default_string self.missile_pointer = 0 self.num_missiles = self.level.num_missiles self.missile = self.level.missile self.l_number += 1 ################### missile style change, health review ############ if (self.l_number % 10) == 1: self.q_text = pi3d.String( camera=self.CAMERA2D, font=self.font, string='level ' + level_names[int( (self.l_number - 1) / 10) % len(level_names)], is_3d=False, y=self.DISPLAY.height / 2.0 - 50.0, size=0.4) self.q_text.set_shader(self.flatsh) ####### also review medals else: self.health += 0.025 # heath boost each round 2.5% if self.health > 1.0: self.health = 1.0 ############################################ else: # ask recharge questions for a in self.asteroid_stock: # kill off any stray asteroids in case they get hit by a still travelling missile a.hit = True all_good = True self.dx = self.dy = self.dz = 0.0 total = 0.0 for i, q in enumerate( self.questions[:self.q_pointer]): #restricted list q.ratio = (q.wrong + 0.5) / (q.right + 0.5) #wrongness total += q.ratio if q.ratio > 0.25: all_good = False if all_good: #add a new question for next time self.q_pointer += 1 if self.q_pointer >= (len(self.questions) - 1): self.q_pointer = len(self.questions) - 1 #if self.q_number == -1: #all over threshold choose a random one r = random.uniform(0.0, total) # weight probability by q.ratio upto = 0.0 for self.q_number, q in enumerate(self.questions[:self.q_pointer]): upto += q.ratio if (upto >= r): break question, ans = self.questions[self.q_number].make_qanda() self.q_text = pi3d.String(camera=self.CAMERA2D, font=self.font, string=question, is_3d=False, y=self.DISPLAY.height / 2.0 - 50.0, size=0.4) self.q_text.set_shader(self.flatsh) ans_list = [ans] #add correct answer first while len(ans_list) < 5: poss_ans = random.choice(list(self.ansimg.keys())) if not (poss_ans in ans_list): ans_list.append(poss_ans) self.asteroids = [] offset = random.randint(0, 4) for i, ans_num in enumerate(ans_list): a = self.asteroid_stock[i] a.launch(self.shinesh, self.ansimg[ans_num], (15.0 * ((i + offset) % 5) - 30.0, 0.0, 50.0), (8.0, 8.0, 2.0), (self.x, self.y, self.z), 0.03, 0.01, threshold=4.0, correct_answer=(i == 0)) self.asteroids.append(a) #set missile self.go_speed = 0.01 #####----------------------------#####-----------------------------##### def __init__(self): ''' need an instance to do initial settings with reset ''' ##### load saved game state if os.path.isfile('game.ini'): with open('game.ini', 'rb') as fp: saved_status = pickle.load(fp) self.scores = saved_status['scores'] self.energy = saved_status['energy'] self.questions = saved_status['questions'] self.q_pointer = saved_status['q_pointer'] self.score = saved_status['score'] self.l_number = saved_status['l_number'] self.health = saved_status['health'] medal_status = saved_status['medal_status'] else: # first load self.scores = [0] self.energy = 1.0 self.questions = questions #from imported questions self.q_pointer = 1 #number to slice with, not really pointer self.score = 0 self.l_number = 0 self.health = 1.0 #start off full health each time medal_status = [False for i in range(0, 7)] self.medals = Medals(self.mflatsh, self.flatsh, self.reflimg, self.font, -2000.0, 505.0, 0.0, FREE_VERSION) for i in range(0, 7): if medal_status[i]: self.medals.m_list[i].achieve() self.mode = SHOOT self.q_number = 0 #set when question asked self.health_meter.change_reading(self.health) self.energy_meter.change_reading(self.energy) self.s_text = self.high_score_text() self.s_text.set_shader(self.flatsh) self.reset() self.toggle_pause() #----############################-----#############################----# #####----------------------------#####-----------------------------##### #----############################-----#############################----# def pi3dloop(self, dt): self.DISPLAY.loop_running() self.CAMERA.reset() self.CAMERA.rotate(self.tilt, self.rot, 0) self.CAMERA.position((self.x, self.y, self.z)) self.sphere.position(self.x, self.y, self.z) # have to draw from far to near for transparency self.sphere.draw() if (self.frame_count % 30) == 0: self.earth.rotateIncY(-0.07) self.clouds.rotateIncY(-0.11) self.earth.draw() self.moon.draw() self.clouds.draw() if self.end_count > 0: # end or world sequence end_text = "the END!.. " alpha = self.end_count / 500.0 self.earth.set_alpha(alpha) self.clouds.set_alpha(alpha) self.magma.set_alpha(alpha) self.magma.draw() self.magma.translateX(-1.5) self.magma.rotateIncX(0.1) self.end_count -= 1 elif self.end_count == 0: # reset end of world end_text = "" self.score = 0 self.magma.positionX(2400) self.end_count = -1 self.earth.set_alpha(1.0) self.clouds.set_alpha(1.0) self.reset() elif self.view_medals: # on moon to review medals end_text = "" self.x, self.y, self.z = -2000.0, 505.0, 0.0 self.medals.draw() self.pause_button.draw() else: # normal drawing etc end_text = "" for a in self.asteroids: a.draw() a.move() self.health_meter.draw() if self.dust: self.dust.draw() self.dust.move() if ((self.frame_count % 10) == 0 and self.dust.test_hit( (self.x, self.y, self.z)) and self.dust_damage_tally < MAX_DUST_DAMAGE): # to prevent destruction if going same direction as dust if len(self.last_ten) > 0: self.last_ten[-1][0] += 1 self.score_mod(DUST_DAMAGE) # hit by dust -0.5% self.dust_damage_tally += DUST_DAMAGE self.energy_meter.draw() if self.mode == RECHARGE or (self.l_number % 10) == 1: self.q_text.draw() self.target.draw() self.skip_button.draw() self.pause_button.draw() if self.check(): self.reset() if self.flash_count < FLASH_FRAMES: self.flash_count += 1 self.s_text.translateY(-0.5) elif self.flash_count == FLASH_FRAMES: self.s_text = pi3d.String(camera=self.CAMERA2D, font=self.font2, string='{}{:,}'.format( end_text, self.score), is_3d=False, y=-self.DISPLAY.height / 2.0 + 50.0, size=0.4) self.s_text.set_shader(self.flatsh) self.s_text.draw() ##### get input for direction and firing ########################### fire = False jump = False cheat = False pause = False if PLATFORM == PLATFORM_ANDROID: # android <<<<<<<<<<<<<<<<<<<<<<<<< #self.skip_button.draw() scr = self.DISPLAY.android.screen # alias for brevity! if scr.touch and scr.touch.ud['down']: #still touching: damped if self.moved_count <= 0: damping = 0.0 else: damping = 0.65 self.moved_count -= 1 else: damping = 0.98 #low damping unless touch still down if scr.moved: if self.moved_count < MOVED_FRAMES: self.moved_count += 2 #if moving use medium damping for speed multiplier sensitivity = 40.0 self.drot -= scr.touch.dsx * sensitivity self.dtilt += scr.touch.dsy * sensitivity scr.moved = False elif scr.tapped or scr.double_tapped: scr.tapped = False scr.double_tapped = False if scr.touch.sx > 0.90 and scr.touch.sy > 0.8: jump = True if (scr.previous_touch and scr.previous_touch.ud['down'] and scr.previous_touch.sx > 0.9 and scr.previous_touch.sy < 0.2): cheat = True if scr.touch.sx < 0.10 and scr.touch.sy > 0.8: pause = True else: fire = True self.rot += self.drot self.tilt += self.dtilt self.drot *= damping self.dtilt *= damping else: # other platforms >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> mx, my = self.mouse.position() self.rot -= (mx - self.omx) * 0.1 self.tilt += (my - self.omy) * 0.1 self.omx = mx self.omy = my #Press ESCAPE to terminate k = self.keys.read() if k > -1: if k == ord(' '): #key space fire = True elif k == ord('x'): #x key jump = True elif k == ord('4'): #cheat jump = True cheat = True elif k == ord('z'): #z key pause = True elif k == 27: #Escape key return False b = self.mouse.button_status() if b == self.mouse.LEFT_BUTTON: fire = True if self.tilt > 90: self.tilt = 90 elif self.tilt < -90: self.tilt = -90 ##### act on results of input ###################################### if pause: self.toggle_pause() if jump: #self.l_number = (self.l_number + 5) % len(questions) #self.reset() self.frame_count = N_FRAMES - 1 # go to final tidy up frame if cheat and FREE_VERSION: # i.e. can cheat if free version! self.score = 0 self.health = 1.0 self.energy = 1.0 if fire: if self.q_number > -1: # shooting at questions self.level = self.levels[0] else: self.last_ten[-1][1] += 1 self.missiles[self.missile][self.missile_pointer].launch( [self.x, self.y, self.z], self.CAMERA.mtrx[ 0:3, 3], #[self.dx / self.go_speed, self.dy / self.go_speed, self.dz / self.go_speed], self.level.missile_speed, self.asteroids, g_asteroid=self.level.g_asteroid, g_missile=self.level.g_missile) self.energy -= 0.05 if self.q_number == -1 else 0.25 if self.energy < -0.5: #prevent excessive energy debt self.energy = -0.5 self.energy_meter.change_reading(self.energy) self.missiles[self.missile][self.missile_pointer].flag = True self.missile_pointer = (self.missile_pointer + 1) % self.num_missiles self.dx = self.dx * 0.95 + self.CAMERA.mtrx[0, 3] * self.go_speed * 0.05 self.dy = self.dy * 0.95 + self.CAMERA.mtrx[1, 3] * self.go_speed * 0.05 self.dz = self.dz * 0.95 + self.CAMERA.mtrx[2, 3] * self.go_speed * 0.05 self.x += self.dx self.y += self.dy self.z += self.dz for m in self.missiles[self.missile][0:self.num_missiles]: if m.flag: m.draw() m.move() i, dist = m.test_hits() if i > -1: m.flag = False a = self.asteroids[i] if a.test_hit(dist): if self.q_number == -1: # not asking actual question so score rng = 1.0 + (((a.loc[0] - self.x)**2 + (a.loc[1] - self.y)**2 + (a.loc[2] - self.z)**2)**0.5) / 50.0 score = int(2000 * (1.0 - 0.25 / (0.25 + dist / a.threshold) / rng)) if a.good: score = -0.25 # penalty for hitting a good asteroid 25% if len(self.last_ten) > 0: self.last_ten[-1][2] += 1 self.score_mod(score) else: # questioning q = self.questions[self.q_number] if self.asteroids[i].correct_answer: self.energy += 0.5 if self.energy > 1.0: self.energy = 1.0 self.energy_meter.change_reading(self.energy) q.right = q.right * 0.9 + 1.0 #exponential decay old scores q.wrong = q.wrong * 0.9 else: q.right = q.right * 0.9 q.wrong = q.wrong * 0.9 + 1.0 return True #####----------------------------#####-----------------------------##### def run(self): if PLATFORM == PLATFORM_ANDROID: # android <<<<<<<<<<<<<<<<<<<<<<<<< self.DISPLAY.android.set_loop(self.pi3dloop) self.DISPLAY.android.run() else: # other platforms >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> # Fetch key presses self.keys = pi3d.Keyboard() self.mouse = pi3d.Mouse(restrict=False) self.mouse.start() self.omx, self.omy = self.mouse.position() while self.pi3dloop(0.0): # not using the argument kivy passes pass self.keys.close() self.mouse.stop() self.DISPLAY.stop()
# Setting 2nd param to True renders 'True' Blending # (this can be changed later to 'False' with 'rockimg2.blend = False') groundimg = pi3d.Texture("textures/stripwood.jpg") monstimg = pi3d.Texture("textures/pong3.png") ballimg = pi3d.Texture("textures/pong2.jpg") # environment cube ectex = pi3d.Texture("textures/ecubes/skybox_stormydays.jpg") myecube = pi3d.EnvironmentCube(camera, light, 900.0, "CROSS") myecube.set_draw_details(flatsh, [ectex]) #ball maxdsz = 0.3 radius = 1.0 radius0 = 1.0 ball = pi3d.Triangle(corners=((-0.01, 0.0), (0.0, 0.01), (0.01, 0.0))) ball_shape = pi3d.Sphere(radius=radius) ball.add_child(ball_shape) # to get realistic 'rolling' # Shape.set_draw_details is a wrapper for calling the method on each item in buf # as is done explicitly here for no reason than to show that it can be done! ball_shape.set_draw_details(shader, [ballimg]) #monster monster = pi3d.Plane(camera, light, 5.0, 5.0, "monster", 0, 0, 0, 0, 0, 0) monster.set_draw_details(flatsh, [monstimg]) # Create elevation map mapwidth = 50.0 mapdepth = 50.0 maphalf = 22.0 mapheight = 40.0
def __init__(self, angle_fr=-140, angle_to=140, step=8, x=0, y=0, outer=250, inner=180, min_v=15, max_v=30, text_format="{:4.1f}°", set_field="set_temp", act_field="act_temp", shader=None, camera=None): self.angle_fr = angle_fr self.angle_to = ((angle_to - angle_fr) // step + 1) * step + angle_fr self.step = step self.outer = outer self.inner = inner self.mid = (outer + inner) / 2 self.min_v = min_v self.max_v = max_v self.x = x self.y = y self.set_field = set_field self.act_field = act_field self.text_format = text_format tick_verts = [] dial_verts = [] # first make tick vertices for x2 in range(self.angle_fr, self.angle_to, self.step): (s, c) = (sin(radians(x2)), cos(radians(x2)) ) # re-use for brevity below tick_verts.extend([(self.inner * s, self.inner * c, 0.1), (self.outer * s, self.outer * c, 0.1)]) dial_verts.append((self.mid * s, self.mid * c, 2.0)) tex = pi3d.Texture( resource_filename("shpi", "sprites/color_gradient.jpg")) self.ticks = pi3d.PolygonLines(camera=graphics.CAMERA, x=self.x, y=self.y, vertices=tick_verts, strip=False, line_width=8) self.ticks.set_shader(graphics.MATSH) self.ticks.set_alpha(0.8) self.sensorticks = pi3d.PolygonLines(camera=graphics.CAMERA, x=self.x, y=self.y, vertices=tick_verts, line_width=8, strip=False) self.sensorticks.set_shader(graphics.MATSH) self.bline = pi3d.PolygonLines(camera=graphics.CAMERA, x=self.x, y=self.y, vertices=dial_verts, line_width=80) self.bline.set_textures([tex]) self.bline.set_alpha(0.8) self.bline.set_shader(graphics.SHADER) self.bline.set_material((0.5, 0.5, 0.5)) self.trian = pi3d.Triangle(camera=graphics.CAMERA, x=self.x, y=self.y, z=0.1, corners=((-15, self.inner - 20, 0), (0, self.inner + 5, 0), (15, self.inner - 20, 0))) self.trian.set_shader(graphics.MATSH) self.trian.set_material((0.3, 0.1, 0)) self.trian.set_alpha(1) self.dial = pi3d.PolygonLines(camera=graphics.CAMERA, x=self.x, y=self.y, vertices=dial_verts, line_width=84) self.dial.set_alpha(0.2) self.dial.set_shader(graphics.MATSH) self.dial.set_material((0, 0, 0)) self.actval = pi3d.PointText(graphics.pointFont, graphics.CAMERA, max_chars=23, point_size=100) self.val_block = pi3d.TextBlock(self.x, self.y + 10, 0.1, 0.0, 11, justify=0.6, text_format=text_format, size=0.99, spacing="F", space=0.02, colour=(1.0, 1.0, 1.0, 1.0)) self.actval.add_text_block(self.val_block) self.value = getattr(peripherals.eg_object, self.set_field) self.sensorvalue = getattr(peripherals.eg_object, self.act_field) self.set_block = pi3d.TextBlock(0, self.inner - 30, 0.1, 0, 11, text_format=self.text_format.format( self.value), size=0.35, spacing="F", space=0.02, colour=(1.0, 1.0, 1.0, 1), justify=0.6) self.actval.add_text_block(self.set_block) self.dot1 = pi3d.Disk(radius=130, sides=30, x=self.x, y=self.y, z=2, rx=90, camera=graphics.CAMERA) self.dot1.set_shader(graphics.MATSH) self.dot1.set_material((0, 0, 0)) self.dot1.set_alpha(0.4) self.dot2 = pi3d.Disk(radius=30, sides=20, x=self.x, y=self.y, z=0.1, rx=90, camera=graphics.CAMERA) self.dot2.set_shader(graphics.MATSH) self.dot2.set_material((1, 1, 1)) self.dot2_alpha = 1.0 self.degree = (self.angle_fr + (self.angle_to - self.angle_fr) * (self.value - self.min_v) / (self.max_v - self.min_v)) self.trian.rotateToZ(-self.degree + self.step) if self.sensorvalue < self.min_v: self.sensorvalue = self.min_v if self.sensorvalue > self.max_v: self.sensorvalue = self.max_v self.sensordegree = (self.angle_fr + (self.angle_to - self.angle_fr) * (self.sensorvalue - self.min_v) / (self.max_v - self.min_v)) self.x1 = self.mid * sin(radians(self.degree)) + self.x self.y1 = self.mid * cos(radians(self.degree)) + self.y self.changed = 0 self.dot2.position(self.x1, self.y1, 0.5) self.dot2_alpha = 1.0 self.set_block.set_position( x=(self.inner - 33) * sin(radians(self.degree - self.step)) + self.x, y=(self.inner - 33) * cos(radians(self.degree - self.step)) + self.y, rot=-self.degree + self.step)