Pygame: Cell Physics

匿名 (未验证) 提交于 2019-12-03 00:56:02

问题:

I'm making a dumbed down version of agar.io.

Currently, the cell is placed upon a grid background like in the game. The cell eats food, but only a smaller square section inside the circle actually eats the food (in my program), which is noticeable when you are big enough. Also, when you press the spacebar, it would split the cell into 2 smaller parts, which after a few seconds would merge back. This would require a KEY_UP and K_SPACE event, but I am not sure how to implement that. Also, once you are around a mass of 34, you can press w to shoot a tiny bit of yourself, a smaller cell at around 14 set mass.

I attempted to slow down the cell once it reaches a certain mass with a bunch of if statements. In the game, it slows down naturally. Here and Here are sources depicting the math used in the game.

Here is the code I have:

import pygame, sys, random from pygame.locals import *  # set up pygame pygame.init() mainClock = pygame.time.Clock()  # set up the window width = 800 height = 600 thesurface = pygame.display.set_mode((width, height), 0, 32) pygame.display.set_caption('')  bg = pygame.image.load("bg.png") basicFont = pygame.font.SysFont('calibri', 36)  # set up the colors BLACK = (0, 0, 0) GREEN = (0, 255, 0) WHITE = (255, 255, 255) BLUE = (0, 0, 255) size = 10 playercolor = BLUE # set up the player and food data structure foodCounter = 0 NEWFOOD = 35 FOODSIZE = 10 player = pygame.draw.circle(thesurface, playercolor, (60, 250), 40) foods = [] for i in range(20):     foods.append(pygame.Rect(random.randint(0, width - FOODSIZE), random.randint(0, height - FOODSIZE), FOODSIZE, FOODSIZE))  # set up movement variables moveLeft = False moveRight = False moveUp = False moveDown = False  MOVESPEED = 10  score = 0 # run the game loop while True:     # check for events     for event in pygame.event.get():         if event.type == QUIT:             pygame.quit()             sys.exit()         if event.type == KEYDOWN:             # change the keyboard variables             if event.key == K_LEFT or event.key == ord('a'):                 moveRight = False                 moveLeft = True             if event.key == K_RIGHT or event.key == ord('d'):                 moveLeft = False                 moveRight = True             if event.key == K_UP or event.key == ord('w'):                 moveDown = False                 moveUp = True             if event.key == K_DOWN or event.key == ord('s'):                 moveUp = False                 moveDown = True         if event.type == KEYUP:             if event.key == K_ESCAPE:                 pygame.quit()                 sys.exit()             if event.key == K_LEFT or event.key == ord('a'):                 moveLeft = False             if event.key == K_RIGHT or event.key == ord('d'):                 moveRight = False             if event.key == K_UP or event.key == ord('w'):                 moveUp = False             if event.key == K_DOWN or event.key == ord('s'):                 moveDown = False             if event.key == ord('x'):                 player.top = random.randint(0, height - player.height)                 player.left = random.randint(0, width - player.width)          if event.type == MOUSEBUTTONUP:             foods.append(pygame.Rect(event.pos[0], event.pos[1], FOODSIZE, FOODSIZE))      foodCounter += 1     if foodCounter >= NEWFOOD:         # add new food         foodCounter = 0         foods.append(pygame.Rect(random.randint(0, width - FOODSIZE), random.randint(0, height - FOODSIZE), FOODSIZE, FOODSIZE))     if 100>score>50:         MOVESPEED = 9     elif 150>score>100:         MOVESPEED = 8     elif 250>score>150:         MOVESPEED = 6     elif 400>score>250:         MOVESPEED = 5     elif 600>score>400:         MOVESPEED = 3     elif 800>score>600:         MOVESPEED = 2     elif score>800:         MOVESPEED = 1     # move the player     if moveDown and player.bottom < height:         player.top += MOVESPEED     if moveUp and player.top > 0:         player.top -= MOVESPEED     if moveLeft and player.left > 0:         player.left -= MOVESPEED     if moveRight and player.right < width:         player.right += MOVESPEED     thesurface.blit(bg, (0, 0))      # draw the player onto the surface     pygame.draw.circle(thesurface, playercolor, player.center, size)      # check if the player has intersected with any food squares.     for food in foods[:]:         if player.colliderect(food):             foods.remove(food)             size+=1             score+=1      # draw the food     for i in range(len(foods)):         pygame.draw.rect(thesurface, GREEN, foods[i])      printscore = basicFont.render("Score: %d" % score, True, (0,0,0))     thesurface.blit(printscore, (495, 10))      pygame.display.update()     # draw the window onto the thesurface     pygame.display.update()     mainClock.tick(80) 

Once again, here are the issues I want to solve.

  • I want the cell to split into 2 parts when the spacebar is pressed. This can happen only if the cell is above 30 size.
  • I want the cell to spit out a fraction of itself when you press W. The part that is spit out will be a set 15 mass. The original cell will be 15 smaller. Hitting W multiple times will allow multiple small balls to be spit out, until the original cell's mass is 20, in which case it isn't viable to spit out any more.

Edit: I have tried doing the splitting thing:

if event.key == K_SPACE:     pygame.draw.circle(thesurface, playercolor,(player.centerx,player.centery),int(size/2))     pygame.draw.circle(thesurface, playercolor,(player.centerx+size,player.centery+size),int(size/2)) 

After putting the above code in, and running the program and pressing the spacebar, nothing happens. The program acts like I never pressed it.

回答1:

You will need to move the .draw call to after the call to blit your background else it will cover your player's circle. I use a boolean flag here which you could then use with a timer to toggle whenever you want the split to turn off:

import pygame, sys, random from pygame.locals import *  # set up pygame pygame.init() mainClock = pygame.time.Clock()  # set up the window width = 800 height = 600 thesurface = pygame.display.set_mode((width, height), 0, 32) pygame.display.set_caption('')  bg = pygame.image.load("bg.png") basicFont = pygame.font.SysFont('calibri', 36)  # set up the colors BLACK = (0, 0, 0) GREEN = (0, 255, 0) WHITE = (255, 255, 255) BLUE = (0, 0, 255) size = 10 playercolor = BLUE # set up the player and food data structure foodCounter = 0 NEWFOOD = 35 FOODSIZE = 10 splitting = False player = pygame.draw.circle(thesurface, playercolor, (60, 250), 40) foods = [] for i in range(20):     foods.append(pygame.Rect(random.randint(0, width - FOODSIZE), random.randint(0, height - FOODSIZE), FOODSIZE, FOODSIZE))  # set up movement variables moveLeft = False moveRight = False moveUp = False moveDown = False  MOVESPEED = 10  score = 0 # run the game loop while True:     # check for events     for event in pygame.event.get():         if event.type == QUIT:             pygame.quit()             sys.exit()         if event.type == KEYDOWN:             # change the keyboard variables             if event.key == K_LEFT or event.key == ord('a'):                 moveRight = False                 moveLeft = True             if event.key == K_RIGHT or event.key == ord('d'):                 moveLeft = False                 moveRight = True             if event.key == K_UP or event.key == ord('w'):                 moveDown = False                 moveUp = True             if event.key == K_DOWN or event.key == ord('s'):                 moveUp = False                 moveDown = True             if event.key == K_SPACE and size >= 30: # XXX if size and space set splitting to true                 splitting = True         if event.type == KEYUP:             if event.key == K_ESCAPE:                 pygame.quit()                 sys.exit()             if event.key == K_LEFT or event.key == ord('a'):                 moveLeft = False             if event.key == K_RIGHT or event.key == ord('d'):                 moveRight = False             if event.key == K_UP or event.key == ord('w'):                 moveUp = False             if event.key == K_DOWN or event.key == ord('s'):                 moveDown = False             if event.key == ord('x'):                 player.top = random.randint(0, height - player.height)                 player.left = random.randint(0, width - player.width)          if event.type == MOUSEBUTTONUP:             foods.append(pygame.Rect(event.pos[0], event.pos[1], FOODSIZE, FOODSIZE))      foodCounter += 1     if foodCounter >= NEWFOOD:         # add new food         foodCounter = 0         foods.append(pygame.Rect(random.randint(0, width - FOODSIZE), random.randint(0, height - FOODSIZE), FOODSIZE, FOODSIZE))     if 100>score>50:         MOVESPEED = 9     elif 150>score>100:         MOVESPEED = 8     elif 250>score>150:         MOVESPEED = 6     elif 400>score>250:         MOVESPEED = 5     elif 600>score>400:         MOVESPEED = 3     elif 800>score>600:         MOVESPEED = 2     elif score>800:         MOVESPEED = 1     # move the player     if moveDown and player.bottom < height:         player.top += MOVESPEED     if moveUp and player.top > 0:         player.top -= MOVESPEED     if moveLeft and player.left > 0:         player.left -= MOVESPEED     if moveRight and player.right < width:         player.right += MOVESPEED     thesurface.blit(bg, (0, 0))      # draw the player onto the surface     if not splitting: # XXX check the split flag and draw accordingly...         pygame.draw.circle(thesurface, playercolor, player.center, size)     else:         pygame.draw.circle(thesurface, playercolor,(player.centerx,player.centery),int(size/2))         pygame.draw.circle(thesurface, playercolor,(player.centerx+size,player.centery+size),int(size/2))     # check if the player has intersected with any food squares.     for food in foods[:]:         if player.colliderect(food):             foods.remove(food)             size+=1             score+=1      # draw the food     for i in range(len(foods)):         pygame.draw.rect(thesurface, GREEN, foods[i])      printscore = basicFont.render("Score: %d" % score, True, (0,0,0))     thesurface.blit(printscore, (495, 10))      pygame.display.update()     # draw the window onto the thesurface     pygame.display.update()     mainClock.tick(80) 

You will definitely want to make this into a few functions and/or classes too.



文章来源: Pygame: Cell Physics
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!