Level Change In Ursina Game Engine - python-3.x

I'm making a 3d platformer game in ursina and finishing level 1. But I can't get the Player to touch the portal and move to the next level. Also, I'm using my own player controller for some smoother jumping so I can't use intersect. I'll show you my code and the player code:
main.py File:
from ursina import *
from ursina import curve
from player import Player
from ursina.prefabs.sky import Sky
from ursina.shaders import lit_with_shadows_shader
app = Ursina(borderless=False)
window.exit_button.enabled = True
window.cog_button.enabled = True
window.fps_counter.enabled = False
window.exit_button.text = ''
window.exit_button.color = color.gray
window.exit_button.texture = "sword"
window.cog_menu.enabled = False
window.title = 'Urono'
window.icon = 'duh.png'
Sky()
player = Player("cube", (0, 10, 0), "box")
player.SPEED = 3
player.jump_height = 0.5
ground = Entity(model='cube', texture='assets/hrllohrllo', collider='mesh', position=(
0, 0, 0), scale=(7, 2, 7), shader=lit_with_shadows_shader)
FPC_POS = player.position
background = Audio(
'audio/urono-cheerbeat-background',
loop=True,
autoplay=True
)
quM = Audio(
'audio/quit',
loop=False,
autoplay=False
)
grappler = Entity(parent=camera.ui, model='assets/grappler.obj', position=(0.8, -0.4, 0), scale=(0.25, 0.25, 0.25),
color=color.red, texture="white_cube", rotation=(-10, -10, -10), shader=lit_with_shadows_shader, on_click=camera.shake)
lava = Entity(parent=scene, model = "plane", texture = "white_cube", position = (0, -100, 0), scale = (10000, 1, 10000), color = color.orange, collider = "plane")
class Grapple(Button):
def __init__(self, position=(0, 0, 0)):
super().__init__(
parent=scene,
model="cube",
texture="assets/grappler_texture",
collider="box",
position=position,
shader=lit_with_shadows_shader,
scale=(10, 10, 10)
)
self.player = player
def update(self):
self.on_click = Func(self.player.animate_position,
self.position, duration=0.5, curve=curve.linear)
ray = raycast(self.player.position, self.player.forward,
distance=0.5, ignore=[player, ])
if ray.entity == self:
self.player.y += 2
class Portal(Entity):
def __init__(self, position=(0, 0, 0)):
super().__init__(
parent=scene,
model="assets/portal.obj",
scale=(2, 4, 2),
texture="portal_texture",
collider="box",
position=position,
shader=lit_with_shadows_shader
)
self.player = player
def update(self):
if hit.entity == self.player:
level2()
class Platform(Entity):
def __init__(self, position=(0, 0, 0)):
super().__init__(
parent=scene,
model="cube",
scale=(7, 2, 7),
texture="grappler_texture",
collider="box",
position=position,
shader=lit_with_shadows_shader
)
FPC_POS_text = Text("", scale=2, x=0.2, y=0.2)
QUIT_WARN_text = Text("", scale=2, x=0.2, y=0.2)
def level1():
Platform(Vec3(1, -1, -27.2754))
Platform(Vec3(0.0640625, 0.00125, -53.2754))
Platform(Vec3(0.169236, 14.3008, -33.3041))
Platform(Vec3(-0.886462, 7.42754, -73.0878))
Platform(Vec3(-1.10773, 12.6191, -90.2041))
Platform(Vec3(-1.3286, 19.5097, -107.289))
Platform(Vec3(-1.55644, 25.4606, -124.914))
Platform(Vec3(-2.07368, 25.0602, -164.926))
Platform(Vec3(-4.56876, 24.3813, -206.787))
Platform(Vec3(-6.55665, 36.2641, -210.516))
Platform(Vec3(-5.2145, 24.7415, -232.169))
Platform(Vec3(-8.12956, 19.0883, -313.253))
Grapple(Vec3(-7.73628, 24.0123, -262.297))
Platform(Vec3(-8.12433, 26.1495, -245.986))
Platform(Vec3(6.65358, 20.0725, -312.287))
Platform(Vec3(25.9705, 20.3887, -312.661))
Platform(Vec3(44.783, 20.6966, -313.026))
Platform(Vec3(63.9781, 21.0108, -313.399))
Platform(Vec3(106.336, 21.7041, -314.22))
Platform(Vec3(127.271, 22.0467, -314.626))
Platform(Vec3(140.357, 27.1054, -314.879))
Platform(Vec3(155.502, 31.5333, -315.172))
Platform(Vec3(183.088, 32.3551, -313.688))
Platform(Vec3(207.893, 32.8512, -313.688))
Platform(Vec3(272.206, 34.1376, -313.688))
Platform(Vec3(286.402, 40.7493, -313.687))
Platform(Vec3(279.467, 45.2291, -298.974))
Platform(Vec3(276.644, 47.8035, -247.383))
Platform(Vec3(275.481, 47.0466, -206.259))
Portal(Vec3(275.486, 52.046, -206.386))
Platform(Vec3(280.947, 52.4222, -273.657))
Platform(Vec3(-1.45974, 25.976, -178.793))
Platform(Vec3(-2.1425, 25.0246, -178.681))
Platform(Vec3(-1.51808, 25.5806, -140.103))
Platform(Vec3(-2.0098, 26.0397, -150))
Platform(Vec3(-2.38591, 26.2334, -191.67))
Grapple(Vec3(91.2361, 32.216, -313.007))
Platform(Vec3(-9.097, 32.2579, -280.842))
Platform(Vec3(279.779, 52.2863, -288.757))
Platform(Vec3(277.064, 51.1692, -255.344))
Grapple(Vec3(274.925, 56.6227, -223.522))
Platform(Vec3(251.518, 40.172, -314.807))
Platform(Vec3(234.105, 33.5976, -314.413))
Platform(Vec3(225.337, 34.8861, -314.214))
Platform(Vec3(215.52, 33.2659, -316.504))
level1()
def level2():
Platform(Vec3(1, -1, -27.2754))
Platform(Vec3(0.0640625, 0.00125, -53.2754))
def update():
if held_keys['i']:
FPC_POS_text.text = f"{player.position}"
else:
FPC_POS_text.text = ' '
if held_keys['escape']:
if not quM.playing:
quM.play()
QUIT_WARN_text.text = 'Press "q" to quit'
else:
QUIT_WARN_text.text = ' '
if held_keys['q']:
quit()
PointLight(parent=camera, color=color.white, position=(0, 10, -1.5))
AmbientLight(color=color.rgba(100, 100, 100, 0.1))
AmbientLight(parent=lava, color = color.white, position = (0, -50, 0))
app.run()
Then The player File:
from ursina import *
import math
def sign(x): return -1 if x < 0 else (1 if x > 0 else 0)
class Player(Entity):
def __init__(self, model, position, collider, scale=(1, 1, 1), SPEED=3, velocity=(0, 0, 0), MAXJUMP=1, gravity=1, controls="wasd", **kwargs):
super().__init__(
model="cube",
position=position,
scale=(1, 1, 1),
visible_self=False
)
self.collider = BoxCollider(
self, center=Vec3(0, 1, 0), size=Vec3(1, 2, 1))
mouse.locked = True
camera.parent = self
camera.position = (0, 2, 0)
camera.rotation = (0, 0, 0)
camera.fov = 100
self.velocity_x, self.velocity_y, self.velocity_z = velocity
self.SPEED = SPEED
self.MAXJUMP = MAXJUMP
self.jump_count = 0
self.gravity = gravity
self.jump_height = 0.3
self.slope = 40
self.controls = controls
self.sensibility = 70
self.crosshair = Entity(model="quad", color=color.red, parent=camera, position=(
0, 0, 1), scale=(0.01, 0.01, 0.01))
for key, value in kwargs.items():
try:
setattr(self, key, value)
except:
print(key, value)
def jump(self):
self.velocity_y = self.jump_height * 40
self.jump_count += 1
def update(self):
y_movement = self.velocity_y * time.dt
direction = (0, sign(y_movement), 0)
yRay = boxcast(origin=self.world_position, direction=direction,
distance=self.scale_y/2+abs(y_movement), ignore=[self, ])
if yRay.hit:
move = False
self.jump_count = 0
self.velocity_y = 0
else:
self.y += y_movement
self.velocity_y -= self.gravity * time.dt * 25
x_movement = (self.forward[0]*held_keys[self.controls[0]] +
self.left[0]*held_keys[self.controls[1]] +
self.back[0]*held_keys[self.controls[2]] +
self.right[0]*held_keys[self.controls[3]]) * time.dt*6 * self.SPEED
z_movement = (self.forward[2]*held_keys[self.controls[0]] +
self.left[2]*held_keys[self.controls[1]] +
self.back[2]*held_keys[self.controls[2]] +
self.right[2]*held_keys[self.controls[3]]) * time.dt*6 * self.SPEED
if x_movement != 0:
direction = (sign(x_movement), 0, 0)
xRay = boxcast(origin=self.world_position, direction=direction,
distance=self.scale_x/2+abs(x_movement), ignore=[self, ], thickness=(1, 1))
if not xRay.hit:
self.x += x_movement
else:
TopXRay = raycast(origin=self.world_position-(0, self.scale_y/2-.1, 0),
direction=direction, distance=self.scale_x /
2+math.tan(math.radians(self.slope))*.1,
ignore=[self, ])
if not TopXRay.hit:
self.x += x_movement
HeightRay = raycast(origin=self.world_position+(sign(x_movement)*self.scale_x/2, -self.scale_y/2, 0),
direction=(0, 1, 0), ignore=[self, ])
if HeightRay.hit:
self.y += HeightRay.distance
if z_movement != 0:
direction = (0, 0, sign(z_movement))
zRay = boxcast(origin=self.world_position, direction=direction,
distance=self.scale_z/2+abs(z_movement), ignore=[self, ], thickness=(1, 1))
if not zRay.hit:
self.z += z_movement
else:
TopZRay = raycast(origin=self.world_position-(0, self.scale_y/2-.1, 0),
direction=direction, distance=self.scale_z /
2+math.tan(math.radians(self.slope))*.1,
ignore=[self, ])
if not TopZRay.hit:
self.z += z_movement
HeightRay = raycast(origin=self.world_position+(0, -self.scale_y/2, sign(z_movement)*self.scale_z/2),
direction=(0, 1, 0), ignore=[self, ])
if HeightRay.hit:
self.y += HeightRay.distance
camera.rotation_x -= mouse.velocity[1] * self.sensibility
self.rotation_y += mouse.velocity[0] * self.sensibility
camera.rotation_x = min(max(-80, camera.rotation_x), 80)
def input(self, key):
if key == 'space':
if self.jump_count < self.MAXJUMP:
self.jump()
There's no intersecton variable, and I don't know what to do.
Credit to Mandaw for the player.

Related

Bug causes player to collide with the first two obstacles and nothing else [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
I'm making a game environment for NEAT. The first two obstacles seem to collide with the players just fine, but none of the other obstacles do anything. The visuals won't work, but based on the size of the player list, yeah no it's not working. The collide class also wouldn't work before I started implementing NEAT, so there's that.
Anyway here's some (probably) irrelevant code:
import pygame
from pygame.locals import *
import random
import os
import neat
debugfun = 0
W = 300
H = 300
win = pygame.display.set_mode((W, H))
pygame.display.set_caption("bruv moment")
coords = [0, 60, 120, 180, 240]
class Player(object):
def __init__(self, x):
self.x = x
self.y = 600 - 60
self.width = 60
self.height = 60
self.pos = 0
self.left = False
self.right = False
def move(self):
if self.left:
self.pos -= 1
if self.right:
self.pos += 1
if self.pos < 0:
self.pos = 4
if self.pos > 4:
self.pos = 0
self.x = coords[self.pos]
class Block(object):
def __init__(self, pos, vel):
self.pos = pos
self.x = coords[self.pos]
self.y = -60
self.width = 60
self.height = 60
self.vel = vel
def move(self):
self.y += self.vel
def redraw_window():
pygame.draw.rect(win, (0, 0, 0), (0, 0, W, H))
for ob in obs:
pygame.draw.rect(win, (0, 255, 0), (ob.x, ob.y, ob.width, ob.height))
for ind in homies:
pygame.draw.rect(win, (255, 0, 0), (ind.x, ind.y, ind.width, ind.height))
pygame.display.update()
obs = []
homies = []
player_collision = False
ge = []
nets = []
And here's some relevant code:
def collide():
for ob in obs:
for x, ind in enumerate(homies):
if ind.y < ob.y + ob.height and ind.y + ind.height > ob.y and ind.x + ind.width > ob.x and ind.x < ob.x + ob.width:
ge[x].fitness -= 1
homies.pop(x)
nets.pop(x)
ge.pop(x)
def main(genomes, config):
speed = 30
pygame.time.set_timer(USEREVENT + 1, 550)
pygame.time.set_timer(USEREVENT + 2, 1000)
for _, g in genomes:
net = neat.nn.FeedForwardNetwork.create(g, config)
nets.append(net)
homies.append(Player(0))
g.fitness = 0
ge.append(g)
clock = pygame.time.Clock()
ran = True
while ran and len(homies) > 0:
clock.tick(27)
collide()
for x, ind in enumerate(homies):
ind.move()
ge[x].fitness += 0.1
try:
output = nets[x].activate((ind.x, abs(obs[0].x - ind.x)))
except IndexError:
output = 50
try:
if output in range(5, 25):
ind.left = True
else:
ind.left = False
if output > 25:
ind.right = True
else:
ind.right = False
except TypeError:
if output[0] in range(5, 25):
ind.left = True
else:
ind.left = False
if output[1] > 25:
ind.right = True
else:
ind.right = False
for ob in obs:
ob.move()
if ob.x > H:
obs.pop(obs.index(ob))
for event in pygame.event.get():
if event.type == pygame.QUIT:
ran = False
pygame.quit()
if event.type == USEREVENT+1:
if speed <= 200:
speed += 3
if event.type == USEREVENT+2:
for g in ge:
g.fitness += 0.5
if len(obs) == 0:
obs.append(Block(round(random.randint(0, 4)), speed))
print(len(homies))
print(len(obs))
redraw_window()
def run(config_file):
config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet,
neat.DefaultStagnation, config_path)
p = neat.Population(config)
p.add_reporter(neat.StdOutReporter(True))
stats = neat.StatisticsReporter()
p.add_reporter(stats)
winner = p.run(main, 50)
if __name__ == "__main__":
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, "avoidpedofiles.txt")
run(config_path)

Display multiple images in PIL

-------------------------------Solved(Partially)----------------------------------------
My problem is that when I try to display multiple images on the canvas using PIL, I end up with only the last image.
All the images have slightly different characteristics(angle offset). Also the having a plethora of entries, I have to use a loop for sure. Also I'll need to use PIL(tkinter objects not possible) for the angle offset feature.
Here is the code;
#!/usr/bin/python
# Filename: weather_sim.py
import os
import tkinter as tk
import h5py as hp
import numpy as np
import ntpath as ntp
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfilename
def path_leaf(path):
head, tail = ntp.split(path)
return tail or ntp.basename(head)
class CoordFind:
def __init__(self):
self.LatPx = 0
self.LonPx = 0
def find_px(self, Lat, Lon):
self.LatPx = (Lat - LatN)/LatLc
self.LonPx = (Lon - LonW)/LonLc
class PlottingGUI(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.coord = CoordFind()
self.root = parent
self.root.wm_title("-|-|-|-|||Wind Vector Plotter|||-|-|-|-")
self.root.resizable(False, False)
self.path = "None Selected"
self.HaM = 0
self.Lat = 0
self.Lon = 0
self.WiD = 0
self.WiS = 0
self.fr = tk.Frame(self.root, width = (width+20), height = (height+20), bd = 2)
self.fr.grid(row = 1, column = 0)
self.frBro = tk.Frame(self.root, width = (width+20), height = 50, bd = 2)
self.frBro.grid(row = 0, column = 0)
self.frHi = tk.Frame(self.root, width = (width+20), height = 50, bd = 2)
self.frHi.grid(row = 2, column = 0)
self.cv = tk.Canvas(self.fr, width = width, height = height, background = "white", bd = 0, relief = tk.SUNKEN)
self.cv.grid(row = 0, column = 0)
self.cv.create_image(1, 1, anchor = "nw", image = photo)
self.broButton = tk.Button(self.frBro, text = "Browse Dsets", command = self.analyseDset, height = 3, width = 16, bg = "yellow")
self.broButton.grid(row = 0, column = 0, padx = 20)
self.selFile = tk.Label(self.frBro, text = self.path)
self.selFile.grid(row = 0, column = 1)
self.caution = tk.Label(self.frHi, text = "Optional use. Warning!!, May lead to lags in program", fg = "red")
self.caution.grid(row = 0, column = 1)
self.shoRedBut = tk.Button(self.frHi, text = "Show H1", command = self.show_barbs1().__next__, height = 3, width = 16, bg = "#FF0000", fg = "white", activebackground="#E533B5")
self.shoRedBut.grid(row = 1, column = 0, padx = 7, pady = 2)
self.shoGrnBut = tk.Button(self.frHi, text = "Show H2", command = self.show_barbs2().__next__, height = 3, width = 16, bg = "#00B400", fg = "white", activebackground="#B5E533")
self.shoGrnBut.grid(row = 1, column = 1, padx = 7, pady = 2)
self.shoBluBut = tk.Button(self.frHi, text = "Show H3", command = self.show_barbs3().__next__, height = 3, width = 16, bg = "#0000FF", fg = "white", activebackground="#33B5E5")
self.shoBluBut.grid(row = 1, column = 2, padx = 7, pady = 2)
self.desc1 = tk.Label(self.frHi, text = "100-250 hPa", fg = "white", bg = "black")
self.desc1.grid(row = 2, column = 0)
self.desc2 = tk.Label(self.frHi, text = "250-350 hPa", fg = "white", bg = "black")
self.desc2.grid(row = 2, column = 1)
self.desc3 = tk.Label(self.frHi, text = "350-700 hPa", fg = "white", bg = "black")
self.desc3.grid(row = 2, column = 2)
def analyseDset(self):
self.path = askopenfilename(filetypes = (("Dataset files", "*.h5")
,("All files", "*.*") ))
self.jfname = path_leaf(self.path)
self.selFile = tk.Label(self.frBro, text = self.jfname)
self.selFile.grid(row = 0, column = 1)
self.extDset()
def extDset(self):
hf = hp.File(self.path, 'r')
HaM = hf.get('HEIGHT_ASSIGNMENT_METHOD')
Lat = hf.get('Latitude')
Lon = hf.get('Longitude')
WiD = hf.get('WIND_DIRECTION')
WiS = hf.get('WIND_SPEED')
self.HaM = np.array(HaM)
self.Lat = np.array(Lat)/100
self.Lon = np.array(Lon)/100
self.WiD = np.array(WiD)
self.WiS = np.array(WiS)
self.BrbImR = np.empty((self.HaM.shape[0],1))
self.BrbImB = np.empty((self.HaM.shape[0],1))
def show_barbs1(self):
self.coord = CoordFind()
script_dir = os.path.dirname(os.path.abspath(__file__))
im = Image.open(os.path.join(script_dir, 'Red_Barbs\icons8-wind-speed-43-47-50.png'))
w, h = im.size
im = im.resize((int(w/2), int(h/2)), Image.ANTIALIAS)
vec_im = ImageTk.PhotoImage(im.rotate(45))
for i in range(0, self.HaM.shape[0]):
if self.HaM[i] == 0:
self.coord.find_px(self.Lat[i], self.Lon[i])
x = self.coord.LonPx
y = self.coord.LatPx
self.BrbImR[i] = self.cv.create_image(x, y, image = vec_im)
while True:
for i in range(0, self.HaM.shape[0]):
self.cv.itemconfigure(self.BrbImR[i], state = tk.NORMAL)
self.shoRedBut.configure(text = "Showing H1")
yield
def show_barbs2(self):
self.coord = CoordFind()
BrbImG = np.empty((self.HaM.shape[0],1))
script_dir = os.path.dirname(os.path.abspath(__file__))
im = Image.open(os.path.join(script_dir, 'Green_Barbs\icons8-wind-speed-43-47-50.png'))
w, h = im.size
im = im.resize((int(w/2), int(h/2)), Image.ANTIALIAS)
for i in range(0, self.HaM.shape[0]):
if self.HaM[i] == 1:
vec_im = ImageTk.PhotoImage(im.rotate(self.WiD[i]))
self.coord.find_px(self.Lat[i], self.Lon[i])
x = self.coord.LonPx
y = self.coord.LatPx
BrbImG[i] = self.cv.create_image(x, y, image = vec_im)
while True:
for i in range(0, self.HaM.shape[0]):
self.cv.itemconfigure(BrbImG[i], state = tk.NORMAL)
self.shoGrnBut.configure(text = "Showing H2")
yield
def show_barbs3(self):
self.coord = CoordFind()
script_dir = os.path.dirname(os.path.abspath(__file__))
im = Image.open(os.path.join(script_dir, 'Blue_Barbs\icons8-wind-speed-43-47-50.png'))
w, h = im.size
im = im.resize((int(w/2), int(h/2)), Image.ANTIALIAS)
vec_im = ImageTk.PhotoImage(im.rotate(180))
for i in range(0, self.HaM.shape[0]):
if self.HaM[i] == 2:
self.coord.find_px(self.Lat[i], self.Lon[i])
x = self.coord.LonPx
y = self.coord.LatPx
self.BrbImB[i] = self.cv.create_image(x, y, image = vec_im)
while True:
for i in range(0, self.HaM.shape[0]):
self.cv.itemconfigure(self.BrbImB[i], state = tk.NORMAL)
self.shoBluBut.configure(text = "Showing H3")
yield
if __name__ == "__main__":
root = tk.Tk()
backmap = "Map.png"
photo = ImageTk.PhotoImage(file = backmap)
width = photo.width()
height = photo.height()
LatN = 69.5
LatS = -69.3
LonE = 148.9
LonW = 1.0
LatLc = (LatS - LatN)/height
LonLc = (LonE - LonW)/width
app = PlottingGUI(root)
root.mainloop()
The output currently is this;(For the green arrows as that is what I have tested on)
This is what I want;(But with different angles)
I am using Python 3.6 on Windows 10.
Thanks in advance!!
P.S.: Also there is another problem if someone can help me with that. I would like to be able to choose a particular image based on a range factor(Wind Speed) by doing like a switch-case(or if-elif-else) procedure if possible. But when I try to do that it says "No such File or Directory". I may put it in another Question though.
-------------------------------Solved(Till this point)---------------------------------
EDIT: Solved the problem of displaying multiple arrows according to
choice and at different angles.
Here's the code;
#!/usr/bin/python
# Filename: weather_sim.py
import os
import tkinter as tk
import h5py as hp
import numpy as np
import ntpath as ntp
from PIL import Image, ImageTk
from tkinter.filedialog import askopenfilename
def path_leaf(path):
head, tail = ntp.split(path)
return tail or ntp.basename(head)
class CoordFind:
def __init__(self):
self.LatPx = 0
self.LonPx = 0
def find_px(self, Lat, Lon):
self.LatPx = (Lat - LatN)/LatLc
self.LonPx = (Lon - LonW)/LonLc
class PlottingGUI(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.coord = CoordFind()
self.root = parent
self.root.wm_title("-|-|-|-|||Wind Vector Plotter|||-|-|-|-")
self.root.resizable(False, False)
self.path = "None Selected"
self.HaM = 0
self.Lat = 0
self.Lon = 0
self.WiD = 0
self.WiS = 0
self.ima = []
self.fr = tk.Frame(self.root, width = (width+20), height = (height+20), bd = 2)
self.fr.grid(row = 1, column = 0)
self.frBro = tk.Frame(self.root, width = (width+20), height = 50, bd = 2)
self.frBro.grid(row = 0, column = 0)
self.frHi = tk.Frame(self.root, width = (width+20), height = 50, bd = 2)
self.frHi.grid(row = 2, column = 0)
self.cv = tk.Canvas(self.fr, width = width, height = height, background = "white", bd = 0, relief = tk.SUNKEN)
self.cv.grid(row = 0, column = 0)
self.cv.create_image(1, 1, anchor = "nw", image = photo)
self.broButton = tk.Button(self.frBro, text = "Browse Dsets", command = self.analyseDset, height = 3, width = 16, bg = "yellow")
self.broButton.grid(row = 0, column = 0, padx = 20)
self.selFile = tk.Label(self.frBro, text = self.path)
self.selFile.grid(row = 0, column = 1)
self.caution = tk.Label(self.frHi, text = "Optional use. Warning!!, May lead to lags in program", fg = "red")
self.caution.grid(row = 0, column = 1)
self.shoRedBut = tk.Button(self.frHi, text = "Show H1", command = self.show_barbs1().__next__, height = 3, width = 16, bg = "#FF0000", fg = "white", activebackground="#E533B5")
self.shoRedBut.grid(row = 1, column = 0, padx = 7, pady = 2)
self.shoGrnBut = tk.Button(self.frHi, text = "Show H2", command = self.show_barbs2().__next__, height = 3, width = 16, bg = "#00B400", fg = "white", activebackground="#B5E533")
self.shoGrnBut.grid(row = 1, column = 1, padx = 7, pady = 2)
self.shoBluBut = tk.Button(self.frHi, text = "Show H3", command = self.show_barbs3().__next__, height = 3, width = 16, bg = "#0000FF", fg = "white", activebackground="#33B5E5")
self.shoBluBut.grid(row = 1, column = 2, padx = 7, pady = 2)
self.desc1 = tk.Label(self.frHi, text = "100-250 hPa", fg = "white", bg = "black")
self.desc1.grid(row = 2, column = 0)
self.desc2 = tk.Label(self.frHi, text = "250-350 hPa", fg = "white", bg = "black")
self.desc2.grid(row = 2, column = 1)
self.desc3 = tk.Label(self.frHi, text = "350-700 hPa", fg = "white", bg = "black")
self.desc3.grid(row = 2, column = 2)
def analyseDset(self):
self.path = askopenfilename(filetypes = (("Dataset files", "*.h5")
,("All files", "*.*") ))
self.jfname = path_leaf(self.path)
self.selFile = tk.Label(self.frBro, text = self.jfname)
self.selFile.grid(row = 0, column = 1)
self.extDset()
def extDset(self):
hf = hp.File(self.path, 'r')
HaM = hf.get('HEIGHT_ASSIGNMENT_METHOD')
Lat = hf.get('Latitude')
Lon = hf.get('Longitude')
WiD = hf.get('WIND_DIRECTION')
WiS = hf.get('WIND_SPEED')
self.HaM = np.array(HaM)
self.Lat = np.array(Lat)/100
self.Lon = np.array(Lon)/100
self.WiD = np.array(WiD)
self.WiS = np.array(WiS)
self.BrbImR = np.empty((self.HaM.shape[0],1))
self.BrbImG = np.empty((self.HaM.shape[0],1))
self.BrbImB = np.empty((self.HaM.shape[0],1))
def barb_def(self, WiS):
if WiS < 1:
self.ima = "1.png"
elif WiS < 3:
self.ima = "2.png"
elif WiS < 8:
self.ima = "3.png"
elif WiS < 13:
self.ima = "4.png"
elif WiS < 18:
self.ima = "5.png"
elif WiS < 23:
self.ima = "6.png"
elif WiS < 28:
self.ima = "7.png"
elif WiS < 33:
self.ima = "8.png"
elif WiS < 38:
self.ima = "9.png"
elif WiS < 43:
self.ima = "10.png"
elif WiS < 48:
self.ima = "11.png"
elif WiS < 53:
self.ima = "12.png"
elif WiS < 58:
self.ima = "13.png"
elif WiS < 63:
self.ima = "14.png"
elif WiS < 68:
self.ima = "15.png"
elif WiS < 73:
self.ima = "16.png"
elif WiS < 78:
self.ima = "17.png"
elif WiS < 83:
self.ima = "18.png"
elif WiS < 88:
self.ima = "19.png"
elif WiS < 93:
self.ima = "20.png"
elif WiS < 98:
self.ima = "21.png"
elif WiS < 103:
self.ima = "22.png"
else:
self.ima = "23.png"
def show_barbs1(self):
self.coord = CoordFind()
vec_im = []
im = []
p = []
script_dir = os.path.dirname(os.path.abspath(__file__))
for i in range(0, self.HaM.shape[0]):
self.barb_def(self.WiS[i])
p.append("{}{}".format('Red_Barbs\\', self.ima))
im.append(Image.open(os.path.join(script_dir, p[i])))
w, h = im[i].size
im[i] = im[i].resize((int(w/2), int(h/2)), Image.ANTIALIAS)
vec_im.append(ImageTk.PhotoImage(im[i].rotate(self.WiD[i])))
for i in range(0, self.HaM.shape[0]):
if self.HaM[i] == 0:
self.coord.find_px(self.Lat[i], self.Lon[i])
x = self.coord.LonPx
y = self.coord.LatPx
self.BrbImR[i] = self.cv.create_image(x, y, image = vec_im[i])
while True:
for i in range(0, self.HaM.shape[0]):
self.cv.itemconfigure(self.BrbImR[i], state = tk.NORMAL)
self.shoRedBut.configure(text = "Showing H1")
yield
def show_barbs2(self):
self.coord = CoordFind()
vec_im = []
im = []
p = []
script_dir = os.path.dirname(os.path.abspath(__file__))
for i in range(0, self.HaM.shape[0]):
self.barb_def(self.WiS[i])
p.append("{}{}".format('Green_Barbs\\', self.ima))
im.append(Image.open(os.path.join(script_dir, p[i])))
w, h = im[i].size
im[i] = im[i].resize((int(w/2), int(h/2)), Image.ANTIALIAS)
vec_im.append(ImageTk.PhotoImage(im[i].rotate(self.WiD[i])))
for i in range(0, self.HaM.shape[0]):
if self.HaM[i] == 1:
self.coord.find_px(self.Lat[i], self.Lon[i])
x = self.coord.LonPx
y = self.coord.LatPx
self.BrbImG[i] = self.cv.create_image(x, y, image = vec_im[i])
while True:
for i in range(0, self.HaM.shape[0]):
self.cv.itemconfigure(self.BrbImG[i], state = tk.NORMAL)
self.shoGrnBut.configure(text = "Showing H2")
yield
def show_barbs3(self):
self.coord = CoordFind()
vec_im = []
im = []
p = []
script_dir = os.path.dirname(os.path.abspath(__file__))
for i in range(0, self.HaM.shape[0]):
self.barb_def(self.WiS[i])
p.append("{}{}".format('Blue_Barbs\\', self.ima))
im.append(Image.open(os.path.join(script_dir, p[i])))
w, h = im[i].size
im[i] = im[i].resize((int(w/2), int(h/2)), Image.ANTIALIAS)
vec_im.append(ImageTk.PhotoImage(im[i].rotate(self.WiD[i])))
for i in range(0, self.HaM.shape[0]):
if self.HaM[i] == 2:
self.coord.find_px(self.Lat[i], self.Lon[i])
x = self.coord.LonPx
y = self.coord.LatPx
self.BrbImB[i] = self.cv.create_image(x, y, image = vec_im[i])
while True:
for i in range(0, self.HaM.shape[0]):
self.cv.itemconfigure(self.BrbImB[i], state = tk.NORMAL)
self.shoBluBut.configure(text = "Showing H3")
yield
if __name__ == "__main__":
root = tk.Tk()
backmap = "Map.png"
photo = ImageTk.PhotoImage(file = backmap)
width = photo.width()
height = photo.height()
LatN = 69.5
LatS = -69.3
LonE = 148.9
LonW = 1.0
LatLc = (LatS - LatN)/height
LonLc = (LonE - LonW)/width
app = PlottingGUI(root)
root.mainloop()
But this ended up having a new problem. One set of coloured arrows is showing at a time but when I click the button to display another set it goes "Python stopped working because of some error" and then the shell restarts. Don't know what's the prob though.

Issue with pygame.transform.rotate(), Index is apparently out of range

So I am working on a basic PacMan game, and am trying to get my player to run through its sprite_sheet to show an animation. It works flawlessly when I am moving it right (thats the original orientation of the image), however for any of the other directions where I pygame.transform.rotate() the image, it returns the following:
self.image = (PAC_UP[self.spritesheet_index % 4])
IndexError: list index out of range
Not sure why this is happening (clearly it has to do with rotation). Any explanation on rotations and why this is happening would be greatly appreciated!
Thanks!
Heres my code:
class sprite_sheet():
def __init__ (self, filename):
self.spritesheet = pygame.image.load(filename)
def get_image(self, x, y, width, height):
image = pygame.Surface((width, height))
image.set_colorkey(BLACK)
image.blit(self.spritesheet, (0,0), (x, y, width, height))
return image
PAC_RIGHT = []
for x in range(4):
image = (sprite_sheet('pacman-spritesheet.png').get_image(x*24, 0, 24, 24))
PAC_RIGHT.append(image)
PAC_UP = []
for x in range(4):
image = sprite_sheet('pacman-spritesheet.png').get_image(x*24, 0, 24, 24)
PAC_RIGHT.append(pygame.transform.rotate(image, 90))
PAC_LEFT = []
for x in range(4):
image = sprite_sheet('pacman-spritesheet.png').get_image(x*24, 0, 24, 24)
PAC_RIGHT.append(pygame.transform.rotate(image, 180))
PAC_DOWN = []
for x in range(4):
image = sprite_sheet('pacman-spritesheet.png').get_image(x*24, 0, 24, 24)
PAC_RIGHT.append(pygame.transform.rotate(image, 270))
class Player (pygame.sprite.Sprite):
def __init__(self, game, x, y):
self.groups = game.all_sprites
pygame.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.image = sprite_sheet('pacman-spritesheet.png').get_image(0, 0, 24, 24)
self.x = x * TILESIZE
self.y = y * TILESIZE
self.rect = self.image.get_rect()
self.vx, self.vy = 0, 0
self.spritesheet_index = 0
self.first_time = pygame.time.get_ticks()
self.delay = 43
def get_keys(self):
self.vx, self.vy = 0, 0
keys = pygame.key.get_pressed()
self.spritesheet_index += 1
if keys[pygame.K_LEFT]:
self.vx = -PLAYER_SPEED
self.second_time = pygame.time.get_ticks()
if self.second_time-self.first_time > self.delay:
self.image = (PAC_LEFT[self.spritesheet_index % 4])
self.first_time = pygame.time.get_ticks()
if keys[pygame.K_RIGHT]:
self.vx = PLAYER_SPEED
self.second_time = pygame.time.get_ticks()
if self.second_time-self.first_time > self.delay:
self.image = (PAC_RIGHT[self.spritesheet_index % 4])
self.first_time = pygame.time.get_ticks()
if keys[pygame.K_UP]:
self.vy = -PLAYER_SPEED
self.second_time = pygame.time.get_ticks()
if self.second_time-self.first_time > self.delay:
self.image = (PAC_UP[self.spritesheet_index % 4])
self.first_time = pygame.time.get_ticks()
if keys[pygame.K_DOWN]:
self.vy = PLAYER_SPEED
self.second_time = pygame.time.get_ticks()
if self.second_time - self.first_time > self.delay:
self.image = (PAC_DOWN[self.spritesheet_index % 4])
self.first_time = pygame.time.get_ticks()
Looks like you're only adding your sprite images to the PAC_UP list:
PAC_RIGHT = []
for x in range(4):
image = (sprite_sheet('pacman-spritesheet.png').get_image(x*24, 0, 24, 24))
PAC_RIGHT.append(image)
PAC_UP = []
for x in range(4):
image = sprite_sheet('pacman-spritesheet.png').get_image(x*24, 0, 24, 24)
PAC_RIGHT.append(pygame.transform.rotate(image, 90))
Modify your code to append to the appropriate lists, PAC_DOWN, PAC_LEFT & PAC_RIGHT.
Additionally, this looks to be a copy-paste error. Instead of copy-pasting, it would be better to create a function to do your image loading.
Here's an untested example:
def load_sprite_images(rotation, filename='pacman-spritesheet.png'):
"""Load four sprite images from the specified file"""
images = []
for x in range(4):
image = (sprite_sheet(filename).get_image(x*24, 0, 24, 24))
images.append(pygame.transform.rotate(image, rotation))
return images
PAC_RIGHT = load_sprite_images(0)
PAC_UP = load_sprite_images(90)
PAC_LEFT = load_sprite_images(180)
PAC_RIGHT = load_sprite_images(270)

why is my player sprite falling throught the platform? [duplicate]

This question already has answers here:
How do I detect collision in pygame?
(5 answers)
How to detect collisions between two rectangular objects or images in pygame
(1 answer)
Closed 2 years ago.
It can collide properly on all sides and when i jump from the the ground onto the platform the player will land ontop of it and collide properly. However when i am standing on the platform and i jump and try to land on the platform again i fall straight through. Why does this happen?
Also if i hold down space bar then my sprite does not fall through the box and jumps ontop of it normally.
What it looks like: https://gyazo.com/6e0c9dfd15cdd99e72f14137fb5ef1cb
What it should look like: https://gyazo.com/bec5dc5a07d0d323b4d1cc8597eafb39
main.py
import pygame
from map import *
from char import *
pygame.init()
class game():
def __init__(self):
self.width = 1280
self.height = 720
self.gameRunning = True
self.clock = pygame.time.Clock()
self.FPS = 60
self.screen = pygame.display.set_mode((self.width, self.height))
self.loadMapData()
def update(self):
pygame.display.set_caption("{:.2f}".format(self.clock.get_fps()))
self.screen.fill(white)
self.screen.blit(self.map_img, (0,336))
playerGroup.draw(self.screen)
pygame.display.update()
def gameLoop(self):
self.clock.tick(self.FPS)
self.event()
player1.move()
self.update()
def event(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.gameRunning = False
def loadMapData(self):
self.map = TiledMap()
self.map_img = self.map.make_mapSurface()
for tile_object in self.map.gameMap.objects:
if tile_object.name == "Floor":
Collision(tile_object.x, tile_object.y + 336, tile_object.width, tile_object.height)
if tile_object.name == "Collision Box":
Platform(tile_object.x, tile_object.y + 336, tile_object.width, tile_object.height)
g = game()
player1 = player()
while g.gameRunning == True:
g.gameLoop()
map.py
import pygame
import pytmx
from char import *
pygame.init()
class TiledMap():
def __init__(self):
self.gameMap = pytmx.load_pygame("CollisionMap.tmx")
self.mapwidth = self.gameMap.tilewidth * self.gameMap.width
self.mapheight = self.gameMap.tileheight * self.gameMap.height
def renderMap(self, surface):
for layer in self.gameMap.visible_layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x,y,gid in layer:
tile = self.gameMap.get_tile_image_by_gid(gid)
if tile:
surface.blit(tile, (x * self.gameMap.tilewidth, y * self.gameMap.tileheight))
def make_mapSurface(self):
mapSurface = pygame.Surface((self.mapwidth, self.mapheight), pygame.SRCALPHA)
self.renderMap(mapSurface)
return mapSurface
class Collision(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
self.groups = SolidGroup
pygame.sprite.Sprite.__init__(self, self.groups)
self.rect = pygame.Rect(x, y, width, height)
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
self.groups = platformGroup
pygame.sprite.Sprite.__init__(self, self.groups)
self.rect = pygame.Rect(x, y, width, height)
char.py
import pygame
pygame.init()
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
playerGroup = pygame.sprite.Group()
SolidGroup = pygame.sprite.Group()
platformGroup = pygame.sprite.Group()
class player(pygame.sprite.Sprite):
def __init__(self):
self.groups = playerGroup
pygame.sprite.Sprite.__init__(self, self.groups)
self.image = pygame.Surface((50, 50))
self.image.fill(blue)
self.rect = self.image.get_rect()
self.rect.center = (1280/2, 720/2)
self.position = pygame.math.Vector2(400, 300)
self.acceleration = pygame.math.Vector2(0, 0)
self.velocity = pygame.math.Vector2(0, 0)
self.friction = -0.18
self.falling = False
self.up = False
self.down = False
self.right = False
self.Left = False
def checkFalling(self):
self.rect.y += 1
if not pygame.sprite.spritecollideany(self, SolidGroup, False):
self.falling = True
if self.velocity.y < 0:
self.up = True
self.down = False
if self.velocity.y > 0:
self.up = False
self.down = True
else:
self.falling = False
self.up = False
self.down = False
self.rect.y -= 1
def move(self):
self.checkFalling()
if self.falling:
self.acceleration = pygame.math.Vector2(0, 0.5)
if not self.falling:
self.acceleration = pygame.math.Vector2(0, 0)
key = pygame.key.get_pressed()
if key[pygame.K_RIGHT]:
self.acceleration.x = 1
self.right = True
if key[pygame.K_LEFT]:
self.acceleration.x = -1
self.left = True
if key[pygame.K_SPACE]:
self.jump()
self.acceleration.x += self.velocity.x * self.friction
self.velocity += self.acceleration
if abs(self.velocity.x) < 0.1:
self.velocity.x = 0
self.position += self.velocity + 0.5 * self.acceleration
hitsPlatform = pygame.sprite.spritecollide(self, platformGroup, False)
if hitsPlatform:
if self.up:
self.position.y -= self.velocity.y - 0.5 * self.acceleration.y
self.velocity.y = 0
self.rect.midbottom = self.position
"""
Collision Code, not in function because of screen tearing and bouncy collisions
"""
hits = pygame.sprite.spritecollide(self, SolidGroup, False)
if hits:
self.position.y = hits[0].rect.top
self.velocity.y = 0
hitsPlatform = pygame.sprite.spritecollide(self, platformGroup, False)
if hitsPlatform:
if self.down and self.position.y <= 340:
self.position.y = hitsPlatform[0].rect.top
self.velocity.y = 0
if self.velocity.x > 0 and self.position.x + 64 < 239:
self.position.x -= self.velocity.x - 0.5 * self.acceleration.x
if self.velocity.x < 0 and self.position.x > 256:
self.position.x -= self.velocity.x - 0.5 * self.acceleration.x
self.rect.midbottom = self.position
def jump(self):
self.rect.y += 1
hits = pygame.sprite.spritecollide(self, SolidGroup, False)
hitsPlatform = pygame.sprite.spritecollide(self, platformGroup, False)
self.rect.y -= 1
if hits:
self.velocity.y = -15
if hitsPlatform:
self.velocity.y = -15

Simple physics string

I am currently attempting to make a simple string simulation. The purpose is to just look like string but mine looks a bit weird and I don't know what the solution is. Does anyone have any ideas, here is the code
from pygame.locals import *
from math import sqrt
import pygame
pygame.init()
screen = pygame.display.set_mode([500, 500])
clock = pygame.time.Clock()
class Node():
def __init__(self, position, mass, initalVelocity):
self.position = position[:]
self.mass = mass
self.velocity = initalVelocity
def update(self):
self.position[0] += self.velocity[0]
self.position[1] += self.velocity[1]
class String():
def __init__(self, nodes, gravity = .981 , springConstant = 10, iterations = 1):
self.nodes = nodes[:]
self.gravity = gravity
self.springC = springConstant
self.iterations = iterations
self.setDistance = 1
def calculateForces(self):
for x in range(self.iterations):
for i in range(1, len(self.nodes), 1):
distance = sqrt((self.nodes[i].position[0] - self.nodes[i - 1].position[0]) ** 2 + (self.nodes[i].position[1] - self.nodes[i - 1].position[1]) ** 2)
force = -self.springC * (distance - self.setDistance)
force = force / self.nodes[i].mass
nDistanceVector = [(self.nodes[i].position[0] - self.nodes[i - 1].position[0]) / distance, (self.nodes[i].position[1] - self.nodes[i - 1].position[1]) / distance]
nDistanceVector = [nDistanceVector[0] * force, nDistanceVector[1] * force]
self.nodes[i].velocity[0] = 0.71 * self.nodes[i].velocity[0] + nDistanceVector[0]
self.nodes[i].velocity[1] = 0.71 * self.nodes[i].velocity[1] + (nDistanceVector[1] + self.gravity)
self.nodes[i].update()
pygame.draw.aalines(screen, [0, 0, 0], False, a)
a = [Node([250 + i * 10, 100], 100, [0, 1]) for i in range(25)]
s = String(a)
while 1:
screen.fill([255, 255, 255])
s.calculateForces()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
pygame.display.update()
clock.tick(60)`
I'm using Hooke's law and each node acts as a spring as soon as it goes beyond a certain distance from the previous node, but it just looks clunky and unrealistic. What am i missing?
Use pygame.math.Vector2 to simplify the code. Divide the calculateForces into 2 loops. First calculate the new velocity, then move the positions:
import pygame
pygame.init()
window = pygame.display.set_mode([500, 500])
clock = pygame.time.Clock()
class Node():
def __init__(self, position, mass, initial_velocity):
self.position = pygame.math.Vector2(position)
self.mass = mass
self.velocity = pygame.math.Vector2(initial_velocity)
class String():
def __init__(self, nodes, gravity = .981, spring_constant = 10):
self.nodes = nodes[:]
self.gravity = gravity
self.spring_constant = spring_constant
self.set_distance = 1
def calculateForces(self):
for i in range(1, len(self.nodes), 1):
n1, n0 = self.nodes[i], self.nodes[i - 1]
distance = n1.position.distance_to(n0.position)
force = -self.spring_constant * (distance - self.set_distance) / n1.mass
n_dist_v = (n1.position - n0.position) / distance * force
n1.velocity = 0.71 * n1.velocity + n_dist_v + pygame.math.Vector2(0, self.gravity)
for i in range(1, len(self.nodes), 1):
self.nodes[i].position += self.nodes[i].velocity
def draw(self, surf):
pygame.draw.aalines(surf, [0, 0, 0], False, [node.position for node in self.nodes])
def createString():
return String([Node([150 + i * 10, 100], 120, [0, 1]) for i in range(25)])
s = createString()
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
s = createString()
s.calculateForces()
window.fill([255, 255, 255])
s.draw(window)
pygame.display.update()
clock.tick(60)
pygame.quit()
exit()

Resources