How do you make a Sprite blitting twice have two separate collision boxes in Pygame?
I don't know if my title was very clear, so I'm going to try to explain this more clearly here. So I have a Sprite in Pygame called spikes
. I want there to be more than one spikes
so I blit
a second one. Problem is, my spike_collision
box only works on the first one that I blit, and not the second one. Other than having to make a second collision box, how can I have the second spikes
to have its own collision box as well?
Here's the blit
code:
screen.blit(spikes, (spike_x, 500 - player_y + 476))
screen.blit(spikes, (spike_x + 200, 500 - player_y + 476))
Here's the collision-box code:
spike_collision = spikes.get_rect(topleft=(spike_x, 500 - player_y + 476))
Thanks.
1 answer
-
answered 2020-12-02 00:29
Kingsley
I'm assuming when you write "sprite", you mean a bitmap-sprite, and not a
pygame.sprite.Sprite
.It's probably best to maintain a sprite as a bitmap and a rectangle, then always draw the sprite at its rectangle, adjusting the rectangle to re-position the sprite, and using it for any collisions.
This could easily be done with list-pairs:
spike_image = pygame.image.load('spikes.png').convert_alpha() spike_rect = spike_image.get_rect( ) spikes_a = [ spike_image, spike_rect( top_left=( 100, 100 ) ) spikes_b = [ spike_image, spike_rect( top_left=( 200, 200 ) ) # ... screen.blit( spikes_a[0], spikes_a[1] ) screen.blit( spikes_b[0], spikes_b[1] ) # etc. if ( spikes_a[1].colliderect( player_rect ) ): print( "ouch!" )
However, it would behoove you to use a "proper" sprite object. Sure there's a bit of extra set-up, but it's repaid multiple times with ease of use:
class Spike( pygame.sprite.Sprite ): def __init__( self, position=( 0, 0 ) ): self.image = pygame.image.load('spikes.png').convert_alpha() self.rect = self.image.get_rect( top_left = position ) def moveTo( self, position ): self.rect = self.image.get_rect( top_left = position ) def moveBy( self, dx, dy ): self.rect.move_ip( dx, dy ) spike_a = Spike( ( 100, 100 ) ) spike_b = Spike( ( 200, 200 ) ) spike_a.draw( window ) # get this for free
There's a whole lot of useful group & collision functionality that comes along with using Sprite objects, it's well worth a read: https://www.pygame.org/docs/ref/sprite.html
See also questions close to this topic
-
Capture live output of a subprocess whithout blocking it
I am currently writing a script that will need at some point to capture the output of a heavy
grep
command.The problem is, I can't obtain decent performance from the command compared to just running in the shell. (It appears to be at least 2x slower, sometimes never ending). I'm grepping a whole partition (that's part of the purpose of the script), I know it's a slow operation, I'm talking about the huge difference between runtime in the shell and in my python script.
I've struggled with it for quite some time. Tried the queue library, threading, multiprocessing, gave asyncio a bit of a shot. I'm getting really lost.
I've shortened it to simplest form, here it is :
from subprocess import PIPE, Popen p = Popen(['grep', '-a', '-b', 'MyTestString', '/dev/sda1'], stdin = None, stdout = PIPE, stderr = PIPE, bufsize=-1) while True: output = p.stdout.readline() if output: print(output.strip())
So here, my
grep
command is way slower than in the shell. I've tried putting atime.sleep
in my main loop but it seems to be worse.Just a few more infos :
- There will be very few output from the command.
- The final goal would be to grab the output without blocking the main thread but one problem at time.
- Again, I know that my grep command is a heavy one
Thanks for your help if you have any idea or suggestion. I'm on the verge of despair :(
-
Invalid base64-encoded string: number of data characters (217) cannot be 1 more than a multiple of 4 error in python django
You see I am getting this incredibly weird error related to the no of characters in a string I guess. I am a bit new to django and I have never see such an weird error. I checked a few threads and according to that this is about encoding and decoding something which I really do not know how to resolve. Here is my code:
Request Method: GET Request URL: http://127.0.0.1:8000/profiles/myprofile/ Django Version: 2.1.5 Python Version: 3.9.0 Installed Applications: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'posts', 'profiles'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] Traceback: File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\sessions\backends\base.py" in _get_session 190. return self._session_cache During handling of the above exception ('SessionStore' object has no attribute '_session_cache'), another exception occurred: File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\exception.py" in inner 34. response = get_response(request) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py" in _get_response 126. response = self.process_exception_by_middleware(e, request) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py" in _get_response 124. response = wrapped_callback(request, *callback_args, **callback_kwargs) File "D:\PROJECTS\social\src\profiles\views.py" in my_profile_view 6. profile = Profile.objects.get(user=request.user) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\manager.py" in manager_method 82. return getattr(self.get_queryset(), name)(*args, **kwargs) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py" in get 390. clone = self.filter(*args, **kwargs) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py" in filter 844. return self._filter_or_exclude(False, *args, **kwargs) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py" in _filter_or_exclude 862. clone.query.add_q(Q(*args, **kwargs)) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py" in add_q 1263. clause, _ = self._add_q(q_object, self.used_aliases) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py" in _add_q 1284. child_clause, needed_inner = self.build_filter( File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py" in build_filter 1176. value = self.resolve_lookup_value(value, can_reuse, allow_joins) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py" in resolve_lookup_value 1009. if hasattr(value, 'resolve_expression'): File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\utils\functional.py" in inner 213. self._setup() File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\utils\functional.py" in _setup 347. self._wrapped = self._setupfunc() File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\auth\middleware.py" in <lambda> 24. request.user = SimpleLazyObject(lambda: get_user(request)) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\auth\middleware.py" in get_user 12. request._cached_user = auth.get_user(request) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\auth\__init__.py" in get_user 182. user_id = _get_user_session_key(request) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\auth\__init__.py" in _get_user_session_key 59. return get_user_model()._meta.pk.to_python(request.session[SESSION_KEY]) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\sessions\backends\base.py" in __getitem__ 55. return self._session[key] File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\sessions\backends\base.py" in _get_session 195. self._session_cache = self.load() File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\sessions\backends\db.py" in load 44. return self.decode(s.session_data) if s else {} File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\site-packages\django\contrib\sessions\backends\base.py" in decode 101. encoded_data = base64.b64decode(force_bytes(session_data)) File "C:\Users\aarti\AppData\Local\Programs\Python\Python39\lib\base64.py" in b64decode 87. return binascii.a2b_base64(s) Exception Type: Error at /profiles/myprofile/ Exception Value: Invalid base64-encoded string: number of data characters (217) cannot be 1 more than a multiple of 4 ```
-
Django register user
Hi i want to connect normal user using UserCreationForm and my own Creation when i post it with button my postgre auth_user and auth_users_register nthing add to database when i click on button my code:
forms.py
class RegisterForm(ModelForm): class Meta: model = Register fields = ['date_of_birth', 'image_add'] widgets = { 'date_of_birth': DateInput(attrs={'type': 'date'}) } class CreateUserForm(UserCreationForm): class Meta: model = User fields = ['username', 'email', 'password1', 'password2']
models.py
def validate_image(image_add): max_height = 250 max_width = 250 if 250 < max_width or 250 < max_height: raise ValidationError("Height or Width is larger than what is allowed") class Register(models.Model): user = models.OneToOneField( User, on_delete=models.CASCADE) date_of_birth = models.DateField( max_length=8, verbose_name="date of birth") image_add = models.ImageField( upload_to="avatars", verbose_name="avatar", validators=[validate_image])
views.py
class RegisterPageView(View): def get(self, request): if request.user.is_authenticated: return redirect('/') user_form = CreateUserForm(request.POST) register_form = RegisterForm(request.POST) return render(request, 'register.html', {'user_form': user_form, 'register_form': register_form}) def post(self, request): if request.method == 'POST': user_form = CreateUserForm(request.POST) register_form = RegisterForm(request.POST) if user_form.is_valid() and register_form.is_valid(): user_form.save() register_form.save(commit=False) user = user_form.cleaned_data.get('username') messages.success( request, 'Your account has been registered' + user) return redirect('login') user_form = CreateUserForm() register_form = RegisterForm() context = {'user_form': user_form, 'register_form': register_form} return render(request, 'register.html', context)
-
how can I solve Snake game in python code error?
I finished writing code for a simple snake game where the player controls the head of the snake this python code for Snake game but it is not run correctly, please help. I can not figure out how to what I have to solve in this code I also can not figure out how to move the body segments in the same pattern as the head of the snake (the part of the snake the user controls). Any suggestions?
import math import random import pygame import tkinter as tk from tkinter import messagebox class cube(object): rows = 20 w = 500 def __init__(self, start, dirnx = 1, dirny = 0, color=(255, 0, 0)): self.pos = start self.dirnx = 1 self.dirny = 0 self.color = color def move(self, dirnx, dirny): self.dirnx = dirnx self.dirny = dirny self.pos = (self.pos[0] + self.dirnx, self.pos[1] + self.dirny) def draw(self, surface, eyes=False): dis = self.w // self.rows i = self.pos[0] j = self.pos[1] pygame.draw.rect(surface, self.color, (i * dis + 1, j * dis + 1, dis - 2, dis - 2)) if eyes: centre = dis // 2 radius = 3 circleMiddle = (i * dis + centre - radius, j * dis + 8) circleMiddle2 = (i * dis + dis - radius * 2, j * dis + 8) pygame.draw.circle(surface, (0, 0, 0), circleMiddle, radius) pygame.draw.circle(surface, (0, 0, 0), circleMiddle2, radius) class snack(object): body = [] turns = {} def __init__(self, color, pos): self.color = color self.head = cube(pos) self.body.append(self.head) self.dirnx = 0 self.dirny = 1 def move(self): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() keys = pygame.key.get_pressed() for key in keys: if keys[pygame.K_LEFT]: self.dirnx = -1 self.dirny = 0 self.turns[self.head.pos[:]] = [self.dirnx, self.dirny] elif keys[pygame.K_RIGHT]: self.dirnx = 1 self.dirny = 0 self.turns[self.head.pos[:]] = [self.dirnx, self.dirny] elif keys[pygame.K_UP]: self.dirnx = 0 self.dirny = -1 self.turns[self.head.pos[:]] = [self.dirnx, self.dirny] elif keys[pygame.K_DOWN]: self.dirnx = 0 self.dirny = 1 self.turns[self.head.pos[:]] = [self.dirnx, self.dirny] for i, c in enumerate(self.body): p = c.pos[:] if p in self.turns: turn = self.turns[p] c.move(turn[0], turn[1]) if i == len(self.body) - 1: self.turns.pop(p) else: if c.dirnx == -1 and c.pos[0] <= 0: c.pos = (c.rows - 1, c.pos[1]) elif c.dirnx == 1 and c.pos[0] >= c.rows - 1: c.pos = (0, c.pos[1]) elif c.dirny == 1 and c.pos[1] >= c.rows - 1: c.pos = (c.pos[0], 0) elif c.dirny == -1 and c.pos[1] <= 0: c.pos = (c.pos[0], c.rows - 1) else: c.rows(c.dirnx, c.dirny) def reset(self, pos): self.head = cube(pos) self.body = [] self.body.append(self.head) self.turns = {} self.dirnx = 0 self.dirny = 1 def addcube(self): tail = self.body[-1] dx, dy = tail.dirnx, tail.dirny if dx == 1 and dy == 0: self.body.append(cube((tail.pos[0] - 1, tail.pos[1]))) elif dx == -1 and dy == 0: self.body.append(cube((tail.pos[0] + 1, tail.pos[1]))) elif dx == 0 and dy == 1: self.body.append(cube((tail.pos[0], tail.pos[1] - 1))) elif dx == 0 and dy == -1: self.body.append(cube((tail.pos[0], tail.pos[1] + 1))) self.body[-1].dirnx = dx self.body[-1].dirny = dy def draw(self, surface): for i, c in enumerate(self.body): if i == 0: c.draw(surface, True) else: c.draw(surface) def drawGrid(w, rows, surface): sizeBetween = w // rows x = 0 y = 0 for i in range(rows): x = x + sizeBetween y = y + sizeBetween pygame.draw.line(surface, (255, 255, 255), (x, 0), (x, w)) pygame.draw.line(surface, (255, 255, 255), (0, y), (w, y)) def redrawindow(surface): global rows, width, s, snack surface.fill((0, 0, 0)) s.drow(surface) snack.draw(surface) drawGrid(width, rows, surface) pygame.display.update() def randomSnack(rows, item): positions = item while True: x = random.randrange(rows) y = random.randrange(rows) if len(list(filter(lambda z : z.pos == (x, y), positions))) > 0: continue else: break return (x, y) def message_box(subject, content): root = tk.Tk() root.attributes("-topmost", True) root.withdraw() messagebox.showinfo(subject, content) try: root.destroy() except: pass def main(): global width, rows, snack width = 500 rows = 20 win = pygame.display.set_mode((width, width)) s = snack((255, 0, 0), (10, 10)) snack = cube(randomSnack(rows, s), color=(0, 255, 0)) flag = True clock = pygame.time.Clock() # Main loop while flag: pygame.time.delay(50) clock.tick(10) s.move() if s.body[0].pos == snack.pos: s.addcube() snack = cube(randomSnack(rows, s), color=(0, 255, 0)) for x in range(len(s.body)): if s.body[x].pos in list(map(lambda z : z.pos, s.body[x + 1 :])): print("Score: ", len(s.body)) #print(\"Score: \", len(s.body)) message_box("you lost!", "play again...") s.reset((10, 10)) break redrawindow(win) pass main() ```
-
How do I center objects so the rectangle is around my character?
I'm trying to make a small game using pygame (Just for fun) but I can't get my collision between objects right. So I decided to draw the collisions and noticed the collision is not around my character. Here's what I mean: The rectangles are the collisions
Here's my code:
import pygame pygame.init() winWidth = 400 winHeigth = 400 win = pygame.display.set_mode((winWidth, winHeigth)) pygame.display.set_caption("Pokemon copy") Items = [] walkUp = [pygame.image.load('Up1.png'), pygame.image.load('Up2.png'), pygame.image.load('Up3.png'), pygame.image.load('Up4.png'), pygame.image.load('Up5.png'), pygame.image.load('idleUp.png'), pygame.image.load('Up6.png'), pygame.image.load('Up5.png'), pygame.image.load('Up6.png')] walkDown = [pygame.image.load('D1.png'), pygame.image.load('D2.png'), pygame.image.load('D3.png'), pygame.image.load('D4.png'), pygame.image.load('D5.png'), pygame.image.load('idle.png'), pygame.image.load('D3.png'), pygame.image.load('D4.png'), pygame.image.load('D2.png')] walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('idleRight.png')] walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'), pygame.image.load('L4.png'), pygame.image.load('L3.png'), pygame.image.load('L2.png'), pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('idleLeft.png')] bg = pygame.image.load('Test.png') idle = [pygame.image.load('idle.png'), pygame.image.load("idleUp.png"), pygame.image.load("idleLeft.png"), pygame.image.load("idleRight.png")] myfont = pygame.font.SysFont("monospace", 15) clock = pygame.time.Clock() class trainer(): def __init__(self, x, y): self.x = x self.y = y self.width = 32 self.heigth = 32 self.enemy = pygame.image.load('idleE.png') self.rect = self.enemy.get_rect() def draw(self, win): win.blit(self.enemy, (self.x, self.y)) class player(): def __init__(self, x, y, width, heigth): self.x = x self.y = y self.width = width self.heigth = heigth self.vel = 5 self.left = False self.right = False self.up = False self.down = False self.walkCount = 0 self.stamina = 100 self.Event = pygame.USEREVENT+1 self.previous = "right" self.player = pygame.image.load("idle.png") self.rect = self.player.get_rect(center=(self.x, self.y)) self.pos = self.x, self.y def draw(self, win): if self.walkCount + 1 >= 27: self.walkCount = 0 if self.up: self.rect.center = self.x, self.y win.blit(walkUp[self.walkCount//3], (self.x, self.y)) self.walkCount += 1 elif self.down: self.rect.center = self.x, self.y win.blit(walkDown[self.walkCount//3], (self.x, self.y)) self.walkCount += 1 elif self.right: self.rect.center = self.x, self.y win.blit(walkRight[self.walkCount//3], (self.x, self.y)) self.walkCount += 1 elif self.left: self.rect.center = self.x, self.y win.blit(walkLeft[self.walkCount//3], (self.x, self.y)) self.walkCount += 1 else: if self.previous == "up": win.blit(idle[1], (self.x, self.y)) elif self.previous == "down": win.blit(idle[0], (self.x, self.y)) elif self.previous == "left": win.blit(idle[2], (self.x, self.y)) elif self.previous == "right": win.blit(idle[3], (self.x, self.y)) def Collision(self, Potion): if self.rect.colliderect(Potion.rect): return True else: return False def getPos(self): return self.x, self.y class usableItems(): def __init__(self, x, y): self.usable = True self.x = x self.y = y class potion(usableItems): def __init__(self, usable, x, y): super().__init__(x, y) self.heal = 20 self.potion = pygame.image.load("Potion.png") self.rect = self.potion.get_rect(center=(self.x, self.y)) def draw(self, win): self.rect.center = self.x, self.y win.blit(self.potion, (self.x, self.y)) def write(text, x, y, color): text = myfont.render(text, 4, pygame.Color(color)) text_rect = text.get_rect(center=(winWidth//2, y)) return text, text_rect def inventory(): Inventory = True while Inventory: clock.tick(27) for event in pygame.event.get(): if event.type == pygame.QUIT: Inventory = False keys = pygame.key.get_pressed() if keys[pygame.K_ESCAPE]: Inventory = False redrawInventoryWindow(Items) def redrawInventoryWindow(items): win.fill((0, 0, 0)) if len(items) == 0: message = "You currently have no items!" text, text_rect = write(message, 10, 70, (255, 255, 255)) win.blit(text, text_rect) else: distance = 10 for item in items: text2, text_rect2 = write(item, 0, distance, (255, 255, 255)) distance += 25 win.blit(text2, text_rect2) pygame.display.update() def redrawGameWindow(character, trainer1, Potion): win.fill((255, 255, 255)) text = "Stamina: " + str(int(character.stamina)) + "/100" label = myfont.render(text, 1, (0, 0, 0)) win.blit(label, (0, winHeigth - 50)) character.draw(win) pygame.draw.rect(win, (0, 255, 0), character, 3, 1) trainer1.draw(win) Potion.draw(win) pygame.draw.rect(win, (200, 55, 0), Potion, 3, 2) pygame.display.update() def game(): character = player(50, 50, 32, 32) trainer1 = trainer(300, 360) Potion = potion(True, 150, 150) run = True while run: clock.tick(27) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() if keys[pygame.K_i]: inventory() elif keys[pygame.K_LCTRL] and character.stamina > 0: vel = 7.5 pygame.time.set_timer(character.Event, 1000) character.stamina -= 1 elif not keys[pygame.K_LCTRL] and character.stamina < 100: vel = 5 pygame.time.set_timer(character.Event, 1000) character.stamina += 0.5 else: vel = 5 if keys[pygame.K_LEFT] and character.x > 0: character.previous = "left" character.x -= vel character.left = True character.right = False character.up = False character.down = False elif keys[pygame.K_RIGHT] and character.x < winWidth - character.width: character.previous = "right" character.x += vel character.right = True character.left = False character.up = False character.down = False elif keys[pygame.K_UP] and character.y > 0: character.previous = "up" character.y -= vel character.up = True character.down = False character.left = False character.right = False elif keys[pygame.K_DOWN] and character.y < winHeigth - character.heigth: character.previous = "down" character.y += vel character.down = True character.up = False character.left = False character.right = False else: character.right = False character.left = False character.up = False character.down = False character.walkCount = 0 if character.Collision(Potion): if keys[pygame.K_DOWN]: character.y -= vel elif keys[pygame.K_UP]: character.y += vel elif keys[pygame.K_LEFT]: character.x += vel elif keys[pygame.K_RIGHT]: character.x -= vel vel = 0 redrawGameWindow(character, trainer1, Potion) pygame.quit() game()
Note that I'm pretty new to programming so I'm aware there's a lot to improve in my code.
-
Can you text wrap displayed text in pygame?
I'm working on a project in pygame and the text is supposed to display a character's speech. I've got the text displayed, but it runs off the screen. I tried one way to text wrap, but it didn't move to the next line, so it just overlapped on the same line. I don't know if there is some sort of boundary or border I can set or text wrap. I could only find things for python, not pygame.
Here's what I have for the text
white = (255,255,255) def text_objects(text, font): textSurface = font.render(text, True, white) return textSurface, textSurface.get_rect() def words(text): largeText = pygame.font.Font('freesansbold.ttf', 18) TextSurf, TextRect = text_objects((text), largeText) TextRect = ((13), (560)) screen.blit(TextSurf, TextRect) ` pygame.display.update() words("This is just filler. Yup, filler to test if this will run off the screen. And apparently \n doesn't start a new line... Doo duh doo. Bum Dum pssst.")
-
Collision detection with javascript
Hi i have to use this code ina project of mine - where i check for the collision of a ball and a rectangle.
function collision(b,p){ // b is ball p is padlet b.top = b.y - b.radius; b.bottom = b.y + b.radius; b.left = b.x - b.radius; b.right = b.x + b.radius; p.top = p.y; p.bottom = p.y + p.height; p.left = p.x; p.right = p.x + p.width; // collision verification return b.right > p.left && b.bottom > p.top && b.left < p.right && b.top < b.bottom; }
My question is if i check (like it says in the tutorial) with && all of the 4 values must be true so that the results says true. But if the ball only hits the rectangle on its surface and not the bottom or top it should say false. Why use AND here and not OR ? I hope my question is clear. Thanks for all your help.
-
Collision detection between OBB and spheroid without SAT?
I have a working OBB vs. OBB collision detection using SAT.
I now want to have OBB vs. any kind of sphere (spheroid). I have found very easy methods to test OBB Vs. spheres, but is there a way to test OBBs against spheroids?
My (expensive) SAT approach would be to create a coarse version of a sphere with about 16 normals and and then run the typical SAT test. But this way I would not get a realistically looking collision response.
Does anyone have a good source with example code for me to point me in the right direction?
-
OnTriggerEnter2D not working when I set collider.isTrigger to true via script
I have two objects, both with rigidbodies and with colliders (one has box collider 2D and the other, circle collider 2D).
Initially I let both be normal colliders, but when a condition is met, the square one is set to be a trigger via script (
collider.isTrigger = true;
).When I do this and the circle collider goes through the box collider (which is now a trigger), the method
OnTriggerEnter2D
isn't called. I tried to set the box collider to be a trigger from the beginning and it works. Why doesn't it work when it is set to trigger via script?
I was able to make it work by doing this:
bool isTrigger = evaluate_condition(); if(collider.isTrigger != isTrigger()){ collider.isTrigger = isTrigger; collider.enabled = false; collider.enabled = true; }
Turning it off and on after changing its value made it work, but it looks like a workaround.
-
Matter.js creating custom polygon using an svg
I have an SVG that I would like to use to make a collision object using mattter.js...I have done this successfully with rectangles etc. but im stuck creating a custom polygon. Im not sure how to get from the svg or vertex data to adding it to the world.
Here is the svg data and image converted to png. It will be no fill as it is going to be the collision detection for an object.
<path class="cls-1" d="M880.17,329.09,873.78,364,877,368.9l3.2,4.91,13.27,8.36v29l-3,14.25-16.71,9.83-24.57,24.08-11.3,25.55-2,41.28,10.32,201.48,11.3,17.69,7.13,9.83L885.57,763l48.16,7.37h47.18l54.54-6.39,20.15-8.35,21.13-25.06,2.46-18.19,7.86-213.27L1082.63,476l-10.32-19.17-17.69-18.67-20.15-12.78-3-1L1031,380.2l9.83-5.9,7.86-6.88,1.48-4.91-6.88-36.86-5.41-6.87-11.3-6.88-9.83-2.95-3.93,80.59,3.44,33.91,5.4,4.42L1033,442.61l27,22.11,5.41,10.32,5.9,20.64,2,25.06-6.39,155.78-1.47,43.74-7.37,12.28-18.18,14.74-16.71,3.94-19.66,3.93-24.08,2.45-27-.49L919,754.66l-39.81-9.83L864,731.56l-5.9-9.83-2.45-8.84-5.9-126.3L848.23,506l6.38-25.55,9.83-20.15,14.74-15.23,16.71-13.27,7.37-5.41,3-12.77,3.44-22.12s-2-16.7-2-19.16-1.48-48.65-1.48-48.65L905.72,309l-17.2,8.35-6.39,6.39Z" transform="translate(-835.94 -308.95)"/>
im to the point I might just use lots of rectangles to make the collision detection but this seems cumbersome and a bit silly tbh.
Help apprectiated,
Thanks
-
How to avoid collision among turtles in netlogo?
I am trying to simulate the movement of turtles in netlogo where:
1)Turtles avoid collision with each other, if the separation between the turtles get too small, they move away/repel each other.
2)Turtles also avoid collision with obstacles in the environment. If the obstacle is to the right, the turtle move left and vice versa.
So far I have been able to create the rectangular obstacle and randomised the movement of turtles. But I cant figure out how to write the collision avoidance code. Any help will be hugely appreciated.
Thank you very much!
to setup clear-all reset-ticks set-default-shape turtles "bird" draw-obstacle create-turtles 5 ;; create some turtles [randomise] ;; place turtles randomly ask turtles [ set shape "bird" set size 2 set color green ] end to draw-obstacle ask patches with [pxcor <= 10 and pxcor > 0 and pycor < 0 and pycor >= -5] [set pcolor red] end to randomise setxy random-xcor random-ycor if pcolor = red ; if it's on the obstacle... [ randomise ] ; ...try again end to move ask turtles [ if-else moveright? [right random 10][left random 10] forward random 5 left 15 ] end to-report moveright? report random 5 = 1 end
-
No bounce with 2 contacts point
and sorry in advance for my bad level in english :/
I have the same issue as the one on this topic :
I must separate linear and angular impulse resolution, else I don't have bounce with 2 contacts point. I don't understand why because I am using the same way like Matter.js
If I solve my OBB like an AABB its ok, my box bounce
If I multiply my scalar impulse by (numberOfcontact * numberOfcontact) its ok only with elasticity ==1.
I really don't understand why I need to do some tricks. All papers, all tutorials, all physics engine works but for me, nothing.
public void SolveVelocity(Pair _pair) { if (!_pair.tk_isActive) return; Vector3 rpA_; Vector3 rpB_; //Normal Impulse float linearImpulse_X; float linearImpulse_Y; float angularImpulse_X; float angularImpulse_Y; //tangent Impulse float tangentLinearImpulse_X = 0; float tangentLinearImpulse_Y = 0; float tangentAngularImpulse_X = 0; float tangentAngularImpulse_Y = 0; Vector3 tangent; Vector3 _normal = _pair.tk_normal; int _count = _pair.tk_count; float J_Scalar; float JT_Scalar; float _miA = _pair.tk_bodyA.massI_; float _miB = _pair.tk_bodyB.massI_; float _iA = _pair.tk_bodyA.inertiaI_; float _iB = _pair.tk_bodyB.inertiaI_; float rv; float _uS = (float)Math.Sqrt(_pair.tk_bodyA.uS_ * _pair.tk_bodyA.uS_ + _pair.tk_bodyB.uS_ * _pair.tk_bodyB.uS_); float _uC = (_pair.tk_bodyA.uC_ * _pair.tk_bodyA.uC_ + _pair.tk_bodyB.uC_ * _pair.tk_bodyB.uC_)/2.0f; float _elasticity = (_pair.tk_bodyA.tk_elasticity + _pair.tk_bodyB.tk_elasticity) / 2.0f; Vector3 _positionA = _pair.tk_bodyA.position_; Vector3 _positionB = _pair.tk_bodyB.position_; Vector3 _velocityA = _pair.tk_bodyA.velocity_; float _omegaA = _pair.tk_bodyA.omega_; Vector3 _velocityB = _pair.tk_bodyB.velocity_; float _omegaB = _pair.tk_bodyB.omega_; for (int c = 0; c < _count; c++) { rpA_ = _pair.tk_contacts[c].tk_position - _positionA; rpB_ = _pair.tk_contacts[c].tk_position - _positionB; Vector3 _relativeVelocity = (_velocityB + new Vector3(rpB_.Y * -_omegaB, rpB_.X * _omegaB, 0)) - (_velocityA + new Vector3(rpA_.Y * -_omegaA, rpA_.X * _omegaA, 0)); float _countInv = 1.0f / (_count); float _relativeNormalVelocity = _relativeVelocity.X * _normal.X + _relativeVelocity.Y * _normal.Y; rv = _relativeNormalVelocity; #region Normal J_Scalar = (1 + _elasticity) * _relativeNormalVelocity;// * _count*_count float crossNA = (rpA_.X * _normal.Y) - (rpA_.Y * _normal.X); float crossNB = (rpB_.X * _normal.Y) - (rpB_.Y * _normal.X); float _crossASqr = crossNA * crossNA * _iA; float _crossBSqr = crossNB * crossNB * _iB; float invSum = _miA + _miB + _crossASqr + _crossBSqr; float invShareSum = _countInv / invSum; float J = J_Scalar * invShareSum; if(rv > 0) { _pair.tk_contacts[c].tk_normalImpulse = 0; } else { var contactNormalImpulse = _pair.tk_contacts[c].tk_normalImpulse; _pair.tk_contacts[c].tk_normalImpulse = _pair.tk_contacts[c].tk_normalImpulse + J; if (_pair.tk_contacts[c].tk_normalImpulse < 0) _pair.tk_contacts[c].tk_normalImpulse = 0; J = _pair.tk_contacts[c].tk_normalImpulse - contactNormalImpulse; } /* if(contactNormalImpulse !=0) { int i = 0; J += i; }*/ linearImpulse_X = (J) * _normal.X; linearImpulse_Y = (J) * _normal.Y; angularImpulse_X = (J) * _normal.X; angularImpulse_Y = (J) * _normal.Y; #endregion #region Impulse //if (rv > 0) { Vector2 totalImpulseLinear = new Vector2(linearImpulse_X, linearImpulse_Y) + 0 * new Vector2(tangentLinearImpulse_X, tangentLinearImpulse_Y); Vector2 totalImpulseAngular = new Vector2(angularImpulse_X, angularImpulse_Y) + 0 * new Vector2(tangentAngularImpulse_X, tangentAngularImpulse_Y); if (!(_pair.tk_bodyA.is_Sleeping || _pair.tk_bodyA.Is_Static)) { _pair.tk_bodyA.oldPosition_.X -= totalImpulseLinear.X * _miA; _pair.tk_bodyA.oldPosition_.Y -= totalImpulseLinear.Y * _miA; _pair.tk_bodyA.oldTheta_ -= (rpA_.X * totalImpulseAngular.Y - rpA_.Y * totalImpulseAngular.X) * _iA; } if (!(_pair.tk_bodyB.is_Sleeping || _pair.tk_bodyB.Is_Static)) { _pair.tk_bodyB.oldPosition_.X += totalImpulseLinear.X * _miB; _pair.tk_bodyB.oldPosition_.Y += totalImpulseLinear.Y * _miB; _pair.tk_bodyB.oldTheta_ += (rpB_.X * totalImpulseAngular.Y - rpB_.Y * totalImpulseAngular.X) * _iB; } } #endregion } }
EDIT : I don't have presolve velocity method in my code, Do you think is it the problem? My sat implementation is not conventional at all, not like box2d or box2d like (a lot of physics engine start with box2D lite then box2D). Not sure because if I test with no positional correction and only one iteration for velocity solver it's the same. It's very very strange and hard for me to understand what happened here. All papers are in english, french forum never help at all, we don't have the same education xd. I just want to know why, after that, I hope, I can solve this issue alone Thx
Thank you in advance for your advise
-
Pygame surface resize
When I make window resize, surfaces boundaries not resizing as window do. Text render at main surface in starting window boundaries (600x340). Why? Also a render images (I cut this code part to simplify problem) as background and it render normally according new window's boundaries (I blit direct to main surface(win)). So problem I think is in additional surfaces (text_surf). Why they don't RESIZABLE?
import pygame import time pygame.init() run=True screen_width=600 screen_height=340 black=(0,0,0) white=(255,255,255) font1=pygame.font.SysFont("arial",45) text_press=font1.render("press any key to play!",0,(100,0,0)) win=pygame.display.set_mode((screen_width,screen_height),pygame.RESIZABLE) text_surf=pygame.Surface((screen_width,screen_height),pygame.RESIZABLE) background=pygame.Surface((screen_width,screen_height),pygame.RESIZABLE) while run==True: pygame.time.delay(16) for event in pygame.event.get(): if event.type == pygame.QUIT: run=False if event.type == pygame.VIDEORESIZE: surface = pygame.display.set_mode((event.w, event.h),pygame.RESIZABLE) screen_width=event.w screen_height=event.h win.fill((white)) background.fill((120,120,100)) win.blit(background,(0,0)) text_surf.fill((black)) text_surf.blit(text_press, (screen_width*0.5-50,screen_height*0.5+100)) text_surf.set_colorkey(black) text_surf.set_alpha(150) win.blit(text_surf,(0,0)) pygame.display.update() pygame.quit()
-
Double buffering in x86 VGA
To bring back some memories I decided to sit down and code a little assembler game in VGA mode 13h - until the point I realized the visual output is flickering as hell.
At first I suspected it might be my clearscreen routine. Indeed by using a STOSW instead of writing a single byte to the video memory a time the flickering is less annoying but still present.
Digging some further I recalled I might have to wait for the vertical retrace and update my screen right after but that didn't make things much better.
So the final solution I'm aware of goes a little like this:
- do all graphical operations - clearing the screen, setting pixels - on a separate memory region
- wait for the vertical retrace
- copy the memory over to the video memory
The theory is of course simple but I just can't figure out how to do my writes to the buffer and ultimately blit it into the video memory!
Here's a striped-down - though working - snippet of my code written for TASM:
VGA256 EQU 13h TEXTMODE EQU 3h VIDEOMEMORY EQU 0a000h RETRACE EQU 3dah .MODEL LARGE .STACK 100h .DATA spriteColor DW ? spriteOffset DW ? spriteWidth DW ? spriteHeight DW ? enemyOneA DB 0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0 spriteToDraw DW ? buffer DB 64000 dup (0) ; HERE'S MY BUFFER .CODE Main: MOV AX,@DATA; MOV DS,AX MOV AH,0 MOV AL,VGA256 INT 10h CLI MainLoop: MOV DX,RETRACE Vsync1: IN AL,DX TEST AL,8 JZ Vsync1 Vsync2: IN AL,DX TEST AL,8 JNZ Vsync2 CALL clearScreen CALL updateSprites JMP MainLoop mov AH,1 int 21h mov AH,0 mov AL,TEXTMODE int 10h ; program end clearScreen PROC NEAR MOV BX,VIDEOMEMORY MOV ES,BX XOR DI,DI MOV CX,320*200/2 MOV AL,12 MOV AH,AL REP STOSW RET clearScreen ENDP drawSprite PROC NEAR MOV DI,0 MOV CX,0 ForLoopA: PUSH CX MOV SI,CX MOV CX,0 ForLoopB: MOV BX,spriteToDraw MOV AL,[BX+DI] CMP AL,0 JE DontDraw MOV BX,spriteColor MUL BX PUSH SI PUSH DI PUSH AX MOV AX,SI MOV BX,320 MUL BX MOV BX,AX POP AX POP DI ADD BX,CX ADD BX,spriteOffset MOV SI,BX MOV BX,VIDEOMEMORY MOV ES,BX MOV ES:[SI],AL POP SI DontDraw: INC DI INC CX CMP CX,spriteWidth JNE ForLoopB POP CX INC CX CMP CX,spriteHeight JNE ForLoopA RET drawSprite ENDP updateSprites PROC NEAR MOV spriteOffset,0 MOV spriteColor,15 MOV spriteWidth,16 MOV spriteHeight,8 MOV spriteOffset,0 MOV spriteToDraw, OFFSET enemyOneA CALL drawSprite RET updateSprites ENDP END Main
-
How to make an imported module blit onto a surface from the main script?
In my main file I have a surface called
win
. I import a module like sofrom draw import *
.def draw(image,x,y): win.blit(image,(x,y))
This is a function from
draw
. It doesn't work becausewin
is not defined. How to make it defined?