Related
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.
So, I have been trying to implement water physics in pygame based on this tutorial
https://gamedevelopment.tutsplus.com/tutorials/make-a-splash-with-dynamic-2d-water-effects--gamedev-236
The issue is, when I implemented this code in pygame, the water decides that instead of having a nice ripple effect, its going to go crazy and wiggle all over the screen until it eventually crashes.
I looked around on some discord server and found someone else had tried to implement the same thing, and had got the same problem. Their code is basically the same as mine just more neatly organized so I will post it instead of mine.
import pygame, random
import math as m
from pygame import *
pygame.init()
WINDOW_SIZE = (854, 480)
screen = pygame.display.set_mode(WINDOW_SIZE,0,32) # initiate the window
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 18)
class surface_water_particle():
def __init__(self, x,y):
self.x_pos = x
self.y_pos = y
self.target_y = y
self.velocity = 0
self.k = 0.02
self.d = 0.02
self.time = 1
def update(self):
x = -(self.target_y - self.y_pos)
a = -(self.k * x - self.d * self.velocity)
self.y_pos += self.velocity
self.velocity += a
class water():
def __init__(self, x_start, x_end, y_start, y_end, segment_length):
self.springs = []
self.x_start = x_start
self.y_start = y_start
self.x_end = x_end
self.y_end = y_end - 10
for i in range(abs(x_end - x_start) // segment_length):
self.springs.append(surface_water_particle(i * segment_length + x_start, y_end))
def update(self, spread):
for i in range(len(self.springs)):
self.springs[i].update()
leftDeltas = [0] * len(self.springs)
rightDeltas = [0] * len(self.springs)
for i in range(0, len(self.springs) ):
if i > 0:
leftDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i - 1].y_pos)
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs) - 1:
rightDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i + 1].y_pos)
self.springs[i + 1].velocity += rightDeltas[i]
for i in range(0, len(self.springs) ):
if i > 0:
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs) - 1:
self.springs[i + 1].velocity += rightDeltas[i]
def splash(self, index, speed):
if index > 0 and index < len(self.springs) :
self.springs[index].velocity = speed
def draw(self):
water_surface = pygame.Surface((abs(self.x_start - self.x_end), abs(self.y_start - self.y_end))).convert_alpha()
water_surface.fill((0,0,0,0))
water_surface.set_colorkey((0,0,0,0))
polygon_points = []
polygon_points.append((self.x_start, self.y_start))
for spring in range(len(self.springs)):
polygon_points.append((water_test.springs[spring].x_pos, water_test.springs[spring].y_pos))
polygon_points.append((water_test.springs[len(self.springs) - 1].x_pos, self.y_start))
#pygame.draw.polygon(water_surface, (0,0,255), polygon_points)
for spring in range(0,len(self.springs) - 1):
pygame.draw.line(screen, (0,0,255), (water_test.springs[spring].x_pos, water_test.springs[spring].y_pos), (water_test.springs[spring + 1].x_pos, water_test.springs[spring + 1].y_pos), 2)
#water_surface.set_alpha(100)
return water_surface
def update_fps():
fps_text = font.render(str(int(clock.get_fps())), 1, pygame.Color("coral"))
screen.blit(fps_text, (0,0))
water_test = water(0,800,200,80, 20)
while True:
screen.fill((255,255,255))
water_test.update(0.5)
screen.blit(water_test.draw(), (0,0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == MOUSEBUTTONDOWN:
water_test.splash(10,0.1)
pygame.display.update()
clock.tick(60)
I tried looking for any issues with our implementations of the tutorial but I could not find anything that seemed out of place. I then tried adding a resistance function that would divide the water velocity each time it updates. This however did not fix the issue.
Does anyone know what was done wrong and how to fix this?
Many of the same observations as the other post. I commented a few things up, changed your velocity statement a bit. And in the "spreading" I added the passes.
Tinkered with the numbers a bit, and got some real nice splashes. (better than the accepted solution! :( lol.
If you need to troubleshoot this some more, I would suggest you comment out the spreading piece (or give it a value of zero) and you can check the springiness of the water by itself. This made it much easier to T/S.
import pygame, random
import math as m
from pygame import *
pygame.init()
WINDOW_SIZE = (854, 480)
screen = pygame.display.set_mode(WINDOW_SIZE,0,32) # initiate the window
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 18)
class surface_water_particle():
k = 0.04 # spring constant
d = 0.08 # damping constant
def __init__(self, x,y):
self.x_pos = x
self.y_pos = y
self.target_y = y
self.velocity = 0
def update(self):
x = self.y_pos - self.target_y # displacement of "spring"
a = -self.k * x - self.d * self.velocity # unit of acceleration
self.y_pos += self.velocity
self.velocity += a
class water():
def __init__(self, x_start, x_end, y_start, y_end, segment_length):
self.springs = []
self.x_start = x_start
self.y_start = y_start
self.x_end = x_end
self.y_end = y_end - 10
for i in range(abs(x_end - x_start) // segment_length):
self.springs.append(surface_water_particle(i * segment_length + x_start, y_end))
def update(self, spread):
passes = 4 # more passes = more splash spreading
for i in range(len(self.springs)):
self.springs[i].update()
leftDeltas = [0] * len(self.springs)
rightDeltas = [0] * len(self.springs)
for p in range(passes):
for i in range(0, len(self.springs) -1 ):
if i > 0:
leftDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i - 1].y_pos)
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs) - 1:
rightDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i + 1].y_pos)
self.springs[i + 1].velocity += rightDeltas[i]
for i in range(0, len(self.springs) -1):
if i > 0:
self.springs[i - 1].y_pos += leftDeltas[i] # you were updating velocity here!
if i < len(self.springs) - 1:
self.springs[i + 1].y_pos += rightDeltas[i]
def splash(self, index, speed):
if index > 0 and index < len(self.springs) :
self.springs[index].velocity = speed
def draw(self):
water_surface = pygame.Surface((abs(self.x_start - self.x_end), abs(self.y_start - self.y_end))).convert_alpha()
water_surface.fill((0,0,0,0))
water_surface.set_colorkey((0,0,0,0))
polygon_points = []
polygon_points.append((self.x_start, self.y_start))
for spring in range(len(self.springs)):
polygon_points.append((water_test.springs[spring].x_pos, water_test.springs[spring].y_pos))
polygon_points.append((water_test.springs[len(self.springs) - 1].x_pos, self.y_start))
#pygame.draw.polygon(water_surface, (0,0,255), polygon_points)
for spring in range(0,len(self.springs) - 1):
pygame.draw.line(screen, (0,0,255), (water_test.springs[spring].x_pos, water_test.springs[spring].y_pos), (water_test.springs[spring + 1].x_pos, water_test.springs[spring + 1].y_pos), 2)
#water_surface.set_alpha(100)
return water_surface
def update_fps():
fps_text = font.render(str(int(clock.get_fps())), 1, pygame.Color("coral"))
screen.blit(fps_text, (0,0))
water_test = water(0,800,200,200, 3)
while True:
screen.fill((255,255,255))
water_test.update(0.025)
screen.blit(water_test.draw(), (0,0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == MOUSEBUTTONDOWN:
water_test.splash(50,100)
pygame.display.update()
clock.tick(60)
I modified the code to match the example exactly and at least it doesn't explode instantly any more.
The main problem seemed to be the loops with the deltas. Adjusting the code for the spring update and commenting those out lead to a nice oscillation which didn't stop, but also did not explode.
The outer loop seems to be important to ease everything out a bit.
I would think it is because of the added height, as changing the height changes the force of the spring.
import pygame, random
import math as m
from pygame import *
pygame.init()
WINDOW_SIZE = (854, 480)
screen = pygame.display.set_mode(WINDOW_SIZE,0,32) # initiate the window
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 18)
class surface_water_particle():
def __init__(self, x,y):
self.x_pos = x
self.y_pos = y
self.target_y = y
self.velocity = 0
self.k = 0.02
self.d = 0.02
self.time = 1
def update(self):
x = self.y_pos - self.target_y #this was overly complicated for some reason
a = -self.k * x - self.d * self.velocity #here was a wrong sign for the dampening
self.y_pos += self.velocity
self.velocity += a
class water():
def __init__(self, x_start, x_end, y_start, y_end, segment_length):
self.springs = []
self.x_start = x_start
self.y_start = y_start
self.x_end = x_end
self.y_end = y_end - 10
for i in range(abs(x_end - x_start) // segment_length):
self.springs.append(surface_water_particle(i * segment_length + x_start, y_end))
def update(self, spread):
for i in range(len(self.springs)):
self.springs[i].update()
leftDeltas = [0] * len(self.springs)
rightDeltas = [0] * len(self.springs)
# adding this outer loop gave the real success
for j in range(0,8):
for i in range(0, len(self.springs) ):
if i > 0:
leftDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i - 1].y_pos)
self.springs[i - 1].velocity += leftDeltas[i]
if i < len(self.springs) - 1:
rightDeltas[i] = spread * (self.springs[i].y_pos - self.springs[i + 1].y_pos)
self.springs[i + 1].velocity += rightDeltas[i]
# here you used velocity instead of height before
for i in range(0, len(self.springs) ):
if i > 0:
self.springs[i - 1].y_pos += leftDeltas[i]
if i < len(self.springs) - 1:
self.springs[i + 1].y_pos += rightDeltas[i]
def splash(self, index, speed):
if index > 0 and index < len(self.springs) :
self.springs[index].velocity = speed
def draw(self):
water_surface = pygame.Surface((abs(self.x_start - self.x_end), abs(self.y_start - self.y_end))).convert_alpha()
water_surface.fill((0,0,0,0))
water_surface.set_colorkey((0,0,0,0))
polygon_points = []
polygon_points.append((self.x_start, self.y_start))
for spring in range(len(self.springs)):
polygon_points.append((water_test.springs[spring].x_pos, water_test.springs[spring].y_pos))
polygon_points.append((water_test.springs[len(self.springs) - 1].x_pos, self.y_start))
#pygame.draw.polygon(water_surface, (0,0,255), polygon_points)
for spring in range(0,len(self.springs) - 1):
pygame.draw.line(screen, (0,0,255), (water_test.springs[spring].x_pos, water_test.springs[spring].y_pos), (water_test.springs[spring + 1].x_pos, water_test.springs[spring + 1].y_pos), 2)
#water_surface.set_alpha(100)
return water_surface
def update_fps():
fps_text = font.render(str(int(clock.get_fps())), 1, pygame.Color("coral"))
screen.blit(fps_text, (0,0))
water_test = water(0,800,200,80, 20)
while True:
screen.fill((255,255,255))
water_test.update(0.5)
screen.blit(water_test.draw(), (0,0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
if event.type == MOUSEBUTTONDOWN:
water_test.splash(10,0.1)
pygame.display.update()
clock.tick(60)
Generally, what you want is that the acceleration goes in the opposite direction of the height difference (it wants to restore the original position). The velocity should decreases and eventually get back to 0.
With the original code you had, even without the loops that perform the spread, the velocity increased instead of decreased.
The velocity will probably never reach 0, so you should probably also add a threshold where you will just set it to 0 so avoid flickering.
For debugging, always print your values and have a look if they make sense. In this case you would have noticed the velocity goes up even for the single spring update step.
Edit:
This answer fixes the issue but does not tweak parameters to make it look good. See Jeff H.'s answer for a good choice of parameters.
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)
I am trying to build my first Platformer Game. So far, I have make moving left and right but unfortunately, I have encountered a error that I have not been able to fix when I implemented collisions and gravity. My player keeps on dissolving like spider man if it lands on the platform. The character is still existent, and lands on the platform, but unfortunately, he becomes invisible. There is no error message, and I suspect is has to do with the collision check.
hits = pygame.sprite.spritecollide(object, allPlatforms, False)
if hits:
object.rect.y = hits[0].rect.top + 1
object.vy = 0
print(object.rect.midbottom)
It prints out the Players location in the code, and the player is still existent and movable, but it just doesn't show. Is there something that I did that makes the character vanish?
import pygame
import random
WIDTH = 500
HEIGHT = 400
FPS = 30
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
playerImage = "blockBandit/BlockBandit.png"
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image = pygame.image.load(playerImage).convert()
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
self.vx = 0
self.vy = 0
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((w, h))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Block Bandit")
clock = pygame.time.Clock()
allPlatforms = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
p1 = Platform(0, HEIGHT - 40, WIDTH, 40)
all_sprites.add(p1)
allPlatforms.add(p1)
def moveCharacter(object):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
object.vx += -2
if keys[pygame.K_RIGHT]:
object.vx += 2
object.vx = object.vx * 0.9
if (abs(object.vx) < 1):
object.vx = 0
if (abs(object.vx) > 10):
if(object.vx < 0):
object.vx = -10
else:
object.vx = 10
object.vy = object.vy + 1
object.rect.x += object.vx
object.rect.y += object.vy
hits = pygame.sprite.spritecollide(object, allPlatforms, False)
if hits:
object.rect.y = hits[0].rect.top + 1
object.vy = 0
print(object.rect.midbottom)
running = True
while running:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
moveCharacter(player)
#Update State
all_sprites.update()
#Render
screen.fill(BLACK)
all_sprites.draw(screen)
#screen.blit(player.icon, (20, 40))
pygame.display.flip()
pygame.quit()
Am I doing something wrong? Thanks!
The y attribute of the rect is the same as the top coordinate, so you're setting the top of the player sprite to the top of the platform sprite here object.rect.y = hits[0].rect.top + 1. And if the platform comes later in the sprite group, it will be blitted after the player and the player won't be visible.
Just change that line to object.rect.bottom = hits[0].rect.top + 1.
This question already has answers here:
Pygame how to let balls collide
(2 answers)
pygame Get the balls to bounce off each other
(1 answer)
Closed 2 years ago.
I am trying to create my first game, where I have successfully added a bouncing ball and another ball around the mouse-pointer. The collision between these two circles works fine except sometimes the circles intersects each other hugely and the collision does not occur in a single frame, and some strange behaviour thereafter. How do I fix this?
import pygame
from pygame.locals import *
import numpy as np
# Define the colors we will use in RGB format
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
BLUE = ( 0, 0, 255)
GREEN = ( 0, 255, 0)
RED = (255, 0, 0)
width = 800
height = 600
radius = 40
mRadius = 60
base = 20
g = 0.2
pygame.init()
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption('Testing')
clock = pygame.time.Clock()
class Circle:
def __init__(self):
self.pos = np.array([100,100])
self.velocity = np.array([2,0])
def upgrade(self,mouse):
self.pos = np.add(self.velocity,self.pos)
if ((self.pos[0] > width - radius - 1) or (self.pos[0] < 0 + radius)):
self.velocity[0] *= -1
if self.pos[1] > height - radius - base - 1:
self.velocity[1] *= -1
#print(str(self.velocity[1])+"\t"+str(self.pos[1]))
else:
self.velocity = np.add(self.velocity,[0,g])
if ((radius + mRadius)**2 >= ((self.pos[0] - mouse[0])**2 +(self.pos[1] - mouse[1])**2)):
self.pos = np.subtract(self.pos,self.velocity)
lx = self.pos[0] - mouse[0]
ly = self.pos[1] - mouse[1]
A = (lx**2 - ly**2)/(lx**2 + ly**2)
B = 2*lx*ly/(lx**2 + ly**2)
M = np.array([[A,B],[B,(-1)*A]])
self.velocity = list((-1)*M.dot(self.velocity))
print(str(lx)+"\t"+str(ly)+"\t"+str(mouse))
pygame.draw.circle(screen, GREEN, [int(self.pos[0]),int(self.pos[1])], radius)
return True
def main():
mouse = [100,100]
running = True
ball = Circle()
while running:
(mouse[0],mouse[1]) = pygame.mouse.get_pos()
screen.fill(WHITE)
pygame.draw.circle(screen, BLUE, mouse, mRadius)
running = ball.upgrade(mouse)
pygame.draw.rect(screen,RED,(0,height-base,width,base))
pygame.display.update()
clock.tick(120)
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == KEYDOWN and event.key == K_ESCAPE:
running = False
pygame.display.quit()
if __name__ == '__main__':
main()
Here is the github link