I am trying to make a game with similar concepts to the snake game for a project. I want to make it such that when the player "eats" the "food", another one appears randomly elsewhere.
I have tried several codes from here and other sources but I can't seem to get them to run. There will always be different errors.
This is the code that I am using for now. I got it from online and it worked for the person but it doesn't work for me. My guess is that list.remove might be the problem with this code but I don't know how to edit it:
food_collide = pygame.sprite.spritecollide(player,food_list,False)
for food in food_collide:
score += 1
food_list.remove(food)
all_sprite_list.remove(food)
food.update()
all_sprite_list.update()
Seems to me that you never create a new instance of Food() after you kill the previous one (when eated by the player). So obviously the game doesn't spawn a new food.
This quick fix of the for food in food_collide should works:
for food in food_collide:
score += 1
food_list.remove(food)
newfood = Food()
food_list.add(newfood)
all_sprite_list.add(newfood)
all_sprite_list.remove(food)
food_list.update()
all_sprite_list.update()
Related
I am currently making 2048 and am having trouble with creating a new block whenever a move is made.
I made a list storing all the blocks there are, within the list there objects:
class Blocks:
~~~~~~~ code ~~~~~~~~~
block1 = Blocks()
block2 = Blocks()
block_list = [block1, block2]
The issue is that it works perfectly when the blocks are pre-written, but I can not make a new block while the game is already running, is there any way to do this? Thank you in advance, stay safe :)
I don't see why this would not be possible. You should simply be able append a new block to your block_list:
block_n = Blocks()
block_list.append(block_n)
You place this in your game loop where you detect when a move is made.
Where you blit I assume you go through the block_list and blit all the blocks to the screen? Also make sure to always update the screen with pygame.display.flip().
I suppose that you need "Reflection" in python. Reflection can get type of instance, create instance of type during code runtime.
You can get some inspirations from the question Can you use a string to instantiate a class? or the article Classes and Class Creation
I'm starting out with python, I only know the basics and I want to create a top-down type of game to the one I have currently.
I've tried some solutions on the internet and sadly, none of them has worked for me.
As I said, I can't find a working solution as of right now but I've tried a few, including this one
How can I make the player “look” to the mouse direction? (Pygame / 2D).
I'm also using pygame, forgot to mention that. I also have pgzero if you need to know.
This code works and it just places a new actor when you click on it, but I want to have a type of 'character' with a weapon that can move around and 'look' at the mouse.
import pgzrun
from random import randint
apple = Actor("apple")
score = 0
def draw():
screen.clear()
apple.draw()
def place_apple():
apple.x = randint(10, 800)
apple.y = randint(10, 600)
def on_mouse_down(pos):
global score
if apple.collidepoint(pos):
print("Good Shot!")
place_apple()
score = score + 1
print(score)
else:
print("You Missed!")
quit()
pgzrun.go()
I just need to know how to make the picture 'look' at the cursor and then what each bit does to I know hot to do it for next time.
The first time I tried with the link given above, It returned a positional argument and I can't figure it out.
I may have messed something up when I put in the fixed code but I don't know, I was kind of tired.
I am not sure what exactly you mean with "aim at the mouse" but I guess you want to change the drawn image according to some program logic.
You do this simply setting the image property of the Actor to another picture, eg. when you click on the image, see my modified version of your
def on_mouse_down(pos):
global score
if apple.collidepoint(pos):
print("Good Shot!")
place_apple()
score = score + 1
apple.image = "cactus" # ADDED: Change the image if your click hit the Actor
print(score)
else:
print("You Missed!")
quit()
You can find the documentation of the complete API (function calls and properties) here:
https://pygame-zero.readthedocs.io/en/stable/builtins.html
I'm making my own game with Python2.7 through the pygame libraby.
It's a 1v1 combat game where players use the same keyboard.
The game works in a main loop that is repeated 60times per second, every time the loop is executed, it calculates lots of things e.g the position, problem is that I have 2 players, so I have to write the lines two times.
Example here:
if p1direction == 'right' and p1XS < p1Attributes[1]: p1XS +=
p1Attributes[0]
and:
if p2direction == 'right' and p2XS < p2Attributes[1]: p2XS +=
p2Attributes[0]
See the differences p1 and p2, they are variables that belongs to Player 1 and Player 2 respectively.
I just want to find a solution to not write every time the same lines just for p2. I was thinking about the for function so I can even add players easly but I don't know how to do it in this case...
Can someone help me ? :) Please
Create a class player.
Then add the attributes of each player to the class.
Instantiate your class with player 1 and 2.
class Player():
direction = "right"
etc.
def shoot(self):
if self.direction == "right"
shoot_right()
playerOne = Player()
playerTwo = Player()
direction = playerOne.direction
If you haven't used classes yet, I wouldn't recommend using them though. Inheritance can get pretty nasty...
Hope that helped,
Narusan
EDIT:
If you haven't used classes in Python yet, I recommend catching up there first and then continuing your game development. I have programmed several games in pygame as well, and classes come in very hand. In fact, it is almost impossible to create pygame games without using proper classes (or endless if-clauses and for-loops that will make everything super slow).
Wish you all the best of luck
How about storing your variables(for example p1direction and p2direction) in a vector(player_directions) indexed by the player number and using a loop access it, for example:
number_of_players = 2
playersXS = function_that_fills_playersXS() # return a vector containing your p1XS and p2XS variables in a vector
for player_number in xrange(number_of_players):
if player_directions[player_number]=='right' and playersXS[player_number]< Attributes[player_number][1]:
playersXS[player_number]+=Attributes[player_number][0]
OKay, so i wrote a code to develop a game using pygame. this is the aim of the game :
there is a player (Mario) which can move only vertically. from the right side of the window, flames appear which the mario has to dodge. the game is very similar to dodger.py !
now, when i run the game, it gets stuck at "Press any key to Enter"
PLEASE HELP !
You are not doing anything in the waitforkey() function.
if event.type == KEYDOWN:
# if key exit blah blah
else:
runGame()
You could put your game in a function called runGame and that would probabaly be the easiest way of doing this. Just remember that the variables will then be local to the scope of that function and any changes won't affect the rest of the program.
Having checked the code on a PC, I have found 3 errors. Two of which are typing errors. First one is on Line 77:
playerrect.topleft = (50,window_hight/2)
Needs to be:
playerrect.topleft = (50,window_height/2)
and the second is on line 126:
WindowSurface.fill(bgcolour)
You haven't defined bgcolour (as far as I could see) so by adding the following to the variables at the top of the file:
bgcolour(255,255,255) #change to what colour you want
The third error I found was in your waitForKey() function. I don't know whether this is important to the running of the program, but you have your if event.type == "QUIT" in speech marks. Like I said, this may not matter but I thought I'd point it out. You have also done this for the other conditions in this function.
By making these changes, you get running code. However, flames do not appear and I don't have time to figure this one out. By fiddling though, I'm sure you'll figure it out!
To download the code, follow the link:
Background:
So I've been going through pygame tutorials since I'm new to it and I found Eli Bendersky's well-known tutorial. I was going through part one and was attempting to add my own flair to it by making it "Social Cats". The cats would wander around and if they touched each other then they would graze each other and go their separate ways. In other words the same thing Eli had but with collision detection and new sprites. I figure this would be good practice. I've spent the past few days researching collision detection and how different people do it, but I've yet to see one that would work with my scenario or something similar. I'm beginning to see how small of a community I'm in.
Objective:
Ultimately, I am trying to make it so when a cat runs into another one, the one that collided will go off in a random direction that equals 45 degrees less or more than its current direction.
Problem:
I'm importing vec2d and I have my Cat class and my main. I would like to do the collision detection in the main because later on I will create a GameManager class that watches over what's going on. According to OOP, the cats shouldn't know about each other anyways. I've been having trouble getting the collision detection to work. I've tried a couple of different ways. In both ways nothing happens when they touch each other. I'm getting the impression what I'm wanting to do is way more complex than how I'm perceiving it. How am I screwing this up? I feel as if I've wasted enough time on this one aspect. Of course, that's the learning process. Thoughts?
Way 1:
mainWindow.fill(_white_)
for cat in cats:
cat.update(timePassed)
cat.blitme()
catsCollided = pg.sprite.spritecollide(cat, catGroup, True)
print pg.sprite.spritecollide(cat, catGroup, False)
for cat in catsCollided:
cat.currentDirection.angle = randint(int(cat.currentDirection.angle - 45), int(cat.currentDirection.angle + 45))
Way 2:
mainWindow.fill(_white_)
for cat in cats:
cat.update(timePassed)
cat.blitme()
print pg.sprite.spritecollide(cat, catGroup, False)
tempCatList = list(cats)
for catA in cats:
tempCatList.remove(catA)
for catB in cats:
if catA.rect.colliderect(catB.rect):
cats[cats.index(catA)].currentDirection.angle = randint(int(cat.currentDirection.angle - 45), int(cat.currentDirection.angle + 45))
Your first way is correct, however there are just a few bugs. Sprite collide is the best way to do it. First of all, there are very few circumstances when you want the third argument in sprite collide to be true, and unless I completely misunderstand how your code is doing it, you do not want to use True. When you specify True, it will automatically delete both sprites upon collision. The other thing is that you want to make sure to filter out self collisions. Basically, if a sprite runs sprite collide on itself it registers a collision with itself. One final thing about your code is that although your randint chooser might work (you may want to test what it is returning though), random.choice() would be a better fit for what you are looking for. When these changes are implemented, it looks something like this:
mainWindow.fill(_white_)
for cat in cats:
cat.update(timePassed)
cat.blitme()
catsCollided = pg.sprite.spritecollide(cat, catGroup, False) #False makes it so colliding sprites are not deleted
print pg.sprite.spritecollide(cat, catGroup, False)
for cat in catsCollided: #by the way although this is perfectly fine code, the repetition of the cat variable could be confusing
if cat != self: #checks that this is not a self collision
cat.currentDirection.angle = random.choice([int(cat.currentDirection.angle - 45), int(cat.currentDirection.angle + 45])